History

Merge tag 'clang-lto-v5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux

Pull clang LTO updates from Kees Cook: "Clang Link Time Optimization. This is built on the work done preparing for LTO by arm64 folks, tracing folks, etc. This includes the core changes as well as the remaining pieces for arm64 (LTO has been the default build method on Android for about 3 years now, as it is the prerequisite for the Control Flow Integrity protections). While x86 LTO enablement is done, it depends on some pending objtool clean-ups. It's possible that I'll send a "part 2" pull request for LTO that includes x86 support. For merge log posterity, and as detailed in commit dc5723b02e52 ("kbuild: add support for Clang LTO"), here is the lt;dr to do an LTO build: make LLVM=1 LLVM_IAS=1 defconfig scripts/config -e LTO_CLANG_THIN make LLVM=1 LLVM_IAS=1 (To do a cross-compile of arm64, add "CROSS_COMPILE=aarch64-linux-gnu-" and "ARCH=arm64" to the "make" command lines.) Summary: - Clang LTO build infrastructure and arm64-specific enablement (Sami Tolvanen) - Recursive build CC_FLAGS_LTO fix (Alexander Lobakin)" * tag 'clang-lto-v5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: kbuild: prevent CC_FLAGS_LTO self-bloating on recursive rebuilds arm64: allow LTO to be selected arm64: disable recordmcount with DYNAMIC_FTRACE_WITH_REGS arm64: vdso: disable LTO drivers/misc/lkdtm: disable LTO for rodata.o efi/libstub: disable LTO scripts/mod: disable LTO for empty.c modpost: lto: strip .lto from module names PCI: Fix PREL32 relocations for LTO init: lto: fix PREL32 relocations init: lto: ensure initcall ordering kbuild: lto: add a default list of used symbols kbuild: lto: merge module sections kbuild: lto: limit inlining kbuild: lto: fix module versioning kbuild: add support for Clang LTO tracing: move function tracer options to Kconfig

Linus Torvalds committed 5 years ago

Commit 79db4d22 parents 3b9cdaf 2b8689524 files · +704 −59Browse files

Showing the changes to scripts (12 of 24 files). Show all

Unified · Split

12 files
  1. scripts/Makefile.build +41 −7
  2. scripts/Makefile.lib +4 −2
  3. scripts/Makefile.modfinal +8 −1
  4. scripts/Makefile.modpost +23 −2
  5. scripts/generate_initcall_order.pl +270 −0
  6. scripts/link-vmlinux.sh +61 −9
  7. scripts/lto-used-symbollist.txt +5 −0
  8. scripts/mod/Makefile +1 −0
  9. scripts/mod/modpost.c +7 −9
  10. scripts/mod/modpost.h +9 −0
  11. scripts/mod/sumversion.c +5 −1
  12. scripts/module.lds.S +24 −0
