Skip to content

Commit c25e1c5

Browse files
committed
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) Signed-off-by: Masahiro Yamada <[email protected]> Reviewed-by: Nicolas Schier <[email protected]> Tested-by: Nathan Chancellor <[email protected]> Reviewed-by: Sami Tolvanen <[email protected]> Tested-by: Sedat Dilek <[email protected]> # LLVM-14 (x86-64) Acked-by: Josh Poimboeuf <[email protected]>
1 parent 0cfd900 commit c25e1c5

File tree

6 files changed

+28
-67
lines changed

6 files changed

+28
-67
lines changed

scripts/Kbuild.include

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ pound := \#
1515
# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o
1616
dot-target = $(dir $@).$(notdir $@)
1717

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+
1822
###
1923
# The temporary file to save gcc -MMD generated dependencies must not
2024
# contain a comma

scripts/Makefile.build

Lines changed: 20 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,6 @@ endif
8888
targets-for-modules := $(foreach x, o mod $(if $(CONFIG_TRIM_UNUSED_KSYMS), usyms), \
8989
$(patsubst %.o, %.$x, $(filter %.o, $(obj-m))))
9090

91-
ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
92-
targets-for-modules += $(patsubst %.o, %.prelink.o, $(filter %.o, $(obj-m)))
93-
endif
94-
9591
ifdef need-modorder
9692
targets-for-modules += $(obj)/modules.order
9793
endif
@@ -152,8 +148,18 @@ $(obj)/%.ll: $(src)/%.c FORCE
152148
# The C file is compiled and updated dependency information is generated.
153149
# (See cmd_cc_o_c + relevant part of rule_cc_o_c)
154150

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+
155159
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)
157163

158164
ifdef CONFIG_MODVERSIONS
159165
# When module versioning is enabled the following steps are executed:
@@ -219,7 +225,7 @@ objtool_args = \
219225
$(if $(CONFIG_STACK_VALIDATION), --stackval) \
220226
$(if $(CONFIG_HAVE_STATIC_CALL_INLINE), --static-call) \
221227
--uaccess \
222-
$(if $($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT)), --link) \
228+
$(if $(delay-objtool), --link) \
223229
$(if $(part-of-module), --module) \
224230
$(if $(CONFIG_GCOV_KERNEL), --no-unreachable)
225231

@@ -228,21 +234,15 @@ cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(o
228234

229235
endif # CONFIG_OBJTOOL
230236

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-
238237
# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
239238
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
240239
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file
241240

242-
$(obj)/%.o: objtool-enabled = $(if $(filter-out y%, \
243-
$(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y)
241+
is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y)
244242

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))
246246

247247
ifdef CONFIG_TRIM_UNUSED_KSYMS
248248
cmd_gen_ksymdeps = \
@@ -271,24 +271,6 @@ $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE
271271
$(call if_changed_rule,cc_o_c)
272272
$(call cmd,force_checksrc)
273273

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-
292274
cmd_mod = echo $(addprefix $(obj)/, $(call real-search, $*.o, .o, -objs -y -m)) | \
293275
$(AWK) -v RS='( |\n)' '!x[$$0]++' > $@
294276

@@ -298,7 +280,7 @@ $(obj)/%.mod: FORCE
298280
# List module undefined symbols
299281
cmd_undefined_syms = $(NM) $< | sed -n 's/^ *U //p' > $@
300282

301-
$(obj)/%.usyms: $(obj)/%$(mod-prelink-ext).o FORCE
283+
$(obj)/%.usyms: $(obj)/%.o FORCE
302284
$(call if_changed,undefined_syms)
303285

304286
quiet_cmd_cc_lst_c = MKLST $@
@@ -420,16 +402,11 @@ $(obj)/modules.order: $(obj-m) FORCE
420402
$(obj)/lib.a: $(lib-y) FORCE
421403
$(call if_changed,ar)
422404

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
429405
quiet_cmd_link_multi-m = LD [M] $@
430-
cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ @$(patsubst %.o,%.mod,$@)
431-
endif
406+
cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ @$(patsubst %.o,%.mod,$@) $(cmd_objtool)
432407

