From nobody Tue Dec 2 01:49:04 2025 Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 78D4834AB14 for ; Fri, 21 Nov 2025 09:54:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.165.32 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763718878; cv=none; b=LzD6L55nOQ0UMeaAJrkabDpMlI4WuSGGR2mUx87oDjtCxXJI+V0OURpsyRaPg+Rn6Uu72NhqslYdaEkJqs8cQNpSxLIAU2x0yiUqKl1C/LZxIgmXewW4eiSYPdRjwxLNtW7WxHe/ErZ5RfDEzmsrpTRKDsDM4GCC+g00KGpYjFs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763718878; c=relaxed/simple; bh=+V8GrtPKTKMDzjmAow5mqPg998QnTvapVwC4WQpnh2g=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ZaSPtRF8WwblB3Ih9CklG41gAyClTNnrcAN2JpwIrJAr+vV2gq93zmShQNBxylLwLy7u3cESpnY2VDTkeGkxB3a2N+J79JXpr72onSTbKsuQMp+8NdgFkEXSXUlSy5CCWAHCn0biQRknL2qTfLYwTJwAvOUr9FJxS11WF1mpheE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com; spf=pass smtp.mailfrom=oracle.com; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b=lT8ZRyN4; arc=none smtp.client-ip=205.220.165.32 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oracle.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oracle.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="lT8ZRyN4" Received: from pps.filterd (m0246617.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 5AL1uakr015688; Fri, 21 Nov 2025 09:54:29 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=cc :content-transfer-encoding:date:from:in-reply-to:message-id :mime-version:references:subject:to; s=corp-2025-04-25; bh=wjq6E CWSIeQCBEREJQ0CYHuWyPifXpXJ2bvL4Cu2AVs=; b=lT8ZRyN47UkyVFyc515Aj BHNOzU4fStVrkINvyMV/YxMMkIHdasDrGGsE3a9zqO6vQrBvdp1w8b0myc+uc/Ke KeaAmJcM0E8F8iuYsHFFWKVXru234qzcvtzk0EYjBi8nuwGL64xtwDWy99n4A9Sp LAXU42OE9UL2CjqVHgKIvNS+49DxUVI3Y3pg1pYBy+c0Jmy/1apkzrQe0QR22TFY gl65TXn5SUKaQUOfKDEdTkY1VGwHsS8/xGG95KxzaXmopjvigX6TkLc0/vMdIphl opyhTzOi1VN8pyRy9LZootV3pwe7rFu6CCPD5SiDCUd6KhNNvBNy1dFR/KvNwS/R g== Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.appoci.oracle.com [138.1.114.2]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 4aej96atg5-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 21 Nov 2025 09:54:28 +0000 (GMT) Received: from pps.filterd (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 5AL8T30n004363; Fri, 21 Nov 2025 09:54:28 GMT Received: from pps.reinject (localhost [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 4aefyd4ux1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 21 Nov 2025 09:54:28 +0000 Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 5AL9rgUq021648; Fri, 21 Nov 2025 09:54:27 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-175-150.vpn.oracle.com [10.154.175.150]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTP id 4aefyd4ub2-25; Fri, 21 Nov 2025 09:54:27 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org, david.laight.linux@gmail.com Cc: alexandre.chartre@oracle.com Subject: [PATCH v6 24/30] objtool: Fix address references in alternatives Date: Fri, 21 Nov 2025 10:53:34 +0100 Message-ID: <20251121095340.464045-25-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20251121095340.464045-1-alexandre.chartre@oracle.com> References: <20251121095340.464045-1-alexandre.chartre@oracle.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1121,Hydra:6.1.9,FMLib:17.12.100.49 definitions=2025-11-21_03,2025-11-20_01,2025-10-01_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 mlxlogscore=999 suspectscore=0 malwarescore=0 mlxscore=0 bulkscore=0 phishscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2510240000 definitions=main-2511210075 X-Authority-Analysis: v=2.4 cv=DYoaa/tW c=1 sm=1 tr=0 ts=692036d4 cx=c_pps a=XiAAW1AwiKB2Y8Wsi+sD2Q==:117 a=XiAAW1AwiKB2Y8Wsi+sD2Q==:17 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=yPCof4ZbAAAA:8 a=YtZ4u2YuLOXz1tegIYEA:9 X-Proofpoint-GUID: RWucRz5PlF5RBJe0Rf3FPaXU01OE4H1x X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTE1MDAzMSBTYWx0ZWRfX2lQrZ0tvbnWC Y7vrMcpGvY32C9+4gRCTvl7Vzm9oXeiHlbDb6UUNbFY3j9C94eARIll6xe7tk/9q6S+6Hb0dfS5 yJeKCZzO8CJHsKpustfllMbgjJXDwvMEGZm32m6A/P59f4ALPgxCX94Rg60ZMyogAkKN+J6hxgk VZ+FAc5eAdm/v8RlNBGErzVklfLK9RFXuPgiuyBD+HYQii7wVdCME690UavUCGdpPoo2S36/iCv o2rO0syY/55yqYxjOfOqAYxwBGGHjHsTjUIgfCpbHhnIJDq7H8a92G2eriiJV+Jx8djPV9hiWox 96YeUF9W1iBLNO8O3OnarFNxVy1Q0jUABJZg6O2krDVlEXSz+mnCKv7mEulYUFG0nMzvNGtiqrG X1xPKdOdh/CKV0Oybyi+oy6zO79t9w== X-Proofpoint-ORIG-GUID: RWucRz5PlF5RBJe0Rf3FPaXU01OE4H1x Content-Type: text/plain; charset="utf-8" When using the --disas option, alternatives are disassembled but address references in non-default alternatives can be incorrect. The problem is that alternatives are shown as if they were replacing the original code of the alternative. So if an alternative is referencing an address inside the alternative then the reference has to be adjusted to the location of the original code. Signed-off-by: Alexandre Chartre --- tools/objtool/disas.c | 70 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index 326e16c9f30a8..f8917c8405d32 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -24,6 +24,7 @@ struct disas_context { struct objtool_file *file; struct instruction *insn; + bool alt_applied; char result[DISAS_RESULT_SIZE]; disassembler_ftype disassembler; struct disassemble_info info; @@ -160,6 +161,43 @@ static void disas_print_addr_sym(struct section *sec, = struct symbol *sym, } } =20 +static bool disas_print_addr_alt(bfd_vma addr, struct disassemble_info *di= nfo) +{ + struct disas_context *dctx =3D dinfo->application_data; + struct instruction *orig_first_insn; + struct alt_group *alt_group; + unsigned long offset; + struct symbol *sym; + + /* + * Check if we are processing an alternative at the original + * instruction address (i.e. if alt_applied is true) and if + * we are referencing an address inside the alternative. + * + * For example, this happens if there is a branch inside an + * alternative. In that case, the address should be updated + * to a reference inside the original instruction flow. + */ + if (!dctx->alt_applied) + return false; + + alt_group =3D dctx->insn->alt_group; + if (!alt_group || !alt_group->orig_group || + addr < alt_group->first_insn->offset || + addr > alt_group->last_insn->offset) + return false; + + orig_first_insn =3D alt_group->orig_group->first_insn; + offset =3D addr - alt_group->first_insn->offset; + + addr =3D orig_first_insn->offset + offset; + sym =3D orig_first_insn->sym; + + disas_print_addr_sym(orig_first_insn->sec, sym, addr, dinfo); + + return true; +} + static void disas_print_addr_noreloc(bfd_vma addr, struct disassemble_info *dinfo) { @@ -167,6 +205,9 @@ static void disas_print_addr_noreloc(bfd_vma addr, struct instruction *insn =3D dctx->insn; struct symbol *sym =3D NULL; =20 + if (disas_print_addr_alt(addr, dinfo)) + return; + if (insn->sym && addr >=3D insn->sym->offset && addr < insn->sym->offset + insn->sym->len) { sym =3D insn->sym; @@ -232,8 +273,9 @@ static void disas_print_address(bfd_vma addr, struct di= sassemble_info *dinfo) */ jump_dest =3D insn->jump_dest; if (jump_dest && jump_dest->sym && jump_dest->offset =3D=3D addr) { - disas_print_addr_sym(jump_dest->sec, jump_dest->sym, - addr, dinfo); + if (!disas_print_addr_alt(addr, dinfo)) + disas_print_addr_sym(jump_dest->sec, jump_dest->sym, + addr, dinfo); return; } =20 @@ -490,13 +532,22 @@ void disas_print_insn(FILE *stream, struct disas_cont= ext *dctx, =20 /* * Disassemble a single instruction. Return the size of the instruction. + * + * If alt_applied is true then insn should be an instruction from of an + * alternative (i.e. insn->alt_group !=3D NULL), and it is disassembled + * at the location of the original code it is replacing. When the + * instruction references any address inside the alternative then + * these references will be re-adjusted to replace the original code. */ -size_t disas_insn(struct disas_context *dctx, struct instruction *insn) +static size_t disas_insn_common(struct disas_context *dctx, + struct instruction *insn, + bool alt_applied) { disassembler_ftype disasm =3D dctx->disassembler; struct disassemble_info *dinfo =3D &dctx->info; =20 dctx->insn =3D insn; + dctx->alt_applied =3D alt_applied; dctx->result[0] =3D '\0'; =20 if (insn->type =3D=3D INSN_NOP) { @@ -515,6 +566,17 @@ size_t disas_insn(struct disas_context *dctx, struct i= nstruction *insn) return disasm(insn->offset, &dctx->info); } =20 +size_t disas_insn(struct disas_context *dctx, struct instruction *insn) +{ + return disas_insn_common(dctx, insn, false); +} + +static size_t disas_insn_alt(struct disas_context *dctx, + struct instruction *insn) +{ + return disas_insn_common(dctx, insn, true); +} + static struct instruction *next_insn_same_alt(struct objtool_file *file, struct alt_group *alt_grp, struct instruction *insn) @@ -706,7 +768,7 @@ static int disas_alt_group(struct disas_context *dctx, = struct disas_alt *dalt) =20 alt_for_each_insn(file, DALT_GROUP(dalt), insn) { =20 - disas_insn(dctx, insn); + disas_insn_alt(dctx, insn); str =3D strdup(disas_result(dctx)); if (!str) return -1; --=20 2.43.5