mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
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
1
.gitignore
vendored
1
.gitignore
vendored
@ -41,6 +41,7 @@
|
|||||||
*.so.dbg
|
*.so.dbg
|
||||||
*.su
|
*.su
|
||||||
*.symtypes
|
*.symtypes
|
||||||
|
*.symversions
|
||||||
*.tab.[ch]
|
*.tab.[ch]
|
||||||
*.tar
|
*.tar
|
||||||
*.xz
|
*.xz
|
||||||
|
3
Makefile
3
Makefile
@ -1837,7 +1837,8 @@ clean: $(clean-dirs)
|
|||||||
-o -name '.tmp_*.o.*' \
|
-o -name '.tmp_*.o.*' \
|
||||||
-o -name '*.c.[012]*.*' \
|
-o -name '*.c.[012]*.*' \
|
||||||
-o -name '*.ll' \
|
-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
|
# Generate tags for editors
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
@ -668,7 +668,6 @@ config HAS_LTO_CLANG
|
|||||||
depends on !FTRACE_MCOUNT_USE_RECORDMCOUNT
|
depends on !FTRACE_MCOUNT_USE_RECORDMCOUNT
|
||||||
depends on !KASAN
|
depends on !KASAN
|
||||||
depends on !GCOV_KERNEL
|
depends on !GCOV_KERNEL
|
||||||
depends on !MODVERSIONS
|
|
||||||
help
|
help
|
||||||
The compiler and Kconfig options support building with Clang's
|
The compiler and Kconfig options support building with Clang's
|
||||||
LTO.
|
LTO.
|
||||||
|
@ -166,6 +166,15 @@ ifdef CONFIG_MODVERSIONS
|
|||||||
# the actual value of the checksum generated by genksyms
|
# the actual value of the checksum generated by genksyms
|
||||||
# o remove .tmp_<file>.o to <file>.o
|
# 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 = \
|
cmd_modversions_c = \
|
||||||
if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
|
if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
|
||||||
$(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
|
$(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
|
||||||
@ -177,6 +186,7 @@ cmd_modversions_c = \
|
|||||||
rm -f $(@D)/.tmp_$(@F:.o=.ver); \
|
rm -f $(@D)/.tmp_$(@F:.o=.ver); \
|
||||||
fi
|
fi
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
|
ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
|
||||||
# compiler will not generate __mcount_loc use recordmcount or recordmcount.pl
|
# 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-builtin): $(obj)/%/built-in.a: $(obj)/% ;
|
||||||
$(subdir-modorder): $(obj)/%/modules.order: $(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)
|
# 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 $@
|
quiet_cmd_ar_builtin = AR $@
|
||||||
cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs)
|
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
|
$(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
|
# 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)
|
# 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
|
$(obj)/lib.a: $(lib-y) FORCE
|
||||||
$(call if_changed,ar)
|
$(call if_changed,ar_lib)
|
||||||
|
|
||||||
# NOTE:
|
# NOTE:
|
||||||
# Do not replace $(filter %.o,^) with $(real-prereqs). When a single object
|
# 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
|
ifdef CONFIG_LTO_CLANG
|
||||||
quiet_cmd_link_multi-m = AR [M] $@
|
quiet_cmd_link_multi-m = AR [M] $@
|
||||||
cmd_link_multi-m = \
|
cmd_link_multi-m = \
|
||||||
|
$(cmd_update_lto_symversions); \
|
||||||
rm -f $@; \
|
rm -f $@; \
|
||||||
$(AR) cDPrsT $@ $(filter %.o,$^)
|
$(AR) cDPrsT $@ $(filter %.o,$^)
|
||||||
else
|
else
|
||||||
|
@ -111,7 +111,11 @@ ifdef CONFIG_LTO_CLANG
|
|||||||
prelink-ext := .lto
|
prelink-ext := .lto
|
||||||
|
|
||||||
quiet_cmd_cc_lto_link_modules = LTO [M] $@
|
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
|
%.lto.o: %.o
|
||||||
$(call if_changed,cc_lto_link_modules)
|
$(call if_changed,cc_lto_link_modules)
|
||||||
|
@ -43,11 +43,26 @@ info()
|
|||||||
fi
|
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
|
# Link of vmlinux.o used for section mismatch analysis
|
||||||
# ${1} output file
|
# ${1} output file
|
||||||
modpost_link()
|
modpost_link()
|
||||||
{
|
{
|
||||||
local objects
|
local objects
|
||||||
|
local lds=""
|
||||||
|
|
||||||
objects="--whole-archive \
|
objects="--whole-archive \
|
||||||
${KBUILD_VMLINUX_OBJS} \
|
${KBUILD_VMLINUX_OBJS} \
|
||||||
@ -57,6 +72,11 @@ modpost_link()
|
|||||||
--end-group"
|
--end-group"
|
||||||
|
|
||||||
if [ -n "${CONFIG_LTO_CLANG}" ]; then
|
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
|
# This might take a while, so indicate that we're doing
|
||||||
# an LTO link
|
# an LTO link
|
||||||
info LTO ${1}
|
info LTO ${1}
|
||||||
@ -64,7 +84,7 @@ modpost_link()
|
|||||||
info LD ${1}
|
info LD ${1}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${objects}
|
${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${lds} ${objects}
|
||||||
}
|
}
|
||||||
|
|
||||||
objtool_link()
|
objtool_link()
|
||||||
@ -242,6 +262,7 @@ cleanup()
|
|||||||
{
|
{
|
||||||
rm -f .btf.*
|
rm -f .btf.*
|
||||||
rm -f .tmp_System.map
|
rm -f .tmp_System.map
|
||||||
|
rm -f .tmp_symversions.lds
|
||||||
rm -f .tmp_vmlinux*
|
rm -f .tmp_vmlinux*
|
||||||
rm -f System.map
|
rm -f System.map
|
||||||
rm -f vmlinux
|
rm -f vmlinux
|
||||||
|
Loading…
Reference in New Issue
Block a user