Skip to content

Commit

Permalink
kbuild: Fix TRIM_UNUSED_KSYMS with LTO_CLANG
Browse files Browse the repository at this point in the history
With CONFIG_LTO_CLANG, we currently link modules into native
code just before modpost, which means with TRIM_UNUSED_KSYMS
enabled, we still look at the LLVM bitcode in the .o files when
generating the list of used symbols. As the bitcode doesn't
yet have calls to compiler intrinsics and llvm-nm doesn't see
function references that only exist in function-level inline
assembly, we currently need a whitelist for TRIM_UNUSED_KSYMS to
work with LTO.

This change moves module LTO linking to happen earlier, and
thus avoids the issue with LLVM bitcode and TRIM_UNUSED_KSYMS
entirely, allowing us to also drop the whitelist from
gen_autoksyms.sh.

Link: ClangBuiltLinux#1369
Signed-off-by: Sami Tolvanen <[email protected]>
Reviewed-by: Alexander Lobakin <[email protected]>
Tested-by: Alexander Lobakin <[email protected]>
Signed-off-by: Masahiro Yamada <[email protected]>
  • Loading branch information
samitolvanen authored and masahir0y committed Sep 2, 2021
1 parent 7d73c3e commit 850ded4
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 51 deletions.
27 changes: 26 additions & 1 deletion scripts/Makefile.build
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ endif

targets-for-modules := $(patsubst %.o, %.mod, $(filter %.o, $(obj-m)))

ifdef CONFIG_LTO_CLANG
targets-for-modules += $(patsubst %.o, %.lto.o, $(filter %.o, $(obj-m)))
endif

ifdef need-modorder
targets-for-modules += $(obj)/modules.order
endif
Expand Down Expand Up @@ -271,12 +275,33 @@ $(obj)/%.o: $(src)/%.c $(recordmcount_source) $$(objtool_dep) FORCE
$(call if_changed_rule,cc_o_c)
$(call cmd,force_checksrc)

ifdef CONFIG_LTO_CLANG
# Module .o files may contain LLVM bitcode, compile them into native code
# before ELF processing
quiet_cmd_cc_lto_link_modules = LTO [M] $@
cmd_cc_lto_link_modules = \
$(LD) $(ld_flags) -r -o $@ \
$(shell [ -s $(@:.lto.o=.o.symversions) ] && \
echo -T $(@:.lto.o=.o.symversions)) \
--whole-archive $(filter-out FORCE,$^)

ifdef CONFIG_STACK_VALIDATION
# objtool was skipped for LLVM bitcode, run it now that we have compiled
# modules into native code
cmd_cc_lto_link_modules += ; \
$(objtree)/tools/objtool/objtool $(objtool_args) --module $@
endif

$(obj)/%.lto.o: $(obj)/%.o FORCE
$(call if_changed,cc_lto_link_modules)
endif

cmd_mod = { \
echo $(if $($*-objs)$($*-y)$($*-m), $(addprefix $(obj)/, $($*-objs) $($*-y) $($*-m)), $(@:.mod=.o)); \
$(undefined_syms) echo; \
} > $@

$(obj)/%.mod: $(obj)/%.o FORCE
$(obj)/%.mod: $(obj)/%$(mod-prelink-ext).o FORCE
$(call if_changed,mod)

quiet_cmd_cc_lst_c = MKLST $@
Expand Down
7 changes: 7 additions & 0 deletions scripts/Makefile.lib
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,13 @@ dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \
$(addprefix -I,$(DTC_INCLUDE)) \
-undef -D__DTS__

ifeq ($(CONFIG_LTO_CLANG),y)
# With CONFIG_LTO_CLANG, .o files in modules might be LLVM bitcode, so we
# need to run LTO to compile them into native code (.lto.o) before further
# processing.
mod-prelink-ext := .lto
endif

# Objtool arguments are also needed for modfinal with LTO, so we define
# then here to avoid duplication.
objtool_args = \
Expand Down
21 changes: 2 additions & 19 deletions scripts/Makefile.modfinal
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ __modfinal:
include include/config/auto.conf
include $(srctree)/scripts/Kbuild.include

# for c_flags and objtool_args
# for c_flags and mod-prelink-ext
include $(srctree)/scripts/Makefile.lib

