From patchwork Wed Nov 1 15:03:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 13442860 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8F669C41535 for ; Wed, 1 Nov 2023 15:04:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229518AbjKAPE5 (ORCPT ); Wed, 1 Nov 2023 11:04:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36082 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232437AbjKAPE4 (ORCPT ); Wed, 1 Nov 2023 11:04:56 -0400 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2B390FD; Wed, 1 Nov 2023 08:04:54 -0700 (PDT) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 776A1C433CD; Wed, 1 Nov 2023 15:04:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1698851093; bh=T11bWBI9YO8ZTft74BUB8/taHx/JC1055+wmzAKgdGI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jSetNX/jH2BNa0lWJSuJnaYZBfiymurs+qWOk5lWteXDlTxsv38TqRr+T7Fb4K/7x MP4yPOU4yr9/mhixWyj0vhxBUi1ly9S/fpTPhJM0M3TmOAQR/W/lXDSer/o0nxbPC1 gbpd2tTQO791y7tiAngRVYUXvjQ5+kZcIcR4WnPGmprrJLZzX5ZpMjBOK6F134AaSN xxzgMZAhCoGaOebkddesidDXGiBo1gpQV8hINS6z+AqkMixcI3rQJ71niMms18Li1C soVRSRB8ZRz/p+423aUyHILsRaool04Y7ASoDPgEx2sjiECdagGo5sDz2xgUXx0SWX uECLz7tTfdbdQ== From: Masahiro Yamada To: linux-kbuild@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Greg Ungerer , Jack Brennen , Masahiro Yamada , Nathan Chancellor , Nick Desaulniers , Nicolas Schier Subject: [PATCH 1/7] modpost: move sym_name() to modpost.h Date: Thu, 2 Nov 2023 00:03:58 +0900 Message-Id: <20231101150404.754108-2-masahiroy@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101150404.754108-1-masahiroy@kernel.org> References: <20231101150404.754108-1-masahiroy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kbuild@vger.kernel.org Move sym_name() to modpost.h so it can be used in other source files. Also, add the 'const' qualifier to the function arguments. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 8 -------- scripts/mod/modpost.h | 9 +++++++++ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 973b5e5ae2dd..896ecfa8483f 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -710,14 +710,6 @@ static char *get_modinfo(struct elf_info *info, const char *tag) return get_next_modinfo(info, tag, NULL); } -static const char *sym_name(struct elf_info *elf, Elf_Sym *sym) -{ - if (sym) - return elf->strtab + sym->st_name; - else - return "(unknown)"; -} - /* * Check whether the 'string' argument matches one of the 'patterns', * an array of shell wildcard patterns (glob). diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 1392afec118c..9834ac44846d 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -156,6 +156,15 @@ static inline unsigned int get_secindex(const struct elf_info *info, return index; } +static inline const char *sym_name(const struct elf_info *elf, + const Elf_Sym *sym) +{ + if (sym) + return elf->strtab + sym->st_name; + else + return "(unknown)"; +} + /* * If there's no name there, ignore it; likewise, ignore it if it's * one of the magic symbols emitted used by current tools. From patchwork Wed Nov 1 15:03:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 13442861 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 65EE6C4167D for ; Wed, 1 Nov 2023 15:04:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231995AbjKAPE7 (ORCPT ); Wed, 1 Nov 2023 11:04:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39944 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232519AbjKAPE6 (ORCPT ); Wed, 1 Nov 2023 11:04:58 -0400 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EDBA5DC; Wed, 1 Nov 2023 08:04:55 -0700 (PDT) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3BD3FC433CA; Wed, 1 Nov 2023 15:04:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1698851095; bh=wPhcCh2R5mo1LuWpZ6AE/5k4PZ89Ug41tO+Ww2sWSJY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RLJfP929G898YCZnm8fG0Z8UEYoSCW5ezQCzlUFOsxV4VOgx0C7slWecL3/MlxVqa SO64HtipVGBgdtqlfCQzHmxvTZlJZVjsbP/pVy6on0YT6I+hR50kgjnENgg32JEft3 EyQp93H4paPi7/HFZZJvJkwovU6LXOlDR26keTd9cCXTp4xgpJ0/+3GkvlRVXeogWR AtayS6mMN2cLcd3xCVPBNuLOhV7NVCj3TqqVysDMK2v6eF9fGSgU85BrNDOwZZnlaW M5SRDbd/jv2W8sPs0lxt1FH4p6EjkGKgYiYWxcuK9bxyr2zv+wfeRT++/9RDZK2baW QpC9MhPte6TbA== From: Masahiro Yamada To: linux-kbuild@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Greg Ungerer , Jack Brennen , Masahiro Yamada , Nathan Chancellor , Nick Desaulniers , Nicolas Schier Subject: [PATCH 2/7] modpost: add const qualifier to syminfo table Date: Thu, 2 Nov 2023 00:03:59 +0900 Message-Id: <20231101150404.754108-3-masahiroy@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101150404.754108-1-masahiroy@kernel.org> References: <20231101150404.754108-1-masahiroy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kbuild@vger.kernel.org symsearch_find_nearest() does not modify the table. Signed-off-by: Masahiro Yamada --- scripts/mod/symsearch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mod/symsearch.c b/scripts/mod/symsearch.c index aa4ed51f9960..00f0f9c354db 100644 --- a/scripts/mod/symsearch.c +++ b/scripts/mod/symsearch.c @@ -156,7 +156,7 @@ Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr, { unsigned int hi = elf->symsearch->table_size; unsigned int lo = 0; - struct syminfo *table = elf->symsearch->table; + const struct syminfo *table = elf->symsearch->table; struct syminfo target; target.addr = addr; From patchwork Wed Nov 1 15:04:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 13442862 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D9075C4167B for ; Wed, 1 Nov 2023 15:05:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232538AbjKAPFB (ORCPT ); Wed, 1 Nov 2023 11:05:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39962 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229596AbjKAPE7 (ORCPT ); Wed, 1 Nov 2023 11:04:59 -0400 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA5B0FD; Wed, 1 Nov 2023 08:04:57 -0700 (PDT) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0D235C433CD; Wed, 1 Nov 2023 15:04:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1698851097; bh=/1OKijib/XQjxvI5gIn4dRbp8P97f6PNc9AKR+6aMVs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=AuO9OK1ID8Bd+002S6WsnJbMMhFLoi7cqZdQrsyVy8mXE5AgvWBkj6Dyj1PhuwMw7 je1P48CBXUVfbW92u2kikCKXQDZI//lSUmKYLIrDUhi1Ddy9q0cuB3qzX0HAl+08GL GBo21IXYQdGPdAStQCdE16E5M363oGYU49HWpVuPiyEmrvu1hwDQoLJwGL6hZDP33Y q/pOcM1NgdQCmoU7r2dqBWa0+Wq1YD2PteY0XndPa7eCLFY9ttT7fQjt95mtwUFV1I Ui7Evg0rnzgoR3UsjtbtUrT+x0BDZy/vN/Ol+rjXVtYevS5XebUeI5rHwANV5LbS4+ UqG3qqSvTKvgA== From: Masahiro Yamada To: linux-kbuild@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Greg Ungerer , Jack Brennen , Masahiro Yamada , Nathan Chancellor , Nick Desaulniers , Nicolas Schier Subject: [PATCH 3/7] modpost: add table_size local variable to symsearch_find_nearest() Date: Thu, 2 Nov 2023 00:04:00 +0900 Message-Id: <20231101150404.754108-4-masahiroy@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101150404.754108-1-masahiroy@kernel.org> References: <20231101150404.754108-1-masahiroy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kbuild@vger.kernel.org Keep consistency with 'table', and make the conditional part slightly shorter. Signed-off-by: Masahiro Yamada --- scripts/mod/symsearch.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/mod/symsearch.c b/scripts/mod/symsearch.c index 00f0f9c354db..97566aee0979 100644 --- a/scripts/mod/symsearch.c +++ b/scripts/mod/symsearch.c @@ -154,9 +154,10 @@ Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr, unsigned int secndx, bool allow_negative, Elf_Addr min_distance) { - unsigned int hi = elf->symsearch->table_size; - unsigned int lo = 0; const struct syminfo *table = elf->symsearch->table; + unsigned int table_size = elf->symsearch->table_size; + unsigned int hi = table_size; + unsigned int lo = 0; struct syminfo target; target.addr = addr; @@ -183,8 +184,7 @@ Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr, */ Elf_Sym *result = NULL; - if (allow_negative && - hi < elf->symsearch->table_size && + if (allow_negative && hi < table_size && table[hi].section_index == secndx && table[hi].addr - addr <= min_distance) { min_distance = table[hi].addr - addr; From patchwork Wed Nov 1 15:04:01 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 13442864 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CC80BC4167B for ; Wed, 1 Nov 2023 15:05:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232783AbjKAPFH (ORCPT ); Wed, 1 Nov 2023 11:05:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39994 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232591AbjKAPFE (ORCPT ); Wed, 1 Nov 2023 11:05:04 -0400 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7EE3010C; Wed, 1 Nov 2023 08:04:59 -0700 (PDT) Received: by smtp.kernel.org (Postfix) with ESMTPSA id CA0BCC43215; Wed, 1 Nov 2023 15:04:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1698851099; bh=JtLodipaGPF999feXSGnDvTxAtoqNAWxEAUjQUNvakM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=kHNj6pS4OyGwkRF8mHZhF+YVeLtrDGwcNAKX1Zwq7SVqBaUinKfojmeq61mmW93ue aVZXMQkUH5pLMuQ5Kaelo4ooNejJ4jksN2d+Eg+0ZScv15cLJtcyrPWqxeTVetNlMF 8UEea089U8sUyU2HgFFoW0N2fkE8oPSB/2a39oBZB+PAJbkaKQ/zAfsGkMOCWaGnBQ qAtFnwgPLInYKcwp/41z8I3GoQIioOh9eMbz337H/zRIWgMInDlVQ94hyP+irQNR3c L69698PAr+M/CkRp15c3q7x50/j2wAwzNnrWPFXHqiqFu1ZymFoUrrj/IQJwbeBQCn zId1tz02kA3sw== From: Masahiro Yamada To: linux-kbuild@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Greg Ungerer , Jack Brennen , Masahiro Yamada , Nathan Chancellor , Nick Desaulniers , Nicolas Schier Subject: [PATCH 4/7] modpost: introduce a filtering feature to symsearch Date: Thu, 2 Nov 2023 00:04:01 +0900 Message-Id: <20231101150404.754108-5-masahiroy@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101150404.754108-1-masahiroy@kernel.org> References: <20231101150404.754108-1-masahiroy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kbuild@vger.kernel.org If adjacent table entries have the same section index and address, symsearch_fixup() modifies the entries so the symbol lookup returns the first symbol entry in the original .symtab section, but it may not be the optimal result. Add the filter() callback for more flexible symbol selection. After the binary search is finished, a linear search begins to determine the best symbol. Typically, the one found in the first iteration is the closest, but the linear search continues as long as it sees another symbol on the same distance. In each iteration, filter() is called to determine if the current symbol should be taken. Here are some useful scenarios: - When multiple entries share the same section index and address, filter() can be used to break a tie. - When there is an unwanted symbol depending on the search context, filter() can return false to skip it. Currently, there is one hard-coded policy: if the target address falls perfectly in the middle of the two neighbors, the lower address is preferred. Let's move this preference to the filter function because it is not directly related to the binary search algorithm. This commit does not introduce any functional change, but more useful filtering policies will be added in subsequent commits. Signed-off-by: Masahiro Yamada --- scripts/mod/symsearch.c | 102 ++++++++++++++++++++++++++++++---------- 1 file changed, 77 insertions(+), 25 deletions(-) diff --git a/scripts/mod/symsearch.c b/scripts/mod/symsearch.c index 97566aee0979..4549c5b0bb81 100644 --- a/scripts/mod/symsearch.c +++ b/scripts/mod/symsearch.c @@ -5,6 +5,8 @@ * to a given address. */ +#include + #include "modpost.h" struct syminfo { @@ -142,17 +144,11 @@ void symsearch_finish(struct elf_info *elf) elf->symsearch = NULL; } -/* - * Find the syminfo which is in secndx and "nearest" to addr. - * allow_negative: allow returning a symbol whose address is > addr. - * min_distance: ignore symbols which are further away than this. - * - * Returns a pointer into the symbol table for success. - * Returns NULL if no legal symbol is found within the requested range. - */ -Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr, - unsigned int secndx, bool allow_negative, - Elf_Addr min_distance) +static Elf_Sym *symsearch_find(struct elf_info *elf, Elf_Addr addr, + unsigned int secndx, bool allow_negative, + Elf_Addr min_distance, + bool (*filter)(const Elf_Sym *, const Elf_Sym *, void *), + void *filter_data) { const struct syminfo *table = elf->symsearch->table; unsigned int table_size = elf->symsearch->table_size; @@ -178,22 +174,78 @@ Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr, * entry in the array which comes before target, including the * case where it perfectly matches the section and the address. * - * Note -- if the address we're looking up falls perfectly - * in the middle of two symbols, this is written to always - * prefer the symbol with the lower address. + * If there are multiple candidates, the filter() callback can be used + * to break a tie. filter() is provided with the current symbol and the + * best one so far. If it returns true, the current one is selected. + * Only a few iterations are expected, hence the linear search is fine. */ - Elf_Sym *result = NULL; + Elf_Addr distance; + Elf_Sym *best = NULL; + Elf_Sym *sym; + int i; - if (allow_negative && hi < table_size && - table[hi].section_index == secndx && - table[hi].addr - addr <= min_distance) { - min_distance = table[hi].addr - addr; - result = &elf->symtab_start[table[hi].symbol_index]; + /* Search to the left. */ + for (i = hi - 1; i >= 0; i--) { + if (table[i].section_index != secndx) + break; + + distance = addr - table[i].addr; + if (distance > min_distance) + break; + + sym = &elf->symtab_start[table[i].symbol_index]; + if (filter(sym, best, filter_data)) { + min_distance = distance; + best = sym; + } } - if (hi > 0 && - table[hi - 1].section_index == secndx && - addr - table[hi - 1].addr <= min_distance) { - result = &elf->symtab_start[table[hi - 1].symbol_index]; + + if (!allow_negative) + return best; + + /* Search to the right if allow_negative is true. */ + for (i = hi; i < table_size; i++) { + if (table[i].section_index != secndx) + break; + + distance = table[i].addr - addr; + if (distance > min_distance) + break; + + sym = &elf->symtab_start[table[i].symbol_index]; + if (filter(sym, best, filter_data)) { + min_distance = distance; + best = sym; + } } - return result; + + return best; +} + +/* Return true if sym1 is preferred over sym2. */ +static bool symsearch_nearest_filter(const Elf_Sym *sym1, const Elf_Sym *sym2, + void *data) +{ + /* If sym2 is NULL, this is the first occurrence, always take it. */ + if (sym2 == NULL) + return true; + + /* Prefer lower address. */ + return sym1->st_value < sym2->st_value; +} + +/* + * Find the syminfo which is in secndx and "nearest" to addr. + * allow_negative: allow returning a symbol whose address is > addr. + * min_distance: ignore symbols which are further away than this. + * + * Returns a pointer into the symbol table for success. + * Returns NULL if no legal symbol is found within the requested range. + */ +Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr, + unsigned int secndx, bool allow_negative, + Elf_Addr min_distance) +{ + return symsearch_find(elf, addr, secndx, allow_negative, min_distance, + symsearch_nearest_filter, NULL); } From patchwork Wed Nov 1 15:04:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 13442863 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2228FC4332F for ; Wed, 1 Nov 2023 15:05:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229596AbjKAPFG (ORCPT ); Wed, 1 Nov 2023 11:05:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39986 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232649AbjKAPFE (ORCPT ); Wed, 1 Nov 2023 11:05:04 -0400 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 49B5F11A; Wed, 1 Nov 2023 08:05:01 -0700 (PDT) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 929FFC43395; Wed, 1 Nov 2023 15:04:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1698851101; bh=u2/0EZmNkhteR9yqHKg+ZM6He3MW48mMvU+dc7j/N/0=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ugFZRDltk5Ji75WF2kM1nw4DV4QMsmp3Ew6NnanEH/76zirT1kWCLAImIsZSrtore mDrjURw25SZK383ubVdsB10y+bUZR+MXkcgX9qBz/q8cIv6Ow0EsBqzkyy6KwRVteZ 521C7+4u2SAkkyK7YTNheuZDDAKHrQx1cC+knHjGuYOjv7GcACDkQzhNVWZ2ehJvN6 pOm9jSMdPPPd9KnTGQT9ZhBrj/D59Rn/yxR/mMz3zr7W3oNHCcoobf/Shm5dSUVPU+ Ub1zn+MRgY7RKWYi/08hUxahwdkcaIVwwSdDXjYOiM1AwgQgoimtnBP4tHOhUAZKbv t844YUt4cyqWQ== From: Masahiro Yamada To: linux-kbuild@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Greg Ungerer , Jack Brennen , Masahiro Yamada , Nathan Chancellor , Nick Desaulniers , Nicolas Schier Subject: [PATCH 5/7] modpost: prefer global symbols in symsearch_find_nearest() Date: Thu, 2 Nov 2023 00:04:02 +0900 Message-Id: <20231101150404.754108-6-masahiroy@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101150404.754108-1-masahiroy@kernel.org> References: <20231101150404.754108-1-masahiroy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kbuild@vger.kernel.org When there are multiple symbols that share the same section index and address, symsearch_find_nearest() returns the first occurrence in the original .symtab section. We can add more rules to break a tie based on symbol attributes. Kallsyms does this; compare_symbols() in scripts/kallsyms.c first sorts symbols by address, then by weakness and by underscore-prefixing in order to provide users with the most desirable symbol. This commit gives the following preference, in this order: 1. lower address 2. global symbol 3. no underscore prefix If two symbols still tie, the first one encounterd in the linear search is selected. This does not match the order in the original .symtab section, but it is not a significant issue. Signed-off-by: Masahiro Yamada --- scripts/mod/symsearch.c | 57 +++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/scripts/mod/symsearch.c b/scripts/mod/symsearch.c index 4549c5b0bb81..13464e4f4d72 100644 --- a/scripts/mod/symsearch.c +++ b/scripts/mod/symsearch.c @@ -20,9 +20,7 @@ struct syminfo { * Entries in table are ascending, sorted first by section_index, * then by addr, and last by symbol_index. The sorting by * symbol_index is used to ensure predictable behavior when - * multiple symbols are present with the same address; all - * symbols past the first are effectively ignored, by eliding - * them in symsearch_fixup(). + * multiple symbols are present with the same address. */ struct symsearch { unsigned int table_size; @@ -97,32 +95,6 @@ static void symsearch_populate(struct elf_info *elf, fatal("%s: size mismatch\n", __func__); } -/* - * Do any fixups on the table after sorting. - * For now, this just finds adjacent entries which have - * the same section_index and addr, and it propagates - * the first symbol_index over the subsequent entries, - * so that only one symbol_index is seen for any given - * section_index and addr. This ensures that whether - * we're looking at an address from "above" or "below" - * that we see the same symbol_index. - * This does leave some duplicate entries in the table; - * in practice, these are a small fraction of the - * total number of entries, and they are harmless to - * the binary search algorithm other than a few occasional - * unnecessary comparisons. - */ -static void symsearch_fixup(struct syminfo *table, unsigned int table_size) -{ - /* Don't look at index 0, it will never change. */ - for (unsigned int i = 1; i < table_size; i++) { - if (table[i].addr == table[i - 1].addr && - table[i].section_index == table[i - 1].section_index) { - table[i].symbol_index = table[i - 1].symbol_index; - } - } -} - void symsearch_init(struct elf_info *elf) { unsigned int table_size = symbol_count(elf); @@ -134,8 +106,6 @@ void symsearch_init(struct elf_info *elf) symsearch_populate(elf, elf->symsearch->table, table_size); qsort(elf->symsearch->table, table_size, sizeof(struct syminfo), syminfo_compare); - - symsearch_fixup(elf->symsearch->table, table_size); } void symsearch_finish(struct elf_info *elf) @@ -226,12 +196,33 @@ static Elf_Sym *symsearch_find(struct elf_info *elf, Elf_Addr addr, static bool symsearch_nearest_filter(const Elf_Sym *sym1, const Elf_Sym *sym2, void *data) { + struct elf_info *elf = data; + unsigned int bind1, bind2, unscores1, unscores2; + /* If sym2 is NULL, this is the first occurrence, always take it. */ if (sym2 == NULL) return true; /* Prefer lower address. */ - return sym1->st_value < sym2->st_value; + if (sym1->st_value < sym2->st_value) + return true; + if (sym1->st_value > sym2->st_value) + return false; + + bind1 = ELF_ST_BIND(sym1->st_info); + bind2 = ELF_ST_BIND(sym2->st_info); + + /* Prefer global symbol. */ + if (bind1 == STB_GLOBAL && bind2 != STB_GLOBAL) + return true; + if (bind1 != STB_GLOBAL && bind2 == STB_GLOBAL) + return false; + + /* Prefer less underscores. */ + unscores1 = strspn(sym_name(elf, sym1), "_"); + unscores2 = strspn(sym_name(elf, sym2), "_"); + + return unscores1 < unscores2; } /* @@ -247,5 +238,5 @@ Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr, Elf_Addr min_distance) { return symsearch_find(elf, addr, secndx, allow_negative, min_distance, - symsearch_nearest_filter, NULL); + symsearch_nearest_filter, elf); } From patchwork Wed Nov 1 15:04:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 13442865 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4C3A0C4167B for ; Wed, 1 Nov 2023 15:05:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233064AbjKAPFP (ORCPT ); Wed, 1 Nov 2023 11:05:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52166 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233002AbjKAPFM (ORCPT ); Wed, 1 Nov 2023 11:05:12 -0400 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2885E12B; Wed, 1 Nov 2023 08:05:03 -0700 (PDT) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5B8EEC433C7; Wed, 1 Nov 2023 15:05:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1698851102; bh=J9TDTTp5Th8l4Sk4Cvv9hQrUXmMuJKZ9hBfQCH+y39o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mForM/ElSg9nfUfHoSsS9u0waPf4ExfykoG7pn8Q3XaEFgsuytu/ouZBmYcqQY8rw mBCLgYXYsf/9nsFDRochpXiVbM1DwA2OtewmFI4or+JDh0c8/cnOXG1n9KvZPrO34R XR3XxeLrPAqnnn3W3aaXyYsWXUdRH2RsWT8+z5XWQAtZ2dFQdViSHXC//r9Aa7d9n/ r/L053pdsVpMNa65QHfpWWceGMtD27/WRDnLzz9u1jsm+cnaMmvTfc9ENNegOoaUfY e2eSn8UCofIHVcgoEC8GrhEsPMr5SHW7ge7vA1krBOKkEgAaV+Xi+9vmk0tvA4Kv5C pHhg1GVhlpXWw== From: Masahiro Yamada To: linux-kbuild@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Greg Ungerer , Jack Brennen , Masahiro Yamada , Nathan Chancellor , Nick Desaulniers , Nicolas Schier Subject: [PATCH 6/7] modpost: add symsearch_find_with_name() helper function Date: Thu, 2 Nov 2023 00:04:03 +0900 Message-Id: <20231101150404.754108-7-masahiroy@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101150404.754108-1-masahiroy@kernel.org> References: <20231101150404.754108-1-masahiroy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kbuild@vger.kernel.org This helper function searches for a symbol with the provided name. The symbol must be located in the specified section and within the given distance from the target address. In the expected use case, the min_distance is very small, so the linear search will finish within a few iterations. Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.h | 3 +++ scripts/mod/symsearch.c | 44 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 9834ac44846d..43148b1a762b 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h @@ -186,6 +186,9 @@ void symsearch_finish(struct elf_info *elf); Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr, unsigned int secndx, bool allow_negative, Elf_Addr min_distance); +Elf_Sym *symsearch_find_with_name(struct elf_info *elf, Elf_Addr addr, + unsigned int secndx, bool allow_negative, + Elf_Addr min_distance, const char *name); /* file2alias.c */ void handle_moddevtable(struct module *mod, struct elf_info *info, diff --git a/scripts/mod/symsearch.c b/scripts/mod/symsearch.c index 13464e4f4d72..9101bb9584a4 100644 --- a/scripts/mod/symsearch.c +++ b/scripts/mod/symsearch.c @@ -240,3 +240,47 @@ Elf_Sym *symsearch_find_nearest(struct elf_info *elf, Elf_Addr addr, return symsearch_find(elf, addr, secndx, allow_negative, min_distance, symsearch_nearest_filter, elf); } + +struct name_filter_data { + struct elf_info *elf; + const char *name; +}; + +static bool symsearch_name_filter(const Elf_Sym *sym1, const Elf_Sym *sym2, + void *_data) +{ + struct name_filter_data *data = _data; + const char *name; + + /* Check the symbol name. */ + name = sym_name(data->elf, sym1); + if (strcmp(name, data->name)) + return false; + + /* If sym2 is NULL, this is the first occurrence, always take it. */ + if (!sym2) + return true; + + /* Prefer lower address. */ + return sym1->st_value < sym2->st_value; +} + +/* + * Find the symbol which is in secndx and has the given name, and is located + * close enough to the given address. + * allow_negative: allow returning a symbol whose address is > addr. + * min_distance: ignore symbols which are further away than this. + * name: the name of the symbol to search for. + * + * Returns a pointer into the symbol table for success. + * Returns NULL if no legal symbol is found within the requested range. + */ +Elf_Sym *symsearch_find_with_name(struct elf_info *elf, Elf_Addr addr, + unsigned int secndx, bool allow_negative, + Elf_Addr min_distance, const char *name) +{ + struct name_filter_data data = { .elf = elf, .name = name }; + + return symsearch_find(elf, addr, secndx, allow_negative, min_distance, + symsearch_name_filter, &data); +} From patchwork Wed Nov 1 15:04:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 13442866 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8CDC1C4167D for ; Wed, 1 Nov 2023 15:05:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233104AbjKAPFR (ORCPT ); Wed, 1 Nov 2023 11:05:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52140 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232591AbjKAPFO (ORCPT ); Wed, 1 Nov 2023 11:05:14 -0400 Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC2E9138; Wed, 1 Nov 2023 08:05:04 -0700 (PDT) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 20955C433CC; Wed, 1 Nov 2023 15:05:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1698851104; bh=G5IEU13BAIg0z0NXW6uKOCp7ssGljo/FCvyBke8OHsQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=uE+WrCb7M6EmKJdxJmKMrN/sRX3Hp6ydLqFVsn6B3tVKj8NG2/4jzEs8XIw6a0fn1 Sp4SujkKHUgM1mUPTI1vhmZXJie9QgjC5tsgQTfXGtoRnPoYLKfY0EAwkEN6wm9JhJ 8N9Ynm2p232u7jxkHH2RclCoFG9YeI5YsPWyvR6CaeSbCgzuM7Nc0iL3PRUYk3XlRf ruf8hY+VoJRLNBPpnEbP90M9csUCKeNRsODr4zHU/3xDNcw8icqhRK9rXOYyGVDbwo MPzL1vCOvE+IQ/x0tzgJO84VwgjEbssQ2IwyFcdPMm727TADppazOgsb1Nc16MPV4b TknK6oyhPTzUA== From: Masahiro Yamada To: linux-kbuild@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Greg Ungerer , Jack Brennen , Masahiro Yamada , Nathan Chancellor , Nick Desaulniers , Nicolas Schier Subject: [PATCH 7/7] modpost: look up the correct symbol in check_export_symbol() Date: Thu, 2 Nov 2023 00:04:04 +0900 Message-Id: <20231101150404.754108-8-masahiroy@kernel.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231101150404.754108-1-masahiroy@kernel.org> References: <20231101150404.754108-1-masahiroy@kernel.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kbuild@vger.kernel.org Greg Ungerer reported modpost produced false-positive "local symbol '...' was exported" errors when m68k-uclinux-gcc is used. I had assumed ELF_R_SYM(Elf_Rela::r_info) pointed to the exported symbol itself if it is in the global scope. This assumption worked for many toolchains, but as it turned out, it was not true for m68k-uclinux-gcc, at least. If the 'sym' argument passed to check_export_symbol() is not the exported symbol, look up the correct one in the symbol table. It incurs a search cost, but since we know its section index and address, we can exploit the binary search. Reported-by: Greg Ungerer Closes: https://lore.kernel.org/all/1fac9d12-2ec2-4ccb-bb81-34f3fc34789e@westnet.com.au/ Signed-off-by: Masahiro Yamada --- scripts/mod/modpost.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 896ecfa8483f..ee67bc6d71ee 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1021,6 +1021,18 @@ static Elf_Sym *find_tosym(struct elf_info *elf, Elf_Addr addr, Elf_Sym *sym) true, 20); } +static Elf_Sym *find_tosym_with_name(struct elf_info *elf, Elf_Addr addr, + Elf_Sym *sym, const char *name) +{ + /* If the supplied symbol has the expected name, return it. */ + if (!strcmp(sym_name(elf, sym), name)) + return sym; + + /* Look up a symbol with the given name. */ + return symsearch_find_with_name(elf, addr, get_secindex(elf, sym), + true, 20, name); +} + static bool is_executable_section(struct elf_info *elf, unsigned int secndx) { if (secndx >= elf->num_sections) @@ -1079,7 +1091,7 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, static void check_export_symbol(struct module *mod, struct elf_info *elf, Elf_Addr faddr, const char *secname, - Elf_Sym *sym) + Elf_Sym *sym, Elf_Addr taddr) { static const char *prefix = "__export_symbol_"; const char *label_name, *name, *data; @@ -1096,6 +1108,14 @@ static void check_export_symbol(struct module *mod, struct elf_info *elf, return; } + name = label_name + strlen(prefix); + sym = find_tosym_with_name(elf, taddr, sym, name); + if (!sym) { + error("%s: could not find the the export symbol '%s'\n", + mod->name, name); + return; + } + if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL && ELF_ST_BIND(sym->st_info) != STB_WEAK) { error("%s: local symbol '%s' was exported\n", mod->name, @@ -1103,13 +1123,6 @@ static void check_export_symbol(struct module *mod, struct elf_info *elf, return; } - name = sym_name(elf, sym); - if (strcmp(label_name + strlen(prefix), name)) { - error("%s: .export_symbol section references '%s', but it does not seem to be an export symbol\n", - mod->name, name); - return; - } - data = sym_get_data(elf, label); /* license */ if (!strcmp(data, "GPL")) { is_gpl = true; @@ -1156,7 +1169,7 @@ static void check_section_mismatch(struct module *mod, struct elf_info *elf, const struct sectioncheck *mismatch; if (module_enabled && elf->export_symbol_secndx == fsecndx) { - check_export_symbol(mod, elf, faddr, tosec, sym); + check_export_symbol(mod, elf, faddr, tosec, sym, taddr); return; }