Skip to content

Commit 5f5e734

Browse files
kvanheesmasahir0y
authored andcommitted
kbuild: generate offset range data for builtin modules
Create file module.builtin.ranges that can be used to find where built-in modules are located by their addresses. This will be useful for tracing tools to find what functions are for various built-in modules. The offset range data for builtin modules is generated using: - modules.builtin: associates object files with module names - vmlinux.map: provides load order of sections and offset of first member per section - vmlinux.o.map: provides offset of object file content per section - .*.cmd: build cmd file with KBUILD_MODFILE The generated data will look like: .text 00000000-00000000 = _text .text 0000baf0-0000cb10 amd_uncore .text 0009bd10-0009c8e0 iosf_mbi ... .text 00b9f080-00ba011a intel_skl_int3472_discrete .text 00ba0120-00ba03c0 intel_skl_int3472_discrete intel_skl_int3472_tps68470 .text 00ba03c0-00ba08d6 intel_skl_int3472_tps68470 ... .data 00000000-00000000 = _sdata .data 0000f020-0000f680 amd_uncore For each ELF section, it lists the offset of the first symbol. This can be used to determine the base address of the section at runtime. Next, it lists (in strict ascending order) offset ranges in that section that cover the symbols of one or more builtin modules. Multiple ranges can apply to a single module, and ranges can be shared between modules. The CONFIG_BUILTIN_MODULE_RANGES option controls whether offset range data is generated for kernel modules that are built into the kernel image. How it works: 1. The modules.builtin file is parsed to obtain a list of built-in module names and their associated object names (the .ko file that the module would be in if it were a loadable module, hereafter referred to as <kmodfile>). This object name can be used to identify objects in the kernel compile because any C or assembler code that ends up into a built-in module will have the option -DKBUILD_MODFILE=<kmodfile> present in its build command, and those can be found in the .<obj>.cmd file in the kernel build tree. If an object is part of multiple modules, they will all be listed in the KBUILD_MODFILE option argument. This allows us to conclusively determine whether an object in the kernel build belong to any modules, and which. 2. The vmlinux.map is parsed next to determine the base address of each top level section so that all addresses into the section can be turned into offsets. This makes it possible to handle sections getting loaded at different addresses at system boot. We also determine an 'anchor' symbol at the beginning of each section to make it possible to calculate the true base address of a section at runtime (i.e. symbol address - symbol offset). We collect start addresses of sections that are included in the top level section. This is used when vmlinux is linked using vmlinux.o, because in that case, we need to look at the vmlinux.o linker map to know what object a symbol is found in. And finally, we process each symbol that is listed in vmlinux.map (or vmlinux.o.map) based on the following structure: vmlinux linked from vmlinux.a: vmlinux.map: <top level section> <included section> -- might be same as top level section) <object> -- built-in association known <symbol> -- belongs to module(s) object belongs to ... vmlinux linked from vmlinux.o: vmlinux.map: <top level section> <included section> -- might be same as top level section) vmlinux.o -- need to use vmlinux.o.map <symbol> -- ignored ... vmlinux.o.map: <section> <object> -- built-in association known <symbol> -- belongs to module(s) object belongs to ... 3. As sections, objects, and symbols are processed, offset ranges are constructed in a straight-forward way: - If the symbol belongs to one or more built-in modules: - If we were working on the same module(s), extend the range to include this object - If we were working on another module(s), close that range, and start the new one - If the symbol does not belong to any built-in modules: - If we were working on a module(s) range, close that range Signed-off-by: Kris Van Hees <kris.van.hees@oracle.com> Reviewed-by: Nick Alcock <nick.alcock@oracle.com> Reviewed-by: Alan Maguire <alan.maguire@oracle.com> Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org> Tested-by: Sam James <sam@gentoo.org> Reviewed-by: Sami Tolvanen <samitolvanen@google.com> Tested-by: Sami Tolvanen <samitolvanen@google.com> Signed-off-by: Masahiro Yamada <masahiroy@kernel.org>
1 parent 23d93aa commit 5f5e734

File tree

9 files changed

+559
-0
lines changed

9 files changed

+559
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ modules.order
6969
/Module.markers
7070
/modules.builtin
7171
/modules.builtin.modinfo
72+
/modules.builtin.ranges
7273
/modules.nsdeps
7374

7475
#

Documentation/dontdiff

+1
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ modpost
180180
modules-only.symvers
181181
modules.builtin
182182
modules.builtin.modinfo
183+
modules.builtin.ranges
183184
modules.nsdeps
184185
modules.order
185186
modversions.h*

Documentation/kbuild/kbuild.rst

+5
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ modules.builtin.modinfo
2222
This file contains modinfo from all modules that are built into the kernel.
2323
Unlike modinfo of a separate module, all fields are prefixed with module name.
2424

