kbuild: lto: fix module versioning
With CONFIG_MODVERSIONS, version information is linked into each compilation unit that exports symbols. With LTO, we cannot use this method as all C code is compiled into LLVM bitcode instead. This change collects symbol versions into .symversions files and merges them in link-vmlinux.sh where they are all linked into vmlinux.o at the same time. Signed-off-by: Sami Tolvanen <samitolvanen@google.com> Reviewed-by: Kees Cook <keescook@chromium.org> Signed-off-by: Kees Cook <keescook@chromium.org> Link: https://lore.kernel.org/r/20201211184633.3213045-4-samitolvanen@google.com
This commit is contained in:
parent
dc5723b02e
commit
38e8918490
|
@ -41,6 +41,7 @@
|
|||
*.so.dbg
|
||||
*.su
|
||||
*.symtypes
|
||||
*.symversions
|
||||
*.tab.[ch]
|
||||
*.tar
|
||||
*.xz
|
||||
|
|
3
Makefile
3
Makefile
|
@ -1837,7 +1837,8 @@ clean: $(clean-dirs)
|
|||
-o -name '.tmp_*.o.*' \
|
||||
-o -name '*.c.[012]*.*' \
|
||||
-o -name '*.ll' \
|
||||
-o -name '*.gcno' \) -type f -print | xargs rm -f
|
||||
-o -name '*.gcno' \
|
||||
-o -name '*.*.symversions' \) -type f -print | xargs rm -f
|
||||
|
||||
# Generate tags for editors
|
||||
# ---------------------------------------------------------------------------
|
||||
|
|
|
@ -668,7 +668,6 @@ config HAS_LTO_CLANG
|
|||
depends on !FTRACE_MCOUNT_USE_RECORDMCOUNT
|
||||
depends on !KASAN
|
||||
depends on !GCOV_KERNEL
|
||||
depends on !MODVERSIONS
|
||||
help
|
||||
The compiler and Kconfig options support building with Clang's
|
||||
LTO.
|
||||
|
|
|
@ -166,6 +166,15 @@ ifdef CONFIG_MODVERSIONS
|
|||
# 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 = \
|
||||
if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then \
|
||||
$(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
|
||||
> $@.symversions; \
|
||||
fi;
|
||||
else
|
||||
cmd_modversions_c = \
|
||||
if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
|
||||
$(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
|
||||
|
@ -177,6 +186,7 @@ cmd_modversions_c = \
|
|||
rm -f $(@D)/.tmp_$(@F:.o=.ver); \
|
||||
fi
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
|
||||
# compiler will not generate __mcount_loc use recordmcount or recordmcount.pl
|
||||
|
@ -386,6 +396,18 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler
|
|||
$(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ;
|
||||
$(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ;
|
||||
|
||||
# combine symversions for later processing
|
||||
quiet_cmd_update_lto_symversions = SYMVER $@
|
||||
ifeq ($(CONFIG_LTO_CLANG) $(CONFIG_MODVERSIONS),y y)
|
||||
cmd_update_lto_symversions = \
|
||||
rm -f $@.symversions \
|
||||
$(foreach n, $(filter-out FORCE,$^), \
|
||||
$(if $(wildcard $(n).symversions), \
|
||||
; cat $(n).symversions >> $@.symversions))
|
||||
else
|
||||
cmd_update_lto_symversions = echo >/dev/null
|
||||
endif
|
||||
|
||||
#
|
||||
# Rule to compile a set of .o files into one .a file (without symbol table)
|
||||
#
|
||||
|
@ -393,8 +415,11 @@ $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ;
|
|||
quiet_cmd_ar_builtin = AR $@
|
||||
cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs)
|
||||
|
||||
quiet_cmd_ar_and_symver = AR $@
|
||||
cmd_ar_and_symver = $(cmd_update_lto_symversions); $(cmd_ar_builtin)
|
||||
|
||||
$(obj)/built-in.a: $(real-obj-y) FORCE
|
||||
$(call if_changed,ar_builtin)
|
||||
$(call if_changed,ar_and_symver)
|
||||
|
||||
#
|
||||
# Rule to create modules.order file
|
||||
|
@ -414,8 +439,11 @@ $(obj)/modules.order: $(obj-m) FORCE
|
|||
#
|
||||
# Rule to compile a set of .o files into one .a file (with symbol table)
|
||||
#
|
||||
quiet_cmd_ar_lib = AR $@
|
||||
cmd_ar_lib = $(cmd_update_lto_symversions); $(cmd_ar)
|
||||
|
||||
$(obj)/lib.a: $(lib-y) FORCE
|
||||
$(call if_changed,ar)
|
||||
$(call if_changed,ar_lib)
|
||||
|
||||
# NOTE:
|
||||
# Do not replace $(filter %.o,^) with $(real-prereqs). When a single object
|
||||
|
@ -424,6 +452,7 @@ $(obj)/lib.a: $(lib-y) FORCE
|
|||
ifdef CONFIG_LTO_CLANG
|
||||
quiet_cmd_link_multi-m = AR [M] $@
|
||||
cmd_link_multi-m = \
|
||||
$(cmd_update_lto_symversions); \
|
||||
rm -f $@; \
|
||||
$(AR) cDPrsT $@ $(filter %.o,$^)
|
||||
else
|
||||
|
|
|
@ -111,7 +111,11 @@ ifdef CONFIG_LTO_CLANG
|
|||
prelink-ext := .lto
|
||||
|
||||
quiet_cmd_cc_lto_link_modules = LTO [M] $@
|
||||
cmd_cc_lto_link_modules = $(LD) $(ld_flags) -r -o $@ --whole-archive $^
|
||||
cmd_cc_lto_link_modules = \
|
||||
$(LD) $(ld_flags) -r -o $@ \
|
||||
$(shell [ -s $(@:.lto.o=.o.symversions) ] && \
|
||||
echo -T $(@:.lto.o=.o.symversions)) \
|
||||
--whole-archive $^
|
||||
|
||||
%.lto.o: %.o
|
||||
$(call if_changed,cc_lto_link_modules)
|
||||
|
|
|
@ -43,11 +43,26 @@ info()
|
|||
fi
|
||||
}
|
||||
|
||||
# If CONFIG_LTO_CLANG is selected, collect generated symbol versions into
|
||||
# .tmp_symversions.lds
|
||||
gen_symversions()
|
||||
{
|
||||
info GEN .tmp_symversions.lds
|
||||
rm -f .tmp_symversions.lds
|
||||
|
||||
for o in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do
|
||||
if [ -f ${o}.symversions ]; then
|
||||
cat ${o}.symversions >> .tmp_symversions.lds
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Link of vmlinux.o used for section mismatch analysis
|
||||
# ${1} output file
|
||||
modpost_link()
|
||||
{
|
||||
local objects
|
||||
local lds=""
|
||||
|
||||
objects="--whole-archive \
|
||||
${KBUILD_VMLINUX_OBJS} \
|
||||
|
@ -57,6 +72,11 @@ modpost_link()
|
|||
--end-group"
|
||||
|
||||
if [ -n "${CONFIG_LTO_CLANG}" ]; then
|
||||
if [ -n "${CONFIG_MODVERSIONS}" ]; then
|
||||
gen_symversions
|
||||
lds="${lds} -T .tmp_symversions.lds"
|
||||
fi
|
||||
|
||||
# This might take a while, so indicate that we're doing
|
||||
# an LTO link
|
||||
info LTO ${1}
|
||||
|
@ -64,7 +84,7 @@ modpost_link()
|
|||
info LD ${1}
|
||||
fi
|
||||
|
||||
${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${objects}
|
||||
${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${lds} ${objects}
|
||||
}
|
||||
|
||||
objtool_link()
|
||||
|
@ -242,6 +262,7 @@ cleanup()
|
|||
{
|
||||
rm -f .btf.*
|
||||
rm -f .tmp_System.map
|
||||
rm -f .tmp_symversions.lds
|
||||
rm -f .tmp_vmlinux*
|
||||
rm -f System.map
|
||||
rm -f vmlinux
|
||||
|
|
Loading…
Reference in New Issue