targets-for-builtin += $(obj)/built-in.a
endif
-targets-for-modules := $(patsubst %.o, %.mod, $(filter %.o, $(obj-m)))
-
-ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
-targets-for-modules += $(patsubst %.o, %.prelink.o, $(filter %.o, $(obj-m)))
-endif
+targets-for-modules := $(foreach x, o mod $(if $(CONFIG_TRIM_UNUSED_KSYMS), usyms), \
+ $(patsubst %.o, %.$x, $(filter %.o, $(obj-m))))
ifdef need-modorder
targets-for-modules += $(obj)/modules.order
$(obj)/%.i: $(src)/%.c FORCE
$(call if_changed_dep,cpp_i_c)
+genksyms = scripts/genksyms/genksyms \
+ $(if $(1), -T $(2)) \
+ $(if $(KBUILD_PRESERVE), -p) \
+ -r $(or $(wildcard $(2:.symtypes=.symref)), /dev/null)
+
# These mirror gensymtypes_S and co below, keep them in synch.
-cmd_gensymtypes_c = \
- $(CPP) -D__GENKSYMS__ $(c_flags) $< | \
- scripts/genksyms/genksyms $(if $(1), -T $(2)) \
- $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \
- $(if $(KBUILD_PRESERVE),-p) \
- -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
+cmd_gensymtypes_c = $(CPP) -D__GENKSYMS__ $(c_flags) $< | $(genksyms)
quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
-cmd_cc_symtypes_c = \
- $(call cmd_gensymtypes_c,true,$@) >/dev/null; \
- test -s $@ || rm -f $@
+ cmd_cc_symtypes_c = $(call cmd_gensymtypes_c,true,$@) >/dev/null
$(obj)/%.symtypes : $(src)/%.c FORCE
$(call cmd,cc_symtypes_c)
# The C file is compiled and updated dependency information is generated.
# (See cmd_cc_o_c + relevant part of rule_cc_o_c)
+is-single-obj-m = $(and $(part-of-module),$(filter $@, $(obj-m)),y)
+
+# When a module consists of a single object, there is no reason to keep LLVM IR.
+# Make $(LD) covert LLVM IR to ELF here.
+ifdef CONFIG_LTO_CLANG
+cmd_ld_single_m = $(if $(is-single-obj-m), ; $(LD) $(ld_flags) -r -o $(tmp-target) $@; mv $(tmp-target) $@)
+endif
+
quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
- cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< $(cmd_objtool)
+ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< \
+ $(cmd_ld_single_m) \
+ $(cmd_objtool)
ifdef CONFIG_MODVERSIONS
# When module versioning is enabled the following steps are executed:
# o if <file>.o doesn't contain a __ksymtab version, i.e. does
# not export symbols, it's done.
# o otherwise, we calculate symbol versions using the good old
-# genksyms on the preprocessed source and postprocess them in a way
-# that they are usable as a linker script
-# o generate .tmp_<file>.o from <file>.o using the linker to
-# replace the unresolved symbols __crc_exported_symbol with
-# the actual value of the checksum generated by genksyms
-# o remove .tmp_<file>.o to <file>.o
+# genksyms on the preprocessed source and dump them into the .cmd file.
+# o modpost will extract versions from that file and create *.c files that will
+# be compiled and linked to the kernel and/or modules.
-ifdef CONFIG_LTO_CLANG
-# Generate .o.symversions files for each .o with exported symbols, and link these
-# to the kernel and/or modules at the end.
-cmd_modversions_c = \
+gen_symversions = \
if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then \
- $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
- > $@.symversions; \
- else \
- rm -f $@.symversions; \
- fi;
-else
-cmd_modversions_c = \
- if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
- $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
- > $(@D)/.tmp_$(@F:.o=.ver); \
- \
- $(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \
- -T $(@D)/.tmp_$(@F:.o=.ver); \
- mv -f $(@D)/.tmp_$(@F) $@; \
- rm -f $(@D)/.tmp_$(@F:.o=.ver); \
+ $(call cmd_gensymtypes_$(1),$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
+ >> $(dot-target).cmd; \
fi
-endif
+
+cmd_gen_symversions_c = $(call gen_symversions,c)
+
endif
ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
$(sub_cmd_record_mcount))
endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
-ifdef CONFIG_OBJTOOL
-
-objtool := $(objtree)/tools/objtool/objtool
-
-objtool_args = \
- $(if $(CONFIG_HAVE_JUMP_LABEL_HACK), --hacks=jump_label) \
- $(if $(CONFIG_HAVE_NOINSTR_HACK), --hacks=noinstr) \
- $(if $(CONFIG_X86_KERNEL_IBT), --ibt) \
- $(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \
- $(if $(CONFIG_UNWINDER_ORC), --orc) \
- $(if $(CONFIG_RETPOLINE), --retpoline) \
- $(if $(CONFIG_SLS), --sls) \
- $(if $(CONFIG_STACK_VALIDATION), --stackval) \
- $(if $(CONFIG_HAVE_STATIC_CALL_INLINE), --static-call) \
- --uaccess \
- $(if $(linked-object), --link) \
- $(if $(part-of-module), --module) \
- $(if $(CONFIG_GCOV_KERNEL), --no-unreachable)
-
-cmd_objtool = $(if $(objtool-enabled), ; $(objtool) $(objtool_args) $@)
-cmd_gen_objtooldep = $(if $(objtool-enabled), { echo ; echo '$@: $$(wildcard $(objtool))' ; } >> $(dot-target).cmd)
-
-endif # CONFIG_OBJTOOL
-
-ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
-
-# Skip objtool for LLVM bitcode
-$(obj)/%.o: objtool-enabled :=
-
-else
-
# 'OBJECT_FILES_NON_STANDARD := y': skip objtool checking for a directory
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file
-$(obj)/%.o: objtool-enabled = $(if $(filter-out y%, \
- $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y)
+is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y)
-endif
+$(obj)/%.o: objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y))
ifdef CONFIG_TRIM_UNUSED_KSYMS
cmd_gen_ksymdeps = \
$(CONFIG_SHELL) $(srctree)/scripts/gen_ksymdeps.sh $@ >> $(dot-target).cmd
-
-# List module undefined symbols
-undefined_syms = $(NM) $< | $(AWK) '$$1 == "U" { printf("%s%s", x++ ? " " : "", $$2) }';
endif
+cmd_check_local_export = $(srctree)/scripts/check-local-export $@
+
define rule_cc_o_c
$(call cmd_and_fixdep,cc_o_c)
$(call cmd,gen_ksymdeps)
+ $(call cmd,check_local_export)
$(call cmd,checksrc)
$(call cmd,checkdoc)
$(call cmd,gen_objtooldep)
- $(call cmd,modversions_c)
+ $(call cmd,gen_symversions_c)
$(call cmd,record_mcount)
endef
define rule_as_o_S
$(call cmd_and_fixdep,as_o_S)
$(call cmd,gen_ksymdeps)
+ $(call cmd,check_local_export)
$(call cmd,gen_objtooldep)
- $(call cmd,modversions_S)
+ $(call cmd,gen_symversions_S)
endef
# Built-in and composite module parts
$(call if_changed_rule,cc_o_c)
$(call cmd,force_checksrc)
-ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
-# Module .o files may contain LLVM bitcode, compile them into native code
-# before ELF processing
-quiet_cmd_cc_prelink_modules = LD [M] $@
- cmd_cc_prelink_modules = \
- $(LD) $(ld_flags) -r -o $@ \
- $(shell [ -s $(@:.prelink.o=.o.symversions) ] && \
- echo -T $(@:.prelink.o=.o.symversions)) \
- --whole-archive $(filter-out FORCE,$^) \
- $(cmd_objtool)
-
-# objtool was skipped for LLVM bitcode, run it now that we have compiled
-# modules into native code
-$(obj)/%.prelink.o: objtool-enabled = y
-$(obj)/%.prelink.o: part-of-module := y
-$(obj)/%.prelink.o: linked-object := y
+# To make this rule robust against "Argument list too long" error,
+# ensure to add $(obj)/ prefix by a shell command.
+cmd_mod = echo $(call real-search, $*.o, .o, -objs -y -m) | \
+ $(AWK) -v RS='( |\n)' '!x[$$0]++ { print("$(obj)/"$$0) }' > $@
-$(obj)/%.prelink.o: $(obj)/%.o FORCE
- $(call if_changed,cc_prelink_modules)
-endif
+$(obj)/%.mod: FORCE
+ $(call if_changed,mod)
-cmd_mod = { \
- echo $(if $($*-objs)$($*-y)$($*-m), $(addprefix $(obj)/, $($*-objs) $($*-y) $($*-m)), $(@:.mod=.o)); \
- $(undefined_syms) echo; \
- } > $@
+# List module undefined symbols
+cmd_undefined_syms = $(NM) $< | sed -n 's/^ *U //p' > $@
-$(obj)/%.mod: $(obj)/%$(mod-prelink-ext).o FORCE
- $(call if_changed,mod)
+$(obj)/%.usyms: $(obj)/%.o FORCE
+ $(call if_changed,undefined_syms)
quiet_cmd_cc_lst_c = MKLST $@
cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
$(CPP) $(a_flags) $< | \
grep "\<___EXPORT_SYMBOL\>" | \
sed 's/.*___EXPORT_SYMBOL[[:space:]]*\([a-zA-Z0-9_]*\)[[:space:]]*,.*/EXPORT_SYMBOL(\1);/' ; } | \
- $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | \
- scripts/genksyms/genksyms $(if $(1), -T $(2)) \
- $(patsubst y,-R,$(CONFIG_MODULE_REL_CRCS)) \
- $(if $(KBUILD_PRESERVE),-p) \
- -r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
+ $(CPP) -D__GENKSYMS__ $(c_flags) -xc - | $(genksyms)
quiet_cmd_cc_symtypes_S = SYM $(quiet_modtag) $@
-cmd_cc_symtypes_S = \
- $(call cmd_gensymtypes_S,true,$@) >/dev/null; \
- test -s $@ || rm -f $@
+ cmd_cc_symtypes_S = $(call cmd_gensymtypes_S,true,$@) >/dev/null
$(obj)/%.symtypes : $(src)/%.S FORCE
$(call cmd,cc_symtypes_S)
# versioning matches the C process described above, with difference that
# we parse asm-prototypes.h C header to get function definitions.
-cmd_modversions_S = \
- if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \
- $(call cmd_gensymtypes_S,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
- > $(@D)/.tmp_$(@F:.o=.ver); \
- \
- $(LD) $(KBUILD_LDFLAGS) -r -o $(@D)/.tmp_$(@F) $@ \
- -T $(@D)/.tmp_$(@F:.o=.ver); \
- mv -f $(@D)/.tmp_$(@F) $@; \
- rm -f $(@D)/.tmp_$(@F:.o=.ver); \
- fi
+cmd_gen_symversions_S = $(call gen_symversions,S)
+
endif
$(obj)/%.o: $(src)/%.S FORCE
$(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ;
$(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ;
-# combine symversions for later processing
-ifeq ($(CONFIG_LTO_CLANG) $(CONFIG_MODVERSIONS),y y)
- cmd_update_lto_symversions = \
- rm -f $@.symversions \
- $(foreach n, $(filter-out FORCE,$^), \
- $(if $(shell test -s $(n).symversions && echo y), \
- ; cat $(n).symversions >> $@.symversions))
-else
- cmd_update_lto_symversions = echo >/dev/null
-endif
-
#
# Rule to compile a set of .o files into one .a file (without symbol table)
#
+# To make this rule robust against "Argument list too long" error,
+# remove $(obj)/ prefix, and restore it by a shell command.
quiet_cmd_ar_builtin = AR $@
- cmd_ar_builtin = rm -f $@; $(AR) cDPrST $@ $(real-prereqs)
-
-quiet_cmd_ar_and_symver = AR $@
- cmd_ar_and_symver = $(cmd_update_lto_symversions); $(cmd_ar_builtin)
+ cmd_ar_builtin = rm -f $@; \
+ echo $(patsubst $(obj)/%,%,$(real-prereqs)) | \
+ sed -E 's:([^ ]+):$(obj)/\1:g' | \
+ xargs $(AR) cDPrST $@
$(obj)/built-in.a: $(real-obj-y) FORCE
- $(call if_changed,ar_and_symver)
+ $(call if_changed,ar_builtin)
#
# Rule to create modules.order file
#
# Rule to compile a set of .o files into one .a file (with symbol table)
#
-quiet_cmd_ar_lib = AR $@
- cmd_ar_lib = $(cmd_update_lto_symversions); $(cmd_ar)
$(obj)/lib.a: $(lib-y) FORCE
- $(call if_changed,ar_lib)
-
-# NOTE:
-# Do not replace $(filter %.o,^) with $(real-prereqs). When a single object
-# module is turned into a multi object module, $^ will contain header file
-# dependencies recorded in the .*.cmd file.
-ifneq ($(CONFIG_LTO_CLANG)$(CONFIG_X86_KERNEL_IBT),)
-quiet_cmd_link_multi-m = AR [M] $@
-cmd_link_multi-m = \
- $(cmd_update_lto_symversions); \
- rm -f $@; \
- $(AR) cDPrsT $@ $(filter %.o,$^)
-else
-quiet_cmd_link_multi-m = LD [M] $@
- cmd_link_multi-m = $(LD) $(ld_flags) -r -o $@ $(filter %.o,$^)
-endif
+ $(call if_changed,ar)
+
+quiet_cmd_ld_multi_m = LD [M] $@
+ cmd_ld_multi_m = $(LD) $(ld_flags) -r -o $@ @$(patsubst %.o,%.mod,$@) $(cmd_objtool)
+
+define rule_ld_multi_m
+ $(call cmd_and_savecmd,ld_multi_m)
+ $(call cmd,gen_objtooldep)
+endef
-$(multi-obj-m): FORCE
- $(call if_changed,link_multi-m)
+$(multi-obj-m): objtool-enabled := $(delay-objtool)
+$(multi-obj-m): part-of-module := y
+$(multi-obj-m): %.o: %.mod FORCE
+ $(call if_changed_rule,ld_multi_m)
$(call multi_depend, $(multi-obj-m), .o, -objs -y -m)
-targets += $(multi-obj-m)
targets := $(filter-out $(PHONY), $(targets))
# Add intermediate targets: