This emits a new file, .tmp_vmlinux.ranges, which maps address range/size pairs in vmlinux to the object files which make them up, e.g., in part: 0x0000000000000000 0x30 arch/x86/kernel/cpu/common.o 0x0000000000001000 0x1000 arch/x86/events/intel/ds.o 0x0000000000002000 0x4000 arch/x86/kernel/irq_64.o 0x0000000000006000 0x5000 arch/x86/kernel/process.o 0x000000000000b000 0x1000 arch/x86/kernel/cpu/common.o 0x000000000000c000 0x5000 arch/x86/mm/cpu_entry_area.o 0x0000000000011000 0x10 arch/x86/kernel/espfix_64.o 0x0000000000011010 0x2 arch/x86/kernel/cpu/common.o [...] This will be used by kallmodsyms to let us associate symbols with built-in modules at address-range granularity (i.e., space-efficiently), and to let us disambiguate symbols with identical name and module by annotating them with the translation unit they come from. In my simple tests this seems to work with clang too, but if I'm not sure how stable the format of clang's linker mapfiles is: if it turns out not to work in some versions, the mapfile-massaging awk script added here might need some adjustment. CONFIG_LTO_CLANG by default optimizes by working from the LTOed vmlinux.o file: but this doesn't work for kallmodsyms, as the resulting mapfile lists vmlinux.o as the source object file in all cases, ruining its attempt to disambiguate symbols using object file names. So we suppress that optimization in this case. We also suppress it when IBT is enabled, but IBT *requires* use of the intermediate vmlinux.o, since that's the .o that objtool has run over. We lift this restriction in the next commit. (There are similar problems with everything else that uses ld -r: since this amounts, in total, to a few parts of KVM on aarch64, I haven't implemented a general ld -r fix: the fix in the next commit is specific to vmlinux.o.) Signed-off-by: Nick Alcock <nick.alcock@xxxxxxxxxx> Reviewed-by: Kris Van Hees <kris.van.hees@xxxxxxxxxx> --- Notes: v6: use ${wl} where appropriate to avoid failure on UML v10: mention ultimate use in kallmodsyms, conflicts with IBT and ld -r scripts/link-vmlinux.sh | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 32e573943cf0..a40d372b1289 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -60,7 +60,10 @@ vmlinux_link() # skip output file argument shift - if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then + # kallmodsyms needs a linker mapfile that contains original object + # file names, so cannot use this optimization. + if { is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; } && \ + ! is_enabled CONFIG_KALLMODSYMS; then # Use vmlinux.o instead of performing the slow LTO link again. objs=vmlinux.o libs= @@ -94,7 +97,7 @@ vmlinux_link() ldflags="${ldflags} ${wl}--strip-debug" fi - if is_enabled CONFIG_VMLINUX_MAP; then + if is_enabled CONFIG_VMLINUX_MAP || is_enabled CONFIG_KALLMODSYMS; then ldflags="${ldflags} ${wl}-Map=${output}.map" fi @@ -144,6 +147,21 @@ kallsyms() { local kallsymopt; + # read the linker map to identify ranges of addresses: + # - for each *.o file, report address, size, pathname + # - most such lines will have four fields + # - but sometimes there is a line break after the first field + # - start reading at "Linker script and memory map" + # - stop reading at ".brk" + if is_enabled CONFIG_KALLMODSYMS; then + ${AWK} ' + /\.o$/ && start==1 { print $(NF-2), $(NF-1), $NF } + /^Linker script and memory map/ { start = 1 } + /^\.brk/ { exit(0) } + ' ${3} | sort > .tmp_vmlinux.ranges + fi + + # get kallsyms options if is_enabled CONFIG_KALLSYMS_ALL; then kallsymopt="${kallsymopt} --all-symbols" fi @@ -175,7 +193,7 @@ kallsyms_step() vmlinux_link ${kallsyms_vmlinux} "${kallsymso_prev}" ${btf_vmlinux_bin_o} mksysmap ${kallsyms_vmlinux} ${kallsyms_vmlinux}.syms - kallsyms ${kallsyms_vmlinux}.syms ${kallsyms_S} + kallsyms ${kallsyms_vmlinux}.syms ${kallsyms_S} ${kallsyms_vmlinux}.map info AS ${kallsyms_S} ${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} \ -- 2.38.0.266.g481848f278