From nobody Tue Dec 2 02:04:32 2025 Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.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 5DDEC346FA8 for ; Fri, 21 Nov 2025 09:54:26 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.177.32 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763718868; cv=none; b=XxRcAisCj9RgYU83tWMtQqesBhE7xSptUuOoW9cDgwL6AemiGV14swD+cUrlC/taWnINgE+pb9dpO7mmwrriZNwrYt3O3uGFVVKPZN2Uyu3m2yp6LVQ2D0taUN3QzZmA/R8j3SG9E9kVFzo/qS/fRmHiioj5LmpsYK+ncQE3zoA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1763718868; c=relaxed/simple; bh=4gR3n3Q2aooI6nrAsVpxqgc8JbuVtN/ajXz/x7Lv0Dw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=rdYBmbHLAliKa57lqbviJL/NlaJA6ZlDDhSklhb+Z5SYJ00vm9yQxQ/7jH9jWjsYrHpnJq0rj93QUTKGVUr1TI+A80DB6K/8pgE5EQ4f5y9fnGnwrDxtAmUqpJD6jD7un/niRFNIxS6c8KSCZzgnVvVMj7SDqYfZK4H779/L1Tk= 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=NhX2RORQ; arc=none smtp.client-ip=205.220.177.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="NhX2RORQ" Received: from pps.filterd (m0246631.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 5AL1uObN001242; Fri, 21 Nov 2025 09:54:20 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=iJt6Z LDtjG7kdqEpwDTKDYQzW+5G9ZFpQq1otIuVuYA=; b=NhX2RORQ0GQoeqvdIh9B0 unNqLwCpdGx5YnYtaz9+UT6QNVyjMMg8CQ2TMnOYD2/RHWvOphaBOG9+Bq+MVX4F lVw++uVpVqFa4v2Smkj4XvTH/ZGCpQ5pQ2UKjVlBF2KpQ4JCg1xxdeoKmvn3LiPV ncSv744htCzfcIzhTpfsF0uCP5WnX/5dGjlmd0WFPu+eSo+RO56QpxciWwD7P/55 gyNsiYxgUNv3Ryr1sdDTRA9OZMyL8C2hkfqCQJx6K5yXKR8nV5+UeOn6eVQ1Idww EwWArGAnWHfnL6qGI357PBK/LsE4kQqNH4GDrzSUpnuheThzToHR1d8C96x6w/+G A== Received: from phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (phxpaimrmta01.appoci.oracle.com [138.1.114.2]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 4aej90ax0d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 21 Nov 2025 09:54:19 +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 5AL8s0K9004268; Fri, 21 Nov 2025 09:54:18 GMT Received: from pps.reinject (localhost [127.0.0.1]) by phxpaimrmta01.imrmtpd1.prodappphxaev1.oraclevcn.com (PPS) with ESMTPS id 4aefyd4uue-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 21 Nov 2025 09:54:18 +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 5AL9rgUg021648; Fri, 21 Nov 2025 09:54:18 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-20; Fri, 21 Nov 2025 09:54:18 +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 19/30] objtool: Print headers for alternatives Date: Fri, 21 Nov 2025 10:53:29 +0100 Message-ID: <20251121095340.464045-20-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=OMAqHCaB c=1 sm=1 tr=0 ts=692036cb cx=c_pps a=XiAAW1AwiKB2Y8Wsi+sD2Q==:117 a=XiAAW1AwiKB2Y8Wsi+sD2Q==:17 a=6UeiqGixMTsA:10 a=VkNPw1HP01LnGYTKEx00:22 a=yPCof4ZbAAAA:8 a=oPn5hVstRMuPe18koHEA:9 X-Proofpoint-ORIG-GUID: LTAzrfn7FDrM4fWP0e9Xs4L0zpD7lyKE X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUxMTE1MDAzMSBTYWx0ZWRfX1QK7wiAGRTgB 7fo1+wtRccHJWy+EJMEYJbGR1Bo+krcONws8j/K6O/v0xk8EleecpjJ8wfLdNDwcDFZnaprApHg BN45DI9uIPI1HznUrjm2IjvVk8xigSC1zQPH5ZbXgg8m1VujLGY+E+tmNdVSaBq+31VEfWdUyqU y8YT+sNX0UQdZY65P6q29QxMAXecVYpCs36IPrIRbH0lveRStJh3HXYNWFIb6hpswSYzRppb1gF VGBd0oQiheIjJqnnVAbeSxDF9HSMXpVQlomPaoXqe2iQz6NVwxmZtmCOwr/DrqZiGPKMf0m3Gt6 wIHz8y4Rk1ADyWW1mAn/Ccm8aDrbcRGnJWtx2QK4DbwJ7Pb0hYyv/VELycnUXRYEeYPzniJlEm/ QqiKLGxHIQ/nEesB/sCo/YrHQMHQDw== X-Proofpoint-GUID: LTAzrfn7FDrM4fWP0e9Xs4L0zpD7lyKE Content-Type: text/plain; charset="utf-8" When using the --disas option, objtool doesn't currently disassemble any alternative. Print an header for each alternative. This identifies places where alternatives are present but alternative code is still not disassembled at the moment. Signed-off-by: Alexandre Chartre --- tools/objtool/disas.c | 188 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 182 insertions(+), 6 deletions(-) diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index 9cc952e03c356..f9b13d56acab7 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -29,6 +29,43 @@ struct disas_context { struct disassemble_info info; }; =20 +/* + * Maximum number of alternatives + */ +#define DISAS_ALT_MAX 5 + +/* + * Maximum number of instructions per alternative + */ +#define DISAS_ALT_INSN_MAX 50 + +/* + * Information to disassemble an alternative + */ +struct disas_alt { + struct instruction *orig_insn; /* original instruction */ + struct alternative *alt; /* alternative or NULL if default code */ + char *name; /* name for this alternative */ + int width; /* formatting width */ +}; + +/* + * Wrapper around asprintf() to allocate and format a string. + * Return the allocated string or NULL on error. + */ +static char *strfmt(const char *fmt, ...) +{ + va_list ap; + char *str; + int rv; + + va_start(ap, fmt); + rv =3D vasprintf(&str, fmt, ap); + va_end(ap); + + return rv =3D=3D -1 ? NULL : str; +} + static int sprint_name(char *str, const char *name, unsigned long offset) { int len; @@ -314,6 +351,9 @@ char *disas_result(struct disas_context *dctx) #define DISAS_INSN_OFFSET_SPACE 10 #define DISAS_INSN_SPACE 60 =20 +#define DISAS_PRINSN(dctx, insn, depth) \ + disas_print_insn(stdout, dctx, insn, depth, "\n") + /* * Print a message in the instruction flow. If insn is not NULL then * the instruction address is printed in addition of the message, @@ -354,6 +394,19 @@ static int disas_vprint(FILE *stream, struct section *= sec, unsigned long offset, return n; } =20 +static int disas_print(FILE *stream, struct section *sec, unsigned long of= fset, + int depth, const char *format, ...) +{ + va_list args; + int len; + + va_start(args, format); + len =3D disas_vprint(stream, sec, offset, depth, format, args); + va_end(args); + + return len; +} + /* * Print a message in the instruction flow. If insn is not NULL then * the instruction address is printed in addition of the message, @@ -523,21 +576,144 @@ char *disas_alt_name(struct alternative *alt) return str; } =20 +/* + * Initialize an alternative. The default alternative should be initialized + * with alt=3DNULL. + */ +static int disas_alt_init(struct disas_alt *dalt, + struct instruction *orig_insn, + struct alternative *alt) +{ + dalt->orig_insn =3D orig_insn; + dalt->alt =3D alt; + dalt->name =3D alt ? disas_alt_name(alt) : strdup("DEFAULT"); + if (!dalt->name) + return -1; + dalt->width =3D strlen(dalt->name); + + return 0; +} + +/* + * Print all alternatives one above the other. + */ +static void disas_alt_print_compact(char *alt_name, struct disas_alt *dalt= s, + int alt_count) +{ + struct instruction *orig_insn; + int len; + int i; + + orig_insn =3D dalts[0].orig_insn; + + len =3D disas_print(stdout, orig_insn->sec, orig_insn->offset, 0, NULL); + printf("%s\n", alt_name); + + for (i =3D 0; i < alt_count; i++) + printf("%*s=3D %s\n", len, "", dalts[i].name); +} + +/* + * Disassemble an alternative. + * + * Return the last instruction in the default alternative so that + * disassembly can continue with the next instruction. Return NULL + * on error. + */ +static void *disas_alt(struct disas_context *dctx, + struct instruction *orig_insn) +{ + struct disas_alt dalts[DISAS_ALT_MAX] =3D { 0 }; + struct alternative *alt; + int alt_count =3D 0; + char *alt_name; + int err; + int i; + + alt_name =3D strfmt("<%s.%lx>", disas_alt_type_name(orig_insn), + orig_insn->offset); + if (!alt_name) { + WARN("Failed to define name for alternative at instruction 0x%lx", + orig_insn->offset); + goto done; + } + + /* + * Initialize the default alternative. + */ + err =3D disas_alt_init(&dalts[0], orig_insn, NULL); + if (err) { + WARN("%s: failed to initialize default alternative", alt_name); + goto done; + } + + /* + * Initialize all other alternatives. + */ + i =3D 1; + for (alt =3D orig_insn->alts; alt; alt =3D alt->next) { + if (i >=3D DISAS_ALT_MAX) { + WARN("%s has more alternatives than supported", alt_name); + break; + } + err =3D disas_alt_init(&dalts[i], orig_insn, alt); + if (err) { + WARN("%s: failed to disassemble alternative", alt_name); + goto done; + } + + i++; + } + alt_count =3D i; + + /* + * Print default and non-default alternatives. + * + * At the moment, this just prints an header for each alternative. + */ + disas_alt_print_compact(alt_name, dalts, alt_count); + +done: + for (i =3D 0; i < alt_count; i++) + free(dalts[i].name); + + free(alt_name); + + /* + * Currently we are not disassembling any alternative but just + * printing alternative names. Return NULL to have disas_func() + * resume the disassembly with the default alternative. + */ + return NULL; +} + /* * Disassemble a function. */ static void disas_func(struct disas_context *dctx, struct symbol *func) { + struct instruction *insn_start; struct instruction *insn; - size_t addr; =20 printf("%s:\n", func->name); sym_for_each_insn(dctx->file, func, insn) { - addr =3D insn->offset; - disas_insn(dctx, insn); - printf(" %6lx: %s+0x%-6lx %s\n", - addr, func->name, addr - func->offset, - disas_result(dctx)); + if (insn->alts) { + insn_start =3D insn; + insn =3D disas_alt(dctx, insn); + if (insn) + continue; + /* + * There was an error with disassembling + * the alternative. Resume disassembling + * at the current instruction, this will + * disassemble the default alternative + * only and continue with the code after + * the alternative. + */ + insn =3D insn_start; + } + + DISAS_PRINSN(dctx, insn, 0); } printf("\n"); } --=20 2.43.5