On Wed, Aug 21, 2024 at 1:11 PM Kris Van Hees <kris.van.hees@xxxxxxxxxx> wrote: > > The modules.builtin.ranges offset range data for builtin modules is > generated at compile time based on the list of built-in modules and > the vmlinux.map and vmlinux.o.map linker maps. This data can be used > to determine whether a symbol at a particular address belongs to > module code that was configured to be compiled into the kernel proper > as a built-in module (rather than as a standalone module). > > This patch adds a script that uses the generated modules.builtin.ranges > data to annotate the symbols in the System.map with module names if > their address falls within a range that belongs to one or more built-in > modules. > > It then processes the vmlinux.map (and if needed, vmlinux.o.map) to > verify the annotation: > > - For each top-level section: > - For each object in the section: > - Determine whether the object is part of a built-in module > (using modules.builtin and the .*.cmd file used to compile > the object as suggested in [0]) > - For each symbol in that object, verify that the built-in > module association (or lack thereof) matches the annotation > given to the symbol. > > Signed-off-by: Kris Van Hees <kris.van.hees@xxxxxxxxxx> > Reviewed-by: Nick Alcock <nick.alcock@xxxxxxxxxx> > Reviewed-by: Alan Maguire <alan.maguire@xxxxxxxxxx> > --- > Changes since v6: > - Applied Masahiro Yamada's suggestions to the AWK script. > > Changes since v5: > - Added optional 6th argument to specify kernel build directory. > - Report error and exit if .*.o.cmd files cannot be read. > > Changes since v4: > - New patch in the series > --- > scripts/verify_builtin_ranges.awk | 356 ++++++++++++++++++++++++++++++ > 1 file changed, 356 insertions(+) > create mode 100755 scripts/verify_builtin_ranges.awk > > diff --git a/scripts/verify_builtin_ranges.awk b/scripts/verify_builtin_ranges.awk > new file mode 100755 > index 000000000000..93f66e9a8802 > --- /dev/null > +++ b/scripts/verify_builtin_ranges.awk > @@ -0,0 +1,356 @@ > +#!/usr/bin/gawk -f > +# SPDX-License-Identifier: GPL-2.0 > +# verify_builtin_ranges.awk: Verify address range data for builtin modules > +# Written by Kris Van Hees <kris.van.hees@xxxxxxxxxx> > +# > +# Usage: verify_builtin_ranges.awk modules.builtin.ranges System.map \ > +# modules.builtin vmlinux.map vmlinux.o.map \ > +# [ <build-dir> ] > +# > + > +# Return the module name(s) (if any) associated with the given object. > +# > +# If we have seen this object before, return information from the cache. > +# Otherwise, retrieve it from the corresponding .cmd file. > +# > +function get_module_info(fn, mod, obj, s) { > + if (fn in omod) > + return omod[fn]; > + > + if (match(fn, /\/[^/]+$/) == 0) > + return ""; > + > + obj = fn; > + mod = ""; > + fn = kdir "/" substr(fn, 1, RSTART) "." substr(fn, RSTART + 1) ".cmd"; > + if (getline s <fn == 1) { > + if (match(s, /DKBUILD_MODFILE=['"]+[^'"]+/) > 0) { > + mod = substr(s, RSTART + 16, RLENGTH - 16); > + gsub(/['"]/, "", mod); > + } > + } else { > + print "ERROR: Failed to read: " fn "\n\n" \ > + " Invalid kernel build directory (" kdir ")\n" \ > + " or its content does not match " ARGV[1] >"/dev/stderr"; > + close(fn); > + total = 0; > + exit(1); > + } > + close(fn); > + > + # A single module (common case) also reflects objects that are not part > + # of a module. Some of those objects have names that are also a module > + # name (e.g. core). We check the associated module file name, and if > + # they do not match, the object is not part of a module. > + if (mod !~ / /) { > + if (!(mod in mods)) > + mod = ""; > + } > + > + gsub(/([^/ ]*\/)+/, "", mod); > + gsub(/-/, "_", mod); > + > + # At this point, mod is a single (valid) module name, or a list of > + # module names (that do not need validation). > + omod[obj] = mod; > + close(fn); Same as 2/4. -- Best Regards Masahiro Yamada