Commit 38e89184 authored by Sami Tolvanen's avatar Sami Tolvanen Committed by Kees Cook
Browse files

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: default avatarSami Tolvanen <samitolvanen@google.com>
Reviewed-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20201211184633.3213045-4-samitolvanen@google.com
parent dc5723b0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
*.so.dbg
*.su
*.symtypes
*.symversions
*.tab.[ch]
*.tar
*.xz
+2 −1
Original line number Diff line number Diff line
@@ -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
# ---------------------------------------------------------------------------
+0 −1
Original line number Diff line number Diff line
@@ -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.
+31 −2
Original line number Diff line number Diff line
@@ -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
+5 −1
Original line number Diff line number Diff line
@@ -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)
Loading