From nobody Tue Feb 10 05:39:36 2026 Received: from pegase2.c-s.fr (pegase2.c-s.fr [93.17.235.10]) by smtp.subspace.kernel.org (Postfix) with ESMTP id EA3991DDC3F for ; Wed, 15 Jan 2025 22:51:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=93.17.235.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736981466; cv=none; b=US0mixGy7uENyaVNvXYwkJBi0ZeZPJKHXxe4hTZfe2cLYgO6Msd/4c+ggDWkKLoRksJ3RrFRIsCwoZCY25e57wMhOImT1CR1x5MO9tuTo07BzkpmK+LiRdFINhTkhwoynuDJb+5vRPlSnI2yrlGfQcnN3Azrwveel9VteCDoohY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1736981466; c=relaxed/simple; bh=U81L49Nw0AgeWOM9sdxxGuzlO2Zt+79EWQdKerlwdC8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=gfFS9ukENfiCD88cWOngN/X4DuOTLylRjCY7ld2yvvyFwUmUGcZYB5PjXh+MSQokEGDBECwt1vlGI3cH3TgyPO6sQ/YW8VPBBOU+mqtF69bkkM2JueAkhr1oaG8fiSQgrR4ojeMBpWLXAQz9hGcIFFeb/Wm+uruJA0RqErKjxsA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=csgroup.eu; spf=pass smtp.mailfrom=csgroup.eu; arc=none smtp.client-ip=93.17.235.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=csgroup.eu Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=csgroup.eu Received: from localhost (mailhub3.si.c-s.fr [172.26.127.67]) by localhost (Postfix) with ESMTP id 4YYLcZ6D8Cz9sSW; Wed, 15 Jan 2025 23:43:10 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase2.c-s.fr ([172.26.127.65]) by localhost (pegase2.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id IXAcOl9CibBJ; Wed, 15 Jan 2025 23:43:10 +0100 (CET) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase2.c-s.fr (Postfix) with ESMTP id 4YYLcZ5DQSz9sSV; Wed, 15 Jan 2025 23:43:10 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 9F8058B77A; Wed, 15 Jan 2025 23:43:10 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id aK_2SN5iBKqh; Wed, 15 Jan 2025 23:43:10 +0100 (CET) Received: from PO20335.idsi0.si.c-s.fr (unknown [192.168.202.221]) by messagerie.si.c-s.fr (Postfix) with ESMTP id 461A68B774; Wed, 15 Jan 2025 23:43:08 +0100 (CET) From: Christophe Leroy To: Josh Poimboeuf , Peter Zijlstra , Nathan Chancellor , Nick Desaulniers , Bill Wendling , Justin Stitt , Julien Thierry , Miroslav Benes , Raphael Gault , Michael Ellerman , Nicholas Piggin , Naveen N Rao , Madhavan Srinivasan Cc: Christophe Leroy , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, llvm@lists.linux.dev Subject: [PATCH v5 08/15] objtool: Track general purpose register used for switch table base Date: Wed, 15 Jan 2025 23:42:48 +0100 Message-ID: <36ab728d242109aeb3fe5464123a2da672f406d6.1736955567.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.47.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1736980963; l=5395; i=christophe.leroy@csgroup.eu; s=20211009; h=from:subject:message-id; bh=U81L49Nw0AgeWOM9sdxxGuzlO2Zt+79EWQdKerlwdC8=; b=/3AoT0IbBunpN8fIeZAmfBT1tDugFsaMy4vciiR2Ev7oz0U4eNfGYGo6t94PhVVi+ekkjoRdX oZPEEnQZ95iBlA6yAatcKE7QMTV7e2XcrslIHcfUSzy7jcqVJbmAahm X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" A function can contain nested switch tables using different registers as base address. In order to avoid failure in tracking those switch tables, the register containing the base address needs to be taken into account. To do so, add a 5 bits field in struct instruction that will hold the ID of the register containing the base address of the switch table and take that register into account during the backward search in order to not stop the walk when encountering a jump related to another switch table. On architectures not handling it, the ID stays nul and has no impact on the search. To enable that, also provide to arch_find_switch_table() the dynamic instruction related to a table search. Also allow prev_insn_same_sec() to be used outside check.c so that architectures can backward walk through instruction to find out which register is used as base address for a switch table. Signed-off-by: Christophe Leroy --- tools/objtool/arch/powerpc/special.c | 3 ++- tools/objtool/arch/x86/special.c | 3 ++- tools/objtool/check.c | 9 +++++---- tools/objtool/include/objtool/check.h | 6 ++++-- tools/objtool/include/objtool/special.h | 3 ++- 5 files changed, 15 insertions(+), 9 deletions(-) diff --git a/tools/objtool/arch/powerpc/special.c b/tools/objtool/arch/powe= rpc/special.c index 51610689abf7..0b3a766c4842 100644 --- a/tools/objtool/arch/powerpc/special.c +++ b/tools/objtool/arch/powerpc/special.c @@ -14,7 +14,8 @@ bool arch_support_alt_relocation(struct special_alt *spec= ial_alt, =20 struct reloc *arch_find_switch_table(struct objtool_file *file, struct instruction *insn, - unsigned long *table_size) + unsigned long *table_size, + struct instruction *orig_insn) { exit(-1); } diff --git a/tools/objtool/arch/x86/special.c b/tools/objtool/arch/x86/spec= ial.c index 76c7933bcb19..b0147923a70c 100644 --- a/tools/objtool/arch/x86/special.c +++ b/tools/objtool/arch/x86/special.c @@ -110,7 +110,8 @@ bool arch_support_alt_relocation(struct special_alt *sp= ecial_alt, */ struct reloc *arch_find_switch_table(struct objtool_file *file, struct instruction *insn, - unsigned long *table_size) + unsigned long *table_size, + struct instruction *orig_insn) { struct reloc *text_reloc, *rodata_reloc; struct section *table_sec; diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 613d169eb6b8..72b977f81dd6 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -81,8 +81,8 @@ static struct instruction *next_insn_same_func(struct obj= tool_file *file, return find_insn(file, func->cfunc->sec, func->cfunc->offset); } =20 -static struct instruction *prev_insn_same_sec(struct objtool_file *file, - struct instruction *insn) +struct instruction *prev_insn_same_sec(struct objtool_file *file, + struct instruction *insn) { if (insn->idx =3D=3D 0) { if (insn->prev_len) @@ -2028,7 +2028,8 @@ static void find_jump_table(struct objtool_file *file= , struct symbol *func, insn && insn_func(insn) && insn_func(insn)->pfunc =3D=3D func; insn =3D insn->first_jump_src ?: prev_insn_same_sym(file, insn)) { =20 - if (insn !=3D orig_insn && insn->type =3D=3D INSN_JUMP_DYNAMIC) + if (insn !=3D orig_insn && insn->type =3D=3D INSN_JUMP_DYNAMIC && + insn->gpr =3D=3D orig_insn->gpr) break; =20 /* allow small jumps within the range */ @@ -2038,7 +2039,7 @@ static void find_jump_table(struct objtool_file *file= , struct symbol *func, insn->jump_dest->offset > orig_insn->offset)) break; =20 - table_reloc =3D arch_find_switch_table(file, insn, &table_size); + table_reloc =3D arch_find_switch_table(file, insn, &table_size, orig_ins= n); if (!table_reloc) continue; =20 diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/= objtool/check.h index e1cd13cd28a3..8b68f840dddb 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -63,8 +63,9 @@ struct instruction { noendbr : 1, unret : 1, visited : 4, - no_reloc : 1; - /* 10 bit hole */ + no_reloc : 1, + gpr : 5; + /* 5 bit hole */ =20 struct alt_group *alt_group; struct instruction *jump_dest; @@ -118,6 +119,7 @@ struct instruction *find_insn(struct objtool_file *file, struct section *sec, unsigned long offset); =20 struct instruction *next_insn_same_sec(struct objtool_file *file, struct i= nstruction *insn); +struct instruction *prev_insn_same_sec(struct objtool_file *file, struct i= nstruction *insn); =20 #define sec_for_each_insn(file, _sec, insn) \ for (insn =3D find_insn(file, _sec, 0); \ diff --git a/tools/objtool/include/objtool/special.h b/tools/objtool/includ= e/objtool/special.h index e7ee7ffccefd..aca1f7762f5d 100644 --- a/tools/objtool/include/objtool/special.h +++ b/tools/objtool/include/objtool/special.h @@ -39,5 +39,6 @@ bool arch_support_alt_relocation(struct special_alt *spec= ial_alt, struct reloc *reloc); struct reloc *arch_find_switch_table(struct objtool_file *file, struct instruction *insn, - unsigned long *table_size); + unsigned long *table_size, + struct instruction *orig_insn); #endif /* _SPECIAL_H */ --=20 2.47.0