scripts/Makefile.build+41−7
@@ -111,7 +111,7 @@ endif · 110 unmodified lines
111111 # ---------------------------------------------------------------------------
112112
113113 quiet_cmd_cc_s_c = CC $(quiet_modtag) $@
114− cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS), $(c_flags)) -fverbose-asm -S -o $@ $<
114+ cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS) $(CC_FLAGS_LTO), $(c_flags)) -fverbose-asm -S -o $@ $<
115115
116116 $(obj)/%.s: $(src)/%.c FORCE
117117 $(call if_changed_dep,cc_s_c)
@@ -166,6 +166,15 @@ ifdef CONFIG_MODVERSIONS · 48 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,9 +186,9 @@ cmd_modversions_c = \ · 5 unmodified lines
177186 rm -f $(@D)/.tmp_$(@F:.o=.ver); \
178187 fi
179188 endif
189+endif
180190
181−ifdef CONFIG_FTRACE_MCOUNT_RECORD
182−ifndef CC_USING_RECORD_MCOUNT
191+ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
183192 # compiler will not generate __mcount_loc use recordmcount or recordmcount.pl
184193 ifdef BUILD_C_RECORDMCOUNT
185194 ifeq ("$(origin RECORDMCOUNT_WARN)", "command line")
@@ -206,8 +215,7 @@ recordmcount_source := $(srctree)/scripts/recordmcount.pl · 20 unmodified lines
206215 endif # BUILD_C_RECORDMCOUNT
207216 cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), \
208217 $(sub_cmd_record_mcount))
209−endif # CC_USING_RECORD_MCOUNT
210−endif # CONFIG_FTRACE_MCOUNT_RECORD
218+endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
211219
212220 ifdef CONFIG_STACK_VALIDATION
213221 ifneq ($(SKIP_STACK_VALIDATION),1)
@@ -388,6 +396,18 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler · 174 unmodified lines
388396 $(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ;
389397 $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ;
390398
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+
391411 #
392412 # Rule to compile a set of .o files into one .a file (without symbol table)
393413 #
@@ -395,8 +415,11 @@ $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; · 1 unmodified line
395415 quiet_cmd_ar_builtin = AR $@
396416 cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs)
397417
418+quiet_cmd_ar_and_symver = AR $@
419+ cmd_ar_and_symver = $(cmd_update_lto_symversions); $(cmd_ar_builtin)
420+
398421 $(obj)/built-in.a: $(real-obj-y) FORCE
399− $(call if_changed,ar_builtin)
422+ $(call if_changed,ar_and_symver)
400423
401424 #
402425 # Rule to create modules.order file
@@ -416,15 +439,26 @@ $(obj)/modules.order: $(obj-m) FORCE · 13 unmodified lines
416439 #
417440 # Rule to compile a set of .o files into one .a file (with symbol table)
418441 #
442+quiet_cmd_ar_lib = AR $@
443+ cmd_ar_lib = $(cmd_update_lto_symversions); $(cmd_ar)
444+
419445 $(obj)/lib.a: $(lib-y) FORCE
420− $(call if_changed,ar)
446+ $(call if_changed,ar_lib)
421447
422448 # NOTE:
423449 # Do not replace $(filter %.o,^) with $(real-prereqs). When a single object
424450 # module is turned into a multi object module, $^ will contain header file
425451 # dependencies recorded in the .*.cmd file.
452+ifdef CONFIG_LTO_CLANG
453+quiet_cmd_link_multi-m = AR [M] $@
454+cmd_link_multi-m = \
455+ $(cmd_update_lto_symversions); \
456+ rm -f $@; \
457+ $(AR) cDPrsT $@ $(filter %.o,$^)
458+else
426459 quiet_cmd_link_multi-m = LD [M] $@
427460 cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ $(filter %.o,$^)
461+endif
428462
429463 $(multi-used-m): FORCE
430464 $(call if_changed,link_multi-m)
scripts/Makefile.lib+4−2
@@ -119,9 +119,11 @@ target-stem = $(basename $(patsubst $(obj)/%,%,$@)) · 118 unmodified lines
119119 # These flags are needed for modversions and compiling, so we define them here
120120 # $(modname_flags) defines KBUILD_MODNAME as the name of the module it will
121121 # end up in (or would, if it gets compiled in)
122−name-fix = $(call stringify,$(subst $(comma),_,$(subst -,_,$1)))
122+name-fix-token = $(subst $(comma),_,$(subst -,_,$1))
123+name-fix = $(call stringify,$(call name-fix-token,$1))
123124 basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget))
124−modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname))
125+modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) \
126+ -D__KBUILD_MODNAME=kmod_$(call name-fix-token,$(modname))
125127 modfile_flags = -DKBUILD_MODFILE=$(call stringify,$(modfile))
126128
127129 _c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \
scripts/Makefile.modfinal+8−1
@@ -30,6 +30,12 @@ quiet_cmd_cc_o_c = CC [M] $@ · 29 unmodified lines
3030
3131 ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink)
3232
33+ifdef CONFIG_LTO_CLANG
34+# With CONFIG_LTO_CLANG, reuse the object file we compiled for modpost to
35+# avoid a second slow LTO link
36+prelink-ext := .lto
37+endif
38+
3339 quiet_cmd_ld_ko_o = LD [M] $@
3440 cmd_ld_ko_o = \
3541 $(LD) -r $(KBUILD_LDFLAGS) \
@@ -53,8 +59,9 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ · 17 unmodified lines
5359 $(cmd); \
5460 printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
5561
62+
5663 # Re-generate module BTFs if either module's .ko or vmlinux changed
57−$(modules): %.ko: %.o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE
64+$(modules): %.ko: %$(prelink-ext).o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE
5865 +$(call if_changed_except,ld_ko_o,vmlinux)
5966 ifdef CONFIG_DEBUG_INFO_BTF_MODULES
6067 +$(if $(newer-prereqs),$(call cmd,btf_ko))
scripts/Makefile.modpost+23−2
@@ -43,6 +43,9 @@ __modpost: · 42 unmodified lines
4343 include include/config/auto.conf
4444 include scripts/Kbuild.include
4545
46+# for ld_flags
47+include scripts/Makefile.lib
48+
4649 MODPOST = scripts/mod/modpost \
4750 $(if $(CONFIG_MODVERSIONS),-m) \
4851 $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \
@@ -102,12 +105,30 @@ $(input-symdump): · 53 unmodified lines
102105 @echo >&2 'WARNING: Symbol version dump "$@" is missing.'
103106 @echo >&2 ' Modules may not have dependencies or modversions.'
104107
108+ifdef CONFIG_LTO_CLANG
109+# With CONFIG_LTO_CLANG, .o files might be LLVM bitcode, so we need to run
110+# LTO to compile them into native code before running modpost
111+prelink-ext := .lto
112+
113+quiet_cmd_cc_lto_link_modules = LTO [M] $@
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 $^
119+
120+%.lto.o: %.o
121+ $(call if_changed,cc_lto_link_modules)
122+endif
123+
124+modules := $(sort $(shell cat $(MODORDER)))
125+
105126 # Read out modules.order to pass in modpost.
106127 # Otherwise, allmodconfig would fail with "Argument list too long".
107128 quiet_cmd_modpost = MODPOST $@
108− cmd_modpost = sed 's/ko$$/o/' $< | $(MODPOST) -T -
129+ cmd_modpost = sed 's/\.ko$$/$(prelink-ext)\.o/' $< | $(MODPOST) -T -
109130
110−$(output-symdump): $(MODORDER) $(input-symdump) FORCE
131+$(output-symdump): $(MODORDER) $(input-symdump) $(modules:.ko=$(prelink-ext).o) FORCE
111132 $(call if_changed,modpost)
112133
113134 targets += $(output-symdump)
scripts/generate_initcall_order.pl+270−0
@@ -0,0 +1,270 @@
1+#!/usr/bin/env perl
2+# SPDX-License-Identifier: GPL-2.0
3+#
4+# Generates a linker script that specifies the correct initcall order.
5+#
6+# Copyright (C) 2019 Google LLC
7+
8+use strict;
9+use warnings;
10+use IO::Handle;
11+use IO::Select;
12+use POSIX ":sys_wait_h";
13+
14+my $nm = $ENV{'NM'} || die "$0: ERROR: NM not set?";
15+my $objtree = $ENV{'objtree'} || '.';
16+
17+## currently active child processes
18+my $jobs = {}; # child process pid -> file handle
19+## results from child processes
20+my $results = {}; # object index -> [ { level, secname }, ... ]
21+
22+## reads _NPROCESSORS_ONLN to determine the maximum number of processes to
23+## start
24+sub get_online_processors {
25+ open(my $fh, "getconf _NPROCESSORS_ONLN 2>/dev/null |")
26+ or die "$0: ERROR: failed to execute getconf: $!";
27+ my $procs = <$fh>;
28+ close($fh);
29+
30+ if (!($procs =~ /^\d+$/)) {
31+ return 1;
32+ }
33+
34+ return int($procs);
35+}
36+
37+## writes results to the parent process
38+## format: <file index> <initcall level> <base initcall section name>
39+sub write_results {
40+ my ($index, $initcalls) = @_;
41+
42+ # sort by the counter value to ensure the order of initcalls within
43+ # each object file is correct
44+ foreach my $counter (sort { $a <=> $b } keys(%{$initcalls})) {
45+ my $level = $initcalls->{$counter}->{'level'};
46+
47+ # section name for the initcall function
48+ my $secname = $initcalls->{$counter}->{'module'} . '__' .
49+ $counter . '_' .
50+ $initcalls->{$counter}->{'line'} . '_' .
51+ $initcalls->{$counter}->{'function'};
52+
53+ print "$index $level $secname\n";
54+ }
55+}
56+
57+## reads a result line from a child process and adds it to the $results array
58+sub read_results{
59+ my ($fh) = @_;
60+
61+ # each child prints out a full line w/ autoflush and exits after the
62+ # last line, so even if buffered I/O blocks here, it shouldn't block
63+ # very long
64+ my $data = <$fh>;
65+
66+ if (!defined($data)) {
67+ return 0;
68+ }
69+
70+ chomp($data);
71+
72+ my ($index, $level, $secname) = $data =~
73+ /^(\d+)\ ([^\ ]+)\ (.*)$/;
74+
75+ if (!defined($index) ||
76+ !defined($level) ||
77+ !defined($secname)) {
78+ die "$0: ERROR: child process returned invalid data: $data\n";
79+ }
80+
81+ $index = int($index);
82+
83+ if (!exists($results->{$index})) {
84+ $results->{$index} = [];
85+ }
86+
87+ push (@{$results->{$index}}, {
88+ 'level' => $level,
89+ 'secname' => $secname
90+ });
91+
92+ return 1;
93+}
94+
95+## finds initcalls from an object file or all object files in an archive, and
96+## writes results back to the parent process
97+sub find_initcalls {
98+ my ($index, $file) = @_;
99+
100+ die "$0: ERROR: file $file doesn't exist?" if (! -f $file);
101+
102+ open(my $fh, "\"$nm\" --defined-only \"$file\" 2>/dev/null |")
103+ or die "$0: ERROR: failed to execute \"$nm\": $!";
104+
105+ my $initcalls = {};
106+
107+ while (<$fh>) {
108+ chomp;
109+
110+ # check for the start of a new object file (if processing an
111+ # archive)
112+ my ($path)= $_ =~ /^(.+)\:$/;
113+
114+ if (defined($path)) {
115+ write_results($index, $initcalls);
116+ $initcalls = {};
117+ next;
118+ }
119+
120+ # look for an initcall
121+ my ($module, $counter, $line, $symbol) = $_ =~
122+ /[a-z]\s+__initcall__(\S*)__(\d+)_(\d+)_(.*)$/;
123+
124+ if (!defined($module)) {
125+ $module = ''
126+ }
127+
128+ if (!defined($counter) ||
129+ !defined($line) ||
130+ !defined($symbol)) {
131+ next;
132+ }
133+
134+ # parse initcall level
135+ my ($function, $level) = $symbol =~
136+ /^(.*)((early|rootfs|con|[0-9])s?)$/;
137+
138+ die "$0: ERROR: invalid initcall name $symbol in $file($path)"
139+ if (!defined($function) || !defined($level));
140+
141+ $initcalls->{$counter} = {
142+ 'module' => $module,
143+ 'line' => $line,
144+ 'function' => $function,
145+ 'level' => $level,
146+ };
147+ }
148+
149+ close($fh);
150+ write_results($index, $initcalls);
151+}
152+
153+## waits for any child process to complete, reads the results, and adds them to
154+## the $results array for later processing
155+sub wait_for_results {
156+ my ($select) = @_;
157+
158+ my $pid = 0;
159+ do {
160+ # unblock children that may have a full write buffer
161+ foreach my $fh ($select->can_read(0)) {
162+ read_results($fh);
163+ }
164+
165+ # check for children that have exited, read the remaining data
166+ # from them, and clean up
167+ $pid = waitpid(-1, WNOHANG);
168+ if ($pid > 0) {
169+ if (!exists($jobs->{$pid})) {
170+ next;
171+ }
172+
173+ my $fh = $jobs->{$pid};
174+ $select->remove($fh);
175+
176+ while (read_results($fh)) {
177+ # until eof
178+ }
179+
180+ close($fh);
181+ delete($jobs->{$pid});
182+ }
183+ } while ($pid > 0);
184+}
185+
186+## forks a child to process each file passed in the command line and collects
187+## the results
188+sub process_files {
189+ my $index = 0;
190+ my $njobs = $ENV{'PARALLELISM'} || get_online_processors();
191+ my $select = IO::Select->new();
192+
193+ while (my $file = shift(@ARGV)) {
194+ # fork a child process and read it's stdout
195+ my $pid = open(my $fh, '-|');
196+
197+ if (!defined($pid)) {
198+ die "$0: ERROR: failed to fork: $!";
199+ } elsif ($pid) {
200+ # save the child process pid and the file handle
201+ $select->add($fh);
202+ $jobs->{$pid} = $fh;
203+ } else {
204+ # in the child process
205+ STDOUT->autoflush(1);
206+ find_initcalls($index, "$objtree/$file");
207+ exit;
208+ }
209+
210+ $index++;
211+
212+ # limit the number of children to $njobs
213+ if (scalar(keys(%{$jobs})) >= $njobs) {
214+ wait_for_results($select);
215+ }
216+ }
217+
218+ # wait for the remaining children to complete
219+ while (scalar(keys(%{$jobs})) > 0) {
220+ wait_for_results($select);
221+ }
222+}
223+
224+sub generate_initcall_lds() {
225+ process_files();
226+
227+ my $sections = {}; # level -> [ secname, ...]
228+
229+ # sort results to retain link order and split to sections per
230+ # initcall level
231+ foreach my $index (sort { $a <=> $b } keys(%{$results})) {
232+ foreach my $result (@{$results->{$index}}) {
233+ my $level = $result->{'level'};
234+
235+ if (!exists($sections->{$level})) {
236+ $sections->{$level} = [];
237+ }
238+
239+ push(@{$sections->{$level}}, $result->{'secname'});
240+ }
241+ }
242+
243+ die "$0: ERROR: no initcalls?" if (!keys(%{$sections}));
244+
245+ # print out a linker script that defines the order of initcalls for
246+ # each level
247+ print "SECTIONS {\n";
248+
249+ foreach my $level (sort(keys(%{$sections}))) {
250+ my $section;
251+
252+ if ($level eq 'con') {
253+ $section = '.con_initcall.init';
254+ } else {
255+ $section = ".initcall${level}.init";
256+ }
257+
258+ print "\t${section} : {\n";
259+
260+ foreach my $secname (@{$sections->{$level}}) {
261+ print "\t\t*(${section}..${secname}) ;\n";
262+ }
263+
264+ print "\t}\n";
265+ }
266+
267+ print "}\n";
268+}
269+
270+generate_initcall_lds();
scripts/link-vmlinux.sh+61−9
@@ -43,11 +43,37 @@ info() · 42 unmodified lines
4343 fi
4444 }
4545
46+# Generate a linker script to ensure correct ordering of initcalls.
47+gen_initcalls()
48+{
49+ info GEN .tmp_initcalls.lds
50+
51+ ${PYTHON} ${srctree}/scripts/jobserver-exec \
52+ ${PERL} ${srctree}/scripts/generate_initcall_order.pl \
53+ ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS} \
54+ > .tmp_initcalls.lds
55+}
56+
57+# If CONFIG_LTO_CLANG is selected, collect generated symbol versions into
58+# .tmp_symversions.lds
59+gen_symversions()
60+{
61+ info GEN .tmp_symversions.lds
62+ rm -f .tmp_symversions.lds
63+
64+ for o in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do
65+ if [ -f ${o}.symversions ]; then
66+ cat ${o}.symversions >> .tmp_symversions.lds
67+ fi
68+ done
69+}
70+
4671 # Link of vmlinux.o used for section mismatch analysis
4772 # ${1} output file
4873 modpost_link()
4974 {
5075 local objects
76+ local lds=""
5177
5278 objects="--whole-archive \
5379 ${KBUILD_VMLINUX_OBJS} \
@@ -56,7 +82,23 @@ modpost_link() · 2 unmodified lines
5682 ${KBUILD_VMLINUX_LIBS} \
5783 --end-group"
5884
59− ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${objects}
85+ if [ -n "${CONFIG_LTO_CLANG}" ]; then
86+ gen_initcalls
87+ lds="-T .tmp_initcalls.lds"
88+
89+ if [ -n "${CONFIG_MODVERSIONS}" ]; then
90+ gen_symversions
91+ lds="${lds} -T .tmp_symversions.lds"
92+ fi
93+
94+ # This might take a while, so indicate that we're doing
95+ # an LTO link
96+ info LTO ${1}
97+ else
98+ info LD ${1}
99+ fi
100+
101+ ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${lds} ${objects}
60102 }
61103
62104 objtool_link()
@@ -103,13 +145,22 @@ vmlinux_link() · 40 unmodified lines
103145 fi
104146
105147 if [ "${SRCARCH}" != "um" ]; then
106− objects="--whole-archive \
107− ${KBUILD_VMLINUX_OBJS} \
108− --no-whole-archive \
109− --start-group \
110− ${KBUILD_VMLINUX_LIBS} \
111− --end-group \
112− ${@}"
148+ if [ -n "${CONFIG_LTO_CLANG}" ]; then
149+ # Use vmlinux.o instead of performing the slow LTO
150+ # link again.
151+ objects="--whole-archive \
152+ vmlinux.o \
153+ --no-whole-archive \
154+ ${@}"
155+ else
156+ objects="--whole-archive \
157+ ${KBUILD_VMLINUX_OBJS} \
158+ --no-whole-archive \
159+ --start-group \
160+ ${KBUILD_VMLINUX_LIBS} \
161+ --end-group \
162+ ${@}"
163+ fi
113164
114165 ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} \
115166 ${strip_debug#-Wl,} \
@@ -225,6 +276,8 @@ cleanup() · 109 unmodified lines
225276 {
226277 rm -f .btf.*
227278 rm -f .tmp_System.map
279+ rm -f .tmp_initcalls.lds
280+ rm -f .tmp_symversions.lds
228281 rm -f .tmp_vmlinux*
229282 rm -f System.map
230283 rm -f vmlinux
@@ -274,7 +327,6 @@ fi; · 43 unmodified lines
274327 ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1
275328
276329 #link vmlinux.o
277−info LD vmlinux.o
278330 modpost_link vmlinux.o
279331 objtool_link vmlinux.o
280332
scripts/lto-used-symbollist.txt+5−0
@@ -0,0 +1,5 @@
1+memcpy
2+memmove
3+memset
4+__stack_chk_fail
5+__stack_chk_guard
scripts/mod/Makefile+1−0
@@ -1,5 +1,6 @@
11 # SPDX-License-Identifier: GPL-2.0
22 OBJECT_FILES_NON_STANDARD := y
3+CFLAGS_REMOVE_empty.o += $(CC_FLAGS_LTO)
34
45 hostprogs-always-y += modpost mk_elfconfig
56 always-y += empty.o
scripts/mod/modpost.c+7−9
@@ -17,7 +17,6 @@ · 16 unmodified lines
1717 #include <ctype.h>
1818 #include <string.h>
1919 #include <limits.h>
20−#include <stdbool.h>
2120 #include <errno.h>
2221 #include "modpost.h"
2322 #include "../../include/linux/license.h"
@@ -84,14 +83,6 @@ modpost_log(enum loglevel loglevel, const char *fmt, ...) · 60 unmodified lines
8483 error_occurred = true;
8584 }
8685
87−static inline bool strends(const char *str, const char *postfix)
88−{
89− if (strlen(str) < strlen(postfix))
90− return false;
91−
92− return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
93−}
94−
9586 void *do_nofail(void *ptr, const char *expr)
9687 {
9788 if (!ptr)
@@ -1988,6 +1979,10 @@ static char *remove_dot(char *s) · 1890 unmodified lines
19881979 size_t m = strspn(s + n + 1, "0123456789");
19891980 if (m && (s[n + m] == '.' || s[n + m] == 0))
19901981 s[n] = 0;
1982+
1983+ /* strip trailing .lto */
1984+ if (strends(s, ".lto"))
1985+ s[strlen(s) - 4] = '\0';
19911986 }
19921987 return s;
19931988 }
@@ -2011,6 +2006,9 @@ static void read_symbols(const char *modname) · 17 unmodified lines
20112006 /* strip trailing .o */
20122007 tmp = NOFAIL(strdup(modname));
20132008 tmp[strlen(tmp) - 2] = '\0';
2009+ /* strip trailing .lto */
2010+ if (strends(tmp, ".lto"))
2011+ tmp[strlen(tmp) - 4] = '\0';
20142012 mod = new_module(tmp);
20152013 free(tmp);
20162014 }
scripts/mod/modpost.h+9−0
@@ -2,6 +2,7 @@ · 1 unmodified line
22 #include <stdio.h>
33 #include <stdlib.h>
44 #include <stdarg.h>
5+#include <stdbool.h>
56 #include <string.h>
67 #include <sys/types.h>
78 #include <sys/stat.h>
@@ -180,6 +181,14 @@ static inline unsigned int get_secindex(const struct elf_info *info, · 172 unmodified lines
180181 return info->symtab_shndx_start[sym - info->symtab_start];
181182 }
182183
184+static inline bool strends(const char *str, const char *postfix)
185+{
186+ if (strlen(str) < strlen(postfix))
187+ return false;
188+
189+ return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0;
190+}
191+
183192 /* file2alias.c */
184193 extern unsigned int cross_build;
185194 void handle_moddevtable(struct module *mod, struct elf_info *info,
scripts/mod/sumversion.c+5−1
@@ -391,10 +391,14 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) · 390 unmodified lines
391391 struct md4_ctx md;
392392 char *fname;
393393 char filelist[PATH_MAX + 1];
394+ int postfix_len = 1;
395+
396+ if (strends(modname, ".lto.o"))
397+ postfix_len = 5;
394398
395399 /* objects for a module are listed in the first line of *.mod file. */
396400 snprintf(filelist, sizeof(filelist), "%.*smod",
397− (int)strlen(modname) - 1, modname);
401+ (int)strlen(modname) - postfix_len, modname);
398402
399403 buf = read_text_file(filelist);
400404
scripts/module.lds.S+24−0
@@ -23,6 +23,30 @@ SECTIONS { · 22 unmodified lines
2323 .init_array 0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) }
2424
2525 __jump_table 0 : ALIGN(8) { KEEP(*(__jump_table)) }
26+
27+ __patchable_function_entries : { *(__patchable_function_entries) }
28+
29+ /*
30+ * With CONFIG_LTO_CLANG, LLD always enables -fdata-sections and
31+ * -ffunction-sections, which increases the size of the final module.
32+ * Merge the split sections in the final binary.
33+ */
34+ .bss : {
35+ *(.bss .bss.[0-9a-zA-Z_]*)
36+ *(.bss..L*)
37+ }
38+
39+ .data : {
40+ *(.data .data.[0-9a-zA-Z_]*)
41+ *(.data..L*)
42+ }
43+
44+ .rodata : {
45+ *(.rodata .rodata.[0-9a-zA-Z_]*)
46+ *(.rodata..L*)
47+ }
48+
49+ .text : { *(.text .text.[0-9a-zA-Z_]*) }
2650 }
2751
2852 /* bring in arch-specific sections */