History

kbuild: do not create *.prelink.o for Clang LTO or IBT

When CONFIG_LTO_CLANG=y, additional intermediate *.prelink.o is created for each module. Also, objtool is postponed until LLVM IR is converted to ELF. CONFIG_X86_KERNEL_IBT works in a similar way to postpone objtool until objects are merged together. This commit stops generating *.prelink.o, so the build flow will look similar with/without LTO. The following figures show how the LTO build currently works, and how this commit is changing it. Current build flow ================== [1] single-object module $(LD) $(CC) +objtool $(LD) foo.c --------------------> foo.o -----> foo.prelink.o -----> foo.ko (LLVM IR) (ELF) | (ELF) | foo.mod.o --/ (LLVM IR) [2] multi-object module $(LD) $(CC) $(AR) +objtool $(LD) foo1.c -----> foo1.o -----> foo.o -----> foo.prelink.o -----> foo.ko | (archive) (ELF) | (ELF) foo2.c -----> foo2.o --/ | (LLVM IR) foo.mod.o --/ (LLVM IR) One confusion is that foo.o in multi-object module is an archive despite of its suffix. New build flow ============== [1] single-object module Since there is only one object, there is no need to keep the LLVM IR. Use $(CC)+$(LD) to generate an ELF object in one build rule. When LTO is disabled, $(LD) is unneeded because $(CC) produces an ELF object. $(CC)+$(LD)+objtool $(LD) foo.c ----------------------------> foo.o ---------> foo.ko (ELF) | (ELF) | foo.mod.o --/ (LLVM IR) [2] multi-object module Previously, $(AR) was used to combine LLVM IR files into an archive, but there was no technical reason to do so. Use $(LD) to merge them into a single ELF object. $(LD) $(CC) +objtool $(LD) foo1.c ---------> foo1.o ---------> foo.o ---------> foo.ko | (ELF) | (ELF) foo2.c ---------> foo2.o ----/ | (LLVM IR) foo.mod.o --/ (LLVM IR)

Masahiro Yamada committed 4 years ago

Commit c25e1c51 parent 0cfd9006 files · +28 −67Browse files

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

Unified · Split

6 files
  1. scripts/Kbuild.include +4 −0
  2. scripts/Makefile.build +20 −43
  3. scripts/Makefile.lib +0 −7
  4. scripts/Makefile.modfinal +2 −3
  5. scripts/Makefile.modpost +2 −7
  6. scripts/mod/modpost.c +0 −7
