From 4455b6891e661e85db82ff6c18de987066b162a4 Mon Sep 17 00:00:00 2001 From: Ilie Halip Date: Fri, 26 Jul 2019 08:41:09 +0300 Subject: [PATCH] kbuild: reuse intermediate linker scripts in the final link steps ld.bfd forces `--undefined X` symbols to be added to the resulting binary even if they're never used. In contrast, ld.lld may silently discard them if they're not referenced. If a kernel exported symbol (EXPORT_SYMBOL*(X)) is not used internally, it may get stripped away by ld.lld. An obvious example is __memcat_p(), which is only used by the `stm` module. With CONFIG_STM=m, the build fails: ERROR: "__memcat_p" [drivers/hwtracing/stm/stm_core.ko] undefined! Work around this issue by reusing the intermediate linker scripts in the final link steps. Signed-off-by: Ilie Halip --- Makefile | 4 +++- scripts/Makefile.build | 2 +- scripts/link-vmlinux.sh | 14 +++++++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 3c146e8d93dc5..276657e3376f9 100644 --- a/Makefile +++ b/Makefile @@ -975,6 +975,7 @@ drivers-y := $(patsubst %/, %/built-in.a, $(drivers-y)) net-y := $(patsubst %/, %/built-in.a, $(net-y)) libs-y1 := $(patsubst %/, %/lib.a, $(libs-y)) libs-y2 := $(patsubst %/, %/built-in.a, $(filter-out %.a, $(libs-y))) +libs-lds := $(strip $(patsubst %/, %/.lib-ksyms.o.lds, $(libs-y))) virt-y := $(patsubst %/, %/built-in.a, $(virt-y)) # Externally visible symbols (used by link-vmlinux.sh) @@ -982,11 +983,12 @@ export KBUILD_VMLINUX_INIT := $(head-y) $(init-y) export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y2) $(drivers-y) $(net-y) $(virt-y) export KBUILD_VMLINUX_LIBS := $(libs-y1) export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds +export KBUILD_EXTRA_LDS := $(libs-lds) export LDFLAGS_vmlinux # used by scripts/package/Makefile export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) arch Documentation include samples scripts tools) -vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN) $(KBUILD_VMLINUX_LIBS) +vmlinux-deps := $(KBUILD_LDS) $(KBUILD_EXTRA_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN) $(KBUILD_VMLINUX_LIBS) # Recurse until adjust_autoksyms.sh is satisfied PHONY += autoksyms_recursive diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 64fac0ad32d6b..22b727bd1cca7 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -484,7 +484,7 @@ cmd_export_list = $(OBJDUMP) -h $< | \ rm -f $(dummy-object);\ echo | $(CC) $(a_flags) -c -o $(dummy-object) -x assembler -;\ $(LD) $(ld_flags) -r -o $@ -T $(ksyms-lds) $(dummy-object);\ - rm $(dummy-object) $(ksyms-lds) + rm $(dummy-object) $(obj)/lib-ksyms.o: $(lib-target) FORCE $(call if_changed,export_list) diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index c8cf45362bd6f..03d4f58a880f2 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -84,9 +84,15 @@ modpost_link() vmlinux_link() { local lds="${objtree}/${KBUILD_LDS}" + local extra_lds="" local objects if [ "${SRCARCH}" != "um" ]; then + for extra_ld in ${KBUILD_EXTRA_LDS} + do + extra_lds="$extra_lds -T ${objtree}/$extra_ld" + done + objects="--whole-archive \ built-in.a \ --no-whole-archive \ @@ -96,8 +102,13 @@ vmlinux_link() ${1}" ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \ - -T ${lds} ${objects} + -T ${lds} ${extra_lds} ${objects} else + for extra_ld in ${KBUILD_EXTRA_LDS} + do + extra_lds="$extra_lds -Wl,-T,${objtree}/$extra_ld" + done + objects="-Wl,--whole-archive \ built-in.a \ -Wl,--no-whole-archive \ @@ -108,6 +119,7 @@ vmlinux_link() ${CC} ${CFLAGS_vmlinux} -o ${2} \ -Wl,-T,${lds} \ + ${extra_lds} \ ${objects} \ -lutil -lrt -lpthread rm -f linux