History

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.

Sami Tolvanen committed 5 years ago

Commit 38e89181 parent dc5723b6 files · +61 −6Browse files

Showing the changes to scripts (3 of 6 files). Show all

Unified · Split

3 files
  1. scripts/Makefile.build +31 −2
  2. scripts/Makefile.modpost +5 −1
  3. scripts/link-vmlinux.sh +22 −1
scripts/Makefile.build+31−2
@@ -166,6 +166,15 @@ ifdef CONFIG_MODVERSIONS · 165 unmodified lines
166166 # the actual value of the checksum generated by genksyms
167167 # o remove .tmp_<file>.o to <file>.o
168168
169+ifdef CONFIG_LTO_CLANG
170+# Generate .o.symversions files for each .o with exported symbols, and link these
171+# to the kernel and/or modules at the end.
172+cmd_modversions_c = \
173+ if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then \
174+ $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
175+ > $@.symversions; \
176+ fi;
177+else
169178 cmd_modversions_c = \
170179 if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
171180 $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
@@ -177,6 +186,7 @@ cmd_modversions_c = \ · 5 unmodified lines
177186 rm -f $(@D)/.tmp_$(@F:.o=.ver); \
178187 fi
179188 endif
189+endif
180190
181191 ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
182192 # 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 · 203 unmodified lines
386396 $(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ;
387397 $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ;
388398
399+# combine symversions for later processing
400+quiet_cmd_update_lto_symversions = SYMVER $@
401+ifeq ($(CONFIG_LTO_CLANG) $(CONFIG_MODVERSIONS),y y)
402+ cmd_update_lto_symversions = \
403+ rm -f $@.symversions \
404+ $(foreach n, $(filter-out FORCE,$^), \
405+ $(if $(wildcard $(n).symversions), \
406+ ; cat $(n).symversions >> $@.symversions))
407+else
408+ cmd_update_lto_symversions = echo >/dev/null
409+endif
410+
389411 #
390412 # Rule to compile a set of .o files into one .a file (without symbol table)
391413 #
@@ -393,8 +415,11 @@ $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; · 1 unmodified line
393415 quiet_cmd_ar_builtin = AR $@
394416 cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs)
395417
418+quiet_cmd_ar_and_symver = AR $@
419+ cmd_ar_and_symver = $(cmd_update_lto_symversions); $(cmd_ar_builtin)
420+
396421 $(obj)/built-in.a: $(real-obj-y) FORCE
397− $(call if_changed,ar_builtin)
422+ $(call if_changed,ar_and_symver)
398423
399424 #
400425 # Rule to create modules.order file
@@ -414,8 +439,11 @@ $(obj)/modules.order: $(obj-m) FORCE · 13 unmodified lines
414439 #
415440 # Rule to compile a set of .o files into one .a file (with symbol table)
416441 #
442+quiet_cmd_ar_lib = AR $@
443+ cmd_ar_lib = $(cmd_update_lto_symversions); $(cmd_ar)
444+
417445 $(obj)/lib.a: $(lib-y) FORCE
418− $(call if_changed,ar)
446+ $(call if_changed,ar_lib)
419447
420448 # NOTE:
421449 # Do not replace $(filter %.o,^) with $(real-prereqs). When a single object
@@ -424,6 +452,7 @@ $(obj)/lib.a: $(lib-y) FORCE · 2 unmodified lines
424452 ifdef CONFIG_LTO_CLANG
425453 quiet_cmd_link_multi-m = AR [M] $@
426454 cmd_link_multi-m = \
455+ $(cmd_update_lto_symversions); \
427456 rm -f $@; \
428457 $(AR) cDPrsT $@ $(filter %.o,$^)
429458 else
scripts/Makefile.modpost+5−1
@@ -111,7 +111,11 @@ ifdef CONFIG_LTO_CLANG · 110 unmodified lines
111111 prelink-ext := .lto
112112
113113 quiet_cmd_cc_lto_link_modules = LTO [M] $@
114−cmd_cc_lto_link_modules = $(LD) $(ld_flags) -r -o $@ --whole-archive $^
114+cmd_cc_lto_link_modules = \
115+ $(LD) $(ld_flags) -r -o $@ \
116+ $(shell [ -s $(@:.lto.o=.o.symversions) ] && \
117+ echo -T $(@:.lto.o=.o.symversions)) \
118+ --whole-archive $^
115119
116120 %.lto.o: %.o
117121 $(call if_changed,cc_lto_link_modules)
scripts/link-vmlinux.sh+22−1
@@ -43,11 +43,26 @@ info() · 42 unmodified lines
4343 fi
4444 }
4545
46+# If CONFIG_LTO_CLANG is selected, collect generated symbol versions into
47+# .tmp_symversions.lds
48+gen_symversions()
49+{
50+ info GEN .tmp_symversions.lds
51+ rm -f .tmp_symversions.lds
52+
53+ for o in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do
54+ if [ -f ${o}.symversions ]; then
55+ cat ${o}.symversions >> .tmp_symversions.lds
56+ fi
57+ done
58+}
59+
4660 # Link of vmlinux.o used for section mismatch analysis
4761 # ${1} output file
4862 modpost_link()
4963 {
5064 local objects
65+ local lds=""
5166
5267 objects="--whole-archive \
5368 ${KBUILD_VMLINUX_OBJS} \
@@ -57,6 +72,11 @@ modpost_link() · 3 unmodified lines
5772 --end-group"
5873
5974 if [ -n "${CONFIG_LTO_CLANG}" ]; then
75+ if [ -n "${CONFIG_MODVERSIONS}" ]; then
76+ gen_symversions
77+ lds="${lds} -T .tmp_symversions.lds"
78+ fi
79+
6080 # This might take a while, so indicate that we're doing
6181 # an LTO link
6282 info LTO ${1}
@@ -64,7 +84,7 @@ modpost_link() · 1 unmodified line
6484 info LD ${1}
6585 fi
6686
67− ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${objects}
87+ ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${lds} ${objects}
6888 }
6989
7090 objtool_link()
@@ -242,6 +262,7 @@ cleanup() · 171 unmodified lines
242262 {
243263 rm -f .btf.*
244264 rm -f .tmp_System.map
265+ rm -f .tmp_symversions.lds
245266 rm -f .tmp_vmlinux*
246267 rm -f System.map
247268 rm -f vmlinux