scripts/Kbuild.include+4−0
@@ -15,6 +15,10 @@ pound := \# · 14 unmodified lines
15# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o15# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o
16dot-target = $(dir $@).$(notdir $@)16dot-target = $(dir $@).$(notdir $@)
17 17
18###
19# Name of target with a '.tmp_' as filename prefix. foo/bar.o => foo/.tmp_bar.o
20tmp-target = $(dir $@).tmp_$(notdir $@)
21
18###22###
19# The temporary file to save gcc -MMD generated dependencies must not23# The temporary file to save gcc -MMD generated dependencies must not
20# contain a comma24# contain a comma
scripts/Makefile.build+20−43
@@ -88,10 +88,6 @@ endif · 87 unmodified lines
88targets-for-modules := $(foreach x, o mod $(if $(CONFIG_TRIM_UNUSED_KSYMS), usyms), \88targets-for-modules := $(foreach x, o mod $(if $(CONFIG_TRIM_UNUSED_KSYMS), usyms), \
89 $(patsubst %.o, %.$x, $(filter %.o, $(obj-m))))89 $(patsubst %.o, %.$x, $(filter %.o, $(obj-m))))
90 90
91ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
92targets-for-modules += $(patsubst %.o, %.prelink.o, $(filter %.o, $(obj-m)))
93endif
94
95ifdef need-modorder91ifdef need-modorder
96targets-for-modules += $(obj)/modules.order92targets-for-modules += $(obj)/modules.order
97endif93endif
@@ -152,8 +148,18 @@ $(obj)/%.ll: $(src)/%.c FORCE · 54 unmodified lines
152# The C file is compiled and updated dependency information is generated.148# The C file is compiled and updated dependency information is generated.
153# (See cmd_cc_o_c + relevant part of rule_cc_o_c)149# (See cmd_cc_o_c + relevant part of rule_cc_o_c)
154 150
151is-single-obj-m = $(and $(part-of-module),$(filter $@, $(obj-m)),y)
152
153# When a module consists of a single object, there is no reason to keep LLVM IR.
154# Make $(LD) covert LLVM IR to ELF here.
155ifdef CONFIG_LTO_CLANG
156cmd_ld_single_m = $(if $(is-single-obj-m), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@)
157endif
158
155quiet_cmd_cc_o_c = CC $(quiet_modtag) $@159quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
156 cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< $(cmd_objtool)160 cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \
161 $(cmd_ld_single_m) \
162 $(cmd_objtool)
157 163
158ifdef CONFIG_MODVERSIONS164ifdef CONFIG_MODVERSIONS
159# When module versioning is enabled the following steps are executed:165# When module versioning is enabled the following steps are executed:
@@ -219,7 +225,7 @@ objtool_args = \ · 59 unmodified lines
219 $(if $(CONFIG_STACK_VALIDATION), --stackval) \225 $(if $(CONFIG_STACK_VALIDATION), --stackval) \
220 $(if $(CONFIG_HAVE_STATIC_CALL_INLINE), --static-call) \226 $(if $(CONFIG_HAVE_STATIC_CALL_INLINE), --static-call) \
221 --uaccess \227 --uaccess \
222 $(if $($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT)), --link) \228 $(if $(delay-objtool), --link) \
223 $(if $(part-of-module), --module) \229 $(if $(part-of-module), --module) \
224 $(if $(CONFIG_GCOV_KERNEL), --no-unreachable)230 $(if $(CONFIG_GCOV_KERNEL), --no-unreachable)
225 231
@@ -228,21 +234,15 @@ cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(o · 2 unmodified lines
228 234
229endif # CONFIG_OBJTOOL235endif # CONFIG_OBJTOOL
230 236
231ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
232
233# Skip objtool for LLVM bitcode
234$(obj)/%.o: objtool-enabled :=
235
236else
237
238# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory237# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
239# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file238# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
240# 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file239# 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file
241 240
242$(obj)/%.o: objtool-enabled = $(if $(filter-out y%, \241is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y)
243 $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y)
244 242
245endif243delay-objtool := $(or $(CONFIG_LTO_CLANG),$(CONFIG_X86_KERNEL_IBT))
244
245$(obj)/%.o: objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y))
246 246
247ifdef CONFIG_TRIM_UNUSED_KSYMS247ifdef CONFIG_TRIM_UNUSED_KSYMS
248cmd_gen_ksymdeps = \248cmd_gen_ksymdeps = \
@@ -271,24 +271,6 @@ $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE · 22 unmodified lines
271 $(call if_changed_rule,cc_o_c)271 $(call if_changed_rule,cc_o_c)
272 $(call cmd,force_checksrc)272 $(call cmd,force_checksrc)
273 273
274ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
275# Module .o files may contain LLVM bitcode, compile them into native code
276# before ELF processing
277quiet_cmd_cc_prelink_modules = LD [M] $@
278 cmd_cc_prelink_modules = \
279 $(LD) $(ld_flags) -r -o $@ \
280 --whole-archive $(filter-out FORCE,$^) \
281 $(cmd_objtool)
282
283# objtool was skipped for LLVM bitcode, run it now that we have compiled
284# modules into native code
285$(obj)/%.prelink.o: objtool-enabled = y
286$(obj)/%.prelink.o: part-of-module := y
287
288$(obj)/%.prelink.o: $(obj)/%.o FORCE
289 $(call if_changed,cc_prelink_modules)
290endif
291
292cmd_mod = echo $(addprefix $(obj)/, $(call real-search, $*.o, .o, -objs -y -m)) | \274cmd_mod = echo $(addprefix $(obj)/, $(call real-search, $*.o, .o, -objs -y -m)) | \
293 $(AWK) -v RS='( |\n)' '!x[$$0]++' > $@275 $(AWK) -v RS='( |\n)' '!x[$$0]++' > $@
294 276
@@ -298,7 +280,7 @@ $(obj)/%.mod: FORCE · 3 unmodified lines
298# List module undefined symbols280# List module undefined symbols
299cmd_undefined_syms = $(NM) $< | sed -n 's/^ *U //p' > $@281cmd_undefined_syms = $(NM) $< | sed -n 's/^ *U //p' > $@
300 282
301$(obj)/%.usyms: $(obj)/%$(mod-prelink-ext).o FORCE283$(obj)/%.usyms: $(obj)/%.o FORCE
302 $(call if_changed,undefined_syms)284 $(call if_changed,undefined_syms)
303 285
304quiet_cmd_cc_lst_c = MKLST $@286quiet_cmd_cc_lst_c = MKLST $@
@@ -420,16 +402,11 @@ $(obj)/modules.order: $(obj-m) FORCE · 115 unmodified lines
420$(obj)/lib.a: $(lib-y) FORCE402$(obj)/lib.a: $(lib-y) FORCE
421 $(call if_changed,ar)403 $(call if_changed,ar)
422 404
423ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
424quiet_cmd_link_multi-m = AR [M] $@
425cmd_link_multi-m = \
426 rm -f $@; \
427 $(AR) cDPrsT $@ @$(patsubst %.o,%.mod,$@)
428else
429quiet_cmd_link_multi-m = LD [M] $@405quiet_cmd_link_multi-m = LD [M] $@
430 cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ @$(patsubst %.o,%.mod,$@)406 cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ @$(patsubst %.o,%.mod,$@) $(cmd_objtool)
431endif
432 407
408$(multi-obj-m): objtool-enabled := $(delay-objtool)
409$(multi-obj-m): part-of-module := y
433$(multi-obj-m): %.o: %.mod FORCE410$(multi-obj-m): %.o: %.mod FORCE
434 $(call if_changed,link_multi-m)411 $(call if_changed,link_multi-m)
435$(call multi_depend, $(multi-obj-m), .o, -objs -y -m)412$(call multi_depend, $(multi-obj-m), .o, -objs -y -m)
scripts/Makefile.lib+0−7
@@ -225,13 +225,6 @@ dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \ · 224 unmodified lines
225 $(addprefix -I,$(DTC_INCLUDE)) \225 $(addprefix -I,$(DTC_INCLUDE)) \
226 -undef -D__DTS__226 -undef -D__DTS__
227 227
228ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
229# With CONFIG_LTO_CLANG, .o files in modules might be LLVM bitcode, so we
230# need to run LTO to compile them into native code (.lto.o) before further
231# processing.
232mod-prelink-ext := .prelink
233endif
234
235# Useful for describing the dependency of composite objects228# Useful for describing the dependency of composite objects
236# Usage:229# Usage:
237# $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add)230# $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add)
scripts/Makefile.modfinal+2−3
@@ -9,7 +9,7 @@ __modfinal: · 8 unmodified lines
9include include/config/auto.conf9include include/config/auto.conf
10include $(srctree)/scripts/Kbuild.include10include $(srctree)/scripts/Kbuild.include
11 11
12# for c_flags and mod-prelink-ext12# for c_flags
13include $(srctree)/scripts/Makefile.lib13include $(srctree)/scripts/Makefile.lib
14 14
15# find all modules listed in modules.order15# find all modules listed in modules.order
@@ -54,9 +54,8 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ · 38 unmodified lines
54 $(cmd); \54 $(cmd); \
55 printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)55 printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
56 56
57
58# Re-generate module BTFs if either module's .ko or vmlinux changed57# Re-generate module BTFs if either module's .ko or vmlinux changed
59$(modules): %.ko: %$(mod-prelink-ext).o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE58$(modules): %.ko: %.o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE
60 +$(call if_changed_except,ld_ko_o,vmlinux)59 +$(call if_changed_except,ld_ko_o,vmlinux)
61ifdef CONFIG_DEBUG_INFO_BTF_MODULES60ifdef CONFIG_DEBUG_INFO_BTF_MODULES
62 +$(if $(newer-prereqs),$(call cmd,btf_ko))61 +$(if $(newer-prereqs),$(call cmd,btf_ko))
scripts/Makefile.modpost+2−7
@@ -41,9 +41,6 @@ __modpost: · 40 unmodified lines
41include include/config/auto.conf41include include/config/auto.conf
42include $(srctree)/scripts/Kbuild.include42include $(srctree)/scripts/Kbuild.include
43 43
44# for mod-prelink-ext
45include $(srctree)/scripts/Makefile.lib
46
47MODPOST = scripts/mod/modpost \44MODPOST = scripts/mod/modpost \
48 $(if $(CONFIG_MODVERSIONS),-m) \45 $(if $(CONFIG_MODVERSIONS),-m) \
49 $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \46 $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \
@@ -117,8 +114,6 @@ $(input-symdump): · 67 unmodified lines
117 @echo >&2 ' Modules may not have dependencies or modversions.'114 @echo >&2 ' Modules may not have dependencies or modversions.'
118 @echo >&2 ' You may get many unresolved symbol warnings.'115 @echo >&2 ' You may get many unresolved symbol warnings.'
119 116
120modules := $(sort $(shell cat $(MODORDER)))
121
122# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined symbols117# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined symbols
123ifneq ($(KBUILD_MODPOST_WARN)$(filter-out $(existing-input-symdump), $(input-symdump)),)118ifneq ($(KBUILD_MODPOST_WARN)$(filter-out $(existing-input-symdump), $(input-symdump)),)
124MODPOST += -w119MODPOST += -w
@@ -127,9 +122,9 @@ endif · 2 unmodified lines
127# Read out modules.order to pass in modpost.122# Read out modules.order to pass in modpost.
128# Otherwise, allmodconfig would fail with "Argument list too long".123# Otherwise, allmodconfig would fail with "Argument list too long".
129quiet_cmd_modpost = MODPOST $@124quiet_cmd_modpost = MODPOST $@
130 cmd_modpost = sed 's/\.ko$$/$(mod-prelink-ext)\.o/' $< | $(MODPOST) -T -125 cmd_modpost = sed 's/ko$$/o/' $< | $(MODPOST) -T -
131 126
132$(output-symdump): $(MODORDER) $(input-symdump) $(modules:.ko=$(mod-prelink-ext).o) FORCE127$(output-symdump): $(MODORDER) $(input-symdump) FORCE
133 $(call if_changed,modpost)128 $(call if_changed,modpost)
134 129
135targets += $(output-symdump)130targets += $(output-symdump)
scripts/mod/modpost.c+0−7
@@ -1903,10 +1903,6 @@ static char *remove_dot(char *s) · 1902 unmodified lines
1903 size_t m = strspn(s + n + 1, "0123456789");1903 size_t m = strspn(s + n + 1, "0123456789");
1904 if (m && (s[n + m + 1] == '.' || s[n + m + 1] == 0))1904 if (m && (s[n + m + 1] == '.' || s[n + m + 1] == 0))
1905 s[n] = 0;1905 s[n] = 0;
1906
1907 /* strip trailing .prelink */
1908 if (strends(s, ".prelink"))
1909 s[strlen(s) - 8] = '\0';
1910 }1906 }
1911 return s;1907 return s;
1912}1908}
@@ -2028,9 +2024,6 @@ static void read_symbols(const char *modname) · 115 unmodified lines
2028 /* strip trailing .o */2024 /* strip trailing .o */
2029 tmp = NOFAIL(strdup(modname));2025 tmp = NOFAIL(strdup(modname));
2030 tmp[strlen(tmp) - 2] = '\0';2026 tmp[strlen(tmp) - 2] = '\0';
2031 /* strip trailing .prelink */
2032 if (strends(tmp, ".prelink"))
2033 tmp[strlen(tmp) - 8] = '\0';
2034 mod = new_module(tmp);2027 mod = new_module(tmp);
2035 free(tmp);2028 free(tmp);
2036 }2029 }