[PATCH v2 11/13] kbuild: always postpone CRC links for module versioning
From: Masahiro Yamada
Date: Tue Aug 31 2021 - 03:41:37 EST
When CONFIG_MODVERSIONS=y, the CRCs of EXPORT_SYMBOL are linked into
*.o files in-place.
It is impossible for Clang LTO because *.o files are not ELF, but LLVM
bitcode. The CRCs are stored in separate *.symversions files, and then
supplied to the modpost link.
Let's do so for CONFIG_LTO_CLANG=n, and unify the module versioning code.
Signed-off-by: Masahiro Yamada <masahiroy@xxxxxxxxxx>
Reviewed-by: Kees Cook <keescook@xxxxxxxxxxxx>
---
scripts/Makefile.build | 32 ++++++--------------------------
scripts/link-vmlinux.sh | 22 ++++++++++++++--------
2 files changed, 20 insertions(+), 34 deletions(-)
diff --git a/scripts/Makefile.build b/scripts/Makefile.build
index b94dfc87b7fa..50a6765c9a14 100644
--- a/scripts/Makefile.build
+++ b/scripts/Makefile.build
@@ -158,17 +158,12 @@ quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
ifdef CONFIG_MODVERSIONS
# When module versioning is enabled the following steps are executed:
# o compile a <file>.o from <file>.c
-# o if <file>.o doesn't contain a __ksymtab version, i.e. does
-# not export symbols, it's done.
+# o if <file>.o doesn't contain __ksymtab* symbols, i.e. does
+# not export symbols, create an empty *.symversions
# o otherwise, we calculate symbol versions using the good old
# genksyms on the preprocessed source and postprocess them in a way
# that they are usable as a linker script
-# o generate .tmp_<file>.o from <file>.o using the linker to
-# replace the unresolved symbols __crc_exported_symbol with
-# the actual value of the checksum generated by genksyms
-# o remove .tmp_<file>.o to <file>.o
-ifdef CONFIG_LTO_CLANG
# Generate .o.symversions files for each .o with exported symbols, and link these
# to the kernel and/or modules at the end.
cmd_modversions_c = \
@@ -178,18 +173,6 @@ cmd_modversions_c = \
else \
rm -f $@.symversions; \
fi;
-else
-cmd_modversions_c = \
- if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
- $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
- > $(@D)/.tmp_$(@F:.o=.ver); \
- \
- $(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \
- -T $(@D)/.tmp_$(@F:.o=.ver); \
- mv -f $(@D)/.tmp_$(@F) $@; \
- rm -f $(@D)/.tmp_$(@F:.o=.ver); \
- fi
-endif
endif
ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
@@ -358,12 +341,9 @@ ifdef CONFIG_ASM_MODVERSIONS
cmd_modversions_S = \
if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
$(call cmd_gensymtypes_S,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
- > $(@D)/.tmp_$(@F:.o=.ver); \
- \
- $(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \
- -T $(@D)/.tmp_$(@F:.o=.ver); \
- mv -f $(@D)/.tmp_$(@F) $@; \
- rm -f $(@D)/.tmp_$(@F:.o=.ver); \
+ > $@.symversions; \
+ else \
+ rm -rf $@.symversions; \
fi
endif
@@ -434,7 +414,7 @@ $(obj)/lib.a: $(lib-y) FORCE
# Rule to prelink modules
#
-ifeq ($(CONFIG_LTO_CLANG) $(CONFIG_MODVERSIONS),y y)
+ifdef CONFIG_MODVERSIONS
cmd_merge_symver = $(PERL) scripts/merge-symvers.pl -a $(AR) -o $@ $<
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index 0cc6a03f2cb1..366af3a9d039 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -52,8 +52,7 @@ gen_initcalls()
> .tmp_initcalls.lds
}
-# If CONFIG_LTO_CLANG is selected, collect generated symbol versions into
-# .tmp_symversions.lds
+# Collect generated symbol versions into .tmp_symversions.lds
gen_symversions()
{
info GEN .tmp_symversions.lds
@@ -75,14 +74,13 @@ modpost_link()
${KBUILD_VMLINUX_LIBS} \
--end-group"
+ if [ -n "${CONFIG_MODVERSIONS}" ]; then
+ lds="${lds} -T .tmp_symversions.lds"
+ fi
+
if [ -n "${CONFIG_LTO_CLANG}" ]; then
gen_initcalls
- lds="-T .tmp_initcalls.lds"
-
- if [ -n "${CONFIG_MODVERSIONS}" ]; then
- gen_symversions
- lds="${lds} -T .tmp_symversions.lds"
- fi
+ lds="${lds} -T .tmp_initcalls.lds"
# This might take a while, so indicate that we're doing
# an LTO link
@@ -179,6 +177,10 @@ vmlinux_link()
ldflags="${ldflags} ${wl}--script=${objtree}/${KBUILD_LDS}"
+ if [ -n "${CONFIG_MODVERSIONS}" ]; then
+ ldflags="${ldflags} ${wl}--script=.tmp_symversions.lds"
+ fi
+
# The kallsyms linking does not need debug symbols included.
if [ "$output" != "${output#.tmp_vmlinux.kallsyms}" ] ; then
ldflags="${ldflags} ${wl}--strip-debug"
@@ -332,6 +334,10 @@ fi;
# final build of init/
${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1
+if [ -n "${CONFIG_MODVERSIONS}" ]; then
+ gen_symversions
+fi
+
#link vmlinux.o
modpost_link vmlinux.o
objtool_link vmlinux.o
--
2.30.2