Add support for Clang LTO
Sami Tolvanen
maintainerv9 cover Add support for Clang LTO
This patch series adds support for building the kernel with Clang's Link Time Optimization (LTO). In addition to performance, the primary motivation for LTO is to allow Clang's Control-Flow Integrity (CFI) to be used in the kernel. Google has shipped millions of Pixel devices running three major kernel versions with LTO+CFI since 2018.
Most of the patches are build system changes for handling LLVM bitcode, which Clang produces with LTO instead of ELF object files, postponing ELF processing until a later stage, and ensuring initcall ordering.
Note that arm64 support depends on Will's memory ordering patches [1]. I will post x86_64 patches separately after we have fixed the remaining objtool warnings [2][3].
[1] https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=for-next/lto
[2] https://lore.kernel.org/lkml/20201120040424.a3wctajzft4ufoiw@treble/
[3] https://git.kernel.org/pub/scm/linux/kernel/git/jpoimboe/linux.git/log/?h=objtool-vmlinux
You can also pull this series from
https://github.com/samitolvanen/linux.git lto-v9
---
Changes in v9:
- Added HAS_LTO_CLANG dependencies to LLVM=1 and LLVM_IAS=1 to avoid issues with mismatched toolchains.
- Dropped the .mod patch as Masahiro landed a better solution to the split line issue in commit 7d32358be8ac ("kbuild: avoid split lines in .mod files").
- Updated CC_FLAGS_LTO to use -fvisibility=hidden to avoid weak symbol visibility issues with ThinLTO on x86.
- Changed LTO_CLANG_FULL to depend on !COMPILE_TEST to prevent timeouts in automated testing.
- Added a dependency to CPU_LITTLE_ENDIAN to ARCH_SUPPORTS_LTO_CLANG in arch/arm64/Kconfig.
- Added a default symbol list to fix an issue with TRIM_UNUSED_KSYMS.
Changes in v8:
- Cleaned up the LTO Kconfig options based on suggestions from Nick and Kees.
- Dropped the patch to disable LTO for the arm64 nVHE KVM code as David pointed out it's not needed anymore.
Changes in v7:
- Rebased to master again.
- Added back arm64 patches as the prerequisites are now staged, and dropped x86_64 support until the remaining objtool issues are resolved.
- Dropped ifdefs from module.lds.S.
Changes in v6:
- Added the missing --mcount flag to patch 5.
- Dropped the arm64 patches from this series and will repost them later.
Changes in v5:
- Rebased on top of tip/master.
- Changed the command line for objtool to use --vmlinux --duplicate to disable warnings about retpoline thunks and to fix .orc_unwind generation for vmlinux.o.
- Added --noinstr flag to objtool, so we can use --vmlinux without also enabling noinstr validation.
- Disabled objtool's unreachable instruction warnings with LTO to disable false positives for the int3 padding in vmlinux.o.
- Added ANNOTATE_RETPOLINE_SAFE annotations to the indirect jumps in x86 assembly code to fix objtool warnings with retpoline.
- Fixed modpost warnings about missing version information with CONFIG_MODVERSIONS.
- Included Makefile.lib into Makefile.modpost for ld_flags. Thanks to Sedat for pointing this out.
- Updated the help text for ThinLTO to better explain the trade-offs.
- Updated commit messages with better explanations.
Changes in v4:
- Fixed a typo in Makefile.lib to correctly pass --no-fp to objtool.
- Moved ftrace configs related to generating __mcount_loc to Kconfig, so they are available also in Makefile.modfinal.
- Dropped two prerequisite patches that were merged to Linus' tree.
Changes in v3:
- Added a separate patch to remove the unused DISABLE_LTO treewide, as filtering out CC_FLAGS_LTO instead is preferred.
- Updated the Kconfig help to explain why LTO is behind a choice and disabled by default.
- Dropped CC_FLAGS_LTO_CLANG, compiler-specific LTO flags are now appended directly to CC_FLAGS_LTO.
- Updated $(AR) flags as KBUILD_ARFLAGS was removed earlier.
- Fixed ThinLTO cache handling for external module builds.
- Rebased on top of Masahiro's patch for preprocessing modules.lds, and moved the contents of module-lto.lds to modules.lds.S.
- Moved objtool_args to Makefile.lib to avoid duplication of the command line parameters in Makefile.modfinal.
- Clarified in the commit message for the initcall ordering patch that the initcall order remains the same as without LTO.
- Changed link-vmlinux.sh to use jobserver-exec to control the number of jobs started by generate_initcall_ordering.pl.
- Dropped the x86/relocs patch to whitelist L4_PAGE_OFFSET as it's no longer needed with ToT kernel.
- Disabled LTO for arch/x86/power/cpu.c to work around a Clang bug with stack protector attributes.
Changes in v2:
- Fixed -Wmissing-prototypes warnings with W=1.
- Dropped cc-option from -fsplit-lto-unit and added .thinlto-cache scrubbing to make distclean.
- Added a comment about Clang >=11 being required.
- Added a patch to disable LTO for the arm64 KVM nVHE code.
- Disabled objtool's noinstr validation with LTO unless enabled.
- Included Peter's proposed objtool mcount patch in the series and replaced recordmcount with the objtool pass to avoid whitelisting relocations that are not calls.
- Updated several commit messages with better explanations.
Sami Tolvanen (16):
tracing: move function tracer options to Kconfig
kbuild: add support for Clang LTO
kbuild: lto: fix module versioning
kbuild: lto: limit inlining
kbuild: lto: merge module sections
kbuild: lto: add a default list of used symbols
init: lto: ensure initcall ordering
init: lto: fix PREL32 relocations
PCI: Fix PREL32 relocations for LTO
modpost: lto: strip .lto from module names scripts/mod: disable LTO for empty.c efi/libstub: disable LTO
drivers/misc/lkdtm: disable LTO for rodata.o
arm64: vdso: disable LTO
arm64: disable recordmcount with DYNAMIC_FTRACE_WITH_REGS
arm64: allow LTO to be selected
.gitignore | 1 + Makefile | 45 +++-- arch/Kconfig | 90 +++++++++ arch/arm64/Kconfig | 4 + arch/arm64/kernel/vdso/Makefile | 3 +- drivers/firmware/efi/libstub/Makefile | 2 + drivers/misc/lkdtm/Makefile | 1 + include/asm-generic/vmlinux.lds.h | 11 +- include/linux/init.h | 79 +++++++- include/linux/pci.h | 19 +- init/Kconfig | 1 + kernel/trace/Kconfig | 16 ++ scripts/Makefile.build | 48 ++++- scripts/Makefile.lib | 6 +- scripts/Makefile.modfinal | 9 +- scripts/Makefile.modpost | 25 ++- scripts/generate_initcall_order.pl | 270 ++++++++++++++++++++++++++ scripts/link-vmlinux.sh | 70 ++++++- scripts/lto-used-symbollist | 5 + scripts/mod/Makefile | 1 + scripts/mod/modpost.c | 16 +- scripts/mod/modpost.h | 9 + scripts/mod/sumversion.c | 6 +- scripts/module.lds.S | 24 +++ 24 files changed, 696 insertions(+), 65 deletions(-) create mode 100755 scripts/generate_initcall_order.pl create mode 100644 scripts/lto-used-symbollist
base-commit: 33dc9614dc208291d0c4bcdeb5d30d481dcd2c4c
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Sami Tolvanen
maintainerPATCH v9 1/16 tracing: move function tracer options to Kconfig
Move function tracer options to Kconfig to make it easier to add new methods for generating __mcount_loc, and to make the options available also when building kernel modules.
Note that FTRACE_MCOUNT_USE_* options are updated on rebuild and therefore, work even if the .config was generated in a different environment.
--- Makefile | 20 ++++++++------------ kernel/trace/Kconfig | 16 ++++++++++++++++ scripts/Makefile.build | 6 ++---- 3 files changed, 26 insertions(+), 16 deletions(-)
Makefile +8 -12
@@ -851,12 +851,8 @@ KBUILD_CFLAGS += $(DEBUG_CFLAGS) export DEBUG_CFLAGS ifdef CONFIG_FUNCTION_TRACER -ifdef CONFIG_FTRACE_MCOUNT_RECORD - # gcc 5 supports generating the mcount tables directly - ifeq ($(call cc-option-yn,-mrecord-mcount),y) - CC_FLAGS_FTRACE += -mrecord-mcount - export CC_USING_RECORD_MCOUNT := 1 - endif +ifdef CONFIG_FTRACE_MCOUNT_USE_CC + CC_FLAGS_FTRACE += -mrecord-mcount ifdef CONFIG_HAVE_NOP_MCOUNT ifeq ($(call cc-option-yn, -mnop-mcount),y) CC_FLAGS_FTRACE += -mnop-mcount
@@ -864,6 +860,12 @@ ifdef CONFIG_FTRACE_MCOUNT_RECORD endif endif endif +ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT + ifdef CONFIG_HAVE_C_RECORDMCOUNT + BUILD_C_RECORDMCOUNT := y + export BUILD_C_RECORDMCOUNT + endif +endif ifdef CONFIG_HAVE_FENTRY ifeq ($(call cc-option-yn, -mfentry),y) CC_FLAGS_FTRACE += -mfentry
@@ -873,12 +875,6 @@ endif export CC_FLAGS_FTRACE KBUILD_CFLAGS += $(CC_FLAGS_FTRACE) $(CC_FLAGS_USING) KBUILD_AFLAGS += $(CC_FLAGS_USING) -ifdef CONFIG_DYNAMIC_FTRACE - ifdef CONFIG_HAVE_C_RECORDMCOUNT - BUILD_C_RECORDMCOUNT := y - export BUILD_C_RECORDMCOUNT - endif -endif endif # We trigger additional mismatches with less inlining
kernel/trace/Kconfig +16 -0
@@ -595,6 +595,22 @@ config FTRACE_MCOUNT_RECORD depends on DYNAMIC_FTRACE depends on HAVE_FTRACE_MCOUNT_RECORD +config FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY + bool + depends on FTRACE_MCOUNT_RECORD + +config FTRACE_MCOUNT_USE_CC + def_bool y + depends on $(cc-option,-mrecord-mcount) + depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY + depends on FTRACE_MCOUNT_RECORD + +config FTRACE_MCOUNT_USE_RECORDMCOUNT + def_bool y + depends on !FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY + depends on !FTRACE_MCOUNT_USE_CC + depends on FTRACE_MCOUNT_RECORD + config TRACING_MAP bool depends on ARCH_HAVE_NMI_SAFE_CMPXCHG
scripts/Makefile.build +2 -4
@@ -178,8 +178,7 @@ cmd_modversions_c = \ fi endif -ifdef CONFIG_FTRACE_MCOUNT_RECORD -ifndef CC_USING_RECORD_MCOUNT +ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT # compiler will not generate __mcount_loc use recordmcount or recordmcount.pl ifdef BUILD_C_RECORDMCOUNT ifeq ("$(origin RECORDMCOUNT_WARN)", "command line")
@@ -206,8 +205,7 @@ recordmcount_source := $(srctree)/scripts/recordmcount.pl endif # BUILD_C_RECORDMCOUNT cmd_record_mcount = $(if $(findstring $(strip $(CC_FLAGS_FTRACE)),$(_c_flags)), \ $(sub_cmd_record_mcount)) -endif # CC_USING_RECORD_MCOUNT -endif # CONFIG_FTRACE_MCOUNT_RECORD +endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT ifdef CONFIG_STACK_VALIDATION ifneq ($(SKIP_STACK_VALIDATION),1)
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Re: [PATCH v9 01/16] tracing: move function tracer options to Kconfig (causing parisc build failures)
Quoted 10 lines · Sami Tolvanen
Move function tracer options to
Kconfigto make it easier to add new methods for generating__mcount_loc, and to make the options available also when building kernel modules.Note that FTRACE_MCOUNT_USE_* options are updated on rebuild and therefore, work even if the .config was generated in a different environment.
Signed-off-by Sami Tolvanen <[email protected]>
With this patch in place, parisc:allmodconfig no longer builds.
Error log:
Arch parisc is not supported with CONFIG_FTRACE_MCOUNT_RECORD at scripts/recordmcount.pl line 405. make[2]: *** [scripts/mod/empty.o] Error 2
Due to this problem, CONFIG_FTRACE_MCOUNT_RECORD can no longer be enabled in parisc builds. Since that is auto-selected by DYNAMIC_FTRACE, DYNAMIC_FTRACE can no longer be enabled, and with it everything that depends on it.
Bisect log attached.
Guenter
---
# bad: [414eece95b98b209cef0f49cfcac108fd00b8ced] Merge tag 'clang-lto-v5.12-rc1-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
# good: [b12b47249688915e987a9a2a393b522f86f6b7ab] Merge tag 'powerpc-5.12-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
git bisect start '414eece95b98' 'b12b47249688'
# bad: [f6e1e1d1e149802ed4062fa514c2d184d30aacdf] Merge tag 'gfs2-for-5.12' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
git bisect bad f6e1e1d1e149802ed4062fa514c2d184d30aacdf
# bad: [79db4d2293eba2ce6265a341bedf6caecad5eeb3] Merge tag 'clang-lto-v5.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux
git bisect bad 79db4d2293eba2ce6265a341bedf6caecad5eeb3
# good: [9d5032f97e9e0655e8c507ab1f43237e31520b00] dt-bindings: mediatek: mt8192: Fix dt_binding_check warning
git bisect good 9d5032f97e9e0655e8c507ab1f43237e31520b00
# good: [f81f213850ca84b3d5e59e17d17acb2ecfc24076] Merge tag 'for-linus-5.12-1' of git://github.com/cminyard/linux-ipmi
git bisect good f81f213850ca84b3d5e59e17d17acb2ecfc24076
# bad: [112b6a8e038d793d016e330f53acb9383ac504b3] arm64: allow LTO to be selected
git bisect bad 112b6a8e038d793d016e330f53acb9383ac504b3
# bad: [3578ad11f3fba07e64c26d8db68cfd3dde28c59e] init: lto: fix PREL32 relocations
git bisect bad 3578ad11f3fba07e64c26d8db68cfd3dde28c59e
# bad: [22d429e75f24d114d99223389d6ba7047e952e32] kbuild: lto: limit inlining
git bisect bad 22d429e75f24d114d99223389d6ba7047e952e32
# bad: [dc5723b02e523b2c4a68667f7e28c65018f7202f] kbuild: add support for Clang LTO
git bisect bad dc5723b02e523b2c4a68667f7e28c65018f7202f
# bad: [3b15cdc15956673ba1551d79bceae471436ac6a9] tracing: move function tracer options to Kconfig
git bisect bad 3b15cdc15956673ba1551d79bceae471436ac6a9
# first bad commit: [3b15cdc15956673ba1551d79bceae471436ac6a9] tracing: move function tracer options to Kconfig
Re: [PATCH v9 01/16] tracing: move function tracer options to Kconfig (causing parisc build failures)
Quoted 14 lines · Guenter Roeck
Quoted 10 lines · Sami Tolvanen
Move function tracer options to
Kconfigto make it easier to add new methods for generating__mcount_loc, and to make the options available also when building kernel modules.Note that FTRACE_MCOUNT_USE_* options are updated on rebuild and therefore, work even if the .config was generated in a different environment.
Signed-off-by Sami Tolvanen <[email protected]>With this patch in place, parisc:allmodconfig no longer builds.
Quoted 8 lines
Error log:
Arch parisc is not supported withCONFIG_FTRACE_MCOUNT_RECORDatscripts/recordmcount.plline 405. make[2]: *** [scripts/mod/empty.o] Error 2Due to this problem,
CONFIG_FTRACE_MCOUNT_RECORDcan no longer be enabled in parisc builds. Since that is auto-selected byDYNAMIC_FTRACE,DYNAMIC_FTRACEcan no longer be enabled, and with it everything that depends on it.
Ew. Any idea why this didn't show up while it was in linux-next?
Signature · 1 line
Kees Cook
Sami Tolvanen
maintainerRe: [PATCH v9 01/16] tracing: move function tracer options to Kconfig (causing parisc build failures)
Quoted 20 lines · Kees Cook
Quoted 18 lines · Guenter Roeck
Quoted 10 lines · Sami Tolvanen
Move function tracer options to
Kconfigto make it easier to add new methods for generating__mcount_loc, and to make the options available also when building kernel modules.Note that FTRACE_MCOUNT_USE_* options are updated on rebuild and therefore, work even if the .config was generated in a different environment.
Signed-off-by Sami Tolvanen <[email protected]>With this patch in place, parisc:allmodconfig no longer builds.
Error log:
Arch parisc is not supported withCONFIG_FTRACE_MCOUNT_RECORDatscripts/recordmcount.plline 405. make[2]: *** [scripts/mod/empty.o] Error 2
Quoted 6 lines
Quoted 4 lines
Due to this problem,
CONFIG_FTRACE_MCOUNT_RECORDcan no longer be enabled in parisc builds. Since that is auto-selected byDYNAMIC_FTRACE,DYNAMIC_FTRACEcan no longer be enabled, and with it everything that depends on it.Ew. Any idea why this didn't show up while it was in linux-next?
Does anyone build parisc allmodconfig from -next?
parisc seems to always use -fpatchable-function-entry with dynamic ftrace, so we just need to select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY to stop it from defaulting to recordmcount:
arch/parisc/Kconfig +0 -0
@@ -60,6 +60,7 @@ config PARISC select HAVE_KPROBES select HAVE_KRETPROBES select HAVE_DYNAMIC_FTRACE if
$(cc-option,-fpatchable-function-entry=1,1)
+ select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY if HAVE_DYNAMIC_FTRACE
select HAVE_FTRACE_MCOUNT_RECORD if HAVE_DYNAMIC_FTRACE select HAVE_KPROBES_ON_FTRACE
select HAVE_DYNAMIC_FTRACE_WITH_REGS
I'll send a proper patch shortly.
Sami
Re: [PATCH v9 01/16] tracing: move function tracer options to Kconfig (causing parisc build failures)
Quoted 21 lines · Sami Tolvanen
Quoted 20 lines · Kees Cook
Quoted 18 lines · Guenter Roeck
Quoted 10 lines · Sami Tolvanen
Move function tracer options to
Kconfigto make it easier to add new methods for generating__mcount_loc, and to make the options available also when building kernel modules.Note that FTRACE_MCOUNT_USE_* options are updated on rebuild and therefore, work even if the .config was generated in a different environment.
Signed-off-by Sami Tolvanen <[email protected]>With this patch in place, parisc:allmodconfig no longer builds.
Error log:
Arch parisc is not supported withCONFIG_FTRACE_MCOUNT_RECORDatscripts/recordmcount.plline 405. make[2]: *** [scripts/mod/empty.o] Error 2
Quoted 9 lines
Quoted 6 lines
Quoted 4 lines
Due to this problem,
CONFIG_FTRACE_MCOUNT_RECORDcan no longer be enabled in parisc builds. Since that is auto-selected byDYNAMIC_FTRACE,DYNAMIC_FTRACEcan no longer be enabled, and with it everything that depends on it.Ew. Any idea why this didn't show up while it was in linux-next?
Does anyone build parisc allmodconfig from -next?
https://kerneltests.org/builders/next-parisc-next
Guenter
Quoted 22 lines
parisc seems to always use -fpatchable-function-entry with dynamic ftrace, so we just need to select
FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRYto stop it from defaulting to recordmcount:arch/parisc/Kconfig +1
-0@@ -60,6 +60,7 @@ config PARISC select HAVE_KPROBES select HAVE_KRETPROBES select HAVE_DYNAMIC_FTRACE if $(cc-option,-fpatchable-function-entry=1,1) + select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY if HAVE_DYNAMIC_FTRACE select HAVE_FTRACE_MCOUNT_RECORD if HAVE_DYNAMIC_FTRACE select HAVE_KPROBES_ON_FTRACEselect
HAVE_DYNAMIC_FTRACE_WITH_REGSI'll send a proper patch shortly.
Sami
Re: [PATCH v9 01/16] tracing: move function tracer options to Kconfig (causing parisc build failures)
In reply to Kees CookQuoted 19 lines · Kees Cook
Quoted 18 lines · Guenter Roeck
Quoted 10 lines · Sami Tolvanen
Move function tracer options to
Kconfigto make it easier to add new methods for generating__mcount_loc, and to make the options available also when building kernel modules.Note that FTRACE_MCOUNT_USE_* options are updated on rebuild and therefore, work even if the .config was generated in a different environment.
Signed-off-by Sami Tolvanen <[email protected]>With this patch in place, parisc:allmodconfig no longer builds.
Error log:
Arch parisc is not supported withCONFIG_FTRACE_MCOUNT_RECORDatscripts/recordmcount.plline 405. make[2]: *** [scripts/mod/empty.o] Error 2
Quoted 7 lines
Quoted 4 lines
Due to this problem,
CONFIG_FTRACE_MCOUNT_RECORDcan no longer be enabled in parisc builds. Since that is auto-selected byDYNAMIC_FTRACE,DYNAMIC_FTRACEcan no longer be enabled, and with it everything that depends on it.Ew. Any idea why this didn't show up while it was in linux-next?
It did, I just wasn't able to bisect it there.
Guenter
Re: [PATCH v9 01/16] tracing: move function tracer options to Kconfig (causing parisc build failures)
Quoted 25 lines · Guenter Roeck
Quoted 24 lines · Kees Cook
Quoted 22 lines · Guenter Roeck
Quoted 10 lines · Sami Tolvanen
Move function tracer options to
Kconfigto make it easier to add new methods for generating__mcount_loc, and to make the options available also when building kernel modules.Note that FTRACE_MCOUNT_USE_* options are updated on rebuild and therefore, work even if the .config was generated in a different environment.
Signed-off-by Sami Tolvanen <[email protected]>With this patch in place, parisc:allmodconfig no longer builds.
Error log:
Arch parisc is not supported withCONFIG_FTRACE_MCOUNT_RECORDatscripts/recordmcount.plline 405. make[2]: *** [scripts/mod/empty.o] Error 2Due to this problem,
CONFIG_FTRACE_MCOUNT_RECORDcan no longer be enabled in parisc builds. Since that is auto-selected byDYNAMIC_FTRACE,DYNAMIC_FTRACEcan no longer be enabled, and with it everything that depends on it.
Quoted 4 lines
Quoted 2 lines
Ew. Any idea why this didn't show up while it was in linux-next?
It did, I just wasn't able to bisect it there.
Ah-ha! Okay, thanks. Sorry it's been broken for so long! I've added parisc to my local cross builder now.
Signature · 1 line
Kees Cook
Sami Tolvanen
maintainerPATCH v9 2/16 kbuild: add support for Clang LTO
In reply to Sami TolvanenThis change adds build system support for Clang's Link Time Optimization (LTO). With -flto, instead of ELF object files, Clang produces LLVM bitcode, which is compiled into native code at link time, allowing the final binary to be optimized globally. For more details, see:
https://llvm.org/docs/LinkTimeOptimization.html
The Kconfig option CONFIG_LTO_CLANG is implemented as a choice, which defaults to LTO being disabled. To use LTO, the architecture must select ARCH_SUPPORTS_LTO_CLANG and support:
- compiling with Clang,
- compiling all assembly code with Clang's integrated assembler,
- and linking with LLD.
While using CONFIG_LTO_CLANG_FULL results in the best runtime performance, the compilation is not scalable in time or memory. CONFIG_LTO_CLANG_THIN enables ThinLTO, which allows parallel optimization and faster incremental builds. ThinLTO is used by default if the architecture also selects ARCH_SUPPORTS_LTO_CLANG_THIN:
https://clang.llvm.org/docs/ThinLTO.html
To enable LTO, LLVM tools must be used to handle bitcode files, by passing LLVM=1 and LLVM_IAS=1 options to make:
$ make LLVM=1 LLVM_IAS=1 defconfig $ scripts/config -e LTO_CLANG_THIN $ make LLVM=1 LLVM_IAS=1
To prepare for LTO support with other compilers, common parts are gated behind the CONFIG_LTO option, and LTO can be disabled for specific files by filtering out CC_FLAGS_LTO.
--- Makefile | 19 ++++++- arch/Kconfig | 91 +++++++++++++++++++++++++++++++ include/asm-generic/vmlinux.lds.h | 11 ++-- scripts/Makefile.build | 9 ++- scripts/Makefile.modfinal | 9 ++- scripts/Makefile.modpost | 21 ++++++- scripts/link-vmlinux.sh | 32 ++++++++--- 7 files changed, 174 insertions(+), 18 deletions(-)
Makefile +17 -2
@@ -893,6 +893,21 @@ KBUILD_CFLAGS += $(CC_FLAGS_SCS) export CC_FLAGS_SCS endif +ifdef CONFIG_LTO_CLANG +ifdef CONFIG_LTO_CLANG_THIN +CC_FLAGS_LTO += -flto=thin -fsplit-lto-unit +KBUILD_LDFLAGS += --thinlto-cache-dir=$(extmod-prefix).thinlto-cache +else +CC_FLAGS_LTO += -flto +endif +CC_FLAGS_LTO += -fvisibility=hidden +endif + +ifdef CONFIG_LTO +KBUILD_CFLAGS += $(CC_FLAGS_LTO) +export CC_FLAGS_LTO +endif + ifdef CONFIG_DEBUG_FORCE_FUNCTION_ALIGN_32B KBUILD_CFLAGS += -falign-functions=32 endif
@@ -1479,7 +1494,7 @@ MRPROPER_FILES += include/config include/generated \ *.spec # Directories & files removed with 'make distclean' -DISTCLEAN_FILES += tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS +DISTCLEAN_FILES += tags TAGS cscope* GPATH GTAGS GRTAGS GSYMS .thinlto-cache # clean - Delete most, but leave enough to build external modules #
@@ -1725,7 +1740,7 @@ PHONY += compile_commands.json clean-dirs := $(KBUILD_EXTMOD) clean: rm-files := $(KBUILD_EXTMOD)/Module.symvers $(KBUILD_EXTMOD)/modules.nsdeps \ - $(KBUILD_EXTMOD)/compile_commands.json + $(KBUILD_EXTMOD)/compile_commands.json $(KBUILD_EXTMOD)/.thinlto-cache PHONY += help help:
arch/Kconfig +91 -0
97 lines not on this page · raw message
include/asm-generic/vmlinux.lds.h +7 -4
@@ -90,15 +90,18 @@* .data. We don't want to pull in .data..other sections, which Linux * has defined. Same for text and bss. * +* With LTO_CLANG, the linker also splits sections by default, so we need +* these macros to combine the sections during the final link. +* * RODATA_MAIN is not used because existing code already defines .rodata.x * sections to be brought in with rodata. */ -#ifdef CONFIG_LD_DEAD_CODE_DATA_ELIMINATION +#if defined(CONFIG_LD_DEAD_CODE_DATA_ELIMINATION ) || defined(CONFIG_LTO_CLANG )#define TEXT_MAIN .text .text.[0-9a-zA-Z_]* -#define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data..LPBX* +#define DATA_MAIN .data .data.[0-9a-zA-Z_]* .data..L* .data..compoundliteral*#define SDATA_MAIN .sdata .sdata.[0-9a-zA-Z_]* -#define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]* -#define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* +#define RODATA_MAIN .rodata .rodata.[0-9a-zA-Z_]* .rodata..L* +#define BSS_MAIN .bss .bss.[0-9a-zA-Z_]* .bss..compoundliteral*#define SBSS_MAIN .sbss .sbss.[0-9a-zA-Z_]*#else #define TEXT_MAIN .text
scripts/Makefile.build +8 -1
@@ -111,7 +111,7 @@ endif # --------------------------------------------------------------------------- quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ - cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS), $(c_flags)) -fverbose-asm -S -o $@ $< + cmd_cc_s_c = $(CC) $(filter-out $(DEBUG_CFLAGS) $(CC_FLAGS_LTO), $(c_flags)) -fverbose-asm -S -o $@ $< $(obj)/%.s: $(src)/%.c FORCE $(call if_changed_dep,cc_s_c)
@@ -421,8 +421,15 @@ $(obj)/lib.a: $(lib-y) FORCE # 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. +ifdef CONFIG_LTO_CLANG +quiet_cmd_link_multi-m = AR [M] $@ +cmd_link_multi-m = \ + 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 $(multi-used-m): FORCE $(call if_changed,link_multi-m)
scripts/Makefile.modfinal +8 -1
@@ -6,6 +6,7 @@ PHONY := __modfinal __modfinal: +include $(objtree)/include/config/auto.conf include $(srctree)/scripts/Kbuild.include # for c_flags
@@ -29,6 +30,12 @@ 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 +endif + quiet_cmd_ld_ko_o = LD [M] $@ cmd_ld_ko_o = \ $(LD) -r $(KBUILD_LDFLAGS) \
@@ -36,7 +43,7 @@ quiet_cmd_ld_ko_o = LD [M] $@ -T scripts/module.lds -o $@ $(filter %.o, $^); \ $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) -$(modules): %.ko: %.o %.mod.o scripts/module.lds FORCE +$(modules): %.ko: %$(prelink-ext).o %.mod.o scripts/module.lds FORCE +$(call if_changed,ld_ko_o) targets += $(modules) $(modules:.ko=.mod.o)
scripts/Makefile.modpost +19 -2
@@ -43,6 +43,9 @@ __modpost: include include/config/auto.conf include scripts/Kbuild.include +# for ld_flags +include scripts/Makefile.lib + MODPOST = scripts/mod/modpost \ $(if $(CONFIG_MODVERSIONS),-m) \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a) \
@@ -102,12 +105,26 @@ $(input-symdump): @echo >&2 'WARNING: Symbol version dump "$@" is missing.' @echo >&2 ' Modules may not have dependencies or modversions.' +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 $@ --whole-archive $^ + +%.lto.o: %.o + $(call if_changed,cc_lto_link_modules) +endif + +modules := $(sort $(shell cat $(MODORDER))) + # 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$$/o/' $< | $(MODPOST) -T - + cmd_modpost = sed 's/\.ko$$/$(prelink-ext)\.o/' $< | $(MODPOST) -T - -$(output-symdump): $(MODORDER) $(input-symdump) FORCE +$(output-symdump): $(MODORDER) $(input-symdump) $(modules:.ko=$(prelink-ext).o) FORCE $(call if_changed,modpost) targets += $(output-symdump)
scripts/link-vmlinux.sh +24 -8
@@ -56,6 +56,14 @@ modpost_link() ${KBUILD_VMLINUX_LIBS} \ --end-group" + if [ -n "${CONFIG_LTO_CLANG}" ]; then + # This might take a while, so indicate that we're doing + # an LTO link + info LTO ${1} + else + info LD ${1} + fi + ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${objects} }
@@ -103,13 +111,22 @@ vmlinux_link() fi if [ "${SRCARCH}" != "um" ]; then - objects="--whole-archive \ - ${KBUILD_VMLINUX_OBJS} \ - --no-whole-archive \ - --start-group \ - ${KBUILD_VMLINUX_LIBS} \ - --end-group \ - ${@}" + if [ -n "${CONFIG_LTO_CLANG}" ]; then + # Use vmlinux.o instead of performing the slow LTO + # link again. + objects="--whole-archive \ + vmlinux.o \ + --no-whole-archive \ + ${@}" + else + objects="--whole-archive \ + ${KBUILD_VMLINUX_OBJS} \ + --no-whole-archive \ + --start-group \ + ${KBUILD_VMLINUX_LIBS} \ + --end-group \ + ${@}" + fi ${LD} ${KBUILD_LDFLAGS} ${LDFLAGS_vmlinux} \ ${strip_debug#-Wl,} \
@@ -274,7 +291,6 @@ fi; ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=init need-builtin=1 #link vmlinux.o -info LD vmlinux.o modpost_link vmlinux.o objtool_link vmlinux.o
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Sami Tolvanen
maintainerPATCH v9 3/16 kbuild: lto: fix module versioning
In reply to Sami TolvanenWith CONFIG_MODVERSIONS, version information is linked into each compilation unit that exports symbols. With LTO, we cannot use this method as all C code is compiled into LLVM bitcode instead. This change collects symbol versions into .symversions files and merges them in link-vmlinux.sh where they are all linked into vmlinux.o at the same time.
--- .gitignore | 1 + Makefile | 3 ++- arch/Kconfig | 1 - scripts/Makefile.build | 33 +++++++++++++++++++++++++++++++-- scripts/Makefile.modpost | 6 +++++- scripts/link-vmlinux.sh | 23 ++++++++++++++++++++++- 6 files changed, 61 insertions(+), 6 deletions(-)
.gitignore +1 -0
@@ -41,6 +41,7 @@ *.so.dbg *.su *.symtypes +*.symversions *.tab.[ch] *.tar *.xz
Makefile +2 -1
@@ -1837,7 +1837,8 @@ clean: $(clean-dirs) -o -name '.tmp_*.o.*' \ -o -name '*.c.[012]*.*' \ -o -name '*.ll' \ - -o -name '*.gcno' \) -type f -print | xargs rm -f + -o -name '*.gcno' \ + -o -name '*.*.symversions' \) -type f -print | xargs rm -f # Generate tags for editors # ---------------------------------------------------------------------------
arch/Kconfig +0 -1
@@ -635,7 +635,6 @@ config HAS_LTO_CLANG depends on !FTRACE_MCOUNT_USE_RECORDMCOUNT depends on !KASAN depends on !GCOV_KERNEL - depends on !MODVERSIONS help The compiler and Kconfig options support building with Clang's LTO.
scripts/Makefile.build +31 -2
@@ -166,6 +166,15 @@ ifdef CONFIG_MODVERSIONS # the actual value of the checksum generated by genksyms # o remove .tmp_<file>.o to <file>.o +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 = \ + if $(NM) $@ 2>/dev/null | grep -q __ksymtab; then \ + $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \ + > [email protected]; \ + fi; +else cmd_modversions_c = \ if $(OBJDUMP) -h $@ | grep -q __ksymtab; then \ $(call cmd_gensymtypes_c,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
@@ -177,6 +186,7 @@ cmd_modversions_c = \ rm -f $(@D)/.tmp_$(@F:.o=.ver); \ fi endif +endif ifdef CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT # compiler will not generate __mcount_loc use recordmcount or recordmcount.pl
@@ -386,6 +396,18 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler $(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ; $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; +# combine symversions for later processing +quiet_cmd_update_lto_symversions = SYMVER $@ +ifeq ($(CONFIG_LTO_CLANG) $(CONFIG_MODVERSIONS),y y) + cmd_update_lto_symversions = \ + rm -f [email protected] \ + $(foreach n, $(filter-out FORCE,$^), \ + $(if $(wildcard $(n).symversions), \ + ; cat $(n).symversions >> [email protected])) +else + cmd_update_lto_symversions = echo >/dev/null +endif + # # Rule to compile a set of .o files into one .a file (without symbol table) #
@@ -393,8 +415,11 @@ $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; 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) + $(obj)/built-in.a: $(real-obj-y) FORCE - $(call if_changed,ar_builtin) + $(call if_changed,ar_and_symver) # # Rule to create modules.order file
@@ -414,8 +439,11 @@ $(obj)/modules.order: $(obj-m) FORCE # # 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) + $(call if_changed,ar_lib) # NOTE: # Do not replace $(filter %.o,^) with $(real-prereqs). When a single object
@@ -424,6 +452,7 @@ $(obj)/lib.a: $(lib-y) FORCE ifdef CONFIG_LTO_CLANG quiet_cmd_link_multi-m = AR [M] $@ cmd_link_multi-m = \ + $(cmd_update_lto_symversions); \ rm -f $@; \ $(AR) cDPrsT $@ $(filter %.o,$^) else
scripts/Makefile.modpost +5 -1
@@ -111,7 +111,11 @@ ifdef CONFIG_LTO_CLANG prelink-ext := .lto quiet_cmd_cc_lto_link_modules = LTO [M] $@ -cmd_cc_lto_link_modules = $(LD) $(ld_flags) -r -o $@ --whole-archive $^ +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)
scripts/link-vmlinux.sh +22 -1
@@ -43,11 +43,26 @@ info() fi } +# If CONFIG_LTO_CLANG is selected, collect generated symbol versions into +# .tmp_symversions.lds +gen_symversions() +{ + info GEN .tmp_symversions.lds + rm -f .tmp_symversions.lds + + for o in ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS}; do + if [ -f ${o}.symversions ]; then + cat ${o}.symversions >> .tmp_symversions.lds + fi + done +} + # Link of vmlinux.o used for section mismatch analysis # ${1} output file modpost_link() { local objects + local lds="" objects="--whole-archive \ ${KBUILD_VMLINUX_OBJS} \
@@ -57,6 +72,11 @@ modpost_link() --end-group" if [ -n "${CONFIG_LTO_CLANG}" ]; then + if [ -n "${CONFIG_MODVERSIONS}" ]; then + gen_symversions + lds="${lds} -T .tmp_symversions.lds" + fi + # This might take a while, so indicate that we're doing # an LTO link info LTO ${1}
@@ -64,7 +84,7 @@ modpost_link() info LD ${1} fi - ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${objects} + ${LD} ${KBUILD_LDFLAGS} -r -o ${1} ${lds} ${objects} } objtool_link()
@@ -242,6 +262,7 @@ cleanup() { rm -f .btf.* rm -f .tmp_System.map + rm -f .tmp_symversions.lds rm -f .tmp_vmlinux* rm -f System.map rm -f vmlinux
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Sami Tolvanen
maintainerPATCH v9 4/16 kbuild: lto: limit inlining
In reply to Sami TolvanenThis change limits function inlining across translation unit boundaries in order to reduce the binary size with LTO. The -import-instr-limit flag defines a size limit, as the number of LLVM IR instructions, for importing functions from other TUs, defaulting to 100.
Based on testing with arm64 defconfig, we found that a limit of 5 is a reasonable compromise between performance and binary size, reducing the size of a stripped vmlinux by 11%.
--- Makefile | 3 +++ 1 file changed, 3 insertions(+)
Makefile +3 -0
@@ -901,6 +901,9 @@ else CC_FLAGS_LTO += -flto endif CC_FLAGS_LTO += -fvisibility=hidden + +# Limit inlining across translation units to reduce binary size +KBUILD_LDFLAGS += -mllvm -import-instr-limit=5 endif ifdef CONFIG_LTO
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Sami Tolvanen
maintainerPATCH v9 5/16 kbuild: lto: merge module sections
In reply to Sami TolvanenLLD always splits sections with LTO, which increases module sizes. This change adds linker script rules to merge the split sections in the final module.
--- scripts/module.lds.S | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
scripts/module.lds.S +24 -0
@@ -23,6 +23,30 @@ SECTIONS { .init_array 0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) } __jump_table 0 : ALIGN(8) { KEEP(*(__jump_table)) } + + __patchable_function_entries : { *(__patchable_function_entries) } + + /* + * With CONFIG_LTO_CLANG, LLD always enables -fdata-sections and + * -ffunction-sections, which increases the size of the final module. + * Merge the split sections in the final binary. + */ + .bss : { + *(.bss .bss.[0-9a-zA-Z_]*) + *(.bss..L*) + } + + .data : { + *(.data .data.[0-9a-zA-Z_]*) + *(.data..L*) + } + + .rodata : { + *(.rodata .rodata.[0-9a-zA-Z_]*) + *(.rodata..L*) + } + + .text : { *(.text .text.[0-9a-zA-Z_]*) } } /* bring in arch-specific sections */
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Re: [PATCH v9 05/16] kbuild: lto: merge module sections
Quoting Sami Tolvanen (2020-12-11 10:46:22)
Quoted 8 lines
LLD always splits sections with LTO, which increases module sizes. This change adds linker script rules to merge the split sections in the final module.
Suggested-by Nick Desaulniers <[email protected]>Signed-off-by Sami Tolvanen <[email protected]>Reviewed-by Kees Cook <[email protected]>---
This patch fixes a warning I see on arm64 devices running the 5.10 LTS kernel. Can we queue this to the stable tree once it lands in Linus' tree?
sysfs: cannot create duplicate filename '/module/configs/sections/__patchable_function_entries'
CPU: 3 PID: 4173 Comm: modprobe Not tainted 5.10.13 #10 Hardware name: Google Lazor (rev3+) with KB Backlight (DT) Call trace: dump_backtrace+0x0/0x1c0 show_stack+0x24/0x30 dump_stack+0xc0/0x120 sysfs_warn_dup+0x74/0x90 sysfs_add_file_mode_ns+0x12c/0x178 internal_create_group+0x264/0x36c sysfs_create_group+0x24/0x30 add_sect_attrs+0x154/0x188 mod_sysfs_setup+0x208/0x284 load_module+0xff8/0x1158 __arm64_sys_finit_module+0xb4/0xf0 el0_svc_common+0xf4/0x1c0 do_el0_svc_compat+0x2c/0x40 el0_svc_compat+0x10/0x1c el0_sync_compat_handler+0xc0/0xf0 el0_sync_compat+0x178/0x180
The problem is that the section __patchable_function_entries is present twice in the kernel module I've compiled. I see that __patchable_function_entries is used on arm64 now that we have commit a1326b17ac03 ("module/ftrace: handle patchable-function-entry") combined with commit 3b23e4991fb6 ("arm64: implement ftrace with regs").
This linker script change nicely combines the section into one instead of two.
Before:
$ readelf -WS configs.ko There are 29 section headers, starting at offset 0xad78:
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 [ 1] .plt NOBITS 0000000000000000 000040 000001 00 AX 0 0 16 [ 2] .init.plt NOBITS 0000000000000000 000040 000001 00 AX 0 0 1 [ 3] .text.ftrace_trampoline NOBITS 0000000000000000 000040 000001 00 AX 0 0 1 [ 4] .text PROGBITS 0000000000000000 000040 00004c 00 AX 0 0 4 [ 5] .rela.text RELA 0000000000000000 00aa10 000078 18 I 26 4 8 [ 6] __patchable_function_entries PROGBITS 0000000000000000 000090 000008 00 WAL 4 0 8 [ 7] .rela__patchable_function_entries RELA 0000000000000000 00aa88 000018 18 I 26 6 8 [ 8] .rodata PROGBITS 0000000000000000 000098 009c98 00 A 0 0 8 [ 9] .rela.rodata RELA 0000000000000000 00aaa0 000030 18 I 26 8 8 [10] .init.text PROGBITS 0000000000000000 009d30 000068 00 AX 0 0 4 [11] .rela.init.text RELA 0000000000000000 00aad0 0000f0 18 I 26 10 8 [12] __patchable_function_entries PROGBITS 0000000000000000 009d98 000008 00 WAL 10 0 8 [13] .rela__patchable_function_entries RELA 0000000000000000 00abc0 000018 18 I 26 12 8 [14] .exit.text PROGBITS 0000000000000000 009da0 000028 00 AX 0 0 4 [15] .rela.exit.text RELA 0000000000000000 00abd8 000048 18 I 26 14 8 [16] .modinfo PROGBITS 0000000000000000 009dc8 0000b1 00 A 0 0 1 [17] .rodata.str1.1 PROGBITS 0000000000000000 009e79 00000a 01 AMS 0 0 1 [18] .comment PROGBITS 0000000000000000 009e83 0000ce 01 MS 0 0 1 [19] .note.Linux NOTE 0000000000000000 009f54 000018 00 A 0 0 4 [20] .gnu.linkonce.this_module PROGBITS 0000000000000000 009f80 000380 00 WA 0 0 64 [21] .rela.gnu.linkonce.this_module RELA 0000000000000000 00ac20 000030 18 I 26 20 8 [22] .note.gnu.build-id NOTE 0000000000000000 00a300 000024 00 A 0 0 4 [23] .note.gnu.property NOTE 0000000000000000 00a328 000020 00 A 0 0 8 [24] .note.GNU-stack PROGBITS 0000000000000000 00a348 000000 00 0 0 1 [25] .gnu_debuglink PROGBITS 0000000000000000 00a348 000018 00 0 0 4 [26] .symtab SYMTAB 0000000000000000 00a360 0004f8 18 27 43 8 [27] .strtab STRTAB 0000000000000000 00a858 0001b1 00 0 0 1 [28] .shstrtab STRTAB 0000000000000000 00ac50 000128 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), p (processor specific)
After:
$ readelf -WS configs.ko There are 26 section headers, starting at offset 0xad40:
Section Headers:
[Nr] Name Type Address Off Size ES Flg Lk Inf Al [ 0] NULL 0000000000000000 000000 000000 00 0 0 0 [ 1] __patchable_function_entries PROGBITS 0000000000000000 000040 000010 00 WAL 5 0 8 [ 2] .rela__patchable_function_entries RELA 0000000000000000 00a9e0 000030 18 I 23 1 8 [ 3] .rodata PROGBITS 0000000000000000 000050 009ca2 00 AMS 0 0 8 [ 4] .rela.rodata RELA 0000000000000000 00aa10 000030 18 I 23 3 8 [ 5] .text PROGBITS 0000000000000000 009cf4 00004c 00 AX 0 0 4 [ 6] .rela.text RELA 0000000000000000 00aa40 000078 18 I 23 5 8 [ 7] .plt NOBITS 0000000000000000 009d40 000001 00 AX 0 0 16 [ 8] .init.plt NOBITS 0000000000000000 009d40 000001 00 AX 0 0 1 [ 9] .text.ftrace_trampoline NOBITS 0000000000000000 009d40 000001 00 AX 0 0 1 [10] .init.text PROGBITS 0000000000000000 009d40 000068 00 AX 0 0 4 [11] .rela.init.text RELA 0000000000000000 00aab8 0000f0 18 I 23 10 8 [12] .exit.text PROGBITS 0000000000000000 009da8 000028 00 AX 0 0 4 [13] .rela.exit.text RELA 0000000000000000 00aba8 000048 18 I 23 12 8 [14] .modinfo PROGBITS 0000000000000000 009dd0 0000b1 00 A 0 0 1 [15] .comment PROGBITS 0000000000000000 009e81 0000ce 01 MS 0 0 1 [16] .note.Linux NOTE 0000000000000000 009f50 000018 00 A 0 0 4 [17] .gnu.linkonce.this_module PROGBITS 0000000000000000 009f80 000380 00 WA 0 0 64 [18] .rela.gnu.linkonce.this_module RELA 0000000000000000 00abf0 000030 18 I 23 17 8 [19] .note.gnu.build-id NOTE 0000000000000000 00a300 000024 00 A 0 0 4 [20] .note.gnu.property NOTE 0000000000000000 00a328 000020 00 A 0 0 8 [21] .note.GNU-stack PROGBITS 0000000000000000 00a348 000000 00 0 0 1 [22] .gnu_debuglink PROGBITS 0000000000000000 00a348 000018 00 0 0 4 [23] .symtab SYMTAB 0000000000000000 00a360 0004c8 18 24 41 8 [24] .strtab STRTAB 0000000000000000 00a828 0001b1 00 0 0 1 [25] .shstrtab STRTAB 0000000000000000 00ac20 000119 00 0 0 1
Key to Flags:
W (write), A (alloc), X (execute), M (merge), S (strings), I (info), L (link order), O (extra OS processing required), G (group), T (TLS), C (compressed), x (unknown), o (OS specific), E (exclude), p (processor specific)
Quoted 27 lines
scripts/module.lds.S | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)scripts/module.lds.S +16
-0@@ -23,6 +23,30 @@ SECTIONS { .init_array 0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) } __jump_table 0 : ALIGN(8) { KEEP(*(__jump_table)) } + + __patchable_function_entries : { *(__patchable_function_entries) } + + /* + * With CONFIG_LTO_CLANG, LLD always enables -fdata-sections and + * -ffunction-sections, which increases the size of the final module. + * Merge the split sections in the final binary. + */ + .bss : { + *(.bss .bss.[0-9a-zA-Z_]*) + *(.bss..L*) + } + + .data : { + *(.data .data.[0-9a-zA-Z_]*) + *(.data..L*)
scripts/module.lds.S SECTIONS { · line 51
Quoted 10 lines
scripts/module.lds.S +8
-0+ } + + .rodata : { + *(.rodata .rodata.[0-9a-zA-Z_]*) + *(.rodata..L*) + } + + .text : { *(.text .text.[0-9a-zA-Z_]*) } }
_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Sami Tolvanen
maintainerPATCH v9 6/16 kbuild: lto: add a default list of used symbols
In reply to Sami TolvanenWith 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. This includes intrinsic functions, such as memcpy, memmove, and memset [1], and stack protector symbols [2]. This change adds a default symbol list to use with CONFIG_TRIM_UNUSED_KSYMS when Clang's LTO is used.
[1] https://llvm.org/docs/LangRef.html#standard-c-c-library-intrinsics
[2] https://llvm.org/docs/LangRef.html#llvm-stackprotector-intrinsic
--- init/Kconfig | 1 + scripts/lto-used-symbollist | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 scripts/lto-used-symbollist
init/Kconfig +1 -0
@@ -2297,6 +2297,7 @@ config TRIM_UNUSED_KSYMS config UNUSED_KSYMS_WHITELIST string "Whitelist of symbols to keep in ksymtab" depends on TRIM_UNUSED_KSYMS + default "scripts/lto-used-symbollist" if LTO_CLANG help By default, all unused exported symbols will be un-exported from the build when TRIM_UNUSED_KSYMS is selected.
scripts/lto-used-symbollist new file +5 -0
@@ -0,0 +1,5 @@ +memcpy +memmove +memset +__stack_chk_fail +__stack_chk_guard
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Re: [PATCH v9 06/16] kbuild: lto: add a default list of used symbols
Quoted 8 lines · Sami Tolvanen
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. This includes intrinsic functions, such as memcpy, memmove, and memset [1], and stack protector symbols [2]. This change adds a default symbol list to use withCONFIG_TRIM_UNUSED_KSYMSwhen Clang's LTO is used.
Quoted 4 lines
[1] https://llvm.org/docs/LangRef.html#standard-c-c-library-intrinsics
[2] https://llvm.org/docs/LangRef.html#llvm-stackprotector-intrinsicSigned-off-by Sami Tolvanen <[email protected]>
Quoted 32 lines
--- init/Kconfig | 1 + scripts/lto-used-symbollist | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 scripts/lto-used-symbollistinit/Kconfig +1
-0@@ -2297,6 +2297,7 @@ config TRIM_UNUSED_KSYMS config UNUSED_KSYMS_WHITELIST string "Whitelist of symbols to keep in ksymtab" depends on TRIM_UNUSED_KSYMS + default "scripts/lto-used-symbollist" if LTO_CLANG help By default, all unused exported symbols will be un-exported from the build when TRIM_UNUSED_KSYMS is selected.scripts/lto-used-symbollist new file +5
-0@@ -0,0 +1,5 @@ +memcpy +memmove +memset +__stack_chk_fail +__stack_chk_guardSignature · 1 line
2.29.2.576.ga3fc446d84-goog
bikeshed: Should this filename use some kind of extension, like lto-user-symbols.txt or .list, to make it more human-friendly?
Signature · 1 line
Kees Cook
Sami Tolvanen
maintainerRe: [PATCH v9 06/16] kbuild: lto: add a default list of used symbols
Quoted 44 lines · Kees Cook
Quoted 8 lines · Sami Tolvanen
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. This includes intrinsic functions, such as memcpy, memmove, and memset [1], and stack protector symbols [2]. This change adds a default symbol list to use withCONFIG_TRIM_UNUSED_KSYMSwhen Clang's LTO is used.Quoted 4 lines
[1] https://llvm.org/docs/LangRef.html#standard-c-c-library-intrinsics
[2] https://llvm.org/docs/LangRef.html#llvm-stackprotector-intrinsicSigned-off-by Sami Tolvanen <[email protected]>Reviewed-by Kees Cook <[email protected]>Quoted 27 lines
--- init/Kconfig | 1 + scripts/lto-used-symbollist | 5 +++++ 2 files changed, 6 insertions(+) create mode 100644 scripts/lto-used-symbollistinit/Kconfig +1
-0@@ -2297,6 +2297,7 @@ config TRIM_UNUSED_KSYMS config UNUSED_KSYMS_WHITELIST string "Whitelist of symbols to keep in ksymtab" depends on TRIM_UNUSED_KSYMS + default "scripts/lto-used-symbollist" if LTO_CLANG help By default, all unused exported symbols will be un-exported from the build when TRIM_UNUSED_KSYMS is selected.scripts/lto-used-symbollist new file +3
-0@@ -0,0 +1,5 @@ +memcpy +memmove +memset
Quoted 8 lines
Quoted 5 lines
scripts/lto-used-symbollist new file +2
-1+__stack_chk_fail +__stack_chk_guard --2.29.2.576.ga3fc446d84-goog
bikeshed: Should this filename use some kind of extension, like lto-user-symbols.txt or .list, to make it more human-friendly?
Sure, I can rename this in the next version. Does anyone have strong opinions about the name and/or extension?
Sami
Re: [PATCH v9 06/16] kbuild: lto: add a default list of used symbols
Quoted 19 lines · Sami Tolvanen
Quoted 16 lines · Kees Cook
Quoted 11 lines · Sami Tolvanen
scripts/lto-used-symbollist new file +5
-1@@ -0,0 +1,5 @@ +memcpy +memmove +memset +__stack_chk_fail +__stack_chk_guard --2.29.2.576.ga3fc446d84-goog
bikeshed: Should this filename use some kind of extension, like lto-user-symbols.txt or .list, to make it more human-friendly?
Quoted 2 lines
Sure, I can rename this in the next version. Does anyone have strong opinions about the name and/or extension?
.txt extension would be fine.
Signature · 2 lines
Thanks, ~Nick Desaulniers
Sami Tolvanen
maintainerPATCH v9 7/16 init: lto: ensure initcall ordering
In reply to Sami TolvanenWith LTO, the compiler doesn't necessarily obey the link order for initcalls, and initcall variables need globally unique names to avoid collisions at link time.
This change exports __KBUILD_MODNAME and adds the initcall_id() macro, which uses it together with __COUNTER__ and __LINE__ to help ensure these variables have unique names, and moves each variable to its own section when LTO is enabled, so the correct order can be specified using a linker script.
The generate_initcall_ordering.pl script uses nm to find initcalls from the object files passed to the linker, and generates a linker script that specifies the same order for initcalls that we would have without LTO. With LTO enabled, the script is called in link-vmlinux.sh through jobserver-exec to limit the number of jobs spawned.
--- include/linux/init.h | 52 +++++- scripts/Makefile.lib | 6 +- scripts/generate_initcall_order.pl | 270 +++++++++++++++++++++++++++++ scripts/link-vmlinux.sh | 15 ++ 4 files changed, 334 insertions(+), 9 deletions(-) create mode 100755 scripts/generate_initcall_order.pl
include/linux/init.h +45 -7
@@ -184,19 +184,57 @@ extern bool initcall_debug;* as KEEP() in the linker script. */ +/* Format: <modname>__<counter>_<line>_<fn> */ +#define __initcall_id (fn) \ + __PASTE(__KBUILD_MODNAME, \ + __PASTE(__, \ + __PASTE(__COUNTER__, \ + __PASTE(_, \ + __PASTE(__LINE__, \ + __PASTE(_, fn)))))) + +/* Format: __<prefix>__<iid><id> */ +#define __initcall_name (prefix, __iid, id) \ + __PASTE(__, \ + __PASTE(prefix, \ + __PASTE(__, \ + __PASTE(__iid, id)))) + +#ifdef CONFIG_LTO_CLANG +/* +* With LTO, the compiler doesn't necessarily obey link order for +* initcalls. In order to preserve the correct order, we add each +* variable into its own section and generate a linker script (in +* scripts/link-vmlinux.sh) to specify the order of the sections. +*/ +#define __initcall_section (__sec, __iid) \ + #__sec ".init.." #__iid +#else +#define __initcall_section (__sec, __iid) \ + #__sec ".init" +#endif +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS -#define ___define_initcall (fn, id, __sec) \ +#define ____define_initcall (fn, __name, __sec) \ __ADDRESSABLE(fn) \ - asm(".section \"" #__sec ".init\", \"a\" \n" \ - "__initcall_" #fn #id ": \n" \ + asm(".section \"" __sec "\", \"a\" \n" \ + __stringify(__name) ": \n" \ ".long " #fn " - . \n" \ ".previous \n");#else -#define ___define_initcall (fn, id, __sec) \ - static initcall_t __initcall_##fn##id __used \ - __attribute__((__section__(#__sec ".init"))) = fn; +#define ____define_initcall (fn, __name, __sec) \ + static initcall_t __name __used \ + __attribute__((__section__(__sec))) = fn;#endif +#define __unique_initcall (fn, id, __sec, __iid) \ + ____define_initcall(fn, \ + __initcall_name(initcall, __iid, id), \ + __initcall_section(__sec, __iid)) + +#define ___define_initcall (fn, id, __sec) \ + __unique_initcall(fn, id, __sec, __initcall_id(fn)) +#define __define_initcall (fn, id) ___define_initcall(fn, id, .initcall##id)/*
@@ -236,7 +274,7 @@ extern bool initcall_debug;#define __exitcall (fn) \ static exitcall_t __exitcall_##fn __exit_call = fn -#define console_initcall (fn) ___define_initcall(fn,, .con_initcall) +#define console_initcall (fn) ___define_initcall(fn, con, .con_initcall)struct obs_kernel_param {const char *str;
scripts/Makefile.lib +4 -2
@@ -117,9 +117,11 @@ target-stem = $(basename $(patsubst $(obj)/%,%,$@)) # These flags are needed for modversions and compiling, so we define them here # $(modname_flags) defines KBUILD_MODNAME as the name of the module it will # end up in (or would, if it gets compiled in) -name-fix = $(call stringify,$(subst $(comma),_,$(subst -,_,$1))) +name-fix-token = $(subst $(comma),_,$(subst -,_,$1)) +name-fix = $(call stringify,$(call name-fix-token,$1)) basename_flags = -DKBUILD_BASENAME=$(call name-fix,$(basetarget)) -modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) +modname_flags = -DKBUILD_MODNAME=$(call name-fix,$(modname)) \ + -D__KBUILD_MODNAME=kmod_$(call name-fix-token,$(modname)) modfile_flags = -DKBUILD_MODFILE=$(call stringify,$(modfile)) _c_flags = $(filter-out $(CFLAGS_REMOVE_$(target-stem).o), \
scripts/generate_initcall_order.pl new file +270 -0
270 lines not on this page · raw message
scripts/link-vmlinux.sh +15 -0
@@ -43,6 +43,17 @@ info() fi } +# Generate a linker script to ensure correct ordering of initcalls. +gen_initcalls() +{ + info GEN .tmp_initcalls.lds + + ${PYTHON} ${srctree}/scripts/jobserver-exec \ + ${PERL} ${srctree}/scripts/generate_initcall_order.pl \ + ${KBUILD_VMLINUX_OBJS} ${KBUILD_VMLINUX_LIBS} \ + > .tmp_initcalls.lds +} + # If CONFIG_LTO_CLANG is selected, collect generated symbol versions into # .tmp_symversions.lds gen_symversions()
@@ -72,6 +83,9 @@ modpost_link() --end-group" if [ -n "${CONFIG_LTO_CLANG}" ]; then + gen_initcalls + lds="-T .tmp_initcalls.lds" + if [ -n "${CONFIG_MODVERSIONS}" ]; then gen_symversions lds="${lds} -T .tmp_symversions.lds"
@@ -262,6 +276,7 @@ cleanup() { rm -f .btf.* rm -f .tmp_System.map + rm -f .tmp_initcalls.lds rm -f .tmp_symversions.lds rm -f .tmp_vmlinux* rm -f System.map
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Sami Tolvanen
maintainerPATCH v9 8/16 init: lto: fix PREL32 relocations
In reply to Sami TolvanenWith LTO, the compiler can rename static functions to avoid global naming collisions. As initcall functions are typically static, renaming can break references to them in inline assembly. This change adds a global stub with a stable name for each initcall to fix the issue when PREL32 relocations are used.
--- include/linux/init.h | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-)
include/linux/init.h +27 -4
@@ -209,26 +209,49 @@ extern bool initcall_debug;*/ #define __initcall_section (__sec, __iid) \ #__sec ".init.." #__iid + +/* +* With LTO, the compiler can rename static functions to avoid +* global naming collisions. We use a global stub function for +* initcalls to create a stable symbol name whose address can be +* taken in inline assembly when PREL32 relocations are used. +*/ +#define __initcall_stub (fn, __iid, id) \ + __initcall_name(initstub, __iid, id) + +#define __define_initcall_stub (__stub, fn) \ + int __init __stub(void); \ + int __init __stub(void) \ + { \ + return fn(); \ + } \ + __ADDRESSABLE(__stub)#else #define __initcall_section (__sec, __iid) \ #__sec ".init" + +#define __initcall_stub (fn, __iid, id) fn + +#define __define_initcall_stub (__stub, fn) \ + __ADDRESSABLE(fn)#endif #ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS -#define ____define_initcall (fn, __name, __sec) \ - __ADDRESSABLE(fn) \ +#define ____define_initcall (fn, __stub, __name, __sec) \ + __define_initcall_stub(__stub, fn) \ asm(".section \"" __sec "\", \"a\" \n" \ __stringify(__name) ": \n" \ - ".long " #fn " - . \n" \ + ".long " __stringify(__stub) " - . \n" \ ".previous \n");#else -#define ____define_initcall (fn, __name, __sec) \ +#define ____define_initcall (fn, __unused, __name, __sec) \ static initcall_t __name __used \ __attribute__((__section__(__sec))) = fn;#endif #define __unique_initcall (fn, id, __sec, __iid) \ ____define_initcall(fn, \ + __initcall_stub(fn, __iid, id), \ __initcall_name(initcall, __iid, id), \ __initcall_section(__sec, __iid))
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Sami Tolvanen
maintainerPATCH v9 9/16 PCI: Fix PREL32 relocations for LTO
In reply to Sami TolvanenWith Clang's Link Time Optimization (LTO), the compiler can rename static functions to avoid global naming collisions. As PCI fixup functions are typically static, renaming can break references to them in inline assembly. This change adds a global stub to DECLARE_PCI_FIXUP_SECTION to fix the issue when PREL32 relocations are used.
--- include/linux/pci.h | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-)
include/linux/pci.h +14 -5
@@ -1912,19 +1912,28 @@ enum pci_fixup_pass { };#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS -#define __DECLARE_PCI_FIXUP_SECTION (sec, name, vendor, device, class, \ - class_shift, hook) \ - __ADDRESSABLE(hook) \ +#define ___DECLARE_PCI_FIXUP_SECTION (sec, name, vendor, device, class, \ + class_shift, hook, stub) \ + void stub(struct pci_dev *dev); \ + void stub(struct pci_dev *dev) \ + { \ + hook(dev); \ + } \ asm(".section " #sec ", \"a\" \n" \ ".balign 16 \n" \ ".short " #vendor ", " #device " \n" \ ".long " #class ", " #class_shift " \n" \ - ".long " #hook " - . \n" \ + ".long " #stub " - . \n" \ ".previous \n"); + +#define __DECLARE_PCI_FIXUP_SECTION (sec, name, vendor, device, class, \ + class_shift, hook, stub) \ + ___DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ + class_shift, hook, stub)#define DECLARE_PCI_FIXUP_SECTION (sec, name, vendor, device, class, \ class_shift, hook) \ __DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ - class_shift, hook) + class_shift, hook, __UNIQUE_ID(hook))#else /* Anonymous variables would be nice... */ #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, class, \
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Sami Tolvanen
maintainerPATCH v9 10/16 modpost: lto: strip .lto from module names
In reply to Sami TolvanenWith LTO, everything is compiled into LLVM bitcode, so we have to link each module into native code before modpost. Kbuild uses the .lto.o suffix for these files, which also ends up in module information. This change strips the unnecessary .lto suffix from the module name.
--- scripts/mod/modpost.c | 16 +++++++--------- scripts/mod/modpost.h | 9 +++++++++ scripts/mod/sumversion.c | 6 +++++- 3 files changed, 21 insertions(+), 10 deletions(-)
scripts/mod/modpost.c +7 -9
@@ -17,7 +17,6 @@#include <ctype.h> #include <string.h> #include <limits.h> -#include <stdbool.h> #include <errno.h> #include "modpost.h" #include "../../include/linux/license.h"
@@ -80,14 +79,6 @@ modpost_log(enum loglevel loglevel, const char *fmt, ...)exit (1 ); } -static inline bool strends (const char *str,const char *postfix) -{ -if (strlen (str) <strlen (postfix)) -return false; - -return strcmp (str +strlen (str) -strlen (postfix), postfix) ==0 ; -} -void *do_nofail (void *ptr,const char *expr) {if (!ptr)
@@ -1984,6 +1975,10 @@ static char *remove_dot(char *s)size_t m =strspn (s + n +1 ,"0123456789" );if (m && (s[n + m] =='.' || s[n + m] ==0 )) s[n] =0 ; + +/* strip trailing .lto */ +if (strends (s,".lto" )) + s[strlen (s) -4 ] ='\0' ; }return s; }
@@ -2007,6 +2002,9 @@ static void read_symbols(const char *modname)/* strip trailing .o */ tmp =NOFAIL (strdup (modname)); tmp[strlen (tmp) -2 ] ='\0' ; +/* strip trailing .lto */ +if (strends (tmp,".lto" )) + tmp[strlen (tmp) -4 ] ='\0' ; mod =new_module (tmp);free (tmp); }
scripts/mod/modpost.h +9 -0
@@ -2,6 +2,7 @@#include <stdio.h> #include <stdlib.h> #include <stdarg.h> +#include <stdbool.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h>
@@ -180,6 +181,14 @@ static inline unsigned int get_secindex(const struct elf_info *info,return info->symtab_shndx_start[sym - info->symtab_start]; } +static inline bool strends (const char *str,const char *postfix) +{ +if (strlen (str) <strlen (postfix)) +return false; + +return strcmp (str +strlen (str) -strlen (postfix), postfix) ==0 ; +} +/* file2alias.c */ extern unsigned int cross_build; void handle_moddevtable(struct module *mod, struct elf_info *info,
scripts/mod/sumversion.c +5 -1
@@ -391,10 +391,14 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen)struct md4_ctx md;char *fname;char filelist[PATH_MAX +1 ]; +int postfix_len =1 ; + +if (strends (modname,".lto.o" )) + postfix_len =5 ;/* objects for a module are listed in the first line of *.mod file. */ snprintf (filelist,sizeof (filelist),"%.*smod" , - (int )strlen (modname) -1 , modname); + (int )strlen (modname) - postfix_len, modname); buf =read_text_file (filelist);
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Sami Tolvanen
maintainerPATCH v9 11/16 scripts/mod: disable LTO for empty.c
In reply to Sami TolvanenWith CONFIG_LTO_CLANG, clang generates LLVM IR instead of ELF object files. As empty.o is used for probing target properties, disable LTO for it to produce an object file instead.
--- scripts/mod/Makefile | 1 + 1 file changed, 1 insertion(+)
scripts/mod/Makefile +1 -0
@@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 OBJECT_FILES_NON_STANDARD := y +CFLAGS_REMOVE_empty.o += $(CC_FLAGS_LTO) hostprogs-always-y += modpost mk_elfconfig always-y += empty.o
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Sami Tolvanen
maintainerPATCH v9 12/16 efi/libstub: disable LTO
In reply to Sami TolvanenWith CONFIG_LTO_CLANG, we produce LLVM bitcode instead of ELF object files. Since LTO is not really needed here and the Makefile assumes we produce an object file, disable LTO for libstub.
--- drivers/firmware/efi/libstub/Makefile | 2 ++ 1 file changed, 2 insertions(+)
drivers/firmware/efi/libstub/Makefile +2 -0
@@ -38,6 +38,8 @@ KBUILD_CFLAGS := $(cflags-y) -Os -DDISABLE_BRANCH_PROFILING \ # remove SCS flags from all objects in this directory KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_SCS), $(KBUILD_CFLAGS)) +# disable LTO +KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS)) GCOV_PROFILE := n # Sanitizer runtimes are unavailable and cannot be linked here.
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Sami Tolvanen
maintainerPATCH v9 13/16 drivers/misc/lkdtm: disable LTO for rodata.o
In reply to Sami TolvanenDisable LTO for rodata.o to allow objcopy to be used to manipulate sections.
--- drivers/misc/lkdtm/Makefile | 1 + 1 file changed, 1 insertion(+)
drivers/misc/lkdtm/Makefile +1 -0
@@ -13,6 +13,7 @@ lkdtm-$(CONFIG_LKDTM) += cfi.o KASAN_SANITIZE_stackleak.o := n KCOV_INSTRUMENT_rodata.o := n +CFLAGS_REMOVE_rodata.o += $(CC_FLAGS_LTO) OBJCOPYFLAGS := OBJCOPYFLAGS_rodata_objcopy.o := \
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Sami Tolvanen
maintainerPATCH v9 14/16 arm64: vdso: disable LTO
In reply to Sami TolvanenDisable LTO for the vDSO by filtering out CC_FLAGS_LTO, as there's no point in using link-time optimization for the small amount of C code.
--- arch/arm64/kernel/vdso/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/arm64/kernel/vdso/Makefile +2 -1
@@ -30,7 +30,8 @@ ldflags-y := -shared -nostdlib -soname=linux-vdso.so.1 --hash-style=sysv \ ccflags-y := -fno-common -fno-builtin -fno-stack-protector -ffixed-x18 ccflags-y += -DDISABLE_BRANCH_PROFILING -CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) $(GCC_PLUGINS_CFLAGS) +CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE) -Os $(CC_FLAGS_SCS) $(GCC_PLUGINS_CFLAGS) \ + $(CC_FLAGS_LTO) KASAN_SANITIZE := n UBSAN_SANITIZE := n OBJECT_FILES_NON_STANDARD := y
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Sami Tolvanen
maintainerPATCH v9 15/16 arm64: disable recordmcount with DYNAMIC_FTRACE_WITH_REGS
In reply to Sami TolvanenDYNAMIC_FTRACE_WITH_REGS uses -fpatchable-function-entry, which makes running recordmcount unnecessary as there are no mcount calls in object files, and __mcount_loc doesn't need to be generated.
While there's normally no harm in running recordmcount even when it's not strictly needed, this won't work with LTO as we have LLVM bitcode instead of ELF objects.
This change selects FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY, which disables recordmcount when patchable function entries are used instead.
--- arch/arm64/Kconfig | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/Kconfig +2 -0
@@ -159,6 +159,8 @@ config ARM64 select HAVE_DYNAMIC_FTRACE select HAVE_DYNAMIC_FTRACE_WITH_REGS \ if $(cc-option,-fpatchable-function-entry=2) + select FTRACE_MCOUNT_USE_PATCHABLE_FUNCTION_ENTRY \ + if DYNAMIC_FTRACE_WITH_REGS select HAVE_EFFICIENT_UNALIGNED_ACCESS select HAVE_FAST_GUP select HAVE_FTRACE_MCOUNT_RECORD
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Sami Tolvanen
maintainerPATCH v9 16/16 arm64: allow LTO to be selected
In reply to Sami TolvanenAllow CONFIG_LTO_CLANG to be enabled.
--- arch/arm64/Kconfig | 2 ++ 1 file changed, 2 insertions(+)
arch/arm64/Kconfig +2 -0
@@ -73,6 +73,8 @@ config ARM64 select ARCH_USE_SYM_ANNOTATIONS select ARCH_SUPPORTS_MEMORY_FAILURE select ARCH_SUPPORTS_SHADOW_CALL_STACK if CC_HAVE_SHADOW_CALL_STACK + select ARCH_SUPPORTS_LTO_CLANG if CPU_LITTLE_ENDIAN + select ARCH_SUPPORTS_LTO_CLANG_THIN select ARCH_SUPPORTS_ATOMIC_RMW select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 && (GCC_VERSION >= 50000 || CC_IS_CLANG) select ARCH_SUPPORTS_NUMA_BALANCING
Signature · 1 line
2.29.2.576.ga3fc446d84-goog
Quoted 36 lines · Sami Tolvanen
This patch series adds support for building the kernel with Clang's Link Time Optimization (LTO). In addition to performance, the primary motivation for LTO is to allow Clang's Control-Flow Integrity (CFI) to be used in the kernel. Google has shipped millions of Pixel devices running three major kernel versions with LTO+CFI since 2018.
Most of the patches are build system changes for handling LLVM bitcode, which Clang produces with LTO instead of ELF object files, postponing ELF processing until a later stage, and ensuring initcall ordering.
Note that arm64 support depends on Will's memory ordering patches [1]. I will post
x86_64patches separately after we have fixed the remaining objtool warnings [2][3].[1] https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=for-next/lto
[2] https://lore.kernel.org/lkml/20201120040424.a3wctajzft4ufoiw@treble/
[3] https://git.kernel.org/pub/scm/linux/kernel/git/jpoimboe/linux.git/log/?h=objtool-vmlinuxYou can also pull this series from
https://github.com/samitolvanen/linux.git lto-v9
---
Changes in v9:- Added
HAS_LTO_CLANGdependencies to LLVM=1 and LLVM_IAS=1 to avoid issues with mismatched toolchains.- Dropped the .mod patch as Masahiro landed a better solution to the split line issue in commit
7d32358be8ac("kbuild: avoid split lines in .mod files").- Updated
CC_FLAGS_LTOto use -fvisibility=hidden to avoid weak symbol visibility issues with ThinLTO on x86.
Quoted 7 lines
- Changed
LTO_CLANG_FULLto depend on !COMPILE_TEST to prevent timeouts in automated testing.- Added a dependency to
CPU_LITTLE_ENDIANtoARCH_SUPPORTS_LTO_CLANGinarch/arm64/Kconfig.- Added a default symbol list to fix an issue with
TRIM_UNUSED_KSYMS.
This continues to look good to me. I'd like to see it in -next ASAP so we can continue to find any little needed tweaks. Since it works in the general case, we can add on top of this series once it's in -next.
Masahiro, let me know if you'd rather I not carry this in -next. AFAICT, the bulk of the changes in the build system continue to be confined to the LTO-only cases, so it should not be disruptive to anyone doing non-LTO builds.
Signature · 1 line
Kees Cook
Kees Cook
AppliedQuoted 6 lines · Sami Tolvanen
This patch series adds support for building the kernel with Clang's Link Time Optimization (LTO). In addition to performance, the primary motivation for LTO is to allow Clang's Control-Flow Integrity (CFI) to be used in the kernel. Google has shipped millions of Pixel devices running three major kernel versions with LTO+CFI since 2018.
Quoted 6 lines
Most of the patches are build system changes for handling LLVM bitcode, which Clang produces with LTO instead of ELF object files, postponing ELF processing until a later stage, and ensuring initcall ordering.
[...]
Applied to kspp/lto/v5.11-rc2, thanks!
I'll let 0-day grind on this over the weekend and toss it in -next on Monday if there aren't any objections.
[01/16] tracing: move function tracer options to Kconfig
https://git.kernel.org/kees/c/3b15cdc15956 [02/16] kbuild: add support for Clang LTO https://git.kernel.org/kees/c/833174494976 [03/16] kbuild: lto: fix module versioning https://git.kernel.org/kees/c/6eb20c5338a0 [04/16] kbuild: lto: limit inlining https://git.kernel.org/kees/c/f6db4eff0691 [05/16] kbuild: lto: merge module sections https://git.kernel.org/kees/c/d03e46783689 [06/16] kbuild: lto: add a default list of used symbols https://git.kernel.org/kees/c/81bfbc27b122 [07/16] init: lto: ensure initcall ordering https://git.kernel.org/kees/c/7918ea64195d [08/16] init: lto: fix PREL32 relocations https://git.kernel.org/kees/c/a51d9615ffb5 [09/16] PCI: Fix PREL32 relocations for LTO https://git.kernel.org/kees/c/dc83615370e7 [10/16] modpost: lto: strip .lto from module names https://git.kernel.org/kees/c/5c0312ef3ca0 [11/16] scripts/mod: disable LTO for empty.c https://git.kernel.org/kees/c/3d05432db312 [12/16] efi/libstub: disable LTO https://git.kernel.org/kees/c/b12eba00cb87 [13/16] drivers/misc/lkdtm: disable LTO for rodata.o https://git.kernel.org/kees/c/ed02e86f1752 [14/16] arm64: vdso: disable LTO https://git.kernel.org/kees/c/d73692f0f527 [15/16] arm64: disable recordmcount with DYNAMIC_FTRACE_WITH_REGS https://git.kernel.org/kees/c/09b812ac146f [16/16] arm64: allow LTO to be selected https://git.kernel.org/kees/c/1354b8946c46
Signature · 1 line
Kees Cook
Quoted 12 lines · Sami Tolvanen' via Clang Built Linux
This patch series adds support for building the kernel with Clang's Link Time Optimization (LTO). In addition to performance, the primary motivation for LTO is to allow Clang's Control-Flow Integrity (CFI) to be used in the kernel. Google has shipped millions of Pixel devices running three major kernel versions with LTO+CFI since 2018.
Most of the patches are build system changes for handling LLVM bitcode, which Clang produces with LTO instead of ELF object files, postponing ELF processing until a later stage, and ensuring initcall ordering.
Quoted 8 lines
Note that arm64 support depends on Will's memory ordering patches [1]. I will post
x86_64patches separately after we have fixed the remaining objtool warnings [2][3].[1] https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/log/?h=for-next/lto
[2] https://lore.kernel.org/lkml/20201120040424.a3wctajzft4ufoiw@treble/
[3] https://git.kernel.org/pub/scm/linux/kernel/git/jpoimboe/linux.git/log/?h=objtool-vmlinux
Hi Sami,
Thanks for the update.
I am interested in having Clang LTO (Clang-CFI) for x86-64 working and help with testing.
I tried the Git tree mentioned in [3] <jpoimboe.git#objtool-vmlinux> (together with changes from <peterz.git#x86/urgent>).
I only see in my build-log...
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:
eb_relocate_parse_slow()+0x3d0: stack state mismatch: cfa1=7+120 cfa2=-1+0 drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:
eb_copy_relocations()+0x229: stack state mismatch: cfa1=7+120 cfa2=-1+0
...which was reported and worked on in [1].
This is with Clang-IAS version 11.0.1.
Unfortunately, the recent changes in <samitolvanen.github#clang-cfi> do not cleanly apply with Josh stuff.
My intention/wish was to report this combination of patchsets "heals" a lot of objtool-warnings for vmlinux.o I observed with Clang-CFI.
Is it possible to have a Git branch where Josh's objtool-vmlinux is working together with Clang-LTO?
For testing purposes.
Thanks.
Regards,
- Sedat -
[1] https://github.com/ClangBuiltLinux/linux/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc
Quoted 194 lines
You can also pull this series from
https://github.com/samitolvanen/linux.git lto-v9
---
Changes in v9:- Added
HAS_LTO_CLANGdependencies to LLVM=1 and LLVM_IAS=1 to avoid issues with mismatched toolchains.- Dropped the .mod patch as Masahiro landed a better solution to the split line issue in commit
7d32358be8ac("kbuild: avoid split lines in .mod files").- Updated
CC_FLAGS_LTOto use -fvisibility=hidden to avoid weak symbol visibility issues with ThinLTO on x86.- Changed
LTO_CLANG_FULLto depend on !COMPILE_TEST to prevent timeouts in automated testing.- Added a dependency to
CPU_LITTLE_ENDIANtoARCH_SUPPORTS_LTO_CLANGinarch/arm64/Kconfig.- Added a default symbol list to fix an issue with
TRIM_UNUSED_KSYMS.Changes in v8:
- Cleaned up the LTO
Kconfigoptions based on suggestions from Nick and Kees.- Dropped the patch to disable LTO for the arm64 nVHE KVM code as David pointed out it's not needed anymore.
Changes in v7:
- Rebased to master again.
- Added back arm64 patches as the prerequisites are now staged, and dropped
x86_64support until the remaining objtool issues are resolved.- Dropped ifdefs from
module.lds.S.Changes in v6:
- Added the missing --mcount flag to patch 5.
- Dropped the arm64 patches from this series and will repost them later.
Changes in v5:
- Rebased on top of tip/master.
- Changed the command line for objtool to use --vmlinux --duplicate to disable warnings about retpoline thunks and to fix .orc_unwind generation for vmlinux.o.
- Added --noinstr flag to objtool, so we can use --vmlinux without also enabling noinstr validation.
- Disabled objtool's unreachable instruction warnings with LTO to disable false positives for the int3 padding in vmlinux.o.
- Added
ANNOTATE_RETPOLINE_SAFEannotations to the indirect jumps in x86 assembly code to fix objtool warnings with retpoline.- Fixed modpost warnings about missing version information with
CONFIG_MODVERSIONS.- Included Makefile.lib into Makefile.modpost for
ld_flags. Thanks to Sedat for pointing this out.- Updated the help text for ThinLTO to better explain the trade-offs.
- Updated commit messages with better explanations.
Changes in v4:
- Fixed a typo in Makefile.lib to correctly pass --no-fp to objtool.
- Moved ftrace configs related to generating
__mcount_loctoKconfig, so they are available also in Makefile.modfinal.- Dropped two prerequisite patches that were merged to Linus' tree.
Changes in v3:
- Added a separate patch to remove the unused
DISABLE_LTOtreewide, as filtering outCC_FLAGS_LTOinstead is preferred.- Updated the
Kconfighelp to explain why LTO is behind a choice and disabled by default.- Dropped
CC_FLAGS_LTO_CLANG, compiler-specific LTO flags are now appended directly toCC_FLAGS_LTO.- Updated $(AR) flags as
KBUILD_ARFLAGSwas removed earlier.- Fixed ThinLTO cache handling for external module builds.
- Rebased on top of Masahiro's patch for preprocessing
modules.lds, and moved the contents ofmodule-lto.ldstomodules.lds.S.- Moved
objtool_argsto Makefile.lib to avoid duplication of the command line parameters in Makefile.modfinal.- Clarified in the commit message for the initcall ordering patch that the initcall order remains the same as without LTO.
- Changed
link-vmlinux.shto use jobserver-exec to control the number of jobs started by generate_initcall_ordering.pl.- Dropped the x86/relocs patch to whitelist
L4_PAGE_OFFSETas it's no longer needed with ToT kernel.- Disabled LTO for
arch/x86/power/cpu.cto work around a Clang bug with stack protector attributes.Changes in v2:
- Fixed -Wmissing-prototypes warnings with W=1.
- Dropped cc-option from -fsplit-lto-unit and added .thinlto-cache scrubbing to make distclean.
- Added a comment about Clang >=11 being required.
- Added a patch to disable LTO for the arm64 KVM nVHE code.
- Disabled objtool's noinstr validation with LTO unless enabled.
- Included Peter's proposed objtool mcount patch in the series and replaced recordmcount with the objtool pass to avoid whitelisting relocations that are not calls.
- Updated several commit messages with better explanations.
Sami Tolvanen (16):
tracing: move function tracer options toKconfig
kbuild: add support for Clang LTO
kbuild: lto: fix module versioning
kbuild: lto: limit inlining
kbuild: lto: merge module sections
kbuild: lto: add a default list of used symbols
init: lto: ensure initcall ordering
init: lto: fix PREL32 relocations
PCI: Fix PREL32 relocations for LTO
modpost: lto: strip .lto from module namesscripts/mod: disable LTO forempty.cefi/libstub: disable LTO
drivers/misc/lkdtm: disable LTO for rodata.o
arm64: vdso: disable LTO
arm64: disable recordmcount withDYNAMIC_FTRACE_WITH_REGS
arm64: allow LTO to be selected.gitignore | 1 + Makefile | 45 +++-- arch/Kconfig | 90 +++++++++ arch/arm64/Kconfig | 4 + arch/arm64/kernel/vdso/Makefile | 3 +- drivers/firmware/efi/libstub/Makefile | 2 + drivers/misc/lkdtm/Makefile | 1 + include/asm-generic/vmlinux.lds.h | 11 +- include/linux/init.h | 79 +++++++- include/linux/pci.h | 19 +- init/Kconfig | 1 + kernel/trace/Kconfig | 16 ++ scripts/Makefile.build | 48 ++++- scripts/Makefile.lib | 6 +- scripts/Makefile.modfinal | 9 +- scripts/Makefile.modpost | 25 ++- scripts/generate_initcall_order.pl | 270 ++++++++++++++++++++++++++ scripts/link-vmlinux.sh | 70 ++++++- scripts/lto-used-symbollist | 5 + scripts/mod/Makefile | 1 + scripts/mod/modpost.c | 16 +- scripts/mod/modpost.h | 9 + scripts/mod/sumversion.c | 6 +- scripts/module.lds.S | 24 +++ 24 files changed, 696 insertions(+), 65 deletions(-) create mode 100755 scripts/generate_initcall_order.pl create mode 100644 scripts/lto-used-symbollistbase-commit:
33dc9614dc208291d0c4bcdeb5d30d481dcd2c4c--
2.29.2.576.ga3fc446d84-goog--
You received this message because you are subscribed to the Google Groups "Clang Built Linux" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/clang-built-linux/20201211184633.3213045-1-samitolvanen%40google.com.
Quoted 19 lines · Sedat Dilek
I am interested in having Clang LTO (Clang-CFI) for x86-64 working and help with testing.
I tried the Git tree mentioned in [3] <jpoimboe.git#objtool-vmlinux> (together with changes from <peterz.git#x86/urgent>).
I only see in my build-log...
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:
eb_relocate_parse_slow()+0x3d0: stack state mismatch: cfa1=7+120 cfa2=-1+0drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:
eb_copy_relocations()+0x229: stack state mismatch: cfa1=7+120 cfa2=-1+0...which was reported and worked on in [1].
This is with Clang-IAS version 11.0.1.
Quoted 8 lines
Unfortunately, the recent changes in <samitolvanen.github#clang-cfi> do not cleanly apply with Josh stuff.
My intention/wish was to report this combination of patchsets "heals" a lot of objtool-warnings for vmlinux.o I observed with Clang-CFI.Is it possible to have a Git branch where Josh's objtool-vmlinux is working together with Clang-LTO?
For testing purposes.
I updated my branch with my most recent work from before the holidays, can you try it now? It still doesn't fix any of the crypto warnings, but I'll do that in a separate set after posting these next week.
Signature · 1 line
Josh
Quoted 26 lines · Josh Poimboeuf
Quoted 24 lines · Sedat Dilek
I am interested in having Clang LTO (Clang-CFI) for x86-64 working and help with testing.
I tried the Git tree mentioned in [3] <jpoimboe.git#objtool-vmlinux> (together with changes from <peterz.git#x86/urgent>).
I only see in my build-log...
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:
eb_relocate_parse_slow()+0x3d0: stack state mismatch: cfa1=7+120 cfa2=-1+0drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:
eb_copy_relocations()+0x229: stack state mismatch: cfa1=7+120 cfa2=-1+0...which was reported and worked on in [1].
This is with Clang-IAS version 11.0.1.
Unfortunately, the recent changes in <samitolvanen.github#clang-cfi> do not cleanly apply with Josh stuff.
My intention/wish was to report this combination of patchsets "heals" a lot of objtool-warnings for vmlinux.o I observed with Clang-CFI.
Quoted 8 lines
Quoted 3 lines
Is it possible to have a Git branch where Josh's objtool-vmlinux is working together with Clang-LTO?
For testing purposes.I updated my branch with my most recent work from before the holidays, can you try it now? It still doesn't fix any of the crypto warnings, but I'll do that in a separate set after posting these next week.
Thanks, Josh.
Did you push it (oh ah push it push it really really really good...) to your remote Git please :-).
- Sedat -
Quoted 36 lines · Sedat Dilek
Quoted 26 lines · Josh Poimboeuf
Quoted 24 lines · Sedat Dilek
I am interested in having Clang LTO (Clang-CFI) for x86-64 working and help with testing.
I tried the Git tree mentioned in [3] <jpoimboe.git#objtool-vmlinux> (together with changes from <peterz.git#x86/urgent>).
I only see in my build-log...
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:
eb_relocate_parse_slow()+0x3d0: stack state mismatch: cfa1=7+120 cfa2=-1+0drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:
eb_copy_relocations()+0x229: stack state mismatch: cfa1=7+120 cfa2=-1+0...which was reported and worked on in [1].
This is with Clang-IAS version 11.0.1.
Unfortunately, the recent changes in <samitolvanen.github#clang-cfi> do not cleanly apply with Josh stuff.
My intention/wish was to report this combination of patchsets "heals" a lot of objtool-warnings for vmlinux.o I observed with Clang-CFI.Quoted 8 lines
Quoted 3 lines
Is it possible to have a Git branch where Josh's objtool-vmlinux is working together with Clang-LTO?
For testing purposes.I updated my branch with my most recent work from before the holidays, can you try it now? It still doesn't fix any of the crypto warnings, but I'll do that in a separate set after posting these next week.
Quoted 4 lines
Thanks, Josh.
Did you push it (oh ah push it push it really really really good...) to your remote Git please :-).
I thought I already pushed it pretty good ;-) do you not see it?
git://git.kernel.org/pub/scm/linux/kernel/git/jpoimboe/linux.git objtool-vmlinux
d6baee244f2d — objtool: Alphabetize usage option list (3 weeks ago)c0b2a6a625ac — objtool: Separate vmlinux/noinstr validation config options (3 weeks ago) 84c53551ad17 — objtool: Enable full vmlinux validation (3 weeks ago) e518ac0801cd — x86/power: Support objtool validation in hibernate_asm_64.S (3 weeks ago) d0ac4c7301c1 — x86/power: Move restore_registers() to top of the file (3 weeks ago) d3389bc83538 — x86/power: Convert indirect jumps to retpolines (3 weeks ago) 7a974d90aa40 — x86/acpi: Support objtool validation in wakeup_64.S (3 weeks ago) 6693e26cd6cc — x86/acpi: Convert indirect jump to retpoline (3 weeks ago) 0dfb760c74d1 — x86/ftrace: Support objtool vmlinux.o validation in ftrace_64.S (3 weeks ago) 89a4febfd7bf — x86/xen/pvh: Convert indirect jump to retpoline (3 weeks ago) b62837092140 — x86/xen: Support objtool vmlinux.o validation in xen-head.S (3 weeks ago) 705e18481ed9 — x86/xen: Support objtool validation in xen-asm.S (3 weeks ago) 3548319e21b9 — objtool: Add xen_start_kernel() to noreturn list (3 weeks ago) 6016e8da8c3d — objtool: Combine UNWIND_HINT_RET_OFFSET and UNWIND_HINT_FUNC (3 weeks ago) 56d6a7aee8b1 — objtool: Add asm version of STACK_FRAME_NON_STANDARD (3 weeks ago) 68259d951f1a — objtool: Assume only ELF functions do sibling calls (3 weeks ago) 0d6c8816cf91 — x86/ftrace: Add UNWIND_HINT_FUNC annotation for ftrace_stub (3 weeks ago) 24d6ce8cd8f6 — objtool: Support retpoline jump detection for vmlinux.o (3 weeks ago) 8145ea268f16 — objtool: Fix ".cold" section suffix check for newer versions of GCC (3 weeks ago) b3dfca472514 — objtool: Fix retpoline detection in asm code (3 weeks ago) b82402fa5211 — objtool: Fix error handling for STD/CLD warnings (3 weeks ago) 1f02defb4b79 — objtool: Fix seg fault in BT_FUNC() with fake jump (3 weeks ago) 2c85ebc57b3e — Linux 5.10 (4 weeks ago)
Signature · 1 line
Josh
Quoted 62 lines · Josh Poimboeuf
Quoted 36 lines · Sedat Dilek
Quoted 26 lines · Josh Poimboeuf
Quoted 24 lines · Sedat Dilek
I am interested in having Clang LTO (Clang-CFI) for x86-64 working and help with testing.
I tried the Git tree mentioned in [3] <jpoimboe.git#objtool-vmlinux> (together with changes from <peterz.git#x86/urgent>).
I only see in my build-log...
drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:
eb_relocate_parse_slow()+0x3d0: stack state mismatch: cfa1=7+120 cfa2=-1+0drivers/gpu/drm/i915/gem/i915_gem_execbuffer.o: warning: objtool:
eb_copy_relocations()+0x229: stack state mismatch: cfa1=7+120 cfa2=-1+0...which was reported and worked on in [1].
This is with Clang-IAS version 11.0.1.
Unfortunately, the recent changes in <samitolvanen.github#clang-cfi> do not cleanly apply with Josh stuff.
My intention/wish was to report this combination of patchsets "heals" a lot of objtool-warnings for vmlinux.o I observed with Clang-CFI.Quoted 8 lines
Quoted 3 lines
Is it possible to have a Git branch where Josh's objtool-vmlinux is working together with Clang-LTO?
For testing purposes.I updated my branch with my most recent work from before the holidays, can you try it now? It still doesn't fix any of the crypto warnings, but I'll do that in a separate set after posting these next week.
Quoted 4 lines
Thanks, Josh.
Did you push it (oh ah push it push it really really really good...) to your remote Git please :-).
I thought I already pushed it pretty good ;-) do you not see it?
git://git.kernel.org/pub/scm/linux/kernel/git/jpoimboe/linux.gitobjtool-vmlinux
d6baee244f2d— objtool: Alphabetize usage option list (3 weeks ago)c0b2a6a625ac— objtool: Separate vmlinux/noinstr validation config options (3 weeks ago)84c53551ad17— objtool: Enable full vmlinux validation (3 weeks ago)e518ac0801cd— x86/power: Support objtool validation inhibernate_asm_64.S(3 weeks ago)d0ac4c7301c1— x86/power: Moverestore_registers()to top of the file (3 weeks ago)d3389bc83538— x86/power: Convert indirect jumps to retpolines (3 weeks ago)7a974d90aa40— x86/acpi: Support objtool validation inwakeup_64.S(3 weeks ago)6693e26cd6cc— x86/acpi: Convert indirect jump to retpoline (3 weeks ago)0dfb760c74d1— x86/ftrace: Support objtool vmlinux.o validation inftrace_64.S(3 weeks ago)89a4febfd7bf— x86/xen/pvh: Convert indirect jump to retpoline (3 weeks ago)b62837092140— x86/xen: Support objtool vmlinux.o validation inxen-head.S(3 weeks ago)705e18481ed9— x86/xen: Support objtool validation inxen-asm.S(3 weeks ago)3548319e21b9— objtool: Addxen_start_kernel()to noreturn list (3 weeks ago)6016e8da8c3d— objtool: CombineUNWIND_HINT_RET_OFFSETandUNWIND_HINT_FUNC(3 weeks ago)56d6a7aee8b1— objtool: Add asm version ofSTACK_FRAME_NON_STANDARD(3 weeks ago)
Quoted 9 lines
68259d951f1a— objtool: Assume only ELF functions do sibling calls (3 weeks ago)0d6c8816cf91— x86/ftrace: AddUNWIND_HINT_FUNCannotation forftrace_stub(3 weeks ago)24d6ce8cd8f6— objtool: Support retpoline jump detection for vmlinux.o (3 weeks ago)8145ea268f16— objtool: Fix ".cold" section suffix check for newer versions of GCC (3 weeks ago)b3dfca472514— objtool: Fix retpoline detection in asm code (3 weeks ago)b82402fa5211— objtool: Fix error handling for STD/CLD warnings (3 weeks ago)1f02defb4b79— objtool: Fix seg fault inBT_FUNC()with fake jump (3 weeks ago)2c85ebc57b3e— Linux 5.10 (4 weeks ago)
I already have this one in my patch-series - I hoped you pushed something new to your objtool-vmlinux Git branch.
That is what I mean by shortened... <jpoimboe.git#objtool-vmlinux>.
Hey, it's based on Linux v5.10 - I can test this with Linux v5.10.6 :-).
- Sedat -
Quoted 32 lines
Quoted 22 lines
Quoted 2 lines
Did you push it (oh ah push it push it really really really good...) to your remote Git please :-).
I thought I already pushed it pretty good ;-) do you not see it?
git://git.kernel.org/pub/scm/linux/kernel/git/jpoimboe/linux.gitobjtool-vmlinux
d6baee244f2d— objtool: Alphabetize usage option list (3 weeks ago)c0b2a6a625ac— objtool: Separate vmlinux/noinstr validation config options (3 weeks ago)84c53551ad17— objtool: Enable full vmlinux validation (3 weeks ago)e518ac0801cd— x86/power: Support objtool validation inhibernate_asm_64.S(3 weeks ago)d0ac4c7301c1— x86/power: Moverestore_registers()to top of the file (3 weeks ago)d3389bc83538— x86/power: Convert indirect jumps to retpolines (3 weeks ago)7a974d90aa40— x86/acpi: Support objtool validation inwakeup_64.S(3 weeks ago)6693e26cd6cc— x86/acpi: Convert indirect jump to retpoline (3 weeks ago)0dfb760c74d1— x86/ftrace: Support objtool vmlinux.o validation inftrace_64.S(3 weeks ago)89a4febfd7bf— x86/xen/pvh: Convert indirect jump to retpoline (3 weeks ago)b62837092140— x86/xen: Support objtool vmlinux.o validation inxen-head.S(3 weeks ago)705e18481ed9— x86/xen: Support objtool validation inxen-asm.S(3 weeks ago)3548319e21b9— objtool: Addxen_start_kernel()to noreturn list (3 weeks ago)6016e8da8c3d— objtool: CombineUNWIND_HINT_RET_OFFSETandUNWIND_HINT_FUNC(3 weeks ago)56d6a7aee8b1— objtool: Add asm version ofSTACK_FRAME_NON_STANDARD(3 weeks ago)Quoted 9 lines
68259d951f1a— objtool: Assume only ELF functions do sibling calls (3 weeks ago)0d6c8816cf91— x86/ftrace: AddUNWIND_HINT_FUNCannotation forftrace_stub(3 weeks ago)24d6ce8cd8f6— objtool: Support retpoline jump detection for vmlinux.o (3 weeks ago)8145ea268f16— objtool: Fix ".cold" section suffix check for newer versions of GCC (3 weeks ago)b3dfca472514— objtool: Fix retpoline detection in asm code (3 weeks ago)b82402fa5211— objtool: Fix error handling for STD/CLD warnings (3 weeks ago)1f02defb4b79— objtool: Fix seg fault inBT_FUNC()with fake jump (3 weeks ago)2c85ebc57b3e— Linux 5.10 (4 weeks ago)
Quoted 5 lines
I already have this one in my patch-series - I hoped you pushed something new to your objtool-vmlinux Git branch.
That is what I mean by shortened... <jpoimboe.git#objtool-vmlinux>.Hey, it's based on Linux v5.10 - I can test this with Linux v5.10.6 :-).
This is the most recent version of the patches. I only pushed them this morning since you said the prior version wasn't applying on Sami's clang-cfi branch. This version rebases fine on 'clang-cfi'.
Signature · 1 line
Josh
Quoted 37 lines · Josh Poimboeuf
Quoted 37 lines
Quoted 23 lines
Quoted 3 lines
Did you push it (oh ah push it push it really really really good...) to your remote Git please :-).
I thought I already pushed it pretty good ;-) do you not see it?
git://git.kernel.org/pub/scm/linux/kernel/git/jpoimboe/linux.gitobjtool-vmlinux
d6baee244f2d— objtool: Alphabetize usage option list (3 weeks ago)c0b2a6a625ac— objtool: Separate vmlinux/noinstr validation config options (3 weeks ago)84c53551ad17— objtool: Enable full vmlinux validation (3 weeks ago)e518ac0801cd— x86/power: Support objtool validation inhibernate_asm_64.S(3 weeks ago)d0ac4c7301c1— x86/power: Moverestore_registers()to top of the file (3 weeks ago)d3389bc83538— x86/power: Convert indirect jumps to retpolines (3 weeks ago)7a974d90aa40— x86/acpi: Support objtool validation inwakeup_64.S(3 weeks ago)6693e26cd6cc— x86/acpi: Convert indirect jump to retpoline (3 weeks ago)0dfb760c74d1— x86/ftrace: Support objtool vmlinux.o validation inftrace_64.S(3 weeks ago)89a4febfd7bf— x86/xen/pvh: Convert indirect jump to retpoline (3 weeks ago)b62837092140— x86/xen: Support objtool vmlinux.o validation inxen-head.S(3 weeks ago)705e18481ed9— x86/xen: Support objtool validation inxen-asm.S(3 weeks ago)3548319e21b9— objtool: Addxen_start_kernel()to noreturn list (3 weeks ago)6016e8da8c3d— objtool: CombineUNWIND_HINT_RET_OFFSETandUNWIND_HINT_FUNC(3 weeks ago)56d6a7aee8b1— objtool: Add asm version ofSTACK_FRAME_NON_STANDARD(3 weeks ago)Quoted 9 lines
68259d951f1a— objtool: Assume only ELF functions do sibling calls (3 weeks ago)0d6c8816cf91— x86/ftrace: AddUNWIND_HINT_FUNCannotation forftrace_stub(3 weeks ago)24d6ce8cd8f6— objtool: Support retpoline jump detection for vmlinux.o (3 weeks ago)8145ea268f16— objtool: Fix ".cold" section suffix check for newer versions of GCC (3 weeks ago)b3dfca472514— objtool: Fix retpoline detection in asm code (3 weeks ago)b82402fa5211— objtool: Fix error handling for STD/CLD warnings (3 weeks ago)1f02defb4b79— objtool: Fix seg fault inBT_FUNC()with fake jump (3 weeks ago)2c85ebc57b3e— Linux 5.10 (4 weeks ago)I already have this one in my patch-series - I hoped you pushed something new to your objtool-vmlinux Git branch.
That is what I mean by shortened... <jpoimboe.git#objtool-vmlinux>.
Quoted 6 lines
Quoted 1 line
Hey, it's based on Linux v5.10 - I can test this with Linux v5.10.6 :-).
This is the most recent version of the patches. I only pushed them this morning since you said the prior version wasn't applying on Sami's clang-cfi branch. This version rebases fine on 'clang-cfi'.
I tried merging with clang-cfi Git which is based on Linux v5.11-rc2+ with a lot of merge conflicts.
Did you try on top of cfi-10 Git tag which is based on Linux v5.10?
Whatever you successfully did... Can you give me a step-by-step instruction?
- Sedat -
Quoted 6 lines · Sedat Dilek
I tried merging with clang-cfi Git which is based on Linux v5.11-rc2+ with a lot of merge conflicts.
Did you try on top of cfi-10 Git tag which is based on Linux v5.10?
Whatever you successfully did... Can you give me a step-by-step instruction?
Oops, my bad. My last three commits (which I just added) do conflict. Sorry for the confusion.
Just drop my last three commits:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/jpoimboe/linux.git objtool-vmlinux git checkout -B tmp FETCH_HEAD
git reset --hard HEAD~~~
git fetch https://github.com/samitolvanen/linux clang-lto
git rebase --onto FETCH_HEAD 79881bfc57be
Signature · 1 line
Josh
Quoted 11 lines · Josh Poimboeuf
Quoted 6 lines · Sedat Dilek
I tried merging with clang-cfi Git which is based on Linux v5.11-rc2+ with a lot of merge conflicts.
Did you try on top of cfi-10 Git tag which is based on Linux v5.10?
Whatever you successfully did... Can you give me a step-by-step instruction?
Oops, my bad. My last three commits (which I just added) do conflict. Sorry for the confusion.
Quoted 7 lines
Just drop my last three commits:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/jpoimboe/linux.git objtool-vmlinux git checkout -B tmp
FETCH_HEAD
git reset --hard HEAD~~~
git fetch https://github.com/samitolvanen/linux clang-lto
git rebase --ontoFETCH_HEAD79881bfc57be
Last one should be:
git rebase --onto FETCH_HEAD 2c85ebc57b3e
Signature · 1 line
Josh
Quoted 21 lines · Josh Poimboeuf
Quoted 11 lines · Josh Poimboeuf
Quoted 6 lines · Sedat Dilek
I tried merging with clang-cfi Git which is based on Linux v5.11-rc2+ with a lot of merge conflicts.
Did you try on top of cfi-10 Git tag which is based on Linux v5.10?
Whatever you successfully did... Can you give me a step-by-step instruction?
Oops, my bad. My last three commits (which I just added) do conflict. Sorry for the confusion.
Quoted 7 lines
Just drop my last three commits:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/jpoimboe/linux.git objtool-vmlinux git checkout -B tmp
FETCH_HEAD
git reset --hard HEAD~~~
git fetch https://github.com/samitolvanen/linux clang-lto
git rebase --ontoFETCH_HEAD79881bfc57be
Quoted 4 lines
Last one should be:
git rebase --onto
FETCH_HEAD2c85ebc57b3e
OK, that worked fine.
So commit 2c85ebc57b3e is v5.10 Git tag in upstream.
So, I substituted:
git rebase --onto FETCH_HEAD v5.10
Thanks.
- Sedat -
Quoted 21 lines · Josh Poimboeuf
Quoted 11 lines · Josh Poimboeuf
Quoted 6 lines · Sedat Dilek
I tried merging with clang-cfi Git which is based on Linux v5.11-rc2+ with a lot of merge conflicts.
Did you try on top of cfi-10 Git tag which is based on Linux v5.10?
Whatever you successfully did... Can you give me a step-by-step instruction?
Oops, my bad. My last three commits (which I just added) do conflict. Sorry for the confusion.
Quoted 7 lines
Just drop my last three commits:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/jpoimboe/linux.git objtool-vmlinux git checkout -B tmp
FETCH_HEAD
git reset --hard HEAD~~~
git fetch https://github.com/samitolvanen/linux clang-lto
git rebase --ontoFETCH_HEAD79881bfc57be
Quoted 4 lines
Last one should be:
git rebase --onto
FETCH_HEAD2c85ebc57b3e
Hi Josh,
as said I tried your latest changes on top of Linux v5.10.6 + cfi-5.10. This reduces the objtool-warnings in vmlinux.o from 15 down to 2.
Without your latest changes:
$ grep 'vmlinux.o: warning: objtool:' build-log_5.10.4-3-amd64-clang11-cfi.txt | wc -l 15
$ grep 'vmlinux.o: warning: objtool:' build-log_5.10.4-3-amd64-clang11-cfi.txt vmlinux.o: warning: objtool: wakeup_long64()+0x61: indirect jump found in RETPOLINE build vmlinux.o: warning: objtool: .text+0x408a: indirect jump found in RETPOLINE build vmlinux.o: warning: objtool: .text+0x40c5: indirect jump found in RETPOLINE build vmlinux.o: warning: objtool: .head.text+0x298: indirect jump found in RETPOLINE build vmlinux.o: warning: objtool: __switch_to_asm()+0x0: undefined stack state vmlinux.o: warning: objtool: .entry.text+0xf91: sibling call from callable instruction with modified stack frame vmlinux.o: warning: objtool: .entry.text+0x16c4: unsupported instruction in callable function vmlinux.o: warning: objtool: .entry.text+0x15a4: redundant CLD vmlinux.o: warning: objtool: do_suspend_lowlevel()+0x116: sibling call from callable instruction with modified stack frame vmlinux.o: warning: objtool: kretprobe_trampoline()+0x49: return with modified stack frame vmlinux.o: warning: objtool: machine_real_restart()+0x85: unsupported instruction in callable function vmlinux.o: warning: objtool: __x86_retpoline_rdi()+0x0: stack state mismatch: cfa1=7+8 cfa2=-1+0 vmlinux.o: warning: objtool: .entry.text+0x48: stack state mismatch: cfa1=7-8 cfa2=-1+0 vmlinux.o: warning: objtool: .entry.text+0x156d: stack state mismatch: cfa1=7-8 cfa2=-1+0 vmlinux.o: warning: objtool: .entry.text+0x15fc: stack state mismatch: cfa1=7-8 cfa2=-1+0
With your latest changes in <jpoimboe.git#objtool-vmlinux>:
$ grep 'vmlinux.o: warning: objtool:' build-log_5.10.6-1-amd64-clang11-cfi.txt | wc -l 2
$ grep 'vmlinux.o: warning: objtool:' build-log_5.10.6-1-amd64-clang11-cfi.txt vmlinux.o: warning: objtool: kretprobe_trampoline()+0x49: return with modified stack frame vmlinux.o: warning: objtool: machine_real_restart()+0x85: unsupported instruction in callable function
Awesome.
If you need further information, please let me know.
Regards,
- Sedat -