@@ -79,6 +79,7 @@ SCCS
System.map*
TAGS
aconf
+addaddrs
af_names.h
aic7*reg.h*
aic7*reg_print.c*
@@ -1570,6 +1570,16 @@ config POSIX_TIMERS
If unsure say y.
+config KALLMODSYMS
+ default y
+ bool "Enable support for /proc/kallmodsyms" if EXPERT
+ depends on KALLSYMS
+ select VMLINUX_MAP
+ help
+ This option enables the /proc/kallmodsyms file, which unambiguously
+ maps built-in kernel symbols and their associated object files and
+ modules to addresses.
+
config PRINTK
default y
bool "Enable support for printk" if EXPERT
@@ -1,4 +1,5 @@
# SPDX-License-Identifier: GPL-2.0-only
+/addaddrs
/asn1_compiler
/bin2c
/generate_rust_target
@@ -5,6 +5,7 @@
hostprogs-always-$(CONFIG_BUILD_BIN2C) += bin2c
hostprogs-always-$(CONFIG_KALLSYMS) += kallsyms
+hostprogs-always-$(CONFIG_KALLMODSYMS) += addaddrs
hostprogs-always-$(BUILD_C_RECORDMCOUNT) += recordmcount
hostprogs-always-$(CONFIG_BUILDTIME_TABLE_SORT) += sorttable
hostprogs-always-$(CONFIG_ASN1) += asn1_compiler
@@ -27,6 +27,10 @@ ifdef CONFIG_LTO_CLANG
initcalls-lds := .tmp_initcalls.lds
endif
+ifneq ($(CONFIG_VMLINUX_MAP)$(CONFIG_KALLMODSYMS),)
+KBUILD_MAPFLAGS = -Map=$@.map
+endif
+
# objtool for vmlinux.o
# ---------------------------------------------------------------------------
#
@@ -47,7 +51,7 @@ objtool-args = $(vmlinux-objtool-args-y) --link
quiet_cmd_ld_vmlinux.o = LD $@
cmd_ld_vmlinux.o = \
$(LD) ${KBUILD_LDFLAGS} -r -o $@ \
- $(addprefix -T , $(initcalls-lds)) \
+ $(KBUILD_MAPFLAGS) $(addprefix -T , $(initcalls-lds)) \
--whole-archive vmlinux.a --no-whole-archive \
--start-group $(KBUILD_VMLINUX_LIBS) --end-group \
$(cmd_objtool)
new file mode 100644
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+/* Used only by link-vmlinux.sh */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+
+int main (void)
+{
+ int i = 0;
+ while (!feof(stdin)) {
+ uint64_t a, b;
+ int ret;
+ char *rest = NULL;
+
+ i++;
+ if ((ret = scanf("%" SCNx64 " %" SCNx64 " %m[^\n]\n", &a, &b, &rest)) < 3) {
+ fprintf(stderr,
+ "Syntax error: invalid line %i found in rangefile generation: at least three fields expected, %i converted\n", i, ret);
+ exit(1);
+ }
+
+ printf("0x%018" PRIx64 " %s\n", a+b, rest);
+ free(rest);
+ }
+ exit(0);
+}
@@ -60,10 +60,7 @@ vmlinux_link()
# skip output file argument
shift
- # 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
+ if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then
# Use vmlinux.o instead of performing the slow LTO link again.
objs=vmlinux.o
libs=
@@ -153,12 +150,31 @@ kallsyms()
# - but sometimes there is a line break after the first field
# - start reading at "Linker script and memory map"
# - stop reading at ".brk"
+ # if there is a vmlinux.o.map and LTO_CLANG or KERNEL_IBT are
+ # turned on, we have used a vmlinux -r'ed .o for linking: use this
+ # as our primary information source, but acquire section addresses
+ # from the (later) linker map we were passed in. This makes things
+ # a bit more complex, since we have to recognize and eliminate
+ # sections elided by the linker, and add together numbers larger
+ # than awk can portably handle.
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
+ if is_enabled CONFIG_LTO_CLANG || is_enabled CONFIG_X86_KERNEL_IBT; then
+ ${AWK} 'BEGIN { addresses = 1 }
+ /^Linker script and memory map/ { start = 1 }
+ !start { next }
+ { got_section = 0 }
+ /^ \./ { section = $1; got_section = 1; if (NF == 1) { getline }}
+ addresses && got_section && !(section in addrs) { addrs[section] = $2 }
+ !addresses && got_section && section in addrs { print $(NF-2), addrs[section], $(NF-1), $NF }
+ /^\.brk/ || /^\.bss\.\.brk/ { addresses = 0; start = 0; nextfile }
+ ' ${3} vmlinux.o.map | scripts/addaddrs | sort > .tmp_vmlinux.ranges
+ else
+ ${AWK} '
+ start && /\.o$/ { print $(NF-2), $(NF-1), $NF }
+ /^Linker script and memory map/ { start = 1 }
+ /^\.brk/ { exit(0) }
+ ' ${3} | sort > .tmp_vmlinux.ranges
+ fi
fi
# get kallsyms options