25+
modules.builtin.ranges
26+
----------------------
27+
This file contains address offset ranges (per ELF section) for all modules
28+
that are built into the kernel. Together with System.map, it can be used
29+
to associate module names with symbols.
2530

2631
Environment variables
2732
=====================

Documentation/process/changes.rst

+7
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ GNU tar 1.28 tar --version
6464
gtags (optional) 6.6.5 gtags --version
6565
mkimage (optional) 2017.01 mkimage --version
6666
Python (optional) 3.5.x python3 --version
67+
GNU AWK (optional) 5.1.0 gawk --version
6768
====================== =============== ========================================
6869

6970
.. [#f1] Sphinx is needed only to build the Kernel documentation
@@ -192,6 +193,12 @@ platforms. The tool is available via the ``u-boot-tools`` package or can be
192193
built from the U-Boot source code. See the instructions at
193194
https://docs.u-boot.org/en/latest/build/tools.html#building-tools-for-linux
194195

196+
GNU AWK
197+
-------
198+
199+
GNU AWK is needed if you want kernel builds to generate address range data for
200+
builtin modules (CONFIG_BUILTIN_MODULE_RANGES).
201+
195202
System utilities
196203
****************
197204

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -1482,6 +1482,7 @@ endif # CONFIG_MODULES
14821482
# Directories & files removed with 'make clean'
14831483
CLEAN_FILES += vmlinux.symvers modules-only.symvers \
14841484
modules.builtin modules.builtin.modinfo modules.nsdeps \
1485+
modules.builtin.ranges vmlinux.o.map \
14851486
compile_commands.json rust/test \
14861487
rust-project.json .vmlinux.objs .vmlinux.export.c
14871488

lib/Kconfig.debug

+15
Original file line numberDiff line numberDiff line change
@@ -571,6 +571,21 @@ config VMLINUX_MAP
571571
pieces of code get eliminated with
572572
CONFIG_LD_DEAD_CODE_DATA_ELIMINATION.
573573

574+
config BUILTIN_MODULE_RANGES
575+
bool "Generate address range information for builtin modules"
576+
depends on !LTO
577+
depends on VMLINUX_MAP
578+
help
579+
When modules are built into the kernel, there will be no module name
580+
associated with its symbols in /proc/kallsyms. Tracers may want to
581+
identify symbols by module name and symbol name regardless of whether
582+
the module is configured as loadable or not.
583+
584+
This option generates modules.builtin.ranges in the build tree with
585+
offset ranges (per ELF section) for the module(s) they belong to.
586+
It also records an anchor symbol to determine the load address of the
587+
section.
588+
574589
config DEBUG_FORCE_WEAK_PER_CPU
575590
bool "Force weak per-cpu definitions"
576591
depends on DEBUG_KERNEL

scripts/Makefile.vmlinux

+18
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,24 @@ targets += vmlinux
3333
vmlinux: scripts/link-vmlinux.sh vmlinux.o $(KBUILD_LDS) FORCE
3434
+$(call if_changed_dep,link_vmlinux)
3535

36+
# module.builtin.ranges
37+
# ---------------------------------------------------------------------------
38+
ifdef CONFIG_BUILTIN_MODULE_RANGES
39+
__default: modules.builtin.ranges
40+
41+
quiet_cmd_modules_builtin_ranges = GEN $@
42+
cmd_modules_builtin_ranges = gawk -f $(real-prereqs) > $@
43+
44+
targets += modules.builtin.ranges
45+
modules.builtin.ranges: $(srctree)/scripts/generate_builtin_ranges.awk \
46+
modules.builtin vmlinux.map vmlinux.o.map FORCE
47+
$(call if_changed,modules_builtin_ranges)
48+
49+
vmlinux.map: vmlinux
50+
@:
51+
52+
endif
53+
3654
# Add FORCE to the prerequisites of a target to force it to be always rebuilt.
3755
# ---------------------------------------------------------------------------
3856

scripts/Makefile.vmlinux_o

+3
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,12 @@ objtool-args = $(vmlinux-objtool-args-y) --link
4545
# Link of vmlinux.o used for section mismatch analysis
4646
# ---------------------------------------------------------------------------
4747

48+
vmlinux-o-ld-args-$(CONFIG_BUILTIN_MODULE_RANGES) += -Map=$@.map
49+
4850
quiet_cmd_ld_vmlinux.o = LD $@
4951
cmd_ld_vmlinux.o = \
5052
$(LD) ${KBUILD_LDFLAGS} -r -o $@ \
53+
$(vmlinux-o-ld-args-y) \
5154
$(addprefix -T , $(initcalls-lds)) \
5255
--whole-archive vmlinux.a --no-whole-archive \
5356
--start-group $(KBUILD_VMLINUX_LIBS) --end-group \

0 commit comments

Comments
 (0)