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)
Showing the changes to scripts (6 of 6 files). Show all
Unified · Split
| @@ -15,6 +15,10 @@ pound := \# · 14 unmodified lines | |||
| 15 | # Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o | 15 | # Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o |
| 16 | dot-target = $(dir $@).$(notdir $@) | 16 | dot-target = $(dir $@).$(notdir $@) |
| 17 | 17 | ||
| 18 | ### | ||
| 19 | # Name of target with a '.tmp_' as filename prefix. foo/bar.o => foo/.tmp_bar.o | ||
| 20 | tmp-target = $(dir $@).tmp_$(notdir $@) | ||
| 21 | |||
| 18 | ### | 22 | ### |
| 19 | # The temporary file to save gcc -MMD generated dependencies must not | 23 | # The temporary file to save gcc -MMD generated dependencies must not |
| 20 | # contain a comma | 24 | # contain a comma |
| @@ -88,10 +88,6 @@ endif · 87 unmodified lines | |||
| 88 | targets-for-modules := $(foreach x, o mod $(if $(CONFIG_TRIM_UNUSED_KSYMS), usyms), \ | 88 | targets-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 | ||
| 91 | ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) | ||
| 92 | targets-for-modules += $(patsubst %.o, %.prelink.o, $(filter %.o, $(obj-m))) | ||
| 93 | endif | ||
| 94 | |||
| 95 | ifdef need-modorder | 91 | ifdef need-modorder |
| 96 | targets-for-modules += $(obj)/modules.order | 92 | targets-for-modules += $(obj)/modules.order |
| 97 | endif | 93 | endif |
| @@ -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 | ||
| 151 | is-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. | ||
| 155 | ifdef CONFIG_LTO_CLANG | ||
| 156 | cmd_ld_single_m = $(if $(is-single-obj-m), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@) | ||
| 157 | endif | ||
| 158 | |||
| 155 | quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ | 159 | quiet_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 | ||
| 158 | ifdef CONFIG_MODVERSIONS | 164 | ifdef 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 | ||
| 229 | endif # CONFIG_OBJTOOL | 235 | endif # CONFIG_OBJTOOL |
| 230 | 236 | ||
| 231 | ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) | ||
| 232 | |||
| 233 | # Skip objtool for LLVM bitcode | ||
| 234 | $(obj)/%.o: objtool-enabled := | ||
| 235 | |||
| 236 | else | ||
| 237 | |||
| 238 | # 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory | 237 | # 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory |
| 239 | # 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file | 238 | # '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 file | 239 | # 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file |
| 241 | 240 | ||
| 242 | $(obj)/%.o: objtool-enabled = $(if $(filter-out y%, \ | 241 | is-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 | ||
| 245 | endif | 243 | delay-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 | ||
| 247 | ifdef CONFIG_TRIM_UNUSED_KSYMS | 247 | ifdef CONFIG_TRIM_UNUSED_KSYMS |
| 248 | cmd_gen_ksymdeps = \ | 248 | cmd_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 | ||
| 274 | ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) | ||
| 275 | # Module .o files may contain LLVM bitcode, compile them into native code | ||
| 276 | # before ELF processing | ||
| 277 | quiet_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) | ||
| 290 | endif | ||
| 291 | |||
| 292 | cmd_mod = echo $(addprefix $(obj)/, $(call real-search, $*.o, .o, -objs -y -m)) | \ | 274 | cmd_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 symbols | 280 | # List module undefined symbols |
| 299 | cmd_undefined_syms = $(NM) $< | sed -n 's/^ *U //p' > $@ | 281 | cmd_undefined_syms = $(NM) $< | sed -n 's/^ *U //p' > $@ |
| 300 | 282 | ||
| 301 | $(obj)/%.usyms: $(obj)/%$(mod-prelink-ext).o FORCE | 283 | $(obj)/%.usyms: $(obj)/%.o FORCE |
| 302 | $(call if_changed,undefined_syms) | 284 | $(call if_changed,undefined_syms) |
| 303 | 285 | ||
| 304 | quiet_cmd_cc_lst_c = MKLST $@ | 286 | quiet_cmd_cc_lst_c = MKLST $@ |
| @@ -420,16 +402,11 @@ $(obj)/modules.order: $(obj-m) FORCE · 115 unmodified lines | |||
| 420 | $(obj)/lib.a: $(lib-y) FORCE | 402 | $(obj)/lib.a: $(lib-y) FORCE |
| 421 | $(call if_changed,ar) | 403 | $(call if_changed,ar) |
| 422 | 404 | ||
| 423 | ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),) | ||
| 424 | quiet_cmd_link_multi-m = AR [M] $@ | ||
| 425 | cmd_link_multi-m = \ | ||
| 426 | rm -f $@; \ | ||
| 427 | $(AR) cDPrsT $@ @$(patsubst %.o,%.mod,$@) | ||
| 428 | else | ||
| 429 | quiet_cmd_link_multi-m = LD [M] $@ | 405 | quiet_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) |
| 431 | endif | ||
| 432 | 407 | ||
| 408 | $(multi-obj-m): objtool-enabled := $(delay-objtool) | ||
| 409 | $(multi-obj-m): part-of-module := y | ||
| 433 | $(multi-obj-m): %.o: %.mod FORCE | 410 | $(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) |
| @@ -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 | ||
| 228 | ifneq ($(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. | ||
| 232 | mod-prelink-ext := .prelink | ||
| 233 | endif | ||
| 234 | |||
| 235 | # Useful for describing the dependency of composite objects | 228 | # 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) |
| @@ -9,7 +9,7 @@ __modfinal: · 8 unmodified lines | |||
| 9 | include include/config/auto.conf | 9 | include include/config/auto.conf |
| 10 | include $(srctree)/scripts/Kbuild.include | 10 | include $(srctree)/scripts/Kbuild.include |
| 11 | 11 | ||
| 12 | # for c_flags and mod-prelink-ext | 12 | # for c_flags |
| 13 | include $(srctree)/scripts/Makefile.lib | 13 | include $(srctree)/scripts/Makefile.lib |
| 14 | 14 | ||
| 15 | # find all modules listed in modules.order | 15 | # 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 changed | 57 | # 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) FORCE | 58 | $(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) |
| 61 | ifdef CONFIG_DEBUG_INFO_BTF_MODULES | 60 | ifdef CONFIG_DEBUG_INFO_BTF_MODULES |
| 62 | +$(if $(newer-prereqs),$(call cmd,btf_ko)) | 61 | +$(if $(newer-prereqs),$(call cmd,btf_ko)) |
| @@ -41,9 +41,6 @@ __modpost: · 40 unmodified lines | |||
| 41 | include include/config/auto.conf | 41 | include include/config/auto.conf |
| 42 | include $(srctree)/scripts/Kbuild.include | 42 | include $(srctree)/scripts/Kbuild.include |
| 43 | 43 | ||
| 44 | # for mod-prelink-ext | ||
| 45 | include $(srctree)/scripts/Makefile.lib | ||
| 46 | |||
| 47 | MODPOST = scripts/mod/modpost \ | 44 | MODPOST = 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 | ||
| 120 | modules := $(sort $(shell cat $(MODORDER))) | ||
| 121 | |||
| 122 | # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined symbols | 117 | # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined symbols |
| 123 | ifneq ($(KBUILD_MODPOST_WARN)$(filter-out $(existing-input-symdump), $(input-symdump)),) | 118 | ifneq ($(KBUILD_MODPOST_WARN)$(filter-out $(existing-input-symdump), $(input-symdump)),) |
| 124 | MODPOST += -w | 119 | MODPOST += -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". |
| 129 | quiet_cmd_modpost = MODPOST $@ | 124 | quiet_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) FORCE | 127 | $(output-symdump): $(MODORDER) $(input-symdump) FORCE |
| 133 | $(call if_changed,modpost) | 128 | $(call if_changed,modpost) |
| 134 | 129 | ||
| 135 | targets += $(output-symdump) | 130 | targets += $(output-symdump) |
| @@ -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 | } |