408+
$(multi-obj-m): objtool-enabled := $(delay-objtool)
409+
$(multi-obj-m): part-of-module := y
433410
$(multi-obj-m): %.o: %.mod FORCE
434411
$(call if_changed,link_multi-m)
435412
$(call multi_depend, $(multi-obj-m), .o, -objs -y -m)

scripts/Makefile.lib

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -225,13 +225,6 @@ dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \
225225
$(addprefix -I,$(DTC_INCLUDE)) \
226226
-undef -D__DTS__
227227

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-
235228
# Useful for describing the dependency of composite objects
236229
# Usage:
237230
# $(call multi_depend, multi_used_targets, suffix_to_remove, suffix_to_add)

scripts/Makefile.modfinal

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ __modfinal:
99
include include/config/auto.conf
1010
include $(srctree)/scripts/Kbuild.include
1111

12-
# for c_flags and mod-prelink-ext
12+
# for c_flags
1313
include $(srctree)/scripts/Makefile.lib
1414

1515
# find all modules listed in modules.order
@@ -54,9 +54,8 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \
5454
$(cmd); \
5555
printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:)
5656

57-
5857
# 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
6059
+$(call if_changed_except,ld_ko_o,vmlinux)
6160
ifdef CONFIG_DEBUG_INFO_BTF_MODULES
6261
+$(if $(newer-prereqs),$(call cmd,btf_ko))

scripts/Makefile.modpost

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,6 @@ __modpost:
4141
include include/config/auto.conf
4242
include $(srctree)/scripts/Kbuild.include
4343

44-
# for mod-prelink-ext
45-
include $(srctree)/scripts/Makefile.lib
46-
4744
MODPOST = scripts/mod/modpost \
4845
$(if $(CONFIG_MODVERSIONS),-m) \
4946
$(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \
@@ -117,8 +114,6 @@ $(input-symdump):
117114
@echo >&2 ' Modules may not have dependencies or modversions.'
118115
@echo >&2 ' You may get many unresolved symbol warnings.'
119116

120-
modules := $(sort $(shell cat $(MODORDER)))
121-
122117
# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined symbols
123118
ifneq ($(KBUILD_MODPOST_WARN)$(filter-out $(existing-input-symdump), $(input-symdump)),)
124119
MODPOST += -w
@@ -127,9 +122,9 @@ endif
127122
# Read out modules.order to pass in modpost.
128123
# Otherwise, allmodconfig would fail with "Argument list too long".
129124
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 -
131126

132-
$(output-symdump): $(MODORDER) $(input-symdump) $(modules:.ko=$(mod-prelink-ext).o) FORCE
127+
$(output-symdump): $(MODORDER) $(input-symdump) FORCE
133128
$(call if_changed,modpost)
134129

135130
targets += $(output-symdump)

scripts/mod/modpost.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1903,10 +1903,6 @@ static char *remove_dot(char *s)
19031903
size_t m = strspn(s + n + 1, "0123456789");
19041904
if (m && (s[n + m + 1] == '.' || s[n + m + 1] == 0))
19051905
s[n] = 0;
1906-
1907-
/* strip trailing .prelink */
1908-
if (strends(s, ".prelink"))
1909-
s[strlen(s) - 8] = '\0';
19101906
}
19111907
return s;
19121908
}
@@ -2028,9 +2024,6 @@ static void read_symbols(const char *modname)
20282024
/* strip trailing .o */
20292025
tmp = NOFAIL(strdup(modname));
20302026
tmp[strlen(tmp) - 2] = '\0';
2031-
/* strip trailing .prelink */
2032-
if (strends(tmp, ".prelink"))
2033-
tmp[strlen(tmp) - 8] = '\0';
20342027
mod = new_module(tmp);
20352028
free(tmp);
20362029
}

0 commit comments

Comments
 (0)