Received: by 2002:a05:6a11:4021:0:0:0:0 with SMTP id ky33csp1055403pxb; Wed, 29 Sep 2021 16:02:50 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyWX491t8D8MQlNsGTyiBhn/fP3SfbMSJvawdNIuqFF95Xn18ENGBcLQLqTCyh5uyGHbORf X-Received: by 2002:a50:cfc8:: with SMTP id i8mr3247038edk.223.1632956569948; Wed, 29 Sep 2021 16:02:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1632956569; cv=none; d=google.com; s=arc-20160816; b=byySLKQM8FdYxMkLLbym7jh56/EIS9Gn8yDJYI7LPUkcp1HGgOl0aY7GEx89R0aW/Z iqAaX6bcthOe+T8jFLiX+hRh7nqC1XRDtskhbhPJD2kEqqlIdxx9IcVl13kB6Orq9TgN xjYJWJdyMt4/Gnmd/brO/hYDN7g8mGpLUa8QWyL6f38OwWnwyxaxQs92Da4YiuFHqWAb 94zA+9nNfuw7PVatXtT07uiepleq4ZzBkVehLMWiK4yxW3GlHLveBILAy2iT0C+0q/Xo cM7MhkHXtl42XZ8KeYsk8yFGyCWEwQ4DFKXVzceCgpvLP6N5vW7wfDUqkJqocj0/z+xZ kLjg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:mime-version:message-id:date :dkim-signature; bh=Y0fyPdUie1iSxIBYtbb4DeMpLSWx01C9hO67e6l3dr0=; b=ahoXsRI7fIayp2TUEJUOs6KIIyyyp2SKqRbk7Jid3XT4eMbS3qBxMEpmcymwoIjgMl 2+LWf6++VXnMDNYMDN6f0rI1SwlIhGjLBvmeU9gsZ0NC44W0Eb6mBBjVKXHAtMLKPlTw rYdxW1TfVwgkF9s9VgOb9wJBX9AJEKBxysbX8hUae+o9UaliVM1WxRt33vo48Nu8tSNm Eb8jkktHe5eFwkHHarc3Su7Fi39J/1v+TXE6yGKwsSVSsVsyoEPeg9rTIM1MBCYVmFrw aKltmMmRxBW3d24hy56BON6Ou9W0L9j2JxbDv7s/+qgNNn16V79bK9TYq9LBPkk9UPoa wc+w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=nu9TcOGa; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id w11si1804128edc.191.2021.09.29.16.02.23; Wed, 29 Sep 2021 16:02:49 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20210112 header.b=nu9TcOGa; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345988AbhI2XAn (ORCPT + 99 others); Wed, 29 Sep 2021 19:00:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48580 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1347237AbhI2XAn (ORCPT ); Wed, 29 Sep 2021 19:00:43 -0400 Received: from mail-qt1-x849.google.com (mail-qt1-x849.google.com [IPv6:2607:f8b0:4864:20::849]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 79972C061767 for ; Wed, 29 Sep 2021 15:59:01 -0700 (PDT) Received: by mail-qt1-x849.google.com with SMTP id q24-20020ac84118000000b002a6d14f21e9so10216104qtl.9 for ; Wed, 29 Sep 2021 15:59:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20210112; h=date:message-id:mime-version:subject:from:to:cc; bh=Y0fyPdUie1iSxIBYtbb4DeMpLSWx01C9hO67e6l3dr0=; b=nu9TcOGaSlq3xlUF2IUW3fpIATmfengtbYq6jTg23D+ETIyP5m/nduYBm7l/vJpGYr 8DzmfaTt5faVWB1feuN6nBQ1cOHlBRiyZ9CCTX3nUcR0hhK/wtStvbCAK3z3o9pNIb5r DhhT5vtCfDC99AnWqpTgyAJ6dazpMq79FoXjZMFdZvxAJKyCNo7aTegex/7BEoFii9lH WnZSnMPzxmndP/NYhtA/Acdi7WmJj2LPrge0l60K2BmT7yYyIXvt+0MM/vpzIiNC/VOD cQ6g41MV4dyMjOlHx4iN207wQBcD5ghOBKN3dJeblTcpP0VStzlFHy9Wh43tHS9FBpRo EauA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:message-id:mime-version:subject:from:to:cc; bh=Y0fyPdUie1iSxIBYtbb4DeMpLSWx01C9hO67e6l3dr0=; b=1UV7fiNGTyx7EtsQEFnGIhQ7Kc8z1Js4FdjISy20+09bMOrsieDnNkpaxBbPpMeTH+ 2VwR18Wl7HtsgFp/xFNLdaHY+wrOdIh5mcC9mqHJVBL7AKZl0jBnZGl0muczbilejxeM I2TqDV7zLeZe4W0JttWzgP/QTgpIuVEnocHJtwXLrITcFQgkmBSe+w8CS0Xt61SyBRc/ D4Q5SF0I3IB741sAv4X3PMliy7Nkp2sP8mbjqt9DPYnovYy6vRRLsV5jcO3I2EFFNMKj Lc1nED0oOok/py/ecY3pGrUyb3F3k1uTdNkrOy/z80T6ugbeX4W8K/P7B7X0CjIAT7T7 7Low== X-Gm-Message-State: AOAM5308sKiiP2+0TsF2Hb1gHNq6dQRZwHj/9Jn5kIX4NcfBCmbmEyvA RWoo0u6vE1BkyIiO7bnmbHpz1xQ72uZg4CX+nJM= X-Received: from ndesaulniers1.mtv.corp.google.com ([2620:15c:211:202:da31:1dfd:2e69:dc82]) (user=ndesaulniers job=sendgmr) by 2002:a05:6214:1022:: with SMTP id k2mr916562qvr.53.1632956340603; Wed, 29 Sep 2021 15:59:00 -0700 (PDT) Date: Wed, 29 Sep 2021 15:58:50 -0700 Message-Id: <20210929225850.3889950-1-ndesaulniers@google.com> Mime-Version: 1.0 X-Mailer: git-send-email 2.33.0.685.g46640cef36-goog Subject: [PATCH] modpost: add allow list for llvm IPSCCP From: Nick Desaulniers To: Masahiro Yamada Cc: Linus Torvalds , Arnd Bergmann , Kees Cook , Nick Desaulniers , Nathan Chancellor , Michal Marek , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, llvm@lists.linux.dev Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Modpost validation of calls from .text to .init sections relies on GCC's constant propagation renaming specialized functions being renamed to have .constprop.* suffixes. See the comment on Pattern 5 in scripts/mod/modpost.c: GCC may optimize static inlines when fed constant arg(s) resulting in functions like cpumask_empty() -- generating an associated symbol cpumask_empty.constprop.3 that appears in the audit. If the const that is passed in comes from __init, like say nmi_ipi_mask, we get a meaningless section warning. LLVM does similar optimizations (inter-procedural sparse conditional constant propagation; IPSCCP), but doesn't rename the specialized functions, so we still observe modpost warnings. Add checks in modpost to check if the .comment section contains that string "clang" (ie. was the object file built with clang?), and if so additionally check an allow list. Fixes the following modpost warnings observed on clang-13+: allmodconfig: WARNING: modpost: vmlinux.o(.text+0x*): Section mismatch in reference from the function test_bit() to the variable .init.data:numa_nodes_parsed __first_node() to the variable .init.data:numa_nodes_parsed __next_node() to the variable .init.data:numa_nodes_parsed __nodes_weight() to the variable .init.data:numa_nodes_parsed early_get_smp_config() to the variable .init.data:x86_init defconfig: __nodes_weight() to the variable .init.data:numa_nodes_parsed Link: https://github.com/ClangBuiltLinux/linux/issues/1302 Reported-by: Nathan Chancellor Signed-off-by: Nick Desaulniers --- scripts/mod/modpost.c | 56 ++++++++++++++++++++++++++++++++++++++----- scripts/mod/modpost.h | 2 ++ 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index cb8ab7d91d30..c3d0395315ef 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -865,6 +865,29 @@ static int match(const char *sym, const char * const pat[]) return 0; } +struct secref_exception { + const char * const fromsym, * const tosym; +}; + +static const struct secref_exception secref_allowlist[] = { + { .fromsym = "__first_node", .tosym = "numa_nodes_parsed" }, + { .fromsym = "__next_node", .tosym = "numa_nodes_parsed" }, + { .fromsym = "__nodes_weight", .tosym = "numa_nodes_parsed" }, + { .fromsym = "early_get_smp_config", .tosym = "x86_init" }, + { .fromsym = "test_bit", .tosym = "numa_nodes_parsed" }, +}; + +static int match_allowlist(const char *fromsym, const char *tosym) +{ + int i = 0, e = ARRAY_SIZE(secref_allowlist); + + for (; i != e; ++i) + if (!strcmp(secref_allowlist[i].fromsym, fromsym) && + !strcmp(secref_allowlist[i].tosym, tosym)) + return 1; + return 0; +} + /* sections that we do not want to do full section mismatch check on */ static const char *const section_white_list[] = { @@ -1204,6 +1227,8 @@ static const struct sectioncheck *section_mismatch( * tosec = init section * fromsec = text section * refsymname = *.constprop.* + * LLVM will do similar constant propagation, but it will not rename the + * transformed callee. * * Pattern 6: * Hide section mismatch warnings for ELF local symbols. The goal @@ -1216,7 +1241,8 @@ static const struct sectioncheck *section_mismatch( **/ static int secref_whitelist(const struct sectioncheck *mismatch, const char *fromsec, const char *fromsym, - const char *tosec, const char *tosym) + const char *tosec, const char *tosym, + _Bool isclang) { /* Check for pattern 1 */ if (match(tosec, init_data_sections) && @@ -1247,9 +1273,10 @@ static int secref_whitelist(const struct sectioncheck *mismatch, /* Check for pattern 5 */ if (match(fromsec, text_sections) && - match(tosec, init_sections) && - match(fromsym, optim_symbols)) - return 0; + match(tosec, init_sections)) + if (match(fromsym, optim_symbols) || + (isclang && match_allowlist(fromsym, tosym))) + return 0; /* Check for pattern 6 */ if (strstarts(fromsym, ".L")) @@ -1573,6 +1600,21 @@ static void report_sec_mismatch(const char *modname, fprintf(stderr, "\n"); } +static _Bool is_clang(struct elf_info *elf) +{ + Elf_Sym *sym; + + for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { + if (is_shndx_special(sym->st_shndx)) + continue; + if (strcmp(sec_name(elf, get_secindex(elf, sym)), ".comment") != 0) + continue; + return strstr(sym_get_data(elf, sym), "clang") != NULL; + } + + return false; +} + static void default_mismatch_handler(const char *modname, struct elf_info *elf, const struct sectioncheck* const mismatch, Elf_Rela *r, Elf_Sym *sym, const char *fromsec) @@ -1582,6 +1624,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, Elf_Sym *from; const char *tosym; const char *fromsym; + _Bool isclang; from = find_elf_symbol2(elf, r->r_offset, fromsec); fromsym = sym_name(elf, from); @@ -1592,10 +1635,11 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, tosec = sec_name(elf, get_secindex(elf, sym)); to = find_elf_symbol(elf, r->r_addend, sym); tosym = sym_name(elf, to); + isclang = is_clang(elf); /* check whitelist - we may ignore it */ - if (secref_whitelist(mismatch, - fromsec, fromsym, tosec, tosym)) { + if (secref_whitelist(mismatch, fromsec, fromsym, tosec, tosym, + isclang)) { report_sec_mismatch(modname, mismatch, fromsec, r->r_offset, fromsym, is_function(from), tosec, tosym, diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 0c47ff95c0e2..d8afc912fd92 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -214,3 +214,5 @@ void modpost_log(enum loglevel loglevel, const char *fmt, ...); #define warn(fmt, args...) modpost_log(LOG_WARN, fmt, ##args) #define error(fmt, args...) modpost_log(LOG_ERROR, fmt, ##args) #define fatal(fmt, args...) modpost_log(LOG_FATAL, fmt, ##args) + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) -- 2.33.0.685.g46640cef36-goog