From patchwork Thu Aug 12 21:46:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sami Tolvanen X-Patchwork-Id: 12434343 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-31.2 required=3.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,MENTIONS_GIT_HOSTING, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4F4A3C4338F for ; Thu, 12 Aug 2021 21:46:22 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2D1D960F57 for ; Thu, 12 Aug 2021 21:46:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234970AbhHLVqp (ORCPT ); Thu, 12 Aug 2021 17:46:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36602 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233443AbhHLVqo (ORCPT ); Thu, 12 Aug 2021 17:46:44 -0400 Received: from mail-qv1-xf49.google.com (mail-qv1-xf49.google.com [IPv6:2607:f8b0:4864:20::f49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D0BEDC061756 for ; Thu, 12 Aug 2021 14:46:18 -0700 (PDT) Received: by mail-qv1-xf49.google.com with SMTP id m10-20020a056214158ab029035a6c1e5f3eso2897395qvw.7 for ; Thu, 12 Aug 2021 14:46:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:message-id:mime-version:subject:from:to:cc; bh=sjTPZGTvZKiaOAM86brwyuK7yAS2+708sFuV4hc9PT8=; b=M1L7KG5/2IUfuDN6P+hk2lFs4znvE/uDZxnB1hL38LhpCAlYPPkpq3lwHRj3iC5E35 GxQgqx6js3KqMpZBAMnxhzhtAzQr+Ea5g8CdumlPHhOWJ0LP7lh6C+1F18TwSGt8NvUF aEKcqx1DRneecULSYbpcFk6rwCQu1gBOtOakjrck9kopL/p91BqVCkNygiMmVTuck9cA 3PuHrcGE+5EZXErsybMcYRP4fSnyJOv01ibr+cQxCvb+hdoBW+QXRKyvOS0OOuduU3qv JTGqv+Q3t9C6kT9dEkCgj7BHlaNnxnFk86EEBFjkfFKVIri3u/f3eDksU20IBqROAMHC 0VhA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=sjTPZGTvZKiaOAM86brwyuK7yAS2+708sFuV4hc9PT8=; b=rXZEPKPY397xTjFykelfk2yd9r4YnzIJio7sxamw32HvgiRo5FYEMnSBbc0Fjb8ytF NlW9Jx03/PnGEgoi720kKNaWxHAdsAIreA2bveLcDB7p+FjesZHDqfJFcGgqTtbDymI6 12G7aK1xSr8RBvTbtq5z9Zg5k9Apr+6W/5hN3Wpc7gF8g5oROWjhDKlR8S9mlqq/iAht DR9mI15bAVZE2Lca3kk6P3f7VaoySsGFkCRVk9FmLRR8YeOlD44II/6PWnNZrK1N3V05 bATie5B/rriLVcxIRe3G9DepEBlqE8kkx2/R/UB/2blg5Hg+Pkg2dDLQK+PW4dWU9Ftt VIIA== X-Gm-Message-State: AOAM532bc7AkaTM7fGKMkrmahvm2JEMNAZO+YZIfxbdHNfeOYNU1s0Yi 2NmJpMMp5JDCyObx7iTVqXH0gBMFLtgK9V2MQm8= X-Google-Smtp-Source: ABdhPJzaMNUGNMjUI5PYAddJZnTVUyHXt6h7uDpU0t43x7wh5H01rFSlbrT2u8EVGQU521jHcjQYvsGFyRt1ffCHIp4= X-Received: from samitolvanen1.mtv.corp.google.com ([2620:15c:201:2:e70b:1371:bfbf:9b2c]) (user=samitolvanen job=sendgmr) by 2002:a0c:b450:: with SMTP id e16mr6056860qvf.25.1628804777971; Thu, 12 Aug 2021 14:46:17 -0700 (PDT) Date: Thu, 12 Aug 2021 14:46:14 -0700 Message-Id: <20210812214614.1797845-1-samitolvanen@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.33.0.rc1.237.g0d66db33f3-goog Subject: [PATCH v3] kbuild: Fix TRIM_UNUSED_KSYMS with LTO_CLANG From: Sami Tolvanen To: Kees Cook , Masahiro Yamada , Michal Marek Cc: Alexander Lobakin , Nathan Chancellor , Nick Desaulniers , linux-kbuild@vger.kernel.org, clang-built-linux@googlegroups.com, linux-kernel@vger.kernel.org, Sami Tolvanen Precedence: bulk List-ID: X-Mailing-List: linux-kbuild@vger.kernel.org With CONFIG_LTO_CLANG, we currently link modules into native code just before modpost, which means with TRIM_UNUSED_KSYMS enabled, we still look at the LLVM bitcode in the .o files when generating the list of used symbols. As the bitcode doesn't yet have calls to compiler intrinsics and llvm-nm doesn't see function references that only exist in function-level inline assembly, we currently need a whitelist for TRIM_UNUSED_KSYMS to work with LTO. This change moves module LTO linking to happen earlier, and thus avoids the issue with LLVM bitcode and TRIM_UNUSED_KSYMS entirely, allowing us to also drop the whitelist from gen_autoksyms.sh. Link: https://github.com/ClangBuiltLinux/linux/issues/1369 Signed-off-by: Sami Tolvanen Reviewed-by: Alexander Lobakin Tested-by: Alexander Lobakin --- Changes in v3: - Added missing FORCE. Changes in v2: - Fixed a couple of typos. - Fixed objtool arguments for .lto.o to always include --module. --- scripts/Makefile.build | 24 +++++++++++++++++++++++- scripts/Makefile.lib | 7 +++++++ scripts/Makefile.modfinal | 21 ++------------------- scripts/Makefile.modpost | 22 +++------------------- scripts/gen_autoksyms.sh | 12 ------------ 5 files changed, 35 insertions(+), 51 deletions(-) base-commit: f8fbb47c6e86c0b75f8df864db702c3e3f757361 diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 02197cb8e3a7..524701d9896b 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -271,12 +271,34 @@ $(obj)/%.o: $(src)/%.c $(recordmcount_source) $$(objtool_dep) FORCE $(call if_changed_rule,cc_o_c) $(call cmd,force_checksrc) +ifdef CONFIG_LTO_CLANG +# Module .o files may contain LLVM bitcode, compile them into native code +# before ELF processing +quiet_cmd_cc_lto_link_modules = LTO [M] $@ +cmd_cc_lto_link_modules = \ + $(LD) $(ld_flags) -r -o $@ \ + $(shell [ -s $(@:.lto.o=.o.symversions) ] && \ + echo -T $(@:.lto.o=.o.symversions)) \ + --whole-archive $(filter-out FORCE,$^) + +ifdef CONFIG_STACK_VALIDATION +# objtool was skipped for LLVM bitcode, run it now that we have compiled +# modules into native code +cmd_cc_lto_link_modules += ; \ + $(objtree)/tools/objtool/objtool $(objtool_args) --module \ + $(@:.ko=$(mod-prelink-ext).o) +endif + +$(obj)/%.lto.o: $(obj)/%.o FORCE + $(call if_changed,cc_lto_link_modules) +endif + cmd_mod = { \ echo $(if $($*-objs)$($*-y)$($*-m), $(addprefix $(obj)/, $($*-objs) $($*-y) $($*-m)), $(@:.mod=.o)); \ $(undefined_syms) echo; \ } > $@ -$(obj)/%.mod: $(obj)/%.o FORCE +$(obj)/%.mod: $(obj)/%$(mod-prelink-ext).o FORCE $(call if_changed,mod) quiet_cmd_cc_lst_c = MKLST $@ diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 10950559b223..af1c920a585c 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -225,6 +225,13 @@ dtc_cpp_flags = -Wp,-MMD,$(depfile).pre.tmp -nostdinc \ $(addprefix -I,$(DTC_INCLUDE)) \ -undef -D__DTS__ +ifeq ($(CONFIG_LTO_CLANG),y) +# With CONFIG_LTO_CLANG, .o files in modules might be LLVM bitcode, so we +# need to run LTO to compile them into native code (.lto.o) before further +# processing. +mod-prelink-ext := .lto +endif + # Objtool arguments are also needed for modfinal with LTO, so we define # then here to avoid duplication. objtool_args = \ diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 5e9b8057fb24..ff805777431c 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -9,7 +9,7 @@ __modfinal: include include/config/auto.conf include $(srctree)/scripts/Kbuild.include -# for c_flags and objtool_args +# for c_flags and mod-prelink-ext include $(srctree)/scripts/Makefile.lib # find all modules listed in modules.order @@ -30,23 +30,6 @@ quiet_cmd_cc_o_c = CC [M] $@ ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(SRCARCH)/Makefile.postlink) -ifdef CONFIG_LTO_CLANG -# With CONFIG_LTO_CLANG, reuse the object file we compiled for modpost to -# avoid a second slow LTO link -prelink-ext := .lto - -# ELF processing was skipped earlier because we didn't have native code, -# so let's now process the prelinked binary before we link the module. - -ifdef CONFIG_STACK_VALIDATION -cmd_ld_ko_o += \ - $(objtree)/tools/objtool/objtool $(objtool_args) \ - $(@:.ko=$(prelink-ext).o); - -endif # CONFIG_STACK_VALIDATION - -endif # CONFIG_LTO_CLANG - quiet_cmd_ld_ko_o = LD [M] $@ cmd_ld_ko_o += \ $(LD) -r $(KBUILD_LDFLAGS) \ @@ -72,7 +55,7 @@ if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ # Re-generate module BTFs if either module's .ko or vmlinux changed -$(modules): %.ko: %$(prelink-ext).o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE +$(modules): %.ko: %$(mod-prelink-ext).o %.mod.o scripts/module.lds $(if $(KBUILD_BUILTIN),vmlinux) FORCE +$(call if_changed_except,ld_ko_o,vmlinux) ifdef CONFIG_DEBUG_INFO_BTF_MODULES +$(if $(newer-prereqs),$(call cmd,btf_ko)) diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index c383ba33d837..eef56d629799 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -41,7 +41,7 @@ __modpost: include include/config/auto.conf include $(srctree)/scripts/Kbuild.include -# for ld_flags +# for mod-prelink-ext include $(srctree)/scripts/Makefile.lib MODPOST = scripts/mod/modpost \ @@ -118,22 +118,6 @@ $(input-symdump): @echo >&2 ' Modules may not have dependencies or modversions.' @echo >&2 ' You may get many unresolved symbol warnings.' -ifdef CONFIG_LTO_CLANG -# With CONFIG_LTO_CLANG, .o files might be LLVM bitcode, so we need to run -# LTO to compile them into native code before running modpost -prelink-ext := .lto - -quiet_cmd_cc_lto_link_modules = LTO [M] $@ -cmd_cc_lto_link_modules = \ - $(LD) $(ld_flags) -r -o $@ \ - $(shell [ -s $(@:.lto.o=.o.symversions) ] && \ - echo -T $(@:.lto.o=.o.symversions)) \ - --whole-archive $^ - -%.lto.o: %.o - $(call if_changed,cc_lto_link_modules) -endif - modules := $(sort $(shell cat $(MODORDER))) # KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined symbols @@ -144,9 +128,9 @@ endif # Read out modules.order to pass in modpost. # Otherwise, allmodconfig would fail with "Argument list too long". quiet_cmd_modpost = MODPOST $@ - cmd_modpost = sed 's/\.ko$$/$(prelink-ext)\.o/' $< | $(MODPOST) -T - + cmd_modpost = sed 's/\.ko$$/$(mod-prelink-ext)\.o/' $< | $(MODPOST) -T - -$(output-symdump): $(MODORDER) $(input-symdump) $(modules:.ko=$(prelink-ext).o) FORCE +$(output-symdump): $(MODORDER) $(input-symdump) $(modules:.ko=$(mod-prelink-ext).o) FORCE $(call if_changed,modpost) targets += $(output-symdump) diff --git a/scripts/gen_autoksyms.sh b/scripts/gen_autoksyms.sh index da320151e7c3..6ed0d225c8b1 100755 --- a/scripts/gen_autoksyms.sh +++ b/scripts/gen_autoksyms.sh @@ -26,18 +26,6 @@ if [ -n "$CONFIG_MODVERSIONS" ]; then needed_symbols="$needed_symbols module_layout" fi -# With CONFIG_LTO_CLANG, LLVM bitcode has not yet been compiled into a binary -# when the .mod files are generated, which means they don't yet contain -# references to certain symbols that will be present in the final binaries. -if [ -n "$CONFIG_LTO_CLANG" ]; then - # intrinsic functions - needed_symbols="$needed_symbols memcpy memmove memset" - # ftrace - needed_symbols="$needed_symbols _mcount" - # stack protector symbols - needed_symbols="$needed_symbols __stack_chk_fail __stack_chk_guard" -fi - ksym_wl= if [ -n "$CONFIG_UNUSED_KSYMS_WHITELIST" ]; then # Use 'eval' to expand the whitelist path and check if it is relative