# find all modules listed in modules.order
Expand All @@ -30,23 +30,6 @@ quiet_cmd_cc_o_c = CC [M] $@

ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink)

ifdef CONFIG_LTO_CLANG
# With CONFIG_LTO_CLANG, reuse the object file we compiled for modpost to
# avoid a second slow LTO link
prelink-ext := .lto

# ELF processing was skipped earlier because we didn't have native code,
# so let's now process the prelinked binary before we link the module.

ifdef CONFIG_STACK_VALIDATION
cmd_ld_ko_o += \
$(objtree)/tools/objtool/objtool $(objtool_args) \
$(@:.ko=$(prelink-ext).o);

endif # CONFIG_STACK_VALIDATION

endif # CONFIG_LTO_CLANG

quiet_cmd_ld_ko_o = LD [M] $@
cmd_ld_ko_o += \
$(LD) -r $(KBUILD_LDFLAGS) \
Expand All @@ -72,7 +55,7 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \


# Re-generate module BTFs if either module's .ko or vmlinux changed
$(modules): %.ko: %$(prelink-ext).o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE
$(modules): %.ko: %$(mod-prelink-ext).o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE
+$(call if_changed_except,ld_ko_o,vmlinux)
ifdef CONFIG_DEBUG_INFO_BTF_MODULES
+$(if $(newer-prereqs),$(call cmd,btf_ko))
Expand Down
22 changes: 3 additions & 19 deletions scripts/Makefile.modpost
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ __modpost:
include include/config/auto.conf
include $(srctree)/scripts/Kbuild.include

# for ld_flags
# for mod-prelink-ext
include $(srctree)/scripts/Makefile.lib

MODPOST = scripts/mod/modpost \
Expand Down Expand Up @@ -118,22 +118,6 @@ $(input-symdump):
@echo >&2 ' Modules may not have dependencies or modversions.'
@echo >&2 ' You may get many unresolved symbol warnings.'

ifdef CONFIG_LTO_CLANG
# With CONFIG_LTO_CLANG, .o files might be LLVM bitcode, so we need to run
# LTO to compile them into native code before running modpost
prelink-ext := .lto

quiet_cmd_cc_lto_link_modules = LTO [M] $@
cmd_cc_lto_link_modules = \
$(LD) $(ld_flags) -r -o $@ \
$(shell [ -s $(@:.lto.o=.o.symversions) ] && \
echo -T $(@:.lto.o=.o.symversions)) \
--whole-archive $^

%.lto.o: %.o
$(call if_changed,cc_lto_link_modules)
endif

modules := $(sort $(shell cat $(MODORDER)))

# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined symbols
Expand All @@ -144,9 +128,9 @@ endif
# Read out modules.order to pass in modpost.
# Otherwise, allmodconfig would fail with "Argument list too long".
quiet_cmd_modpost = MODPOST $@
cmd_modpost = sed 's/\.ko$$/$(prelink-ext)\.o/' $< | $(MODPOST) -T -
cmd_modpost = sed 's/\.ko$$/$(mod-prelink-ext)\.o/' $< | $(MODPOST) -T -

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

targets += $(output-symdump)
Expand Down
12 changes: 0 additions & 12 deletions scripts/gen_autoksyms.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,6 @@ if [ -n "$CONFIG_MODVERSIONS" ]; then
needed_symbols="$needed_symbols module_layout"
fi

# With CONFIG_LTO_CLANG, LLVM bitcode has not yet been compiled into a binary
# when the .mod files are generated, which means they don't yet contain
# references to certain symbols that will be present in the final binaries.
if [ -n "$CONFIG_LTO_CLANG" ]; then
# intrinsic functions
needed_symbols="$needed_symbols memcpy memmove memset"
# ftrace
needed_symbols="$needed_symbols _mcount"
# stack protector symbols
needed_symbols="$needed_symbols __stack_chk_fail __stack_chk_guard"
fi

ksym_wl=
if [ -n "$CONFIG_UNUSED_KSYMS_WHITELIST" ]; then
# Use 'eval' to expand the whitelist path and check if it is relative
Expand Down

0 comments on commit 850ded4

Please sign in to comment.