From nobody Fri Sep 12 18:08:59 2025 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 954A2C636CC for ; Wed, 8 Feb 2023 17:24:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231760AbjBHRYM (ORCPT ); Wed, 8 Feb 2023 12:24:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55386 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229539AbjBHRYG (ORCPT ); Wed, 8 Feb 2023 12:24:06 -0500 Received: from desiato.infradead.org (desiato.infradead.org [IPv6:2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DE8AC2BEC5 for ; Wed, 8 Feb 2023 09:23:56 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Type:MIME-Version:References: Subject:Cc:To:From:Date:Message-ID:Sender:Reply-To:Content-Transfer-Encoding: Content-ID:Content-Description:In-Reply-To; bh=ZM2H9NcBYzk3p+h+REZIrOr8Wdv2eWikVDS+/wEJ9YQ=; b=QPSoc0VOKEEOeRBS1h3oyzg4aF B0ACXT394ce1mbXzw6peCznewOKbFYH8iFtM0xyr1jgjnNFirxwwQjEfBFpYKP7dah5m2Aipp/gPU FX/yyS0uMQ2PJIQTdaNXI0zUa+/jNpbwk2z6sLH+OVwg+mlCzezFdejh5cGJd5B+LeL2RnyezLQ0J KLgZNifgVqc+0VDdyvOJNQQ0ZsJZKE0kMadt01JthBlz/YcR1jn5/69iVm0muATWTdaJ9GTojaJxl kCbDeF7jzLw0D0oMFkLuVcoUtxIbOeDyWVOUmyA9yFyDp1Vd33XAgC31FyePRCYe3v+SqPy8skxwx 2ve9GtRw==; Received: from j130084.upc-j.chello.nl ([24.132.130.84] helo=noisy.programming.kicks-ass.net) by desiato.infradead.org with esmtpsa (Exim 4.96 #2 (Red Hat Linux)) id 1pPoA4-007Vve-0A; Wed, 08 Feb 2023 17:23:12 +0000 Received: from hirez.programming.kicks-ass.net (hirez.programming.kicks-ass.net [192.168.1.225]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (Client did not present a certificate) by noisy.programming.kicks-ass.net (Postfix) with ESMTPS id 199C1300446; Wed, 8 Feb 2023 18:23:50 +0100 (CET) Received: by hirez.programming.kicks-ass.net (Postfix, from userid 0) id 026E220A3C1B4; Wed, 8 Feb 2023 18:23:49 +0100 (CET) Message-ID: <20230208172245.291087549@infradead.org> User-Agent: quilt/0.66 Date: Wed, 08 Feb 2023 18:17:57 +0100 From: Peter Zijlstra To: x86@kernel.org, jpoimboe@redhat.com, linux@weissschuh.net Cc: linux-kernel@vger.kernel.org, peterz@infradead.org Subject: [PATCH 01/10] objtool: Change arch_decode_instruction() signature References: <20230208171756.898991570@infradead.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In preparation to changing struct instruction around a bit, avoid passing it's members by pointer and instead pass the whole thing. A cleanup in it's own right too. Signed-off-by: Peter Zijlstra (Intel) --- tools/objtool/arch/powerpc/decode.c | 22 +++---- tools/objtool/arch/x86/decode.c | 105 +++++++++++++++++-------------= ----- tools/objtool/check.c | 4 - tools/objtool/include/objtool/arch.h | 4 - 4 files changed, 64 insertions(+), 71 deletions(-) --- a/tools/objtool/arch/powerpc/decode.c +++ b/tools/objtool/arch/powerpc/decode.c @@ -41,38 +41,36 @@ const char *arch_ret_insn(int len) =20 int arch_decode_instruction(struct objtool_file *file, const struct sectio= n *sec, unsigned long offset, unsigned int maxlen, - unsigned int *len, enum insn_type *type, - unsigned long *immediate, - struct list_head *ops_list) + struct instruction *insn) { unsigned int opcode; enum insn_type typ; unsigned long imm; - u32 insn; + u32 ins; =20 - insn =3D bswap_if_needed(file->elf, *(u32 *)(sec->data->d_buf + offset)); - opcode =3D insn >> 26; + ins =3D bswap_if_needed(file->elf, *(u32 *)(sec->data->d_buf + offset)); + opcode =3D ins >> 26; typ =3D INSN_OTHER; imm =3D 0; =20 switch (opcode) { case 18: /* b[l][a] */ - if ((insn & 3) =3D=3D 1) /* bl */ + if ((ins & 3) =3D=3D 1) /* bl */ typ =3D INSN_CALL; =20 - imm =3D insn & 0x3fffffc; + imm =3D ins & 0x3fffffc; if (imm & 0x2000000) imm -=3D 0x4000000; break; } =20 if (opcode =3D=3D 1) - *len =3D 8; + insn->len =3D 8; else - *len =3D 4; + insn->len =3D 4; =20 - *type =3D typ; - *immediate =3D imm; + insn->type =3D typ; + insn->immediate =3D imm; =20 return 0; } --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -146,12 +146,11 @@ static bool has_notrack_prefix(struct in =20 int arch_decode_instruction(struct objtool_file *file, const struct sectio= n *sec, unsigned long offset, unsigned int maxlen, - unsigned int *len, enum insn_type *type, - unsigned long *immediate, - struct list_head *ops_list) + struct instruction *insn) { + struct list_head *ops_list =3D &insn->stack_ops; const struct elf *elf =3D file->elf; - struct insn insn; + struct insn ins; int x86_64, ret; unsigned char op1, op2, op3, prefix, rex =3D 0, rex_b =3D 0, rex_r =3D 0, rex_w =3D 0, rex_x =3D 0, @@ -165,42 +164,42 @@ int arch_decode_instruction(struct objto if (x86_64 =3D=3D -1) return -1; =20 - ret =3D insn_decode(&insn, sec->data->d_buf + offset, maxlen, + ret =3D insn_decode(&ins, sec->data->d_buf + offset, maxlen, x86_64 ? INSN_MODE_64 : INSN_MODE_32); if (ret < 0) { WARN("can't decode instruction at %s:0x%lx", sec->name, offset); return -1; } =20 - *len =3D insn.length; - *type =3D INSN_OTHER; + insn->len =3D ins.length; + insn->type =3D INSN_OTHER; =20 - if (insn.vex_prefix.nbytes) + if (ins.vex_prefix.nbytes) return 0; =20 - prefix =3D insn.prefixes.bytes[0]; + prefix =3D ins.prefixes.bytes[0]; =20 - op1 =3D insn.opcode.bytes[0]; - op2 =3D insn.opcode.bytes[1]; - op3 =3D insn.opcode.bytes[2]; + op1 =3D ins.opcode.bytes[0]; + op2 =3D ins.opcode.bytes[1]; + op3 =3D ins.opcode.bytes[2]; =20 - if (insn.rex_prefix.nbytes) { - rex =3D insn.rex_prefix.bytes[0]; + if (ins.rex_prefix.nbytes) { + rex =3D ins.rex_prefix.bytes[0]; rex_w =3D X86_REX_W(rex) >> 3; rex_r =3D X86_REX_R(rex) >> 2; rex_x =3D X86_REX_X(rex) >> 1; rex_b =3D X86_REX_B(rex); } =20 - if (insn.modrm.nbytes) { - modrm =3D insn.modrm.bytes[0]; + if (ins.modrm.nbytes) { + modrm =3D ins.modrm.bytes[0]; modrm_mod =3D X86_MODRM_MOD(modrm); modrm_reg =3D X86_MODRM_REG(modrm) + 8*rex_r; modrm_rm =3D X86_MODRM_RM(modrm) + 8*rex_b; } =20 - if (insn.sib.nbytes) { - sib =3D insn.sib.bytes[0]; + if (ins.sib.nbytes) { + sib =3D ins.sib.bytes[0]; /* sib_scale =3D X86_SIB_SCALE(sib); */ sib_index =3D X86_SIB_INDEX(sib) + 8*rex_x; sib_base =3D X86_SIB_BASE(sib) + 8*rex_b; @@ -254,7 +253,7 @@ int arch_decode_instruction(struct objto break; =20 case 0x70 ... 0x7f: - *type =3D INSN_JUMP_CONDITIONAL; + insn->type =3D INSN_JUMP_CONDITIONAL; break; =20 case 0x80 ... 0x83: @@ -278,7 +277,7 @@ int arch_decode_instruction(struct objto if (!rm_is_reg(CFI_SP)) break; =20 - imm =3D insn.immediate.value; + imm =3D ins.immediate.value; if (op1 & 2) { /* sign extend */ if (op1 & 1) { /* imm32 */ imm <<=3D 32; @@ -309,7 +308,7 @@ int arch_decode_instruction(struct objto ADD_OP(op) { op->src.type =3D OP_SRC_AND; op->src.reg =3D CFI_SP; - op->src.offset =3D insn.immediate.value; + op->src.offset =3D ins.immediate.value; op->dest.type =3D OP_DEST_REG; op->dest.reg =3D CFI_SP; } @@ -356,7 +355,7 @@ int arch_decode_instruction(struct objto op->src.reg =3D CFI_SP; op->dest.type =3D OP_DEST_REG_INDIRECT; op->dest.reg =3D modrm_rm; - op->dest.offset =3D insn.displacement.value; + op->dest.offset =3D ins.displacement.value; } break; } @@ -389,7 +388,7 @@ int arch_decode_instruction(struct objto op->src.reg =3D modrm_reg; op->dest.type =3D OP_DEST_REG_INDIRECT; op->dest.reg =3D CFI_BP; - op->dest.offset =3D insn.displacement.value; + op->dest.offset =3D ins.displacement.value; } break; } @@ -402,7 +401,7 @@ int arch_decode_instruction(struct objto op->src.reg =3D modrm_reg; op->dest.type =3D OP_DEST_REG_INDIRECT; op->dest.reg =3D CFI_SP; - op->dest.offset =3D insn.displacement.value; + op->dest.offset =3D ins.displacement.value; } break; } @@ -419,7 +418,7 @@ int arch_decode_instruction(struct objto ADD_OP(op) { op->src.type =3D OP_SRC_REG_INDIRECT; op->src.reg =3D CFI_BP; - op->src.offset =3D insn.displacement.value; + op->src.offset =3D ins.displacement.value; op->dest.type =3D OP_DEST_REG; op->dest.reg =3D modrm_reg; } @@ -432,7 +431,7 @@ int arch_decode_instruction(struct objto ADD_OP(op) { op->src.type =3D OP_SRC_REG_INDIRECT; op->src.reg =3D CFI_SP; - op->src.offset =3D insn.displacement.value; + op->src.offset =3D ins.displacement.value; op->dest.type =3D OP_DEST_REG; op->dest.reg =3D modrm_reg; } @@ -464,7 +463,7 @@ int arch_decode_instruction(struct objto =20 /* lea disp(%src), %dst */ ADD_OP(op) { - op->src.offset =3D insn.displacement.value; + op->src.offset =3D ins.displacement.value; if (!op->src.offset) { /* lea (%src), %dst */ op->src.type =3D OP_SRC_REG; @@ -487,7 +486,7 @@ int arch_decode_instruction(struct objto break; =20 case 0x90: - *type =3D INSN_NOP; + insn->type =3D INSN_NOP; break; =20 case 0x9c: @@ -511,39 +510,39 @@ int arch_decode_instruction(struct objto if (op2 =3D=3D 0x01) { =20 if (modrm =3D=3D 0xca) - *type =3D INSN_CLAC; + insn->type =3D INSN_CLAC; else if (modrm =3D=3D 0xcb) - *type =3D INSN_STAC; + insn->type =3D INSN_STAC; =20 } else if (op2 >=3D 0x80 && op2 <=3D 0x8f) { =20 - *type =3D INSN_JUMP_CONDITIONAL; + insn->type =3D INSN_JUMP_CONDITIONAL; =20 } else if (op2 =3D=3D 0x05 || op2 =3D=3D 0x07 || op2 =3D=3D 0x34 || op2 =3D=3D 0x35) { =20 /* sysenter, sysret */ - *type =3D INSN_CONTEXT_SWITCH; + insn->type =3D INSN_CONTEXT_SWITCH; =20 } else if (op2 =3D=3D 0x0b || op2 =3D=3D 0xb9) { =20 /* ud2 */ - *type =3D INSN_BUG; + insn->type =3D INSN_BUG; =20 } else if (op2 =3D=3D 0x0d || op2 =3D=3D 0x1f) { =20 /* nopl/nopw */ - *type =3D INSN_NOP; + insn->type =3D INSN_NOP; =20 } else if (op2 =3D=3D 0x1e) { =20 if (prefix =3D=3D 0xf3 && (modrm =3D=3D 0xfa || modrm =3D=3D 0xfb)) - *type =3D INSN_ENDBR; + insn->type =3D INSN_ENDBR; =20 =20 } else if (op2 =3D=3D 0x38 && op3 =3D=3D 0xf8) { - if (insn.prefixes.nbytes =3D=3D 1 && - insn.prefixes.bytes[0] =3D=3D 0xf2) { + if (ins.prefixes.nbytes =3D=3D 1 && + ins.prefixes.bytes[0] =3D=3D 0xf2) { /* ENQCMD cannot be used in the kernel. */ WARN("ENQCMD instruction at %s:%lx", sec->name, offset); @@ -591,29 +590,29 @@ int arch_decode_instruction(struct objto =20 case 0xcc: /* int3 */ - *type =3D INSN_TRAP; + insn->type =3D INSN_TRAP; break; =20 case 0xe3: /* jecxz/jrcxz */ - *type =3D INSN_JUMP_CONDITIONAL; + insn->type =3D INSN_JUMP_CONDITIONAL; break; =20 case 0xe9: case 0xeb: - *type =3D INSN_JUMP_UNCONDITIONAL; + insn->type =3D INSN_JUMP_UNCONDITIONAL; break; =20 case 0xc2: case 0xc3: - *type =3D INSN_RETURN; + insn->type =3D INSN_RETURN; break; =20 case 0xc7: /* mov imm, r/m */ if (!opts.noinstr) break; =20 - if (insn.length =3D=3D 3+4+4 && !strncmp(sec->name, ".init.text", 10)) { + if (ins.length =3D=3D 3+4+4 && !strncmp(sec->name, ".init.text", 10)) { struct reloc *immr, *disp; struct symbol *func; int idx; @@ -661,17 +660,17 @@ int arch_decode_instruction(struct objto =20 case 0xca: /* retf */ case 0xcb: /* retf */ - *type =3D INSN_CONTEXT_SWITCH; + insn->type =3D INSN_CONTEXT_SWITCH; break; =20 case 0xe0: /* loopne */ case 0xe1: /* loope */ case 0xe2: /* loop */ - *type =3D INSN_JUMP_CONDITIONAL; + insn->type =3D INSN_JUMP_CONDITIONAL; break; =20 case 0xe8: - *type =3D INSN_CALL; + insn->type =3D INSN_CALL; /* * For the impact on the stack, a CALL behaves like * a PUSH of an immediate value (the return address). @@ -683,30 +682,30 @@ int arch_decode_instruction(struct objto break; =20 case 0xfc: - *type =3D INSN_CLD; + insn->type =3D INSN_CLD; break; =20 case 0xfd: - *type =3D INSN_STD; + insn->type =3D INSN_STD; break; =20 case 0xff: if (modrm_reg =3D=3D 2 || modrm_reg =3D=3D 3) { =20 - *type =3D INSN_CALL_DYNAMIC; - if (has_notrack_prefix(&insn)) + insn->type =3D INSN_CALL_DYNAMIC; + if (has_notrack_prefix(&ins)) WARN("notrack prefix found at %s:0x%lx", sec->name, offset); =20 } else if (modrm_reg =3D=3D 4) { =20 - *type =3D INSN_JUMP_DYNAMIC; - if (has_notrack_prefix(&insn)) + insn->type =3D INSN_JUMP_DYNAMIC; + if (has_notrack_prefix(&ins)) WARN("notrack prefix found at %s:0x%lx", sec->name, offset); =20 } else if (modrm_reg =3D=3D 5) { =20 /* jmpf */ - *type =3D INSN_CONTEXT_SWITCH; + insn->type =3D INSN_CONTEXT_SWITCH; =20 } else if (modrm_reg =3D=3D 6) { =20 @@ -723,7 +722,7 @@ int arch_decode_instruction(struct objto break; } =20 - *immediate =3D insn.immediate.nbytes ? insn.immediate.value : 0; + insn->immediate =3D ins.immediate.nbytes ? ins.immediate.value : 0; =20 return 0; } --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -404,9 +404,7 @@ static int decode_instructions(struct ob =20 ret =3D arch_decode_instruction(file, sec, offset, sec->sh.sh_size - offset, - &insn->len, &insn->type, - &insn->immediate, - &insn->stack_ops); + insn); if (ret) goto err; =20 --- a/tools/objtool/include/objtool/arch.h +++ b/tools/objtool/include/objtool/arch.h @@ -75,9 +75,7 @@ void arch_initial_func_cfi_state(struct =20 int arch_decode_instruction(struct objtool_file *file, const struct sectio= n *sec, unsigned long offset, unsigned int maxlen, - unsigned int *len, enum insn_type *type, - unsigned long *immediate, - struct list_head *ops_list); + struct instruction *insn); =20 bool arch_callee_saved_reg(unsigned char reg);