From nobody Thu Oct 9 06:06:38 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 8266927F166 for ; Thu, 19 Jun 2025 14:57:17 +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=1750345039; cv=none; b=EIXzqh1hH61VKtNI0n5CnZ2xC9XFyGRrFZEhwlZRRVJL/XYfZMoiTdvNIGbecN4NHkFOWyNN/Xphz8cy7g3XhadEuphtA1NHMHorF/vWs4y1ITnndejZ8hvyjdzvQh/DBwnJaO2N5nCFtUOw3Gv+zUKZJzRAo/sGpuvvw2tr8Co= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345039; c=relaxed/simple; bh=uFli8qripjOIKS+FVhZZomp//yZqATpNXfvNFflsUhE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IJ4uGFxDJZoyRA4SZm8TWRWzS71fF12pelt+SrHtboFERtqbqcXL6DE5MyuE0pNnIlDRE2A9Gjtsf7VLDrNQAW4dpuo5iwvEmfc/8960AdctdF79EBt4zfmeOBfmVurnt1qnoWOTmrKZTNUD1FjZ1GkaLcOk+l5VqUaQZT3q4l4= 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=BO2cFz04; 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="BO2cFz04" Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55JEMaE0014939; Thu, 19 Jun 2025 14:57:03 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=TQjWc pisuoarYkrPpFS4fkXe+RQOPP/UyAZhdCaRaSQ=; b=BO2cFz0431WL7/rIFzb0X 1eLKCYvi8rLJzlHY9r8IpACI4JOTSTAvykBkADZjaEttFZjRB4ZDBWM0IaaLUZFJ mMOn0G6O/+iOsvHzuta3NVJXVFE/WGCxAQtp9UNXwr/PrsjlphRcgunkRBQtyqBk rDdPzzn4/+Wlidz8PZr1s5B9lHnbjIwI6ogXesVZbPaYBiriLWtRkposUmXjntoq 1zcfICZO+pMzkyuFBVMXTH+W+r3cdU8p2e7CuOBVh9eYVmz8ERZtU9u2ycyp8U20 SdWv7qBqy6ffKdwsfi6weN7szQd65l8cEhmWzxualu1v/C/ZZl2fQPwd0Cd0qdB/ Q== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 478yp4t4ag-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:03 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDOK9Q022966; Thu, 19 Jun 2025 14:57:02 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8du6-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:02 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0JB008257; Thu, 19 Jun 2025 14:57:01 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-2; Thu, 19 Jun 2025 14:57:01 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 01/17] objtool: Move disassembly functions to a separated file Date: Thu, 19 Jun 2025 16:56:43 +0200 Message-ID: <20250619145659.1377970-2-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=999 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfX5K2m+8rdOrEb wwSG2XbgWmRTntY4STGoVjQxxqnWfqRMSuvZyvNNZ7CSkJX6IagS8hN52KiV1XQnpnbRxVB9N5/ JeDQsq+vARCCksFsM6HBMktMBvdEZU9tU4nd6t2oYSmy9xxgbuxLWThrkNQuvax7gc37C+VGyMy USHGLWRV/1YYvYMHKhIUwYEVxWa0Wl+xPlo5I1tEhLKQZA7p5uixwzvysmwb+yTnbifD/xtSaaI cbzwMsU8nYq2YfNDWyVLUrb024UaAHoywBGCY+/ADbLNJyXYUhoJL4Bf5/dZ1BlUQXZ8ff4EfYA Cf3VgaQDg6L8gOpTowSyfkkyGCrEEYINuNU04CJUqiJuS+HSymco5eYfPRshu+67ZtbXKXw/Bk3 qCvnRIhNERFhW2qMMiZA3lHZtDjojgE3S4Cgj7l4Z6iWZ+t+NXJUy/HRB57xAVByj4fI9yVl X-Authority-Analysis: v=2.4 cv=K5EiHzWI c=1 sm=1 tr=0 ts=6854253f b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=20KFwNOVAAAA:8 a=dBVU6wt392Vc8wzyTJAA:9 cc=ntf awl=host:13207 X-Proofpoint-GUID: gxn8Z8Ab0L1J2-R04nzZWDe_yPANApJC X-Proofpoint-ORIG-GUID: gxn8Z8Ab0L1J2-R04nzZWDe_yPANApJC Content-Type: text/plain; charset="utf-8" objtool disassembles functions which have warnings. Move the code to do that to a dedicated file. The code is just moved, it is not changed. Signed-off-by: Alexandre Chartre --- tools/objtool/Build | 1 + tools/objtool/check.c | 81 ---------------------- tools/objtool/disas.c | 90 +++++++++++++++++++++++++ tools/objtool/include/objtool/objtool.h | 2 + 4 files changed, 93 insertions(+), 81 deletions(-) create mode 100644 tools/objtool/disas.c diff --git a/tools/objtool/Build b/tools/objtool/Build index a3cdf8af6635..677bf9148cba 100644 --- a/tools/objtool/Build +++ b/tools/objtool/Build @@ -7,6 +7,7 @@ objtool-y +=3D special.o objtool-y +=3D builtin-check.o objtool-y +=3D elf.o objtool-y +=3D objtool.o +objtool-y +=3D disas.o =20 objtool-$(BUILD_ORC) +=3D orc_gen.o objtool-$(BUILD_ORC) +=3D orc_dump.o diff --git a/tools/objtool/check.c b/tools/objtool/check.c index f23bdda737aa..bd1974717fa3 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -4561,87 +4561,6 @@ static int validate_reachable_instructions(struct ob= jtool_file *file) return warnings; } =20 -/* 'funcs' is a space-separated list of function names */ -static void disas_funcs(const char *funcs) -{ - const char *objdump_str, *cross_compile; - int size, ret; - char *cmd; - - cross_compile =3D getenv("CROSS_COMPILE"); - if (!cross_compile) - cross_compile =3D ""; - - objdump_str =3D "%sobjdump -wdr %s | gawk -M -v _funcs=3D'%s' '" - "BEGIN { split(_funcs, funcs); }" - "/^$/ { func_match =3D 0; }" - "/<.*>:/ { " - "f =3D gensub(/.*<(.*)>:/, \"\\\\1\", 1);" - "for (i in funcs) {" - "if (funcs[i] =3D=3D f) {" - "func_match =3D 1;" - "base =3D strtonum(\"0x\" $1);" - "break;" - "}" - "}" - "}" - "{" - "if (func_match) {" - "addr =3D strtonum(\"0x\" $1);" - "printf(\"%%04x \", addr - base);" - "print;" - "}" - "}' 1>&2"; - - /* fake snprintf() to calculate the size */ - size =3D snprintf(NULL, 0, objdump_str, cross_compile, objname, funcs) + = 1; - if (size <=3D 0) { - WARN("objdump string size calculation failed"); - return; - } - - cmd =3D malloc(size); - - /* real snprintf() */ - snprintf(cmd, size, objdump_str, cross_compile, objname, funcs); - ret =3D system(cmd); - if (ret) { - WARN("disassembly failed: %d", ret); - return; - } -} - -static void disas_warned_funcs(struct objtool_file *file) -{ - struct symbol *sym; - char *funcs =3D NULL, *tmp; - - for_each_sym(file, sym) { - if (sym->warned) { - if (!funcs) { - funcs =3D malloc(strlen(sym->name) + 1); - if (!funcs) { - ERROR_GLIBC("malloc"); - return; - } - strcpy(funcs, sym->name); - } else { - tmp =3D malloc(strlen(funcs) + strlen(sym->name) + 2); - if (!tmp) { - ERROR_GLIBC("malloc"); - return; - } - sprintf(tmp, "%s %s", funcs, sym->name); - free(funcs); - funcs =3D tmp; - } - } - } - - if (funcs) - disas_funcs(funcs); -} - struct insn_chunk { void *addr; struct insn_chunk *next; diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c new file mode 100644 index 000000000000..77de46beb496 --- /dev/null +++ b/tools/objtool/disas.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2015-2017 Josh Poimboeuf + */ + +#include +#include + +#include + +/* 'funcs' is a space-separated list of function names */ +static void disas_funcs(const char *funcs) +{ + const char *objdump_str, *cross_compile; + int size, ret; + char *cmd; + + cross_compile =3D getenv("CROSS_COMPILE"); + if (!cross_compile) + cross_compile =3D ""; + + objdump_str =3D "%sobjdump -wdr %s | gawk -M -v _funcs=3D'%s' '" + "BEGIN { split(_funcs, funcs); }" + "/^$/ { func_match =3D 0; }" + "/<.*>:/ { " + "f =3D gensub(/.*<(.*)>:/, \"\\\\1\", 1);" + "for (i in funcs) {" + "if (funcs[i] =3D=3D f) {" + "func_match =3D 1;" + "base =3D strtonum(\"0x\" $1);" + "break;" + "}" + "}" + "}" + "{" + "if (func_match) {" + "addr =3D strtonum(\"0x\" $1);" + "printf(\"%%04x \", addr - base);" + "print;" + "}" + "}' 1>&2"; + + /* fake snprintf() to calculate the size */ + size =3D snprintf(NULL, 0, objdump_str, cross_compile, objname, funcs) + = 1; + if (size <=3D 0) { + WARN("objdump string size calculation failed"); + return; + } + + cmd =3D malloc(size); + + /* real snprintf() */ + snprintf(cmd, size, objdump_str, cross_compile, objname, funcs); + ret =3D system(cmd); + if (ret) { + WARN("disassembly failed: %d", ret); + return; + } +} + +void disas_warned_funcs(struct objtool_file *file) +{ + struct symbol *sym; + char *funcs =3D NULL, *tmp; + + for_each_sym(file, sym) { + if (sym->warned) { + if (!funcs) { + funcs =3D malloc(strlen(sym->name) + 1); + if (!funcs) { + ERROR_GLIBC("malloc"); + return; + } + strcpy(funcs, sym->name); + } else { + tmp =3D malloc(strlen(funcs) + strlen(sym->name) + 2); + if (!tmp) { + ERROR_GLIBC("malloc"); + return; + } + sprintf(tmp, "%s %s", funcs, sym->name); + free(funcs); + funcs =3D tmp; + } + } + } + + if (funcs) + disas_funcs(funcs); +} diff --git a/tools/objtool/include/objtool/objtool.h b/tools/objtool/includ= e/objtool/objtool.h index c0dc86a78ff6..4d3e94b70fd8 100644 --- a/tools/objtool/include/objtool/objtool.h +++ b/tools/objtool/include/objtool/objtool.h @@ -47,4 +47,6 @@ int check(struct objtool_file *file); int orc_dump(const char *objname); int orc_create(struct objtool_file *file); =20 +void disas_warned_funcs(struct objtool_file *file); + #endif /* _OBJTOOL_H */ --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 7C0CC230D2B for ; Thu, 19 Jun 2025 14:57:15 +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=1750345037; cv=none; b=C2IS3guIeDtSR5KwTBA9gDk0OTUBmEaDuajZYdbPvQsJJ1TUrz3tnsPfmyfft8Bxi43rb/ZyiUc3dNhlcphyOw47YTO9+xpRxJcn0harZxfHh+rC6d5V9/UqAukoRjFOpM6bdnqJDcFHC5689Yr1fMdifYe5K0Q5oSvNLd+Ccio= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345037; c=relaxed/simple; bh=ZI9VuxpxL6OkMDZdK7rQxtNCWS9uPNyI/dYz/jzQsKU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Tv0ZUpUIORsDoL0ZLbLoAz4ew7pdMKWPkoLKfci5EM6N56uOl/OtHoVyAoaFLZIyTUYi2y7CMg6urMpMAlFSrmhxUZ8CbeWjESc6ZY2BB790t1z375O4x2iRq1WLrtNARn5amGUQlsB0G6+KY1fgWWyS77VBp5uK8ltddNxAdKU= 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=Q9EDnqq1; 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="Q9EDnqq1" 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 55JEMbVL029383; Thu, 19 Jun 2025 14:57:05 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=QiUiN u83/u8PIbpSz74ANU1xCRgFmpKw89MT6iibuVs=; b=Q9EDnqq1D69zb1mqBY0qk X3Ah3MlcTjBhzpWZIn3TXJt/mzfMIHuZ3MyzkUZFVrYtvKpgA+T6qCDRfZevyaUe dBAywyvazE/S/esW8jRnwiqXImBeDH0llVu6+IxsUYcgHehRyuJrlM42DZxOmIhg WHee3LPY5srkUmCNPYOea/RcurwYhTzJKGoOnF+rHRB91otbL1ZTEOSdiZsY/VZl GM7vr3JMqRr3znRPgt8oT2ATd2XDpArGdgXiZ8kMx0yh8Yu05QVbKQujg4b7NZBK rnBxJPVmGk/uqoEl2kmK5b3N9JQsgvzhyOL4mgz29Rw5RpBptLT2ITJk8z9JunMd w== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 47b23xwjxc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:04 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDNm1C022907; Thu, 19 Jun 2025 14:57:03 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8dun-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:03 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0JD008257; Thu, 19 Jun 2025 14:57:02 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-3; Thu, 19 Jun 2025 14:57:02 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 02/17] objtool: Create disassembly context Date: Thu, 19 Jun 2025 16:56:44 +0200 Message-ID: <20250619145659.1377970-3-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=925 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfX4CMdfiNDraT3 eFuLHCdFpchCHb36mgrK16l0V0ATTifnoF5ZIsPHU1Z8QoQISGM8/jzg61z2fuxJC7XBI6ZCeBu JSS9fdjfUaTAUheClanJ8TN2iD/qZlijKFLn7R0qhqXZkUgXSvlWdrHgp8UT6rhMaDr8G4e8FaJ FRWQlyH9TuaWKxFZ8fTuClAfUWx+hB8s2P/vCylOwypixQbT7ThsDGECAR5otb/IYWW91gao5S2 ivi4p5EiIutrQzq+PRAa/yKOq5WEiwXERzi+wc+M1yxJlmPbyZcqVue7AGmiDSGJ3S61ALXc0U8 HBQjm8iof/bSZWwEoGVw7epY8R9Wdz+IB1A+7ZYkprmEsfLgrDeVme5CTY7zNM6lWwZKvHJVxyM 6bR+cpD4FGu0zH60DjxtICH/1sVf/kI5BeDFvppYDXa7zvDN5xjjarTWsVhDjXhTU7qJWl3D X-Authority-Analysis: v=2.4 cv=DM2P4zNb c=1 sm=1 tr=0 ts=68542540 b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=-R_vEHidSSj7PnaEDHgA:9 cc=ntf awl=host:13207 X-Proofpoint-GUID: swcVQduEC-3m3w-w3oyflNBvhJUNFBOP X-Proofpoint-ORIG-GUID: swcVQduEC-3m3w-w3oyflNBvhJUNFBOP Content-Type: text/plain; charset="utf-8" Create a structure to store information for disassembling functions. For now, it is just a wrapper around an objtool file. Signed-off-by: Alexandre Chartre --- tools/objtool/check.c | 6 ++++- tools/objtool/disas.c | 32 +++++++++++++++++++++++-- tools/objtool/include/objtool/disas.h | 14 +++++++++++ tools/objtool/include/objtool/objtool.h | 2 -- 4 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 tools/objtool/include/objtool/disas.h diff --git a/tools/objtool/check.c b/tools/objtool/check.c index bd1974717fa3..cef3a32a6747 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -4591,6 +4592,7 @@ static void free_insns(struct objtool_file *file) =20 int check(struct objtool_file *file) { + struct disas_context *disas_ctx; int ret =3D 0, warnings =3D 0; =20 arch_initial_func_cfi_state(&initial_func_cfi); @@ -4720,7 +4722,9 @@ int check(struct objtool_file *file) if (opts.werror && warnings) WARN("%d warning(s) upgraded to errors", warnings); print_args(); - disas_warned_funcs(file); + disas_ctx =3D disas_context_create(file); + disas_warned_funcs(disas_ctx); + disas_context_destroy(disas_ctx); } =20 return ret; diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index 77de46beb496..67eff2a14832 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -4,10 +4,35 @@ */ =20 #include +#include #include =20 #include =20 +struct disas_context { + struct objtool_file *file; +}; + +struct disas_context *disas_context_create(struct objtool_file *file) +{ + struct disas_context *dctx; + + dctx =3D malloc(sizeof(*dctx)); + if (!dctx) { + ERROR_GLIBC("failed to allocate disassembly context"); + return NULL; + } + + dctx->file =3D file; + + return dctx; +} + +void disas_context_destroy(struct disas_context *dctx) +{ + free(dctx); +} + /* 'funcs' is a space-separated list of function names */ static void disas_funcs(const char *funcs) { @@ -58,12 +83,15 @@ static void disas_funcs(const char *funcs) } } =20 -void disas_warned_funcs(struct objtool_file *file) +void disas_warned_funcs(struct disas_context *dctx) { struct symbol *sym; char *funcs =3D NULL, *tmp; =20 - for_each_sym(file, sym) { + if (!dctx) + return; + + for_each_sym(dctx->file, sym) { if (sym->warned) { if (!funcs) { funcs =3D malloc(strlen(sym->name) + 1); diff --git a/tools/objtool/include/objtool/disas.h b/tools/objtool/include/= objtool/disas.h new file mode 100644 index 000000000000..5c543b69fc61 --- /dev/null +++ b/tools/objtool/include/objtool/disas.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. + */ + +#ifndef _DISAS_H +#define _DISAS_H + +struct disas_context; +struct disas_context *disas_context_create(struct objtool_file *file); +void disas_context_destroy(struct disas_context *dctx); +void disas_warned_funcs(struct disas_context *dctx); + +#endif /* _DISAS_H */ diff --git a/tools/objtool/include/objtool/objtool.h b/tools/objtool/includ= e/objtool/objtool.h index 4d3e94b70fd8..c0dc86a78ff6 100644 --- a/tools/objtool/include/objtool/objtool.h +++ b/tools/objtool/include/objtool/objtool.h @@ -47,6 +47,4 @@ int check(struct objtool_file *file); int orc_dump(const char *objname); int orc_create(struct objtool_file *file); =20 -void disas_warned_funcs(struct objtool_file *file); - #endif /* _OBJTOOL_H */ --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 7E728267714 for ; Thu, 19 Jun 2025 14:57:16 +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=1750345038; cv=none; b=KQgrHoBNY1JGQNKV8X2QOpFEXe3CfpldfnBvPj5M1ufd+tKauKRL6G4VU50tsL+seo3RM8x5XKxLUAY5R3Upw13Yd30jozAIre6BUmS+WC/bmJVArZZVeZUF3u6dqpphqcmxgRSE2cCztxiHr+tX2Y9OYljxJEagHPLwlRNs2ZU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345038; c=relaxed/simple; bh=gxKaBfmTuKPo1WM/FW3VhmjWtmEboXPKraulQLp11js=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VaoYA2XOebt9odXWuF1p6qRVunH8GjXTqx0RyIcaC71Pxv4egS/nmUQVjwBWypQi4zqMox0ln/60FViX/r3rvBIQ5MPyRwq2jDeovtjUzqMNG7rwhPGfmWmr8t3sxCDfUWlAJYMeawFoGQI++ckLKs3D0U5G2WbpJa+oSArOR/U= 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=OLG03zM+; 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="OLG03zM+" Received: from pps.filterd (m0246629.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55JEMbwL003015; Thu, 19 Jun 2025 14:57:06 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=XO6Sb CKW3dst3VqMa8MwXojlRO8JTMC1+Jq0rqLWebQ=; b=OLG03zM+AfdYZr+ciBAb+ Vc9GrVCq5UT7Lr4IGdeYLElo0G+cG5hRfaggZZAcEr+WxE2XHf1FSRu6I41rHqca sKFWQYK3/80EPx6ujvj7/jlU+INRLaL092EDglwX1nOBthb7xg6RCiFC5kbeUmrt 5p8yz7G5+ylSHykm/MXycJP3z8KpyCBx72go7d1Qxr/iarGXGHj5UzGbrQGx4hsg 70K2P2rF1cCE89fp2PJHsTA783PrTJlARQrWnBiCbJkw2VSC8yJKv2IpMygPrzgv VlU3GPcv8nBCwEdC1kGhpb/L9B1nZWn5VJllsVlX3qcOm9mk3jrTMFJyHJq8cQFJ w== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 4790yda16h-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:06 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDPUsM023010; Thu, 19 Jun 2025 14:57:05 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8dvb-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:04 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0JF008257; Thu, 19 Jun 2025 14:57:04 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-4; Thu, 19 Jun 2025 14:57:03 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 03/17] objtool: Disassemble code with libopcodes instead of running objdump Date: Thu, 19 Jun 2025 16:56:45 +0200 Message-ID: <20250619145659.1377970-4-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=999 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-GUID: Aasmz5u0BWHonIEg8ad_UGcytGAoDOcE X-Proofpoint-ORIG-GUID: Aasmz5u0BWHonIEg8ad_UGcytGAoDOcE X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfXyzN4gW/i2Tzn MhaLw1qH++1fkL1wzjFEAfv2JcmprVpr2jRpNffgx9ZGTmYI5FxDCo5/tm/ZMJOUsWmJXaqhZB3 0p7RAcJS/mYPUTfgxa/Hxf/St8HfLdQqAQAK0BzzBmxnVRcqrZ2dXMxW040SktTEu+o/tlTRwwR hPY9Rq51huNNaY8JrRR5S3e3oZ5L65259lWzKGri6CkkMAg0dtlyt/j7FdtVHwgZCjKXU0wdBU5 4Ue6FmxcpRvESACX26vGckmFByBahYB7qBYfWmoCPjyrAOo5YU8o2Re3M1CGlYP20yM9UFfmqt9 KWQBDszSrI0xAySH9mOAhmOgJs9cmh2CZjWMuUHNhLGoIey9mFVmqOASYgU9BxzQFqf7tvpVllX TPgOUAFhfxYZtJb+290i7a3r3oOdjN7fhm/AHm5H4slMo8vhURlCZH30cGdTgoVjt+DW8VpH X-Authority-Analysis: v=2.4 cv=XZGJzJ55 c=1 sm=1 tr=0 ts=68542542 b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=qB_9k6UZtangfgbWIO8A:9 cc=ntf awl=host:13207 Content-Type: text/plain; charset="utf-8" objtool executes the objdump command to disassemble code. Use libopcodes instead to have more control about the disassembly scope and output. If libopcodes is not present then objtool is built without disassembly support. Signed-off-by: Alexandre Chartre --- tools/objtool/Build | 3 +- tools/objtool/Makefile | 22 ++++ tools/objtool/arch/loongarch/decode.c | 12 ++ tools/objtool/arch/powerpc/decode.c | 12 ++ tools/objtool/arch/x86/decode.c | 12 ++ tools/objtool/check.c | 10 +- tools/objtool/disas.c | 183 ++++++++++++++++---------- tools/objtool/include/objtool/arch.h | 9 ++ tools/objtool/include/objtool/check.h | 5 + tools/objtool/include/objtool/disas.h | 29 ++++ 10 files changed, 224 insertions(+), 73 deletions(-) diff --git a/tools/objtool/Build b/tools/objtool/Build index 677bf9148cba..ee04fba8c9d1 100644 --- a/tools/objtool/Build +++ b/tools/objtool/Build @@ -7,7 +7,8 @@ objtool-y +=3D special.o objtool-y +=3D builtin-check.o objtool-y +=3D elf.o objtool-y +=3D objtool.o -objtool-y +=3D disas.o + +objtool-$(BUILD_DISAS) +=3D disas.o =20 objtool-$(BUILD_ORC) +=3D orc_gen.o objtool-$(BUILD_ORC) +=3D orc_dump.o diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile index 8c20361dd100..1100501f4bce 100644 --- a/tools/objtool/Makefile +++ b/tools/objtool/Makefile @@ -7,6 +7,15 @@ srctree :=3D $(patsubst %/,%,$(dir $(CURDIR))) srctree :=3D $(patsubst %/,%,$(dir $(srctree))) endif =20 +# +# To support disassembly, objtool needs libopcodes which is provided +# with libbdf (binutils-dev or binutils-devel package). +# +FEATURE_USER =3D .objtool +FEATURE_TESTS =3D libbfd disassembler-init-styled +FEATURE_DISPLAY =3D libbfd disassembler-init-styled +include $(srctree)/tools/build/Makefile.feature + LIBSUBCMD_DIR =3D $(srctree)/tools/lib/subcmd/ ifneq ($(OUTPUT),) LIBSUBCMD_OUTPUT =3D $(abspath $(OUTPUT))/libsubcmd @@ -40,6 +49,18 @@ OBJTOOL_LDFLAGS :=3D $(LIBELF_LIBS) $(LIBSUBCMD) $(KBUIL= D_HOSTLDFLAGS) elfshdr :=3D $(shell echo '$(pound)include ' | $(HOSTCC) $(OBJTO= OL_CFLAGS) -x c -E - 2>/dev/null | grep elf_getshdr) OBJTOOL_CFLAGS +=3D $(if $(elfshdr),,-DLIBELF_USE_DEPRECATED) =20 +ifeq ($(feature-disassembler-init-styled), 1) + OBJTOOL_CFLAGS +=3D -DDISASM_INIT_STYLED +endif + +BUILD_DISAS :=3D n + +ifeq ($(feature-libbfd),1) + BUILD_DISAS :=3D y + OBJTOOL_CFLAGS +=3D -DDISAS + OBJTOOL_LDFLAGS +=3D -lopcodes +endif + # Always want host compilation. HOST_OVERRIDES :=3D CC=3D"$(HOSTCC)" LD=3D"$(HOSTLD)" AR=3D"$(HOSTAR)" =20 @@ -56,6 +77,7 @@ ifeq ($(SRCARCH),loongarch) BUILD_ORC :=3D y endif =20 +export BUILD_DISAS export BUILD_ORC export srctree OUTPUT CFLAGS SRCARCH AWK include $(srctree)/tools/build/Makefile.include diff --git a/tools/objtool/arch/loongarch/decode.c b/tools/objtool/arch/loo= ngarch/decode.c index b6fdc68053cc..5bf383e7e2e5 100644 --- a/tools/objtool/arch/loongarch/decode.c +++ b/tools/objtool/arch/loongarch/decode.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include #include +#include #include #include #include @@ -387,3 +388,14 @@ unsigned long arch_jump_table_sym_offset(struct reloc = *reloc, struct reloc *tabl return reloc->sym->offset + reloc_addend(reloc); } } + +#ifdef DISAS + +int arch_disas_info_init(struct disassemble_info *dinfo) +{ + return disas_info_init(dinfo, bfd_arch_loongarch, + bfd_mach_loongarch32, bfd_mach_loongarch64, + NULL); +} + +#endif /* DISAS */ diff --git a/tools/objtool/arch/powerpc/decode.c b/tools/objtool/arch/power= pc/decode.c index c851c51d4bd3..3c6fced37bcc 100644 --- a/tools/objtool/arch/powerpc/decode.c +++ b/tools/objtool/arch/powerpc/decode.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -128,3 +129,14 @@ unsigned int arch_reloc_size(struct reloc *reloc) return 8; } } + +#ifdef DISAS + +int arch_disas_info_init(struct disassemble_info *dinfo) +{ + return disas_info_init(dinfo, bfd_arch_powerpc, + bfd_mach_ppc, bfd_mach_ppc64, + NULL); +} + +#endif /* DISAS */ diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decod= e.c index 98c4713c1b09..3c85506f9414 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -16,6 +16,7 @@ =20 #include #include +#include #include #include #include @@ -880,3 +881,14 @@ unsigned int arch_reloc_size(struct reloc *reloc) return 8; } } + +#ifdef DISAS + +int arch_disas_info_init(struct disassemble_info *dinfo) +{ + return disas_info_init(dinfo, bfd_arch_i386, + bfd_mach_i386_i386, bfd_mach_x86_64, + "att"); +} + +#endif /* DISAS */ diff --git a/tools/objtool/check.c b/tools/objtool/check.c index cef3a32a6747..8ba69e0c273b 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -4702,8 +4702,6 @@ int check(struct objtool_file *file) goto out; } =20 - free_insns(file); - if (opts.stats) { printf("nr_insns_visited: %ld\n", nr_insns_visited); printf("nr_cfi: %ld\n", nr_cfi); @@ -4723,9 +4721,13 @@ int check(struct objtool_file *file) WARN("%d warning(s) upgraded to errors", warnings); print_args(); disas_ctx =3D disas_context_create(file); - disas_warned_funcs(disas_ctx); - disas_context_destroy(disas_ctx); + if (disas_ctx) { + disas_warned_funcs(disas_ctx); + disas_context_destroy(disas_ctx); + } } =20 + free_insns(file); + return ret; } diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index 67eff2a14832..9fead6281102 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -4,18 +4,53 @@ */ =20 #include +#include #include #include =20 +#include #include +#include =20 struct disas_context { struct objtool_file *file; + disassembler_ftype disassembler; + struct disassemble_info info; }; =20 +/* + * Initialize disassemble info arch, mach (32 or 64-bit) and options. + */ +int disas_info_init(struct disassemble_info *dinfo, + int arch, int mach32, int mach64, + const char *options) +{ + struct disas_context *dctx =3D dinfo->application_data; + struct objtool_file *file =3D dctx->file; + + dinfo->arch =3D arch; + + switch (file->elf->ehdr.e_ident[EI_CLASS]) { + case ELFCLASS32: + dinfo->mach =3D mach32; + break; + case ELFCLASS64: + dinfo->mach =3D mach64; + break; + default: + return -1; + } + + dinfo->disassembler_options =3D options; + + return 0; +} + struct disas_context *disas_context_create(struct objtool_file *file) { struct disas_context *dctx; + struct disassemble_info *dinfo; + int err; =20 dctx =3D malloc(sizeof(*dctx)); if (!dctx) { @@ -24,8 +59,49 @@ struct disas_context *disas_context_create(struct objtoo= l_file *file) } =20 dctx->file =3D file; + dinfo =3D &dctx->info; + + init_disassemble_info_compat(dinfo, stdout, + (fprintf_ftype)fprintf, + fprintf_styled); + + dinfo->read_memory_func =3D buffer_read_memory; + dinfo->application_data =3D dctx; + + /* + * bfd_openr() is not used to avoid doing ELF data processing + * and caching that has already being done. Here, we just need + * to identify the target file so we call an arch specific + * function to fill some disassemble info (arch, mach). + */ + + dinfo->arch =3D bfd_arch_unknown; + dinfo->mach =3D 0; + + err =3D arch_disas_info_init(dinfo); + if (err || dinfo->arch =3D=3D bfd_arch_unknown || dinfo->mach =3D=3D 0) { + WARN("failed to init disassembly arch"); + goto error; + } + + dinfo->endian =3D (file->elf->ehdr.e_ident[EI_DATA] =3D=3D ELFDATA2MSB) ? + BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE; + + disassemble_init_for_target(dinfo); + + dctx->disassembler =3D disassembler(dinfo->arch, + dinfo->endian =3D=3D BFD_ENDIAN_BIG, + dinfo->mach, NULL); + if (!dctx->disassembler) { + WARN("failed to create disassembler function"); + goto error; + } =20 return dctx; + +error: + free(dctx); + return NULL; } =20 void disas_context_destroy(struct disas_context *dctx) @@ -33,86 +109,57 @@ void disas_context_destroy(struct disas_context *dctx) free(dctx); } =20 -/* 'funcs' is a space-separated list of function names */ -static void disas_funcs(const char *funcs) +/* + * Disassemble a single instruction. Return the size of the instruction. + */ +static size_t disas_insn(struct disas_context *dctx, + struct instruction *insn) { - const char *objdump_str, *cross_compile; - int size, ret; - char *cmd; - - cross_compile =3D getenv("CROSS_COMPILE"); - if (!cross_compile) - cross_compile =3D ""; - - objdump_str =3D "%sobjdump -wdr %s | gawk -M -v _funcs=3D'%s' '" - "BEGIN { split(_funcs, funcs); }" - "/^$/ { func_match =3D 0; }" - "/<.*>:/ { " - "f =3D gensub(/.*<(.*)>:/, \"\\\\1\", 1);" - "for (i in funcs) {" - "if (funcs[i] =3D=3D f) {" - "func_match =3D 1;" - "base =3D strtonum(\"0x\" $1);" - "break;" - "}" - "}" - "}" - "{" - "if (func_match) {" - "addr =3D strtonum(\"0x\" $1);" - "printf(\"%%04x \", addr - base);" - "print;" - "}" - "}' 1>&2"; - - /* fake snprintf() to calculate the size */ - size =3D snprintf(NULL, 0, objdump_str, cross_compile, objname, funcs) + = 1; - if (size <=3D 0) { - WARN("objdump string size calculation failed"); - return; - } - - cmd =3D malloc(size); + disassembler_ftype disasm =3D dctx->disassembler; + struct disassemble_info *dinfo =3D &dctx->info; + + /* + * Set the disassembler buffer to read data from the section + * containing the instruction to disassemble. + */ + dinfo->buffer =3D insn->sec->data->d_buf; + dinfo->buffer_vma =3D 0; + dinfo->buffer_length =3D insn->sec->sh.sh_size; + + return disasm(insn->offset, &dctx->info); +} =20 - /* real snprintf() */ - snprintf(cmd, size, objdump_str, cross_compile, objname, funcs); - ret =3D system(cmd); - if (ret) { - WARN("disassembly failed: %d", ret); - return; +/* + * Disassemble a function. + */ +static void disas_func(struct disas_context *dctx, struct symbol *func) +{ + struct instruction *insn; + size_t addr; + + printf("%s:\n", func->name); + sym_for_each_insn(dctx->file, func, insn) { + addr =3D insn->offset; + printf(" %6lx: %s+0x%-6lx ", + addr, func->name, addr - func->offset); + disas_insn(dctx, insn); + printf("\n"); } + printf("\n"); } =20 +/* + * Disassemble all warned functions. + */ void disas_warned_funcs(struct disas_context *dctx) { struct symbol *sym; - char *funcs =3D NULL, *tmp; =20 if (!dctx) return; =20 for_each_sym(dctx->file, sym) { - if (sym->warned) { - if (!funcs) { - funcs =3D malloc(strlen(sym->name) + 1); - if (!funcs) { - ERROR_GLIBC("malloc"); - return; - } - strcpy(funcs, sym->name); - } else { - tmp =3D malloc(strlen(funcs) + strlen(sym->name) + 2); - if (!tmp) { - ERROR_GLIBC("malloc"); - return; - } - sprintf(tmp, "%s %s", funcs, sym->name); - free(funcs); - funcs =3D tmp; - } - } + if (sym->warned) + disas_func(dctx, sym); } - - if (funcs) - disas_funcs(funcs); } diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/o= bjtool/arch.h index 01ef6f415adf..19b1dec2db15 100644 --- a/tools/objtool/include/objtool/arch.h +++ b/tools/objtool/include/objtool/arch.h @@ -101,4 +101,13 @@ bool arch_pc_relative_reloc(struct reloc *reloc); unsigned int arch_reloc_size(struct reloc *reloc); unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct reloc= *table); =20 +#ifdef DISAS + +#include +#include + +int arch_disas_info_init(struct disassemble_info *dinfo); + +#endif /* DISAS */ + #endif /* _ARCH_H */ diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/= objtool/check.h index 00fb745e7233..5290ac1ebbc1 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -125,4 +125,9 @@ struct instruction *next_insn_same_sec(struct objtool_f= ile *file, struct instruc insn && insn->sec =3D=3D _sec; \ insn =3D next_insn_same_sec(file, insn)) =20 +#define sym_for_each_insn(file, sym, insn) \ + for (insn =3D find_insn(file, sym->sec, sym->offset); \ + insn && insn->offset < sym->offset + sym->len; \ + insn =3D next_insn_same_sec(file, insn)) + #endif /* _CHECK_H */ diff --git a/tools/objtool/include/objtool/disas.h b/tools/objtool/include/= objtool/disas.h index 5c543b69fc61..3ec3ce2e4e6f 100644 --- a/tools/objtool/include/objtool/disas.h +++ b/tools/objtool/include/objtool/disas.h @@ -7,8 +7,37 @@ #define _DISAS_H =20 struct disas_context; +struct disassemble_info; + +#ifdef DISAS + struct disas_context *disas_context_create(struct objtool_file *file); void disas_context_destroy(struct disas_context *dctx); void disas_warned_funcs(struct disas_context *dctx); +int disas_info_init(struct disassemble_info *dinfo, + int arch, int mach32, int mach64, + const char *options); + +#else /* DISAS */ + +#include + +static inline struct disas_context *disas_context_create(struct objtool_fi= le *file) +{ + WARN("Rebuild with libopcodes for disassembly support"); + return NULL; +} + +static inline void disas_context_destroy(struct disas_context *dctx) {} +static inline void disas_warned_funcs(struct disas_context *dctx) {} + +static inline int disas_info_init(struct disassemble_info *dinfo, + int arch, int mach32, int mach64, + const char *options) +{ + return -1; +} + +#endif /* DISAS */ =20 #endif /* _DISAS_H */ --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 826D727F4D9 for ; Thu, 19 Jun 2025 14:57:17 +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=1750345039; cv=none; b=XtaaViszLOpowj+r+ADxU0NOD5Jvg4ZjkvfvpQedpbaNxEIzEdoQi/q++eg5MxpiWggMGEsEEK94JFQBx81Yel3Q55Sr/NeoOPhv9PaxVJgYPcvQGhlOzKNI7NDjfJxfLhkS4C6n5i8iw6rj3jBx/TDsipX62mnMH1gCL8pmPvI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345039; c=relaxed/simple; bh=tCklpb8wK10CCyWhK13gf23iZM3lr+6DCajDx3CmoGg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=fOHMYrQNOxZFpw5toGwGnfuTgv0bEEMQ/c9/5C0vro3SRsBPQTWRL/dGpfajk4mhYlBAzk1saBVcJziKBBv2xgH4O1+tcPxUpPUejXFM/CePwwIsJYI1yNh3HCgCUP1eK+jvvU5/yuu/4wqdd3Aft0TqQoenWMGpyd906TdKkn4= 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=HvyOxP/w; 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="HvyOxP/w" Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55JEMkqP015134; Thu, 19 Jun 2025 14:57:08 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=eKR+7 LgU9IBwQLc1KxkrJXBDCFr0hxFBW8MFnGM786I=; b=HvyOxP/w4gZW6kg6pEmVo 02in2oKiFv71j4J60oxX7WcK+cSxKQvXu8qn7ajRMpBQr+V8+yZeTZ/2yx2Z8Ij2 gCv+cEJ+cUfGsdEdL6Czm9G3032wzpQOe3Iy8EmEHBkHozub6O+GEuz9o7OQnz91 tMk7mDr4sKZf+P/SUATgjgZin7iF+C89WdTXcTN72vk2PRbSZGTHkM5134Ta/mSW wZ3Jv0vnyJuCdnR7TDLxQqhSKkkUDfzlwCxtRCbsJdu6uaGifyiYmr5M1x5kSi/C kFQJoXFOEgxzNJPhZsvGem/cQFXL/Jdpj4Ez5Xr9eHUEAM5VCLLinW5BcrZ5fJJg g== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 478yp4t4an-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:07 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDR6hx022898; Thu, 19 Jun 2025 14:57:06 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8dvq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:05 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0JH008257; Thu, 19 Jun 2025 14:57:05 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-5; Thu, 19 Jun 2025 14:57:05 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 04/17] tool build: Remove annoying newline in build output Date: Thu, 19 Jun 2025 16:56:46 +0200 Message-ID: <20250619145659.1377970-5-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=999 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfX1qcIVjsylJPH JesmUJBv1ab0qBEvUen1BWnXWuW4zjxo67dRVmdtGyVd8V4ap4n+JfMw8QH462QxWFi1euxFx1v 0+cZO9CVEppXeONGB1pzSIlJg3ag1+XZbY3vd0+rmIPJ1hrKqcWdYJ1tBv6LGA39OPCyt8gvww4 18irADRpUshb045ZwMf+6a3j7Br1r59ah68Jv01ecqwtiBv73wY3AogGLeMRdYmGFKkvT5RUXNE KGPEPeLTZ5zD56qMzrxbdMx8plhdlplSNrXTP5jUlMOXgj5zjECNB5ZBCqXnODaUv8D8IB563pe 4F6t0JlkzNhgFCdi1IdyemAqb6zxaixJBsnP/XHsGej01UhMUlkI7CbJPYRZq8v4xob3fks1QUt mW8mFWJaKGSvaEzh2eaoNgflfPaPPw6yBsgsLUp3Zo/LQ4kvID017H18opn9ks2djeqcJ8BH X-Authority-Analysis: v=2.4 cv=K5EiHzWI c=1 sm=1 tr=0 ts=68542543 b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=gaUgYgG710qbGCIvUrAA:9 cc=ntf awl=host:13207 X-Proofpoint-GUID: Q1CafMb6cu6fX5ngBIj-i6adetF8BQDi X-Proofpoint-ORIG-GUID: Q1CafMb6cu6fX5ngBIj-i6adetF8BQDi Content-Type: text/plain; charset="utf-8" Remove the newline which is printed during feature discovery when nothing else is printed. Signed-off-by: Alexandre Chartre --- tools/build/Makefile.feature | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature index 57bd995ce6af..3e45164df894 100644 --- a/tools/build/Makefile.feature +++ b/tools/build/Makefile.feature @@ -326,5 +326,7 @@ endef =20 ifeq ($(FEATURE_DISPLAY_DEFERRED),) $(call feature_display_entries) - $(info ) + ifeq ($(feature_display),1) + $(info ) + endif endif --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 7208B28B4F2 for ; Thu, 19 Jun 2025 14:57:18 +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=1750345040; cv=none; b=jRr/omXXoDEnPUudVsntanNhXHkOkERJz70I1Vh8/3kAHOdq4MygPnB1aM7v0fYYhXOwqjQy02qcZIsAOvxoTCXgpQGh7NHWY4oOvLpkDWJHyt3yoJcGvC16uJ5Zb8mi/Ki4owgJm4dgQxo0NQ1I4ovxzr3yINRT2BxYnMO8+OU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345040; c=relaxed/simple; bh=SgcRfC4aLbauEp7YDUkXfpOYuYCnNeh7MBOxK1mnaao=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HZ8OKFpzGyvDjwr/PlfoJvv0t10stlR/Fvp+Bxn39loqTeeYacvvM9at7uHtnhMkJZR0/p4zTXxD1iWh5NVmjzbVWy8tjIx+9B0TMuA/df12ffFWcy+quGQ1uJKje0pjNVX0Aoe/efDYRSbjeSvi9xAX14XIEqLbNjByUVbIOtM= 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=VhPh6gpP; 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="VhPh6gpP" Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55JEMdn4014981; Thu, 19 Jun 2025 14:57:09 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=W91GK Csq6/X9c64SiyrF6Zzc+6MbOcraJ+NMsQwVfGU=; b=VhPh6gpP/Yx7SKt2NhC5z LynDUGAcELynE8+5hMfvnr+bMSm+nEw+y6wTnnPn7Umtx+hZEQUqgPklP/jY11nA 28FUGk+BzUZx1XKEzPRCkqP5L1UyU0Jv6GXZRR99ZD8I4Ote+qzgckIVA3BxYwtp 3MjI/E2ub8hd82DQ6Ft9sJVMaomRFhrPvmaEqFXd5Gi6MJeGc6rP/DIqm2MDFl3G ntRrWCsuzuBwfOzFfbOvsqFopw015UR6IJcCphQtVLVdISA8A678c9W8okVgPCzz sJxGNdX1OxuuOAsbAoCvM27WQcGMYgHxtpwcotwSRLaIt3Lhx6XnHTumrpqMn3Xc A== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 478yp4t4ar-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:08 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDLUju022936; Thu, 19 Jun 2025 14:57:07 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8dwf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:07 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0JJ008257; Thu, 19 Jun 2025 14:57:06 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-6; Thu, 19 Jun 2025 14:57:06 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 05/17] objtool: Print symbol during disassembly Date: Thu, 19 Jun 2025 16:56:47 +0200 Message-ID: <20250619145659.1377970-6-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=999 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfXyLESDSrI/bwm ZpZC5fmH56IvMcGK6HRXeN0geIVMDUF2lB/dFqcuiAIoEn6dPNECoed/r52sp6czgVMnzTwY6Hf HbxOEGsuePxg+jf5WbEr4xkiGRe421MaSZCOR0migt4Rfr4yjEw8sX8f2/R43OohZn/LUvWdNXD /b52365gwuaGfj33uL2ZIKQldYjxnGSTe955E4ah/wYr5SMZWs8TkZfqP3C+Nuu9ToUfbuMUQb0 Ixowvk00NdkaMbiYQ4sdpkLZ2wpqMs1WM7SHGXiDOLElpW+H5Edni8/rXP9xpfMGObmWXv7R7mj TeO3k0ek53cWGuyTguh31yruF8iss9VOeEnFEYCY2VvPUnEL8mkrjwuCYpENAgQW3JQ2aJ8onWN IEfBKA76GGXGJ8vAWmedWF+VuSB5vx0sUW7w2vdIPVK3c0VK2fYksx4JRaXlEfNRtQVxvZ4Y X-Authority-Analysis: v=2.4 cv=K5EiHzWI c=1 sm=1 tr=0 ts=68542544 b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=zIsJDVpacxTNcREixn4A:9 cc=ntf awl=host:13207 X-Proofpoint-GUID: BzYGDTfcqkRGztY91Z7o9GS5bR8LSucs X-Proofpoint-ORIG-GUID: BzYGDTfcqkRGztY91Z7o9GS5bR8LSucs Content-Type: text/plain; charset="utf-8" Print symbols referenced during disassembly instead of just printing raw addresses. Also handle address relocation. Signed-off-by: Alexandre Chartre --- tools/objtool/arch/loongarch/decode.c | 7 +++ tools/objtool/arch/powerpc/decode.c | 7 +++ tools/objtool/arch/x86/decode.c | 14 +++++ tools/objtool/check.c | 9 --- tools/objtool/disas.c | 89 +++++++++++++++++++++++++++ tools/objtool/include/objtool/arch.h | 2 + tools/objtool/include/objtool/check.h | 9 +++ tools/objtool/include/objtool/warn.h | 12 ++++ 8 files changed, 140 insertions(+), 9 deletions(-) diff --git a/tools/objtool/arch/loongarch/decode.c b/tools/objtool/arch/loo= ngarch/decode.c index 5bf383e7e2e5..09c43f008c9a 100644 --- a/tools/objtool/arch/loongarch/decode.c +++ b/tools/objtool/arch/loongarch/decode.c @@ -28,6 +28,13 @@ bool arch_pc_relative_reloc(struct reloc *reloc) return false; } =20 +unsigned long arch_pc_relative_offset(struct instruction *insn, + struct reloc *reloc) +{ + /* no PC relative relocation */ + return 0; +} + bool arch_callee_saved_reg(unsigned char reg) { switch (reg) { diff --git a/tools/objtool/arch/powerpc/decode.c b/tools/objtool/arch/power= pc/decode.c index 3c6fced37bcc..9c3f49c45587 100644 --- a/tools/objtool/arch/powerpc/decode.c +++ b/tools/objtool/arch/powerpc/decode.c @@ -20,6 +20,13 @@ unsigned long arch_dest_reloc_offset(int addend) return addend; } =20 +unsigned long arch_pc_relative_offset(struct instruction *insn, + struct reloc *reloc) +{ + /* no PC relative relocation */ + return 0; +} + bool arch_callee_saved_reg(unsigned char reg) { return false; diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decod= e.c index 3c85506f9414..6a39cc619d63 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -103,6 +103,20 @@ bool arch_pc_relative_reloc(struct reloc *reloc) return false; } =20 +unsigned long arch_pc_relative_offset(struct instruction *insn, + struct reloc *reloc) +{ + /* + * Relocation information for a RIP-relative instruction is + * based on the RIP value at the end of the instruction. So + * to get the effective relocated address, the reference has + * to be adjusted with the number of bytes between the + * relocation offset and the end of the instruction. + */ + return reloc_addend(reloc) + + insn->offset + insn->len - reloc_offset(reloc); +} + #define ADD_OP(op) \ if (!(op =3D calloc(1, sizeof(*op)))) \ return -1; \ diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 8ba69e0c273b..a4d0a6c62bc0 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -132,15 +132,6 @@ static struct instruction *prev_insn_same_sym(struct o= bjtool_file *file, for (insn =3D next_insn_same_sec(file, insn); insn; \ insn =3D next_insn_same_sec(file, insn)) =20 -static inline struct symbol *insn_call_dest(struct instruction *insn) -{ - if (insn->type =3D=3D INSN_JUMP_DYNAMIC || - insn->type =3D=3D INSN_CALL_DYNAMIC) - return NULL; - - return insn->_call_dest; -} - static inline struct reloc *insn_jump_table(struct instruction *insn) { if (insn->type =3D=3D INSN_JUMP_DYNAMIC || diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index 9fead6281102..91d23f7518e3 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -14,10 +14,96 @@ =20 struct disas_context { struct objtool_file *file; + struct instruction *insn; disassembler_ftype disassembler; struct disassemble_info info; }; =20 +#define DINFO_FPRINTF(dinfo, ...) \ + ((*(dinfo)->fprintf_func)((dinfo)->stream, __VA_ARGS__)) + +static void disas_print_address(bfd_vma addr, struct disassemble_info *din= fo) +{ + struct disas_context *dctx =3D dinfo->application_data; + struct instruction *insn =3D dctx->insn; + struct objtool_file *file =3D dctx->file; + struct instruction *jump_dest; + struct symbol *call_dest; + unsigned long offset; + struct reloc *reloc; + bool is_reloc; + char symstr[1024]; + char *str; + + /* + * If the instruction is a call/jump and it references a + * destination then this is likely the address we are looking + * up. So check it first. + */ + jump_dest =3D insn->jump_dest; + if (jump_dest && jump_dest->sym && jump_dest->offset =3D=3D addr) { + sprint_name(symstr, jump_dest->sym->name, jump_dest->offset - jump_dest-= >sym->offset); + DINFO_FPRINTF(dinfo, "%lx <%s>", addr, symstr); + return; + } + + /* + * Assume the address is a relocation if it points to the next + * instruction. + */ + is_reloc =3D (addr =3D=3D insn->offset + insn->len); + + /* + * The call destination offset can be the address we are looking + * up, or 0 if there is a relocation. + */ + call_dest =3D insn_call_dest(insn); + if (call_dest) { + if (call_dest->offset =3D=3D addr) { + DINFO_FPRINTF(dinfo, "%lx <%s>", addr, call_dest->name); + return; + } + if (call_dest->offset =3D=3D 0 && is_reloc) { + DINFO_FPRINTF(dinfo, "%s", call_dest->name); + return; + } + } + + if (!is_reloc) { + DINFO_FPRINTF(dinfo, "0x%lx", addr); + return; + } + + /* + * If this is a relocation, check if we have relocation information + * for this instruction. + */ + reloc =3D find_reloc_by_dest_range(file->elf, insn->sec, + insn->offset, insn->len); + if (!reloc) { + DINFO_FPRINTF(dinfo, "0x%lx", addr); + return; + } + + if (arch_pc_relative_reloc(reloc)) + offset =3D arch_pc_relative_offset(insn, reloc); + else + offset =3D reloc_addend(reloc); + + /* + * If the relocation symbol is a section name (for example ".bss") + * then we try to further resolve the name. + */ + if (reloc->sym->type =3D=3D STT_SECTION) { + str =3D offstr(reloc->sym->sec, reloc->sym->offset + offset); + DINFO_FPRINTF(dinfo, "%s", str); + free(str); + } else { + sprint_name(symstr, reloc->sym->name, offset); + DINFO_FPRINTF(dinfo, "%s", symstr); + } +} + /* * Initialize disassemble info arch, mach (32 or 64-bit) and options. */ @@ -66,6 +152,7 @@ struct disas_context *disas_context_create(struct objtoo= l_file *file) fprintf_styled); =20 dinfo->read_memory_func =3D buffer_read_memory; + dinfo->print_address_func =3D disas_print_address; dinfo->application_data =3D dctx; =20 /* @@ -118,6 +205,8 @@ static size_t disas_insn(struct disas_context *dctx, disassembler_ftype disasm =3D dctx->disassembler; struct disassemble_info *dinfo =3D &dctx->info; =20 + dctx->insn =3D insn; + /* * Set the disassembler buffer to read data from the section * containing the instruction to disassemble. diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/o= bjtool/arch.h index 19b1dec2db15..baa6eee1977f 100644 --- a/tools/objtool/include/objtool/arch.h +++ b/tools/objtool/include/objtool/arch.h @@ -97,6 +97,8 @@ bool arch_is_embedded_insn(struct symbol *sym); int arch_rewrite_retpolines(struct objtool_file *file); =20 bool arch_pc_relative_reloc(struct reloc *reloc); +unsigned long arch_pc_relative_offset(struct instruction *insn, + struct reloc *reloc); =20 unsigned int arch_reloc_size(struct reloc *reloc); unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct reloc= *table); diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/= objtool/check.h index 5290ac1ebbc1..4adbcd760c6f 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -115,6 +115,15 @@ static inline bool is_jump(struct instruction *insn) return is_static_jump(insn) || is_dynamic_jump(insn); } =20 +static inline struct symbol *insn_call_dest(struct instruction *insn) +{ + if (insn->type =3D=3D INSN_JUMP_DYNAMIC || + insn->type =3D=3D INSN_CALL_DYNAMIC) + return NULL; + + return insn->_call_dest; +} + struct instruction *find_insn(struct objtool_file *file, struct section *sec, unsigned long offset); =20 diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/o= bjtool/warn.h index cb8fe846d9dd..125093d568be 100644 --- a/tools/objtool/include/objtool/warn.h +++ b/tools/objtool/include/objtool/warn.h @@ -17,6 +17,18 @@ =20 extern const char *objname; =20 +static inline int sprint_name(char *str, const char *name, unsigned long o= ffset) +{ + int len; + + if (offset) + len =3D sprintf(str, "%s+0x%lx", name, offset); + else + len =3D sprintf(str, "%s", name); + + return len; +} + static inline char *offstr(struct section *sec, unsigned long offset) { bool is_text =3D (sec->sh.sh_flags & SHF_EXECINSTR); --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 725BD28B4F4 for ; Thu, 19 Jun 2025 14:57:18 +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=1750345040; cv=none; b=HkkY3gYBbqVbsfzaZe+9i2/U8NHAduJlVr0ooGs8vGxeYkse60M86Q2pV4McGKyxyPjs1UVC6eYfWu23Sj3s/D7vYVhqf+PE0P8ovSUx8PzQrYs5ZPcpr1JD3QTzqg7rk1eQXcrr7wSS1U+Xr9n4yST6YOuzMe8i5V4igQI8l2I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345040; c=relaxed/simple; bh=gCMfQZaDgZAa6+fgwvc+M0DkImFzVss5qhfWe7EaR1w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nEmlr6hABxyxPr1ECTOTsv7i26S7wy3ea/0P9nLepBnDUKTeynj/x1E+t5WayVwTBhyzVQtnwXUqw8xPrrGgphHefCwXyLb3c3jXkMATpRqKNKEf2NobUFSx7unH1aREC7IJJrdOuxU3eL+dJr76nGG39cVFLXKRDz3K6BYlvOQ= 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=od4cTT3g; 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="od4cTT3g" Received: from pps.filterd (m0246629.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55JEMaCn002973; Thu, 19 Jun 2025 14:57:10 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=PF7pm YfcDtTPC/InUY7QsSb4h76e3rzVk0Dnlk581Aw=; b=od4cTT3gM1ppJGNIKA03W mCHrl5SM25uRcNPq2apEjbOqXPik/qzrF7fSwQJ2vJReaddVKp9a6KLb0AwhNxfj dRS5VNffdak9pUhxiyOgyliHjpZ4c67/fxKQtfB3Q7s1RlPEFdGXvVBLOMN00mFW RlCatTR9XCoiNKGuIOeSi8oGt+0XxukKBcblxKfU/XHhayiJjhmiWw2RfpJF5M4j 78dZStpgVfncS0xdjMZd2n5fO/Jn/LbQ62UoB/gDVFR8ppje6yyzgLDQel6pOGIP V2hysXLic7E10WKcT516kv3/lz2Hd29kaBkIe9aGhEa5QiBSuZTQfIREG8Av3ngn w== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 4790yda16m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:09 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDLCjN023045; Thu, 19 Jun 2025 14:57:08 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8dww-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:08 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0JL008257; Thu, 19 Jun 2025 14:57:07 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-7; Thu, 19 Jun 2025 14:57:07 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 06/17] objtool: Improve offstr() output Date: Thu, 19 Jun 2025 16:56:48 +0200 Message-ID: <20250619145659.1377970-7-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=798 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-GUID: i_n-bWpVT6c3F4z1SI_Jhc0ElBCZZf10 X-Proofpoint-ORIG-GUID: i_n-bWpVT6c3F4z1SI_Jhc0ElBCZZf10 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfX3v1pe4mDxLHz jtDkAmL03HUWCyYOI2nEcnd/Eu1LgoXTkoDpuQI/ZUQ2HWVMy0WR2SOeFfK2O60HHzvEIotyzoA 3UQcYEk9j7Qp6Yzey7WSiKDXlPyUhRvGuXSqZW0bnKXQIKVBChEfyQ1pB6Rap5oOorHAyGGEHhq I66rK5FQCKjdfBvu3m1uYDjmeudbcfkOCYYRJ7TANdjRdLS2IP6CF52etbAyAF7h5A0FAtcWJli 5kvEXGDUTSy7KjKqM+SxFJ5bsLie83qm/EjlnxCFpCgt9R8NX6RmtmTMMmoOelmPrUC8ldyB+XQ mM1OQB1OBWuLTf3W1LVVt1ejIpWxKKJ3HTFffC0r4wXJdhiDiAd31U8+FcM6I8b0rSBBLoIUNTL lcuc890jG0LMMgzN7hEQdx8p+JbjsKTzLQ/Ba+bpUd1wO1m93v15OcT11ZtHdka8zSQuPlla X-Authority-Analysis: v=2.4 cv=XZGJzJ55 c=1 sm=1 tr=0 ts=68542545 b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=bbKr6aJM5K5ssBc2alEA:9 cc=ntf awl=host:13207 Content-Type: text/plain; charset="utf-8" offset() formats a section offset into a "+" string. Improve the output to just "" when the offset is zero. Signed-off-by: Alexandre Chartre --- tools/objtool/include/objtool/warn.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/o= bjtool/warn.h index 125093d568be..d89e6ae69143 100644 --- a/tools/objtool/include/objtool/warn.h +++ b/tools/objtool/include/objtool/warn.h @@ -43,12 +43,12 @@ static inline char *offstr(struct section *sec, unsigne= d long offset) =20 if (sym) { str =3D malloc(strlen(sym->name) + strlen(sec->name) + 40); - len =3D sprintf(str, "%s+0x%lx", sym->name, offset - sym->offset); + len =3D sprint_name(str, sym->name, offset - sym->offset); if (opts.sec_address) sprintf(str+len, " (%s+0x%lx)", sec->name, offset); } else { str =3D malloc(strlen(sec->name) + 20); - sprintf(str, "%s+0x%lx", sec->name, offset); + sprint_name(str, sec->name, offset); } =20 return str; --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 5D262288C2C for ; Thu, 19 Jun 2025 14:57:20 +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=1750345041; cv=none; b=JakQsLrjFMXjCqDoCQ1frDzSYR/n9on8fLfck/+3IEKHvqTCG5WWKcCmCrngQfJ8i9UpjDPFSKTc/H9UOtP2gB/Bii7Sh+4/DYIkP4HdUfQBDtc4r9yhBvDKJxC/LOGVNE56Fgd29r11HK6cNFywBivhpGW+e4BKSn5eOLOND0U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345041; c=relaxed/simple; bh=eOvrWZYs7cpkr1jC2F6FHT95SEh0+ql4jGl77Y1613Y=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IR3JtXUqZxH8gyyZn0FI9F4vEK+mM/K93e1cHPAT2KjR8h3n8IwUUn1cKOwYekr6s9MpS2jdgdD2rBHqC/ZH1MYpeNyAh08l2nUSEuGORsNjfddDKKfWFwYLt1sJqdQu3dzHQAp9uBGqTDBRGFI45rc9RtuLs++P/PBYXagvOYg= 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=ndEjMbuN; 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="ndEjMbuN" 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 55JEMn3w029814; Thu, 19 Jun 2025 14:57:11 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=OcrmH Vb9VrydAGeRz/jWkrVwwnwuG5f1aGkxLUAikyo=; b=ndEjMbuN3hIDsqGX5HoP/ VfhgWsp0jWkPZ3cR2MVPEHYowji9myC/luYtBciJeCYnwnPIFb0z/Dy+Hyy3ylBv Jc6mL9Bu2yBPzEV2CDxdXivM8vgBuc9kMP4VpBu4I43niDptT4FkCoW6OHn334jP IHaiMwwZ3ZehN4oJjlxk088WVKM3zIiirmMa2VqlsWj6J0HBvFPAWaGpkpqvqrLm I8HSw4SHdFns/Gq1qWY8Mxl2Ib+EKPvEgzfbf7sHGrefRpdq5of2zIXy07bHKd1p +2m+En3PazsGWw3QBedyYg6vxqqoFjVyrrOyw2XTK+56I/fQTXoqVbZqtPKKEDSh g== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 47b23xwjxj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:10 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDNXfu022847; Thu, 19 Jun 2025 14:57:09 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8dxk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:09 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0JN008257; Thu, 19 Jun 2025 14:57:09 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-8; Thu, 19 Jun 2025 14:57:08 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 07/17] objtool: Store instruction disassembly result Date: Thu, 19 Jun 2025 16:56:49 +0200 Message-ID: <20250619145659.1377970-8-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=999 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfX14uYeiE2SPSd +/6YVCo8MCzJjFMLxP1fKXUtlMegAZN60rfP6TM2lBXrzmaWwyScFi1JMY3HtUUEO85y5OXL+rq w6CQsfwjROAGagmz4Wb0dzIoG1Ufq1CZWuPnfjCadyI7NBByre+7MYhC8/mp37htEPky/Rs6jv8 C3sAc9zRWOw+o8Ibh4Sqsx31peOvPTiKBcBizuDWCtqVQO4zI93WPR7X7aUh7Vics6TXiu7+Tzn EaXqsSGtUNwn4jQUPoMSj7fSfj3qmy14ZbEL6uCCIwfcEUvpntNZYDUUozvQbo+hgsMH63BtROG XKMajysWhFLqYrXVh1LtGtoA/MqMWaLVraOrSwTTS77+HvceSxh3UgfBlSjRI2zwdk0gWY0QgKQ X58JlfeNujKQczsHXmquqismoZXcIwMcfCMBWomhdtWr1WHMB4TU7ZXXhdNaoF4mLIvhh8xu X-Authority-Analysis: v=2.4 cv=DM2P4zNb c=1 sm=1 tr=0 ts=68542547 b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=jcmHYjYDc9FjrwFKAggA:9 cc=ntf awl=host:13207 X-Proofpoint-GUID: NoTd7VEjyzEpCzMTRqlM9jHc9ZFdJL0x X-Proofpoint-ORIG-GUID: NoTd7VEjyzEpCzMTRqlM9jHc9ZFdJL0x Content-Type: text/plain; charset="utf-8" When disassembling an instruction store the result instead of directly printing it. Signed-off-by: Alexandre Chartre --- tools/objtool/disas.c | 78 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 72 insertions(+), 6 deletions(-) diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index 91d23f7518e3..fbec062f40eb 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -12,9 +12,16 @@ #include #include =20 +/* + * Size of the buffer for storing the result of disassembling + * a single instruction. + */ +#define DISAS_RESULT_SIZE 1024 + struct disas_context { struct objtool_file *file; struct instruction *insn; + char result[DISAS_RESULT_SIZE]; disassembler_ftype disassembler; struct disassemble_info info; }; @@ -22,6 +29,60 @@ struct disas_context { #define DINFO_FPRINTF(dinfo, ...) \ ((*(dinfo)->fprintf_func)((dinfo)->stream, __VA_ARGS__)) =20 + +static int disas_result_fprintf(struct disas_context *dctx, + const char *fmt, va_list ap) +{ + char *buf =3D dctx->result; + size_t avail, len; + + len =3D strlen(buf); + if (len >=3D DISAS_RESULT_SIZE - 1) { + WARN_FUNC(dctx->insn->sec, dctx->insn->offset, + "disassembly buffer is full"); + return -1; + } + avail =3D DISAS_RESULT_SIZE - len; + + len =3D vsnprintf(buf + len, avail, fmt, ap); + if (len < 0 || len >=3D avail) { + WARN_FUNC(dctx->insn->sec, dctx->insn->offset, + "disassembly buffer is truncated"); + return -1; + } + + return 0; +} + +static int disas_fprintf(void *stream, const char *fmt, ...) +{ + va_list arg; + int rv; + + va_start(arg, fmt); + rv =3D disas_result_fprintf(stream, fmt, arg); + va_end(arg); + + return rv; +} + +/* + * For init_disassemble_info_compat(). + */ +static int disas_fprintf_styled(void *stream, + enum disassembler_style style, + const char *fmt, ...) +{ + va_list arg; + int rv; + + va_start(arg, fmt); + rv =3D disas_result_fprintf(stream, fmt, arg); + va_end(arg); + + return rv; +} + static void disas_print_address(bfd_vma addr, struct disassemble_info *din= fo) { struct disas_context *dctx =3D dinfo->application_data; @@ -147,9 +208,8 @@ struct disas_context *disas_context_create(struct objto= ol_file *file) dctx->file =3D file; dinfo =3D &dctx->info; =20 - init_disassemble_info_compat(dinfo, stdout, - (fprintf_ftype)fprintf, - fprintf_styled); + init_disassemble_info_compat(dinfo, dctx, + disas_fprintf, disas_fprintf_styled); =20 dinfo->read_memory_func =3D buffer_read_memory; dinfo->print_address_func =3D disas_print_address; @@ -196,6 +256,11 @@ void disas_context_destroy(struct disas_context *dctx) free(dctx); } =20 +static char *disas_result(struct disas_context *dctx) +{ + return dctx->result; +} + /* * Disassemble a single instruction. Return the size of the instruction. */ @@ -206,6 +271,7 @@ static size_t disas_insn(struct disas_context *dctx, struct disassemble_info *dinfo =3D &dctx->info; =20 dctx->insn =3D insn; + dctx->result[0] =3D '\0'; =20 /* * Set the disassembler buffer to read data from the section @@ -229,10 +295,10 @@ static void disas_func(struct disas_context *dctx, st= ruct symbol *func) printf("%s:\n", func->name); sym_for_each_insn(dctx->file, func, insn) { addr =3D insn->offset; - printf(" %6lx: %s+0x%-6lx ", - addr, func->name, addr - func->offset); disas_insn(dctx, insn); - printf("\n"); + printf(" %6lx: %s+0x%-6lx %s\n", + addr, func->name, addr - func->offset, + disas_result(dctx)); } printf("\n"); } --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 BA6632356A0 for ; Thu, 19 Jun 2025 14:57:15 +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=1750345037; cv=none; b=a6scatWUHNw4ewo6e8JmoiTGXdsUykkIoj9fHj6XAVvE1ULq1IgQWFV0NaJhPzdAFU5stsRDM9NLvMYw6ZjyHYVBNwTWcuqLBIz9zZ4L8Vhg+85YQFmlIJqs1AsB2T+3qjIWxWkb/mH6URqBWeDaNxDiCuv/Uu9tYzGcGiE64NE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345037; c=relaxed/simple; bh=kf2K/4yHc7UfQpUUCMQcOijB+wqlhvABpHjMA8u4rLs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=URJBSpapFPOZZqUPBQcbz1I0oqB0snbH55HetBSeKyBB9ChGc8/Fu15oMY3TATDJQeuknC/MnslArAI9vAx5eOse82zzY14Wvze1O6NY36Zp0COXlh5oXgkDWUfhXQqN4a5Ln35F6wwk5e641jqLsHo5wiIMecm1UPKo9QhFlZU= 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=LPqZH4AC; 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="LPqZH4AC" 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 55JEMa4K029324; Thu, 19 Jun 2025 14:57:12 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=pOEYx EsOe9UkNR/ofqlxOJIxGVqObktx2bB0sTIhGWQ=; b=LPqZH4AC6rW9ir0TiAoft UkbTLD4cbIWjWhoHXWkwcLxnpQty/j0C3Q6amfU1cCE+fznx5XtD4V/voFAtK7Nk OERUiu4E9AKXa6xrxFuAI7qSCP9IvehB8oqwwBJGgluC9U7Vt05gJs70GReOOG+f 5y+YirGO/Vk0yRyXWhoCTgbdzOGLGLx/yp0TCUDczN6pJuubEP3bs4oj3Ng2v5th XRI210/Gyo8sVOupLHy/IUjPwg8yZBujzZR4znOvtDZmGEr8mflziUZaKiASsVHe 6ItZ2awkUfm6vBo/BQsVmbrX+lGCXJCx282nZX1xjo6CL+KduLorh3sGCPLhrzQj Q== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 47b23xwjxk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:12 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDEZug022842; Thu, 19 Jun 2025 14:57:10 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8dyc-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:10 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0JP008257; Thu, 19 Jun 2025 14:57:10 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-9; Thu, 19 Jun 2025 14:57:10 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 08/17] objtool: Disassemble instruction on warning or backtrace Date: Thu, 19 Jun 2025 16:56:50 +0200 Message-ID: <20250619145659.1377970-9-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=969 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfX+FJMGF4yVtei 0704kNBv+REjlR5EZ7cQVQqLEH1bIC262aXIy8DeRBQxPwlltDGrnqLi4l6jyHoNZ84sRO1F1dZ 2KCdKO8bl7jCaqvHBOOe4WdT9GajzpYDX21Jx5P0S7nFY45aiEjxMhfxGn34vti/A+0h4Jq22IP Ld9wRNYIaAz91AYSp3bGDFZoUyM16iRx6mV7T+9oqBQOamsGPOVWX56kQUulQM1w55wUwnTj5sh pIDR6cLy2FJh8A0Rxl2JAt66IV4HSwAJLo92yV+AKhUkYale8/I2yA00Z5L+MHmzRCw8mljfW5q 25NA8q6wQUVlvITyKDPxys4V0xKYQbqA2i2KIqeWQt+UA25QZbJ8VsBpYK9L3S95abk22jI3fAX 8Zj2fqNeMl11ffsanN3BLQKgdWuNFKAlnBBiVEN8fErp11ZSIvOCL49cKnYg8SVWmrO+49Pg X-Authority-Analysis: v=2.4 cv=DM2P4zNb c=1 sm=1 tr=0 ts=68542548 b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=49cdYLv4DVxkACFpF8YA:9 cc=ntf awl=host:13207 X-Proofpoint-GUID: SCveHgeJddkUem3bJRIaVdWnRKLckwAZ X-Proofpoint-ORIG-GUID: SCveHgeJddkUem3bJRIaVdWnRKLckwAZ Content-Type: text/plain; charset="utf-8" When an instruction warning (WARN_INSN) or backtrace (BT_INSN) is issued, disassemble the instruction to provide more context. Signed-off-by: Alexandre Chartre --- tools/objtool/check.c | 36 ++++++++++++++++++++++----- tools/objtool/disas.c | 5 ++-- tools/objtool/include/objtool/check.h | 2 ++ tools/objtool/include/objtool/disas.h | 13 ++++++++++ tools/objtool/include/objtool/warn.h | 16 ++++++++---- 5 files changed, 58 insertions(+), 14 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index a4d0a6c62bc0..beaafa1f0323 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -4581,11 +4581,34 @@ static void free_insns(struct objtool_file *file) free(chunk->addr); } =20 +static struct disas_context *objtool_disas_ctx; + +const char *objtool_disas_insn(struct instruction *insn) +{ + struct disas_context *dctx =3D objtool_disas_ctx; + + if (!dctx) + return ""; + + disas_insn(dctx, insn); + return disas_result(dctx); +} + int check(struct objtool_file *file) { - struct disas_context *disas_ctx; + struct disas_context *disas_ctx =3D NULL; int ret =3D 0, warnings =3D 0; =20 + /* + * If the verbose or backtrace option is used then we need a + * disassembly context to disassemble instruction or function + * on warning or backtrace. + */ + if (opts.verbose || opts.backtrace) { + disas_ctx =3D disas_context_create(file); + objtool_disas_ctx =3D disas_ctx; + } + arch_initial_func_cfi_state(&initial_func_cfi); init_cfi_state(&init_cfi); init_cfi_state(&func_cfi); @@ -4711,11 +4734,12 @@ int check(struct objtool_file *file) if (opts.werror && warnings) WARN("%d warning(s) upgraded to errors", warnings); print_args(); - disas_ctx =3D disas_context_create(file); - if (disas_ctx) { - disas_warned_funcs(disas_ctx); - disas_context_destroy(disas_ctx); - } + disas_warned_funcs(disas_ctx); + } + + if (disas_ctx) { + disas_context_destroy(disas_ctx); + objtool_disas_ctx =3D NULL; } =20 free_insns(file); diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index fbec062f40eb..3831e46e0f35 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -256,7 +256,7 @@ void disas_context_destroy(struct disas_context *dctx) free(dctx); } =20 -static char *disas_result(struct disas_context *dctx) +char *disas_result(struct disas_context *dctx) { return dctx->result; } @@ -264,8 +264,7 @@ static char *disas_result(struct disas_context *dctx) /* * Disassemble a single instruction. Return the size of the instruction. */ -static size_t disas_insn(struct disas_context *dctx, - struct instruction *insn) +size_t disas_insn(struct disas_context *dctx, struct instruction *insn) { disassembler_ftype disasm =3D dctx->disassembler; struct disassemble_info *dinfo =3D &dctx->info; diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/= objtool/check.h index 4adbcd760c6f..f3ea144d4746 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -139,4 +139,6 @@ struct instruction *next_insn_same_sec(struct objtool_f= ile *file, struct instruc insn && insn->offset < sym->offset + sym->len; \ insn =3D next_insn_same_sec(file, insn)) =20 +const char *objtool_disas_insn(struct instruction *insn); + #endif /* _CHECK_H */ diff --git a/tools/objtool/include/objtool/disas.h b/tools/objtool/include/= objtool/disas.h index 3ec3ce2e4e6f..1aee1fbe0bb9 100644 --- a/tools/objtool/include/objtool/disas.h +++ b/tools/objtool/include/objtool/disas.h @@ -17,6 +17,8 @@ void disas_warned_funcs(struct disas_context *dctx); int disas_info_init(struct disassemble_info *dinfo, int arch, int mach32, int mach64, const char *options); +size_t disas_insn(struct disas_context *dctx, struct instruction *insn); +char *disas_result(struct disas_context *dctx); =20 #else /* DISAS */ =20 @@ -38,6 +40,17 @@ static inline int disas_info_init(struct disassemble_inf= o *dinfo, return -1; } =20 +static inline size_t disas_insn(struct disas_context *dctx, + struct instruction *insn) +{ + return -1; +} + +static inline char *disas_result(struct disas_context *dctx) +{ + return NULL; +} + #endif /* DISAS */ =20 #endif /* _DISAS_H */ diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/o= bjtool/warn.h index d89e6ae69143..f001233b27df 100644 --- a/tools/objtool/include/objtool/warn.h +++ b/tools/objtool/include/objtool/warn.h @@ -89,9 +89,11 @@ static inline char *offstr(struct section *sec, unsigned= long offset) #define WARN_INSN(insn, format, ...) \ ({ \ struct instruction *_insn =3D (insn); \ - if (!_insn->sym || !_insn->sym->warned) \ + if (!_insn->sym || !_insn->sym->warned) { \ WARN_FUNC(_insn->sec, _insn->offset, format, \ ##__VA_ARGS__); \ + BT_INSN(_insn, ""); \ + } \ if (_insn->sym) \ _insn->sym->warned =3D 1; \ }) @@ -99,10 +101,14 @@ static inline char *offstr(struct section *sec, unsign= ed long offset) #define BT_INSN(insn, format, ...) \ ({ \ if (opts.verbose || opts.backtrace) { \ - struct instruction *_insn =3D (insn); \ - char *_str =3D offstr(_insn->sec, _insn->offset); \ - WARN(" %s: " format, _str, ##__VA_ARGS__); \ - free(_str); \ + struct instruction *__insn =3D (insn); \ + char *_str =3D offstr(__insn->sec, __insn->offset); \ + const char *_istr =3D objtool_disas_insn(__insn); \ + int _len; \ + _len =3D snprintf(NULL, 0, " %s: " format, _str, ##__VA_ARGS__); \ + _len =3D (_len < 50) ? 50 - _len : 0; \ + WARN(" %s: " format " %*s%s", _str, ##__VA_ARGS__, _len, "", _istr); \ + free(_str); \ } \ }) =20 --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 75512278753 for ; Thu, 19 Jun 2025 14:57:17 +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=1750345041; cv=none; b=b6JxprnHH1xaldLAjAIcY5E1CVaKs/4oAQEc/M6USbm2xHkPBqOKMf+wAu8FRZpr+qmZFVJ1AyzJodob0QUBq8gtvvD3/PPSY2sGRRxd+/VzQYBBHG4zyb8tB9TcEN51CahTbpgrzrjpPm3651N/eU+fdtHMHAdNi6O7qxKXklI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345041; c=relaxed/simple; bh=8MQgTgbyU7AhoO9IKV6g0zC+wuDyROfOHHLDLTVvPTI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=q8A6MAPSyYbvTkhIu8D1vPgq3i8nj3+uNiaxFfDbn7td3fPxggs8sTl9MEH/Vyu1SHf87J03d6gBm+Sgdio5rhhqVNP/1QGvK25bp4HV5zPF2i/sCGMyeb8vg4PzcniNUzkmcPlYwmp9orCu7uZC3bvRRpHIjP2HaOtjLip062A= 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=R6egBkkl; 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="R6egBkkl" 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 55JEMa4L029324; Thu, 19 Jun 2025 14:57:13 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=QVIur kUasTY4ql6e6cGMyBpP2U5j7bQgQX8Qgd4u2eg=; b=R6egBkklL1bzpwKn3C78T gKztA+SG8yGHTaXnUMKdq3rPs87WF8YbDRqJkU1DEKCeMy+PCcu9soGoX7z1lH/9 8uFN3ohgjVPgYzC72eLzvp0y+JZ8JAOrEoipTeMWaAsgO8dRIsDPaN46YNCtNy/5 F6mybWFxYVDRRlZguP0zEK9JpN2YChTpExyrIoXBRebrtD6FxEdg4nC8FJWvA7Sj EkKF3YKFJiO+ncCiynCco4eUIUIjsvV4M11adRd4ijWMDnDqWX98zD+drcKwiJuP Ra7pnax1UuIg537gUFw9dWLPPLi4aqy7rvkQiQ9hvBt5SpIKUv3ZhyEWGd0KsUiE w== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 47b23xwjxn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:13 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDPoSx022754; Thu, 19 Jun 2025 14:57:12 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8e0h-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:11 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0JR008257; Thu, 19 Jun 2025 14:57:11 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-10; Thu, 19 Jun 2025 14:57:11 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 09/17] objtool: Extract code to validate instruction from the validate branch loop Date: Thu, 19 Jun 2025 16:56:51 +0200 Message-ID: <20250619145659.1377970-10-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=999 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfXykJoHnndy9e1 nUEdLB1yvaeVFcCpGNNE4Q6dqTdhIMLpjYh16Jo8pkssfSI300yZ3HsDZ3XjIBBIye7XDJ3Tkfv vrlONMDKySEifxH7X3uODJ27kCfsPSJiFRXI7aPWMl9jkJNsvgm3oIAnf04qatecwvVAaNE9hGP GH+l/fLdZ5edCUltSLhIWylsU1r1DTnryG6ibu54P7zIn3q7RGJe5IbKPZyTyfofBJgALEn4j+a b8PemYhbOGT2WnumgYCbpOvG0n3KEGLvFWFah1Ms4GLl/8e/4YJxpZbsA8Ah/fDyy1q4V27Ejdk NObdD5Zy6ztvuC3fdvmGdiOdkRwyeZIYROle8/5wyNJaBQHjJfOOMz/HFU6Oqu8KewTZ9sSVP32 25UhOoyshpxM2HhBvFBb81iLXTtgZqGoy2t2Qk0BYM4Il2SRLaqKpWTNVNbz+fM47sIqC31r X-Authority-Analysis: v=2.4 cv=DM2P4zNb c=1 sm=1 tr=0 ts=68542549 b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=45N9rFkX92oTsxCXvtEA:9 cc=ntf awl=host:13207 X-Proofpoint-GUID: jxs3MGk_BR9QfmYazvPPzN73sSSFv-fQ X-Proofpoint-ORIG-GUID: jxs3MGk_BR9QfmYazvPPzN73sSSFv-fQ Content-Type: text/plain; charset="utf-8" The code to validate a branch loops through all instructions of the branch and validate each instruction. Move the code to validate an instruction to a separated function. Signed-off-by: Alexandre Chartre --- tools/objtool/check.c | 388 ++++++++++++++++++++++-------------------- 1 file changed, 206 insertions(+), 182 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index beaafa1f0323..947fe57e9a6d 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3528,254 +3528,278 @@ static bool skip_alt_group(struct instruction *in= sn) return alt_insn->type =3D=3D INSN_CLAC || alt_insn->type =3D=3D INSN_STAC; } =20 -/* - * Follow the branch starting at the given instruction, and recursively fo= llow - * any other branches (jumps). Meanwhile, track the frame pointer state at - * each instruction and validate all the rules described in - * tools/objtool/Documentation/objtool.txt. - */ static int validate_branch(struct objtool_file *file, struct symbol *func, - struct instruction *insn, struct insn_state state) + struct instruction *insn, struct insn_state state); + +static int validate_insn(struct objtool_file *file, struct symbol *func, + struct instruction *insn, struct insn_state *statep, + struct instruction *prev_insn, struct instruction *next_insn, + bool *dead_end) { struct alternative *alt; - struct instruction *next_insn, *prev_insn =3D NULL; - struct section *sec; u8 visited; int ret; =20 - if (func && func->ignore) - return 0; + /* + * Any returns before the end of this function are effectively dead + * ends, i.e. validate_branch() has reached the end of the branch. + */ + *dead_end =3D true; =20 - sec =3D insn->sec; + visited =3D VISITED_BRANCH << statep->uaccess; + if (insn->visited & VISITED_BRANCH_MASK) { + if (!insn->hint && !insn_cfi_match(insn, &statep->cfi)) + return 1; =20 - while (1) { - next_insn =3D next_insn_to_validate(file, insn); + if (insn->visited & visited) + return 0; + } else { + nr_insns_visited++; + } =20 - if (func && insn_func(insn) && func !=3D insn_func(insn)->pfunc) { - /* Ignore KCFI type preambles, which always fall through */ - if (!strncmp(func->name, "__cfi_", 6) || - !strncmp(func->name, "__pfx_", 6)) - return 0; + if (statep->noinstr) + statep->instr +=3D insn->instr; =20 - if (file->ignore_unreachables) - return 0; + if (insn->hint) { + if (insn->restore) { + struct instruction *save_insn, *i; =20 - WARN("%s() falls through to next function %s()", - func->name, insn_func(insn)->name); - func->warned =3D 1; + i =3D insn; + save_insn =3D NULL; =20 - return 1; - } + sym_for_each_insn_continue_reverse(file, func, i) { + if (i->save) { + save_insn =3D i; + break; + } + } =20 - visited =3D VISITED_BRANCH << state.uaccess; - if (insn->visited & VISITED_BRANCH_MASK) { - if (!insn->hint && !insn_cfi_match(insn, &state.cfi)) + if (!save_insn) { + WARN_INSN(insn, "no corresponding CFI save for CFI restore"); return 1; + } =20 - if (insn->visited & visited) - return 0; - } else { - nr_insns_visited++; + if (!save_insn->visited) { + /* + * If the restore hint insn is at the + * beginning of a basic block and was + * branched to from elsewhere, and the + * save insn hasn't been visited yet, + * defer following this branch for now. + * It will be seen later via the + * straight-line path. + */ + if (!prev_insn) + return 0; + + WARN_INSN(insn, "objtool isn't smart enough to handle this CFI save/re= store combo"); + return 1; + } + + insn->cfi =3D save_insn->cfi; + nr_cfi_reused++; } =20 - if (state.noinstr) - state.instr +=3D insn->instr; + statep->cfi =3D *insn->cfi; + } else { + /* XXX track if we actually changed statep->cfi */ =20 - if (insn->hint) { - if (insn->restore) { - struct instruction *save_insn, *i; + if (prev_insn && !cficmp(prev_insn->cfi, &statep->cfi)) { + insn->cfi =3D prev_insn->cfi; + nr_cfi_reused++; + } else { + insn->cfi =3D cfi_hash_find_or_add(&statep->cfi); + } + } =20 - i =3D insn; - save_insn =3D NULL; + insn->visited |=3D visited; =20 - sym_for_each_insn_continue_reverse(file, func, i) { - if (i->save) { - save_insn =3D i; - break; - } - } + if (propagate_alt_cfi(file, insn)) + return 1; =20 - if (!save_insn) { - WARN_INSN(insn, "no corresponding CFI save for CFI restore"); - return 1; - } + if (insn->alts) { + for (alt =3D insn->alts; alt; alt =3D alt->next) { + ret =3D validate_branch(file, func, alt->insn, *statep); + if (ret) { + BT_INSN(insn, "(alt)"); + return ret; + } + } + } =20 - if (!save_insn->visited) { - /* - * If the restore hint insn is at the - * beginning of a basic block and was - * branched to from elsewhere, and the - * save insn hasn't been visited yet, - * defer following this branch for now. - * It will be seen later via the - * straight-line path. - */ - if (!prev_insn) - return 0; + if (skip_alt_group(insn)) + return 0; =20 - WARN_INSN(insn, "objtool isn't smart enough to handle this CFI save/r= estore combo"); - return 1; - } + if (handle_insn_ops(insn, next_insn, statep)) + return 1; =20 - insn->cfi =3D save_insn->cfi; - nr_cfi_reused++; - } + switch (insn->type) { =20 - state.cfi =3D *insn->cfi; - } else { - /* XXX track if we actually changed state.cfi */ + case INSN_RETURN: + return validate_return(func, insn, statep); =20 - if (prev_insn && !cficmp(prev_insn->cfi, &state.cfi)) { - insn->cfi =3D prev_insn->cfi; - nr_cfi_reused++; - } else { - insn->cfi =3D cfi_hash_find_or_add(&state.cfi); - } + case INSN_CALL: + case INSN_CALL_DYNAMIC: + ret =3D validate_call(file, insn, statep); + if (ret) + return ret; + + if (opts.stackval && func && !is_special_call(insn) && + !has_valid_stack_frame(statep)) { + WARN_INSN(insn, "call without frame pointer save/setup"); + return 1; } =20 - insn->visited |=3D visited; + break; =20 - if (propagate_alt_cfi(file, insn)) - return 1; + case INSN_JUMP_CONDITIONAL: + case INSN_JUMP_UNCONDITIONAL: + if (is_sibling_call(insn)) { + ret =3D validate_sibling_call(file, insn, statep); + if (ret) + return ret; =20 - if (insn->alts) { - for (alt =3D insn->alts; alt; alt =3D alt->next) { - ret =3D validate_branch(file, func, alt->insn, state); - if (ret) { - BT_INSN(insn, "(alt)"); - return ret; - } + } else if (insn->jump_dest) { + ret =3D validate_branch(file, func, + insn->jump_dest, *statep); + if (ret) { + BT_INSN(insn, "(branch)"); + return ret; } } =20 - if (skip_alt_group(insn)) + if (insn->type =3D=3D INSN_JUMP_UNCONDITIONAL) return 0; =20 - if (handle_insn_ops(insn, next_insn, &state)) - return 1; - - switch (insn->type) { - - case INSN_RETURN: - return validate_return(func, insn, &state); + break; =20 - case INSN_CALL: - case INSN_CALL_DYNAMIC: - ret =3D validate_call(file, insn, &state); + case INSN_JUMP_DYNAMIC: + case INSN_JUMP_DYNAMIC_CONDITIONAL: + if (is_sibling_call(insn)) { + ret =3D validate_sibling_call(file, insn, statep); if (ret) return ret; + } =20 - if (opts.stackval && func && !is_special_call(insn) && - !has_valid_stack_frame(&state)) { - WARN_INSN(insn, "call without frame pointer save/setup"); - return 1; - } + if (insn->type =3D=3D INSN_JUMP_DYNAMIC) + return 0; =20 - break; + break; =20 - case INSN_JUMP_CONDITIONAL: - case INSN_JUMP_UNCONDITIONAL: - if (is_sibling_call(insn)) { - ret =3D validate_sibling_call(file, insn, &state); - if (ret) - return ret; + case INSN_SYSCALL: + if (func && (!next_insn || !next_insn->hint)) { + WARN_INSN(insn, "unsupported instruction in callable function"); + return 1; + } =20 - } else if (insn->jump_dest) { - ret =3D validate_branch(file, func, - insn->jump_dest, state); - if (ret) { - BT_INSN(insn, "(branch)"); - return ret; - } - } + break; =20 - if (insn->type =3D=3D INSN_JUMP_UNCONDITIONAL) - return 0; + case INSN_SYSRET: + if (func && (!next_insn || !next_insn->hint)) { + WARN_INSN(insn, "unsupported instruction in callable function"); + return 1; + } =20 + return 0; + + case INSN_STAC: + if (!opts.uaccess) break; =20 - case INSN_JUMP_DYNAMIC: - case INSN_JUMP_DYNAMIC_CONDITIONAL: - if (is_sibling_call(insn)) { - ret =3D validate_sibling_call(file, insn, &state); - if (ret) - return ret; - } + if (statep->uaccess) { + WARN_INSN(insn, "recursive UACCESS enable"); + return 1; + } =20 - if (insn->type =3D=3D INSN_JUMP_DYNAMIC) - return 0; + statep->uaccess =3D true; + break; =20 + case INSN_CLAC: + if (!opts.uaccess) break; =20 - case INSN_SYSCALL: - if (func && (!next_insn || !next_insn->hint)) { - WARN_INSN(insn, "unsupported instruction in callable function"); - return 1; - } + if (!statep->uaccess && func) { + WARN_INSN(insn, "redundant UACCESS disable"); + return 1; + } =20 - break; + if (func_uaccess_safe(func) && !statep->uaccess_stack) { + WARN_INSN(insn, "UACCESS-safe disables UACCESS"); + return 1; + } =20 - case INSN_SYSRET: - if (func && (!next_insn || !next_insn->hint)) { - WARN_INSN(insn, "unsupported instruction in callable function"); - return 1; - } + statep->uaccess =3D false; + break; =20 - return 0; + case INSN_STD: + if (statep->df) { + WARN_INSN(insn, "recursive STD"); + return 1; + } =20 - case INSN_STAC: - if (!opts.uaccess) - break; + statep->df =3D true; + break; =20 - if (state.uaccess) { - WARN_INSN(insn, "recursive UACCESS enable"); - return 1; - } + case INSN_CLD: + if (!statep->df && func) { + WARN_INSN(insn, "redundant CLD"); + return 1; + } =20 - state.uaccess =3D true; - break; + statep->df =3D false; + break; =20 - case INSN_CLAC: - if (!opts.uaccess) - break; + default: + break; + } =20 - if (!state.uaccess && func) { - WARN_INSN(insn, "redundant UACCESS disable"); - return 1; - } + *dead_end =3D insn->dead_end; =20 - if (func_uaccess_safe(func) && !state.uaccess_stack) { - WARN_INSN(insn, "UACCESS-safe disables UACCESS"); - return 1; - } + return 0; +} =20 - state.uaccess =3D false; - break; +/* + * Follow the branch starting at the given instruction, and recursively fo= llow + * any other branches (jumps). Meanwhile, track the frame pointer state at + * each instruction and validate all the rules described in + * tools/objtool/Documentation/objtool.txt. + */ +static int validate_branch(struct objtool_file *file, struct symbol *func, + struct instruction *insn, struct insn_state state) +{ + struct instruction *next_insn, *prev_insn =3D NULL; + struct section *sec; + bool dead_end; + int ret; =20 - case INSN_STD: - if (state.df) { - WARN_INSN(insn, "recursive STD"); - return 1; - } + if (func && func->ignore) + return 0; =20 - state.df =3D true; - break; + sec =3D insn->sec; =20 - case INSN_CLD: - if (!state.df && func) { - WARN_INSN(insn, "redundant CLD"); - return 1; - } + while (1) { + next_insn =3D next_insn_to_validate(file, insn); =20 - state.df =3D false; - break; + if (func && insn_func(insn) && func !=3D insn_func(insn)->pfunc) { + /* Ignore KCFI type preambles, which always fall through */ + if (!strncmp(func->name, "__cfi_", 6) || + !strncmp(func->name, "__pfx_", 6)) + return 0; =20 - default: - break; + if (file->ignore_unreachables) + return 0; + + WARN("%s() falls through to next function %s()", + func->name, insn_func(insn)->name); + func->warned =3D 1; + + return 1; } =20 - if (insn->dead_end) - return 0; + ret =3D validate_insn(file, func, insn, &state, prev_insn, next_insn, + &dead_end); + if (dead_end) + break; =20 if (!next_insn) { if (state.cfi.cfa.base =3D=3D CFI_UNDEFINED) @@ -3793,7 +3817,7 @@ static int validate_branch(struct objtool_file *file,= struct symbol *func, insn =3D next_insn; } =20 - return 0; + return ret; } =20 static int validate_unwind_hint(struct objtool_file *file, --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 3844128B4E3 for ; Thu, 19 Jun 2025 14:57:17 +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=1750345040; cv=none; b=TGf1yPpLcwGIy6pIiaSH6UkQOW/Cq0OK9c0+BVFQuNagAKN5OSkjfuFSBQQ/DOPHOZtmBo+jd7zD2Q484Lm2fGa/0b6no5suT7rqg0osAIlLOvcCBLaCAXCVRRogDnXKTL4yLrsAOMKrBA7dALjYWKIkNbTZG3GRNmaSvkyMga8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345040; c=relaxed/simple; bh=2+J0Ma7F8aswnAgESnHjIrlfBsU5+IxaYdlSFeg4rs8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RLc24xwT9d/Jl6ZQK4pptzlWzlgmVSJKsuKlEUKpHCgYbkduRzVECqVATX6VoEXShVmTOl9E4JZru57iMQAQNns4ngpiNqAH4YR2t4dv2Z9a89O5XER/JBozk9+E8TQKaM2VEpPb38Aw46uIDzLX7J+9X5c/1rUEXlFesnvqpcM= 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=WdUhcekc; 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="WdUhcekc" Received: from pps.filterd (m0246629.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55JEMaar002967; Thu, 19 Jun 2025 14:57:14 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=7EfvH dt7hzlIhbWgdXEx3hKGGQCk35d8Qu0bVOuZZwI=; b=WdUhcekcg/EU9sM3/g2Ma OmdHUZLGTYRkoMjKWTBj7/qLrh86p6jp/m3hy66rf86gLzL3Ynh0kMdWmYYHqGjL KEnnqDJ9F6xRFtiRbqeRUWq1TRdQgyx5T3XRrbQsq7grC/haZjKdOGMUjSNaWjGx MIa5HLuZwxxnQAU0KVGwJBlmz7ZubsIGZek8cP3ntXXjBJfWu4Pr4V+WzruAKyqM T32Zy+P+MvdHQmsthPvtXH3ueh20ETatdWd+7EEHFJZfCHIQyx3bDnAOFQes4TZm Tl2Bqn8g/g72PCz967l2XSHz+pMp4TQPGpOwAun8fbFbjbbhZczK2SBS5rBEMpTJ A== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 4790yda16s-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:14 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDOaxY022852; Thu, 19 Jun 2025 14:57:13 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8e1m-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:13 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0JT008257; Thu, 19 Jun 2025 14:57:12 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-11; Thu, 19 Jun 2025 14:57:12 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 10/17] objtool: Record symbol name max length Date: Thu, 19 Jun 2025 16:56:52 +0200 Message-ID: <20250619145659.1377970-11-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=999 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-GUID: yULLnoUm-1vj4kJo4YRTI4ijs6T7yomU X-Proofpoint-ORIG-GUID: yULLnoUm-1vj4kJo4YRTI4ijs6T7yomU X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfXyoq8mz0Tqgmp Xb3267roO9pccHanqTbi6/T86c7kw30yoVBjdjmPAb0Hzn7FM2gvIrI8GaWRNx+ULNO1vrxMV+0 +MtlH/tlfcnly71BI9BoAdlFzuHLWFrNhdyqOl6qFeOACyuARHy/fn7VvxgQyXR8olzy4+hELmu TZSBZek21JoYem9beyPx+sytUzHJzaL93WkFXvKU59DN0zaBDlA4P1tXVa4UKtfTAvvVAqXl/9a aQT35UOYghAm40jI/LbniuT1FZoIoxSDYQ5kRALQC1Pl+5cXkbpkq/rIYANOcGfOgkDbWFHNEk4 gTEkrO8clEB+lz+odKGZSGvaLVr7Lj17W4ZYFJJ2RW+Kl2/2dmQEkSuhdeQz73NiGrSCaelwBnK CYsbjj55naVhNiLsPKzLQ1yIyoOAwXw3Q3d0dKzYBrc/X1o/jNDIYf/cHCxfvDnJEOZ/X5Tc X-Authority-Analysis: v=2.4 cv=XZGJzJ55 c=1 sm=1 tr=0 ts=6854254a b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=xKpiAcmDGk3KfUQPlkUA:9 cc=ntf awl=host:13207 Content-Type: text/plain; charset="utf-8" Keep track of the maximum length of symbol names. This will help formatting the code flow between different functions. Signed-off-by: Alexandre Chartre --- tools/objtool/check.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 947fe57e9a6d..413860f2d7fa 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -35,6 +35,8 @@ static struct cfi_state init_cfi; static struct cfi_state func_cfi; static struct cfi_state force_undefined_cfi; =20 +static size_t sym_name_max_len; + struct instruction *find_insn(struct objtool_file *file, struct section *sec, unsigned long offset) { @@ -2459,6 +2461,7 @@ static bool is_profiling_func(const char *name) static int classify_symbols(struct objtool_file *file) { struct symbol *func; + size_t len; =20 for_each_sym(file, func) { if (func->type =3D=3D STT_NOTYPE && strstarts(func->name, ".L")) @@ -2485,6 +2488,10 @@ static int classify_symbols(struct objtool_file *fil= e) =20 if (is_profiling_func(func->name)) func->profiling_func =3D true; + + len =3D strlen(func->name); + if (len > sym_name_max_len) + sym_name_max_len =3D len; } =20 return 0; --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 095A928B7EE for ; Thu, 19 Jun 2025 14:57:19 +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=1750345042; cv=none; b=ASqS7TrrXpdBFKEpGFdpG/+JIUTdJKPYq+B7woniOhzKjCKq0bisVMWIaR0+Pk3kF2cGrB0ATsMLypfbDGQsjzZyJEiULiNQbV6pp2vU3ZW6HYclKg5qqiMLv8zbJr8d/JVGrw4GfudjLSKb4Cun1s8MxzbFk0bC0YUwKGJ4EKU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345042; c=relaxed/simple; bh=6magznX20X0jHAhjET135FfR2VB22PddMFVzgETf9YE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=B+x8DY2Uptqs4zpfnmjS/FjTIU8OoKbfl3UwKxRfwkW9nPHkymDHHrjPZWN2kp56a9GtX68edTb/JHOc8DfLag3m++WL9d+hfxmlnMbBFA9nfUSPjuR+SnRAWE9woD6arFDNydiYjUICy21V74Kl+Wn+ZFnGC3mCztk1atDjx2Y= 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=LZ4PivG1; 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="LZ4PivG1" Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55JEMmle015142; Thu, 19 Jun 2025 14:57:16 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=yB7OG taKBuPWfpEw7fdf42c6KKE62xC08NAIfuj6Rjs=; b=LZ4PivG1I2YczvvNALS6L jd4og8yIoRk4gmKHSOLagJKzt88wK431xzGZw3A7AJtofGOISSmIOTYszFdoYoYU TPYoOjNBxl0nDj473QeGeKSpz+CG9lv5/TmMojdD1/CKcf+vZsGp+C4fJBQiFs16 FLKuoAObDmhN/gB4ZkJwdUIAAWWzkl4JTf7u/pbm/nQWKfeHyW+5EtG7/6cZiK0m rZxVeMByoTpLV/78cdRst9Ugrfu7NiJGxclIYVE+aCRlJCWeCyTAO9bdjp2BmEMe XD3x4S2NHIp4LPJOZ6xbtzWC2IFiqFu7pREpP1OlzMlmyHnp71yONYWO465EBBJg Q== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 478yp4t4b1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:15 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDOaYN022775; Thu, 19 Jun 2025 14:57:14 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8e29-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:14 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0JV008257; Thu, 19 Jun 2025 14:57:13 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-12; Thu, 19 Jun 2025 14:57:13 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 11/17] objtool: Add option to trace function validation Date: Thu, 19 Jun 2025 16:56:53 +0200 Message-ID: <20250619145659.1377970-12-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=999 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfX5dKKM7jDWx5y 6l4TMRubc+vA9Lq7KfcyJTLdcAEIDvWf+DBpKl3SJP0mzY2tgzuaLOMYKwkrOG32knPF8NYwQpN w+srOa/gZ5h7Wsed83xDDRrwGcdUztJNMgzC6lfumSDgSpMrBbilhtQpL6mS7tArj6qduRj/t8q BtsWW+xhjUV7wUJxXeEdT224GNrcqdm2kilZa+FrJAk+CAL5D6iTjLOm+cjknJBuMKD2gyaH/UY lacrvqX9XCX2CN0BSCxehJ24uWcpk8CHRvky1ZIZVttGQpSuhJGECllvrDYESfgwn1M+aQVyLun kxJQLv6IPbr9eZIV2guJC82Bd9gKOOWo+mFMvg4+sFbYpR4HCqUEJmZezJKhmywYhewpkreCgk5 0WKZ1/s9hgNiRKTnvA+5ZzYrEF5Pyke+jtqiqh6VKDoMciGLuyGiEOlxQQPEt623Z1ToiLd8 X-Authority-Analysis: v=2.4 cv=K5EiHzWI c=1 sm=1 tr=0 ts=6854254b b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=20KFwNOVAAAA:8 a=7nqSK5V4zRp-Hs5t_LEA:9 cc=ntf awl=host:13207 X-Proofpoint-GUID: QLcWm5zjTVBn_QjFQ8HnajMeNjvRrjC4 X-Proofpoint-ORIG-GUID: QLcWm5zjTVBn_QjFQ8HnajMeNjvRrjC4 Content-Type: text/plain; charset="utf-8" Add an option to trace and have information during the validation of specified functions. Functions are specified with the --trace option which can be a single function name (e.g. --trace foo to trace the function with the name "foo"), or a shell wildcard pattern (e.g. --trace foo* to trace all functions with a name starting with "foo"). Signed-off-by: Alexandre Chartre --- tools/objtool/Build | 1 + tools/objtool/builtin-check.c | 1 + tools/objtool/check.c | 111 ++++++++++++++++++++---- tools/objtool/disas.c | 83 ++++++++++++++++++ tools/objtool/include/objtool/builtin.h | 1 + tools/objtool/include/objtool/check.h | 8 +- tools/objtool/include/objtool/disas.h | 11 +++ tools/objtool/include/objtool/trace.h | 68 +++++++++++++++ tools/objtool/include/objtool/warn.h | 1 + tools/objtool/trace.c | 9 ++ 10 files changed, 275 insertions(+), 19 deletions(-) create mode 100644 tools/objtool/include/objtool/trace.h create mode 100644 tools/objtool/trace.c diff --git a/tools/objtool/Build b/tools/objtool/Build index ee04fba8c9d1..6e62ffd40792 100644 --- a/tools/objtool/Build +++ b/tools/objtool/Build @@ -9,6 +9,7 @@ objtool-y +=3D elf.o objtool-y +=3D objtool.o =20 objtool-$(BUILD_DISAS) +=3D disas.o +objtool-$(BUILD_DISAS) +=3D trace.o =20 objtool-$(BUILD_ORC) +=3D orc_gen.o objtool-$(BUILD_ORC) +=3D orc_dump.o diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index 80239843e9f0..c53d738e4fb0 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -99,6 +99,7 @@ static const struct option check_options[] =3D { OPT_STRING('o', "output", &opts.output, "file", "output file name"), OPT_BOOLEAN(0, "sec-address", &opts.sec_address, "print section address= es in warnings"), OPT_BOOLEAN(0, "stats", &opts.stats, "print statistics"), + OPT_STRING(0, "trace", &opts.trace, "func", "trace function validation= "), OPT_BOOLEAN('v', "verbose", &opts.verbose, "verbose warnings"), OPT_BOOLEAN(0, "Werror", &opts.werror, "return error on warnings"), =20 diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 413860f2d7fa..1505dc8812fb 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3,6 +3,7 @@ * Copyright (C) 2015-2017 Josh Poimboeuf */ =20 +#include #include #include #include @@ -14,6 +15,7 @@ #include #include #include +#include #include #include =20 @@ -35,7 +37,9 @@ static struct cfi_state init_cfi; static struct cfi_state func_cfi; static struct cfi_state force_undefined_cfi; =20 -static size_t sym_name_max_len; +struct disas_context *objtool_disas_ctx; + +size_t sym_name_max_len; =20 struct instruction *find_insn(struct objtool_file *file, struct section *sec, unsigned long offset) @@ -3512,8 +3516,10 @@ static bool skip_alt_group(struct instruction *insn) struct instruction *alt_insn =3D insn->alts ? insn->alts->insn : NULL; =20 /* ANNOTATE_IGNORE_ALTERNATIVE */ - if (insn->alt_group && insn->alt_group->ignore) + if (insn->alt_group && insn->alt_group->ignore) { + TRACE_INSN(insn, "alt group ignored"); return true; + } =20 /* * For NOP patched with CLAC/STAC, only follow the latter to avoid @@ -3537,6 +3543,8 @@ static bool skip_alt_group(struct instruction *insn) =20 static int validate_branch(struct objtool_file *file, struct symbol *func, struct instruction *insn, struct insn_state state); +static int do_validate_branch(struct objtool_file *file, struct symbol *fu= nc, + struct instruction *insn, struct insn_state state); =20 static int validate_insn(struct objtool_file *file, struct symbol *func, struct instruction *insn, struct insn_state *statep, @@ -3558,8 +3566,10 @@ static int validate_insn(struct objtool_file *file, = struct symbol *func, if (!insn->hint && !insn_cfi_match(insn, &statep->cfi)) return 1; =20 - if (insn->visited & visited) + if (insn->visited & visited) { + TRACE_INSN(insn, "already visited"); return 0; + } } else { nr_insns_visited++; } @@ -3596,8 +3606,10 @@ static int validate_insn(struct objtool_file *file, = struct symbol *func, * It will be seen later via the * straight-line path. */ - if (!prev_insn) + if (!prev_insn) { + TRACE_INSN(insn, "defer restore"); return 0; + } =20 WARN_INSN(insn, "objtool isn't smart enough to handle this CFI save/re= store combo"); return 1; @@ -3625,13 +3637,24 @@ static int validate_insn(struct objtool_file *file,= struct symbol *func, return 1; =20 if (insn->alts) { + int i, num_alts; + + num_alts =3D 0; + for (alt =3D insn->alts; alt; alt =3D alt->next) + num_alts++; + + i =3D 1; for (alt =3D insn->alts; alt; alt =3D alt->next) { + TRACE_INSN(insn, "alternative %d/%d", i, num_alts); ret =3D validate_branch(file, func, alt->insn, *statep); if (ret) { BT_INSN(insn, "(alt)"); return ret; } + i++; } + + TRACE_INSN(insn, "alternative orig"); } =20 if (skip_alt_group(insn)) @@ -3643,10 +3666,16 @@ static int validate_insn(struct objtool_file *file,= struct symbol *func, switch (insn->type) { =20 case INSN_RETURN: + TRACE_INSN(insn, "return"); return validate_return(func, insn, statep); =20 case INSN_CALL: case INSN_CALL_DYNAMIC: + if (insn->type =3D=3D INSN_CALL) + TRACE_INSN(insn, "call"); + else + TRACE_INSN(insn, "indirect call"); + ret =3D validate_call(file, insn, statep); if (ret) return ret; @@ -3662,13 +3691,18 @@ static int validate_insn(struct objtool_file *file,= struct symbol *func, case INSN_JUMP_CONDITIONAL: case INSN_JUMP_UNCONDITIONAL: if (is_sibling_call(insn)) { + TRACE_INSN(insn, "sibling call"); ret =3D validate_sibling_call(file, insn, statep); if (ret) return ret; =20 } else if (insn->jump_dest) { - ret =3D validate_branch(file, func, - insn->jump_dest, *statep); + if (insn->type =3D=3D INSN_JUMP_UNCONDITIONAL) + TRACE_INSN(insn, "unconditional jump"); + else + TRACE_INSN(insn, "jump taken"); + + ret =3D validate_branch(file, func, insn->jump_dest, *statep); if (ret) { BT_INSN(insn, "(branch)"); return ret; @@ -3678,10 +3712,12 @@ static int validate_insn(struct objtool_file *file,= struct symbol *func, if (insn->type =3D=3D INSN_JUMP_UNCONDITIONAL) return 0; =20 + TRACE_INSN(insn, "jump not taken"); break; =20 case INSN_JUMP_DYNAMIC: case INSN_JUMP_DYNAMIC_CONDITIONAL: + TRACE_INSN(insn, "indirect jump"); if (is_sibling_call(insn)) { ret =3D validate_sibling_call(file, insn, statep); if (ret) @@ -3694,6 +3730,7 @@ static int validate_insn(struct objtool_file *file, s= truct symbol *func, break; =20 case INSN_SYSCALL: + TRACE_INSN(insn, "syscall"); if (func && (!next_insn || !next_insn->hint)) { WARN_INSN(insn, "unsupported instruction in callable function"); return 1; @@ -3702,6 +3739,7 @@ static int validate_insn(struct objtool_file *file, s= truct symbol *func, break; =20 case INSN_SYSRET: + TRACE_INSN(insn, "sysret"); if (func && (!next_insn || !next_insn->hint)) { WARN_INSN(insn, "unsupported instruction in callable function"); return 1; @@ -3710,6 +3748,7 @@ static int validate_insn(struct objtool_file *file, s= truct symbol *func, return 0; =20 case INSN_STAC: + TRACE_INSN(insn, "stac"); if (!opts.uaccess) break; =20 @@ -3722,6 +3761,7 @@ static int validate_insn(struct objtool_file *file, s= truct symbol *func, break; =20 case INSN_CLAC: + TRACE_INSN(insn, "clac"); if (!opts.uaccess) break; =20 @@ -3739,6 +3779,7 @@ static int validate_insn(struct objtool_file *file, s= truct symbol *func, break; =20 case INSN_STD: + TRACE_INSN(insn, "std"); if (statep->df) { WARN_INSN(insn, "recursive STD"); return 1; @@ -3748,6 +3789,7 @@ static int validate_insn(struct objtool_file *file, s= truct symbol *func, break; =20 case INSN_CLD: + TRACE_INSN(insn, "cld"); if (!statep->df && func) { WARN_INSN(insn, "redundant CLD"); return 1; @@ -3760,8 +3802,10 @@ static int validate_insn(struct objtool_file *file, = struct symbol *func, break; } =20 - *dead_end =3D insn->dead_end; + if (insn->dead_end) + TRACE_INSN(insn, "dead end"); =20 + *dead_end =3D insn->dead_end; return 0; } =20 @@ -3771,8 +3815,8 @@ static int validate_insn(struct objtool_file *file, s= truct symbol *func, * each instruction and validate all the rules described in * tools/objtool/Documentation/objtool.txt. */ -static int validate_branch(struct objtool_file *file, struct symbol *func, - struct instruction *insn, struct insn_state state) +static int do_validate_branch(struct objtool_file *file, struct symbol *fu= nc, + struct instruction *insn, struct insn_state state) { struct instruction *next_insn, *prev_insn =3D NULL; struct section *sec; @@ -3784,7 +3828,10 @@ static int validate_branch(struct objtool_file *file= , struct symbol *func, =20 sec =3D insn->sec; =20 - while (1) { + do { + + insn->trace =3D 0; + next_insn =3D next_insn_to_validate(file, insn); =20 if (func && insn_func(insn) && func !=3D insn_func(insn)->pfunc) { @@ -3796,6 +3843,8 @@ static int validate_branch(struct objtool_file *file,= struct symbol *func, if (file->ignore_unreachables) return 0; =20 + TRACE_INSN(insn, "falls through to next function"); + WARN("%s() falls through to next function %s()", func->name, insn_func(insn)->name); func->warned =3D 1; @@ -3805,10 +3854,15 @@ static int validate_branch(struct objtool_file *fil= e, struct symbol *func, =20 ret =3D validate_insn(file, func, insn, &state, prev_insn, next_insn, &dead_end); - if (dead_end) - break; =20 - if (!next_insn) { + if (!insn->trace) { + if (ret) + TRACE_INSN(insn, "warning (%d)", ret); + else + TRACE_INSN(insn, NULL); + } + + if (!dead_end && !next_insn) { if (state.cfi.cfa.base =3D=3D CFI_UNDEFINED) return 0; if (file->ignore_unreachables) @@ -3822,7 +3876,20 @@ static int validate_branch(struct objtool_file *file= , struct symbol *func, =20 prev_insn =3D insn; insn =3D next_insn; - } + + } while (!dead_end); + + return ret; +} + +static int validate_branch(struct objtool_file *file, struct symbol *func, + struct instruction *insn, struct insn_state state) +{ + int ret; + + trace_depth_inc(); + ret =3D do_validate_branch(file, func, insn, state); + trace_depth_dec(); =20 return ret; } @@ -4237,9 +4304,19 @@ static int validate_symbol(struct objtool_file *file= , struct section *sec, if (opts.uaccess) state->uaccess =3D sym->uaccess_safe; =20 + if (opts.trace && !fnmatch(opts.trace, sym->name, 0)) { + trace_enable(); + TRACE("%s: validation begin\n", sym->name); + } + ret =3D validate_branch(file, insn_func(insn), insn, *state); if (ret) BT_INSN(insn, "<=3D=3D=3D (sym)"); + + TRACE("%s: validation %s\n\n", sym->name, ret ? "failed" : "end"); + trace_disable(); + + return ret; } =20 @@ -4612,8 +4689,6 @@ static void free_insns(struct objtool_file *file) free(chunk->addr); } =20 -static struct disas_context *objtool_disas_ctx; - const char *objtool_disas_insn(struct instruction *insn) { struct disas_context *dctx =3D objtool_disas_ctx; @@ -4635,8 +4710,10 @@ int check(struct objtool_file *file) * disassembly context to disassemble instruction or function * on warning or backtrace. */ - if (opts.verbose || opts.backtrace) { + if (opts.verbose || opts.backtrace || opts.trace) { disas_ctx =3D disas_context_create(file); + if (!disas_ctx) + opts.trace =3D false; objtool_disas_ctx =3D disas_ctx; } =20 diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index 3831e46e0f35..004683c2b1ff 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -261,6 +261,89 @@ char *disas_result(struct disas_context *dctx) return dctx->result; } =20 + +#define DISAS_INSN_OFFSET_SPACE 10 +#define DISAS_INSN_SPACE 60 + +/* + * Print a message in the instruction flow. If insn is not NULL then + * the instruction address is printed in addition of the message, + * otherwise only the message is printed. In all cases, the instruction + * itself is not printed. + */ +void disas_print_info(FILE *stream, struct instruction *insn, int depth, + const char *format, ...) +{ + const char *addr_str; + va_list args; + int len; + int i; + + len =3D sym_name_max_len + DISAS_INSN_OFFSET_SPACE; + if (insn && insn->sec) { + addr_str =3D offstr(insn->sec, insn->offset); + fprintf(stream, "%6lx: %-*s ", insn->offset, len, addr_str); + free((char *)addr_str); + } else { + len +=3D 11; + fprintf(stream, "%-*s", len, ""); + } + + /* print vertical bars to show the code flow */ + for (i =3D 0; i < depth; i++) + fprintf(stream, "| "); + + va_start(args, format); + vfprintf(stream, format, args); + va_end(args); +} + +/* + * Print an instruction address (offset and function), the instruction its= elf + * and an optional message. + */ +void disas_print_insn(FILE *stream, struct disas_context *dctx, + struct instruction *insn, int depth, + const char *format, ...) +{ + char fake_nop_insn[32]; + const char *insn_str; + bool fake_nop; + va_list args; + int len; + + /* + * Alternative can insert a fake nop, sometimes with no + * associated section so nothing to disassemble. + */ + fake_nop =3D (!insn->sec && insn->type =3D=3D INSN_NOP); + if (fake_nop) { + snprintf(fake_nop_insn, 32, " (%d bytes)", insn->len); + insn_str =3D fake_nop_insn; + } else { + disas_insn(dctx, insn); + insn_str =3D disas_result(dctx); + } + + /* print the instruction */ + len =3D (depth+1) * 2 < DISAS_INSN_SPACE ? DISAS_INSN_SPACE - (depth+1) *= 2 : 1; + disas_print_info(stream, insn, depth, "%-*s", len, insn_str); + + /* print message if any */ + if (!format) + return; + + if (strcmp(format, "\n") =3D=3D 0) { + fprintf(stream, "\n"); + return; + } + + fprintf(stream, " - "); + va_start(args, format); + vfprintf(stream, format, args); + va_end(args); +} + /* * Disassemble a single instruction. Return the size of the instruction. */ diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/includ= e/objtool/builtin.h index 6b08666fa69d..b3c84b6fdc5f 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -37,6 +37,7 @@ struct opts { const char *output; bool sec_address; bool stats; + const char *trace; bool verbose; bool werror; }; diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/= objtool/check.h index f3ea144d4746..e5f97acb6252 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -64,8 +64,9 @@ struct instruction { noendbr : 1, unret : 1, visited : 4, - no_reloc : 1; - /* 10 bit hole */ + no_reloc : 1, + trace : 1; + /* 9 bit hole */ =20 struct alt_group *alt_group; struct instruction *jump_dest; @@ -141,4 +142,7 @@ struct instruction *next_insn_same_sec(struct objtool_f= ile *file, struct instruc =20 const char *objtool_disas_insn(struct instruction *insn); =20 +extern size_t sym_name_max_len; +extern struct disas_context *objtool_disas_ctx; + #endif /* _CHECK_H */ diff --git a/tools/objtool/include/objtool/disas.h b/tools/objtool/include/= objtool/disas.h index 1aee1fbe0bb9..5db75d06f219 100644 --- a/tools/objtool/include/objtool/disas.h +++ b/tools/objtool/include/objtool/disas.h @@ -19,6 +19,11 @@ int disas_info_init(struct disassemble_info *dinfo, const char *options); size_t disas_insn(struct disas_context *dctx, struct instruction *insn); char *disas_result(struct disas_context *dctx); +void disas_print_info(FILE *stream, struct instruction *insn, int depth, + const char *format, ...); +void disas_print_insn(FILE *stream, struct disas_context *dctx, + struct instruction *insn, int depth, + const char *format, ...); =20 #else /* DISAS */ =20 @@ -51,6 +56,12 @@ static inline char *disas_result(struct disas_context *d= ctx) return NULL; } =20 +static inline void disas_print_info(FILE *stream, struct instruction *insn, + int depth, const char *format, ...) {} +static inline void disas_print_insn(FILE *stream, struct disas_context *dc= tx, + struct instruction *insn, int depth, + const char *format, ...) {} + #endif /* DISAS */ =20 #endif /* _DISAS_H */ diff --git a/tools/objtool/include/objtool/trace.h b/tools/objtool/include/= objtool/trace.h new file mode 100644 index 000000000000..ea0904a0ce00 --- /dev/null +++ b/tools/objtool/include/objtool/trace.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. + */ + +#ifndef _TRACE_H +#define _TRACE_H + +#include +#include + +#ifdef DISAS + +extern bool trace; +extern int trace_depth; + +#define TRACE(fmt, ...) \ +({ if (trace) \ + fprintf(stderr, fmt, ##__VA_ARGS__); \ +}) + +#define TRACE_INSN(insn, fmt, ...) \ +({ \ + if (trace) { \ + disas_print_insn(stderr, objtool_disas_ctx, \ + insn, trace_depth - 1, \ + fmt, ##__VA_ARGS__); \ + fprintf(stderr, "\n"); \ + insn->trace =3D 1; \ + } \ +}) + +static inline void trace_enable(void) +{ + trace =3D true; + trace_depth =3D 0; +} + +static inline void trace_disable(void) +{ + trace =3D false; +} + +static inline void trace_depth_inc(void) +{ + if (trace) + trace_depth++; +} + +static inline void trace_depth_dec(void) +{ + if (trace) + trace_depth--; +} + +#else /* DISAS */ + +#define TRACE(fmt, ...) +#define TRACE_INSN(insn, fmt, ...) + +static inline void trace_enable(void) {} +static inline void trace_disable(void) {} +static inline void trace_depth_inc(void) {} +static inline void trace_depth_dec(void) {} + +#endif + +#endif /* _TRACE_H */ diff --git a/tools/objtool/include/objtool/warn.h b/tools/objtool/include/o= bjtool/warn.h index f001233b27df..e0b43441c577 100644 --- a/tools/objtool/include/objtool/warn.h +++ b/tools/objtool/include/objtool/warn.h @@ -109,6 +109,7 @@ static inline char *offstr(struct section *sec, unsigne= d long offset) _len =3D (_len < 50) ? 50 - _len : 0; \ WARN(" %s: " format " %*s%s", _str, ##__VA_ARGS__, _len, "", _istr); \ free(_str); \ + __insn->trace =3D 1; \ } \ }) =20 diff --git a/tools/objtool/trace.c b/tools/objtool/trace.c new file mode 100644 index 000000000000..bc3113ba72fd --- /dev/null +++ b/tools/objtool/trace.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. + */ + +#include + +bool trace; +int trace_depth; --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 C4B7128BA9F for ; Thu, 19 Jun 2025 14:57:20 +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=1750345042; cv=none; b=icJgjWNVbOwAvhvRt0S/zYphcDlbdqpwAqo/MWgXqDZdJHMHFRfvG4xlf9ueVlBVdVi4Q7dzAbmFEgP5UzhJTQa257ZEWCWKRvA1yyYYonNQt7esFmYM04TB/zDOOg3V7TJy+JgXpocme5Ud2vu+cdTEd2qIuRYnwSwPZhM2wWQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345042; c=relaxed/simple; bh=F8PfXIfzWJ6RkyKXQgM8zxJG43m6MlfkSdRSZPzILFM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=nUDBeaYlFqs88v4fjwJa9nM3+hmFpfVMMS1t6oQnXQTbhKfPNk3YC0MiYIIL3QcfRdP3c9y833AP+kwRyLNvBvceLA8rVeg86j5TULcxc0FyoNN+fgWIlVMn9WwWpMdisRm32KvAi5yCLAvETuPCoejte57mPKMMYcWb70RmvgE= 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=eVhiv+qw; 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="eVhiv+qw" Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55JEMbGx014966; Thu, 19 Jun 2025 14:57:17 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=ekONx pl/jy/BTRt4dLK5HaTQUgYSLv2wGO8hibSauo0=; b=eVhiv+qw2avakHaGjpcy1 DZ2siXTfuuy0woRP3WR599C82vrxBULQpwXDNT8Hj6uLiQvTcZ8Zg+4hLYW4Tgsd f5cF38aaO6jMHHSikCkw7hz+IIJ/nAoMas5gPZajDE+9MxRLEYq/60/4Sl1KE8kC g7g3XAGT75RYF1z0gGoiQvo/8yRO2SC2iebB/bJQ1AEW4YFWXVNa7yFBgY9NWZph gJQFZuh1j8FOM3mLghJnnoinPpQcFEbGMiXaY+gOXQ3bpFrwYuJS27F++WNO5w5G QpOoze2Yt/KRRdtgubaOT+HWlnI0nRY+z5avz+T1AwWCF4xIro1mOArGa/7SlWCL w== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 478yp4t4b2-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:17 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDQCJX022863; Thu, 19 Jun 2025 14:57:15 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8e34-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:15 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0JX008257; Thu, 19 Jun 2025 14:57:15 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-13; Thu, 19 Jun 2025 14:57:15 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 12/17] objtool: Trace instruction state changes during function validation Date: Thu, 19 Jun 2025 16:56:54 +0200 Message-ID: <20250619145659.1377970-13-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=999 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfXy7Fg7dJ66J/4 51N6ZeAi+xR9FL+5+LWLbUarDYl8lmeYQq5Mw7dKjQksgNbBIxCPlVv13BQBWRbD0vtIU4A2pta giI1irxnKuiwJegvcbTUwvNCi5DjQi68X/8Xlgt9LEWm5qD6INvYE8HLajmDgbfUtPgpFBdboaF 6hIK3AK8FbEEHQONzXTsQCz88MtMRMAwvHYktou4W+zv2G3v4TUlfO4SbWggt9g8bHYzuQ5jxOQ RL2AXJVl1J+5CHjydyFT/24CWzYtoAj+y6nQuTTdmzR3OFAYOSKBRUCAVx31nhRuXDBllPz8ACk KJqpfBvt4/BkG+VwP7lDsis+n/mc3fuiVSe6yQZsCxsjpcxi3ndjk2jkJg/fYgKpsIffEKXGh9w xOF2RscKY3ca3CxRdESN3ocvYBZscnbBlX4Ve5ooUUPi7p9nQc+9lezsCfSgYBc1YeInISPg X-Authority-Analysis: v=2.4 cv=K5EiHzWI c=1 sm=1 tr=0 ts=6854254d b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=pqBKm9nhAekokd3aI5kA:9 cc=ntf awl=host:13207 X-Proofpoint-GUID: M6e6ywTbexAtwaBo_hJIBcaXfg_weqi_ X-Proofpoint-ORIG-GUID: M6e6ywTbexAtwaBo_hJIBcaXfg_weqi_ Content-Type: text/plain; charset="utf-8" During function validation, objtool maintains a per-instruction state, in particular to track call frame information. When tracing validation, print any instruction state changes. Signed-off-by: Alexandre Chartre --- tools/objtool/check.c | 8 +- tools/objtool/disas.c | 1 - tools/objtool/include/objtool/trace.h | 10 ++ tools/objtool/trace.c | 131 ++++++++++++++++++++++++++ 4 files changed, 148 insertions(+), 2 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 1505dc8812fb..8a51c871e1dc 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3551,6 +3551,8 @@ static int validate_insn(struct objtool_file *file, s= truct symbol *func, struct instruction *prev_insn, struct instruction *next_insn, bool *dead_end) { + /* prev_state is not used if there is no disassembly support */ + struct insn_state prev_state __maybe_unused; struct alternative *alt; u8 visited; int ret; @@ -3660,7 +3662,11 @@ static int validate_insn(struct objtool_file *file, = struct symbol *func, if (skip_alt_group(insn)) return 0; =20 - if (handle_insn_ops(insn, next_insn, statep)) + prev_state =3D *statep; + ret =3D handle_insn_ops(insn, next_insn, statep); + TRACE_INSN_STATE(insn, &prev_state, statep); + + if (ret) return 1; =20 switch (insn->type) { diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index 004683c2b1ff..376c7bedef47 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -29,7 +29,6 @@ struct disas_context { #define DINFO_FPRINTF(dinfo, ...) \ ((*(dinfo)->fprintf_func)((dinfo)->stream, __VA_ARGS__)) =20 - static int disas_result_fprintf(struct disas_context *dctx, const char *fmt, va_list ap) { diff --git a/tools/objtool/include/objtool/trace.h b/tools/objtool/include/= objtool/trace.h index ea0904a0ce00..5b8abdb9b09f 100644 --- a/tools/objtool/include/objtool/trace.h +++ b/tools/objtool/include/objtool/trace.h @@ -30,6 +30,12 @@ extern int trace_depth; } \ }) =20 +#define TRACE_INSN_STATE(insn, sprev, snext) \ +({ \ + if (trace) \ + trace_insn_state(insn, sprev, snext); \ +}) + static inline void trace_enable(void) { trace =3D true; @@ -53,10 +59,14 @@ static inline void trace_depth_dec(void) trace_depth--; } =20 +void trace_insn_state(struct instruction *insn, struct insn_state *sprev, + struct insn_state *snext); + #else /* DISAS */ =20 #define TRACE(fmt, ...) #define TRACE_INSN(insn, fmt, ...) +#define TRACE_INSN_STATE(insn, sprev, snext) =20 static inline void trace_enable(void) {} static inline void trace_disable(void) {} diff --git a/tools/objtool/trace.c b/tools/objtool/trace.c index bc3113ba72fd..28c0257b02b5 100644 --- a/tools/objtool/trace.c +++ b/tools/objtool/trace.c @@ -7,3 +7,134 @@ =20 bool trace; int trace_depth; + +/* + * Macros to trace CFI state attributes changes. + */ + +#define TRACE_CFI_ATTR(attr, prev, next, fmt, ...) \ +({ \ + if ((prev)->attr !=3D (next)->attr) \ + TRACE("%s=3D" fmt " ", #attr, __VA_ARGS__); \ +}) + +#define TRACE_CFI_ATTR_BOOL(attr, prev, next) \ + TRACE_CFI_ATTR(attr, prev, next, \ + "%s", (next)->attr ? "true" : "false") + +#define TRACE_CFI_ATTR_NUM(attr, prev, next, fmt) \ + TRACE_CFI_ATTR(attr, prev, next, fmt, (next)->attr) + +#define CFI_REG_NAME_MAXLEN 16 + +/* + * Return the name of a register. Note that the same static buffer + * is returned if the name is dynamically generated. + */ +static const char *cfi_reg_name(unsigned int reg) +{ + static char rname_buffer[CFI_REG_NAME_MAXLEN]; + + switch (reg) { + case CFI_UNDEFINED: + return ""; + case CFI_CFA: + return "cfa"; + case CFI_SP_INDIRECT: + return "(sp)"; + case CFI_BP_INDIRECT: + return "(bp)"; + } + + if (snprintf(rname_buffer, CFI_REG_NAME_MAXLEN, "r%d", reg) =3D=3D 1) + return NULL; + + return (const char *)rname_buffer; +} + +/* + * Functions and macros to trace CFI registers changes. + */ + +static void trace_cfi_reg(const char *prefix, int reg, const char *fmt, + int base_prev, int offset_prev, + int base_next, int offset_next) +{ + const char *rname; + + if (base_prev =3D=3D base_next && offset_prev =3D=3D offset_next) + return; + + if (prefix) + TRACE("%s:", prefix); + + rname =3D cfi_reg_name(reg); + + if (base_next =3D=3D CFI_UNDEFINED) { + TRACE("%1$s=3D ", rname); + } else { + TRACE(fmt, rname, + cfi_reg_name(base_next), offset_next); + } +} + +static void trace_cfi_reg_val(const char *prefix, int reg, + int base_prev, int offset_prev, + int base_next, int offset_next) +{ + trace_cfi_reg(prefix, reg, "%1$s=3D%2$s%3$+d ", + base_prev, offset_prev, base_next, offset_next); +} + +static void trace_cfi_reg_ref(const char *prefix, int reg, + int base_prev, int offset_prev, + int base_next, int offset_next) +{ + trace_cfi_reg(prefix, reg, "%1$s=3D(%2$s%3$+d) ", + base_prev, offset_prev, base_next, offset_next); +} + +#define TRACE_CFI_REG_VAL(reg, prev, next) \ + trace_cfi_reg_val(NULL, reg, prev.base, prev.offset, \ + next.base, next.offset) + +#define TRACE_CFI_REG_REF(reg, prev, next) \ + trace_cfi_reg_ref(NULL, reg, prev.base, prev.offset, \ + next.base, next.offset) + +void trace_insn_state(struct instruction *insn, struct insn_state *sprev, + struct insn_state *snext) +{ + struct cfi_state *cprev, *cnext; + int i; + + if (!memcmp(sprev, snext, sizeof(struct insn_state))) + return; + + cprev =3D &sprev->cfi; + cnext =3D &snext->cfi; + + disas_print_insn(stderr, objtool_disas_ctx, insn, + trace_depth - 1, " - state"); + + /* print registers changes */ + TRACE_CFI_REG_VAL(CFI_CFA, cprev->cfa, cnext->cfa); + for (i =3D 0; i < CFI_NUM_REGS; i++) { + TRACE_CFI_REG_VAL(i, cprev->vals[i], cnext->vals[i]); + TRACE_CFI_REG_REF(i, cprev->regs[i], cnext->regs[i]); + } + + /* print attributes changes */ + TRACE_CFI_ATTR_NUM(stack_size, cprev, cnext, "%d"); + TRACE_CFI_ATTR_BOOL(drap, cprev, cnext); + if (cnext->drap) { + trace_cfi_reg_val("drap", cnext->drap_reg, + cprev->drap_reg, cprev->drap_offset, + cnext->drap_reg, cnext->drap_offset); + } + TRACE_CFI_ATTR_BOOL(bp_scratch, cprev, cnext); + TRACE_CFI_ATTR_NUM(instr, sprev, snext, "%d"); + TRACE_CFI_ATTR_NUM(uaccess_stack, sprev, snext, "%u"); + + TRACE("\n"); +} --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 D457D28C2B2 for ; Thu, 19 Jun 2025 14:57:21 +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=1750345045; cv=none; b=YZii9pE4hAIQVUweE22WFZQiM04X5m2YAn+SROOTm64t8ZqDRVS+a/neTh8QH48v9Eja/umX3h6CHeKD3OXC6BCyiy/Ken48X1pm0S8jRekEXCG3ySAAmKekDiXBjJn8jlfcLpZBpZfk7rQwdlU3epNuQj4slpelunBuec84wvA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345045; c=relaxed/simple; bh=xDncNZ1LMSZ2vmrz0U4flqze0YPzr8pIo1W3I1JFvJ0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=g0YM0dANX0mjCW35Ug0ARqNq8FyHS+TJkLDAKYxoakT8uiSa5ogiEyi1ylbf2nUS/rrB3/J+n65pu+xvlvxUCPu9sJqxKkb4ipisjkzj4JQaakqqMBnCnBvSsHlkGN762jIaf71UTdW/demsocwrLigvnxzSvOkxuzlTXsZA3DI= 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=R+KPvIJR; 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="R+KPvIJR" Received: from pps.filterd (m0333521.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55JEMZKd011354; Thu, 19 Jun 2025 14:57:18 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=doqIi 4reJlriDhvs3y7SwGJ48Sv7QImP3E9ho3zRMUc=; b=R+KPvIJRQYDvjNbdLiVyq c/mc+PG9qdyTGlpCF3Ax8V/g6//K2r/oVcx6wMfkwr+njuyM8c1+xrBx2EOIqf9K Ne3p5Zq1ohcKqozlrMjJbWXNNY/9O7/9BpPm+y8gXbaNNZ/jvqOZggkl+pk4XynP OOsxbkS1LTk/wvaIGX/EHdhx7qyr1lWYzTfwdVcPkMUs7HL0evIHA1S9jAyWcqlu jTX5QOir6BdHOpWknogiZY+J8mqnMdnAUzsiiphM2J9kV4eN9hbPNaPAr8Ia84Gr RUarT4lK+bcvcqQXhpqZIcAoIhoSStkV/SaRrNRN2HAzSXjKdWuXOTCYFQRyL9G0 A== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 47900f23qn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:18 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDQ7Ax023309; Thu, 19 Jun 2025 14:57:17 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8e49-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:16 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0JZ008257; Thu, 19 Jun 2025 14:57:16 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-14; Thu, 19 Jun 2025 14:57:16 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 13/17] objtool: Improve register reporting during function validation Date: Thu, 19 Jun 2025 16:56:55 +0200 Message-ID: <20250619145659.1377970-14-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=838 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfX77Sy8mHJT0LM ueW4sh6Vn07uo87RM8C30A6zEWMdfPSfoqVoW+qhifLRdQSdVaQzEnO/xQ73jNH/A8nA/o8Jqf8 1tqQNSSC/yOpncsfdFHT4mZcMpsaURqKRkYOPjg2KPLwASTev8QGkOIma9NvNgpML/+egL+huVZ qvJmJItxjJJTIbxECWfpUS8HXFofFcuxNeo9J2onVkkbknLfnvKopccl9zVhNIkbxiiHz/hCtUG A1e7rA91sAAEAq092fpUluiINkmAkDVZJUa1Zj1ChnDi6vwePyAr+7sMNEisJ34HIIYPKi78Z7I x5NLbSJk2s/gMJPzgAlrtkY1pPfZmMepeV6aHKXeBaD5yY+VJuTcR+SlVv0deddgylMV2DjF6a7 mWjzqO+FVl0+hK+doh3uXfCRX43gzsP4W36qp/NmEDv+e3t00ks9E7AqnWvea3EWAZDIDc2x X-Proofpoint-ORIG-GUID: JDzneLuCzdpCE2ggXwP45zU9Ixqge7Ax X-Authority-Analysis: v=2.4 cv=X/5SKHTe c=1 sm=1 tr=0 ts=6854254e b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=SYeOCZSjma0EYi-zULIA:9 cc=ntf awl=host:13207 X-Proofpoint-GUID: JDzneLuCzdpCE2ggXwP45zU9Ixqge7Ax Content-Type: text/plain; charset="utf-8" When tracing function validation, instruction state changes can report changes involving registers. These registers are reported with the name "r" (e.g. "r3"). Print the CPU specific register name instead of a generic name (e.g. print "rbx" instead of "r3" on x86). Signed-off-by: Alexandre Chartre --- tools/objtool/arch/loongarch/decode.c | 11 +++++++++++ tools/objtool/arch/powerpc/decode.c | 12 ++++++++++++ tools/objtool/arch/x86/decode.c | 8 ++++++++ tools/objtool/include/objtool/arch.h | 2 ++ tools/objtool/trace.c | 7 +++++++ 5 files changed, 40 insertions(+) diff --git a/tools/objtool/arch/loongarch/decode.c b/tools/objtool/arch/loo= ngarch/decode.c index 09c43f008c9a..17eebf358e5d 100644 --- a/tools/objtool/arch/loongarch/decode.c +++ b/tools/objtool/arch/loongarch/decode.c @@ -8,6 +8,17 @@ #include #include =20 +const char *arch_reg_name[CFI_NUM_REGS] =3D { + "zero", "ra", "tp", "sp", + "a0", "a1", "a2", "a3", + "a4", "a5", "a6", "a7", + "t0", "t1", "t2", "t3", + "t4", "t5", "t6", "t7", + "t8", "u0", "fp", "s0", + "s1", "s2", "s3", "s4", + "s5", "s6", "s7", "s8" +}; + int arch_ftrace_match(char *name) { return !strcmp(name, "_mcount"); diff --git a/tools/objtool/arch/powerpc/decode.c b/tools/objtool/arch/power= pc/decode.c index 9c3f49c45587..74d1a8603535 100644 --- a/tools/objtool/arch/powerpc/decode.c +++ b/tools/objtool/arch/powerpc/decode.c @@ -10,6 +10,18 @@ #include #include =20 +const char *arch_reg_name[CFI_NUM_REGS] =3D { + "r0", "sp", "r2", "r3", + "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", + "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", + "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", + "r28", "r29", "r30", "r31", + "ra" +}; + int arch_ftrace_match(char *name) { return !strcmp(name, "_mcount"); diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decod= e.c index 6a39cc619d63..6a8aad383695 100644 --- a/tools/objtool/arch/x86/decode.c +++ b/tools/objtool/arch/x86/decode.c @@ -24,6 +24,14 @@ #include #include =20 +const char *arch_reg_name[CFI_NUM_REGS] =3D { + "rax", "rcx", "rdx", "rbx", + "rsp", "rbp", "rsi", "rdi", + "r8", "r9", "r10", "r11", + "r12", "r13", "r14", "r15", + "ra" +}; + int arch_ftrace_match(char *name) { return !strcmp(name, "__fentry__"); diff --git a/tools/objtool/include/objtool/arch.h b/tools/objtool/include/o= bjtool/arch.h index baa6eee1977f..f4aa8e134276 100644 --- a/tools/objtool/include/objtool/arch.h +++ b/tools/objtool/include/objtool/arch.h @@ -103,6 +103,8 @@ unsigned long arch_pc_relative_offset(struct instructio= n *insn, unsigned int arch_reloc_size(struct reloc *reloc); unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct reloc= *table); =20 +extern const char *arch_reg_name[CFI_NUM_REGS]; + #ifdef DISAS =20 #include diff --git a/tools/objtool/trace.c b/tools/objtool/trace.c index 28c0257b02b5..ea67c41e9128 100644 --- a/tools/objtool/trace.c +++ b/tools/objtool/trace.c @@ -34,6 +34,7 @@ int trace_depth; static const char *cfi_reg_name(unsigned int reg) { static char rname_buffer[CFI_REG_NAME_MAXLEN]; + const char *rname; =20 switch (reg) { case CFI_UNDEFINED: @@ -46,6 +47,12 @@ static const char *cfi_reg_name(unsigned int reg) return "(bp)"; } =20 + if (reg < CFI_NUM_REGS) { + rname =3D arch_reg_name[reg]; + if (rname) + return rname; + } + if (snprintf(rname_buffer, CFI_REG_NAME_MAXLEN, "r%d", reg) =3D=3D 1) return NULL; =20 --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 47E2128CF74 for ; Thu, 19 Jun 2025 14:57:23 +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=1750345045; cv=none; b=Y27UDiwH0QDy3lGXbP7rvYaUpFopsonoZQ+A5uUiBfBnzOSnx1x8YkioCxb97jaxe3W0tHZjMbbJlI4lDK2fVLhMLoEBQrxCKv1pZ2VH1uZoqIOll3FiHX07dXSK6yS5NMbssxipoykve7537zJmMGAODGEB6pOd4mw5JY2OuwA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345045; c=relaxed/simple; bh=H+g7cbISVtaDY1JKt6Ybf8xc/ZLewI60cjadART3OkQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=o30SO5QSLNkcxTB42dCpCcteS98Xql+s0DKWosbVtbttLULU7V/VgvcIdclmVXys2HnrjrmGR0gPufzAI96bWeTMw5/h4G7nHgXxU8pj0oThCjbACrCDmEhk3EAo2YGeIq1EHHebXhebYabzQTkxwpVI/YS8q2tykD44ww7B23c= 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=XuX6uwAc; 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="XuX6uwAc" Received: from pps.filterd (m0333521.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55JEMai5011412; Thu, 19 Jun 2025 14:57:19 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=8ZeRf 10ljaEG1hqhsCLWmhWBbnsfFG1tSxdo2JnGEO0=; b=XuX6uwActotcUcJY+xvJh HMcj7QZP7MmzCd2Qg4Vxh/Q4ehkoqOudHlQn4POyZ36Eyp6emvP8hCSbgH1qL0bb aAiWx8FfMvoKNotG1DkY2akeFxwfTFy/Xc59PWd51mR6RYo4agK+vf0XtEizMno8 WELtt2KtQB7QVRSvzJvOIDxUw/JY/BJrznHjTOT2Xx32La7j2ruEA3mcghBjBxyN kdVqkDzj5BiiUJyURUWhzZCkVTd14VP/JmU7abpZFPJQ9H6I4gRuEv344iAA8u03 7bwRtiH1kV4sWP8HdQ7LjIPmMLMMwRbGfh0wBOvzK4j5d8h5FydMA6Ie67PSWa5M w== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 47900f23qr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:19 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDQ7B1023309; Thu, 19 Jun 2025 14:57:18 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8e5d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:18 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0Jb008257; Thu, 19 Jun 2025 14:57:17 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-15; Thu, 19 Jun 2025 14:57:17 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 14/17] objtool: Improve tracing of alternative instructions Date: Thu, 19 Jun 2025 16:56:56 +0200 Message-ID: <20250619145659.1377970-15-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=999 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfX9I66rYDyhbaR DXVgrlJzyKfy1FrYs+vfHZkQ8TDMHfOoaYypyHQjT17PBmMAt6fZ8sTbQoXPjuXsPF6qNtlRRZX siQ9z5kdO5VSWQgSDuFu2AQE6qZS8izGcHdCqSCGywBgGI3jqQxC0uoebIjiDfyO11S6pg+abcK V+3VzEbZ9EPzIZJ+QdNCCpmDPzA5+w91gDbX6YqYGPERtVB9s+zAfKZBLQygLVP9A9sauacqV27 vx+ZlIEo4U5KohWKLk/ODJhbZpe8yaKx9RiFeQHsqh4I2CW505r5Wos+GLAWSg1MO3aSKkDu04x ytHq0YWbQHFS9A6x8xB0cq0uVJyTbLL9fNlXuWiuh9oHRlwlaHD0OgnbTIu2I5dwvbrDeki727B 9qlvrOaWdBKN0oFPCW+NYP4twsP2bpc1uEZ23Yva3DrayMMeDnrTz7zx+S35GZlyjn8N3afI X-Proofpoint-ORIG-GUID: DP1CzKmDrWi3RAxSBZoHg2OuL6fGk77_ X-Authority-Analysis: v=2.4 cv=X/5SKHTe c=1 sm=1 tr=0 ts=6854254f b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=6-_rUJ9W-rRKKU8erE8A:9 cc=ntf awl=host:13207 X-Proofpoint-GUID: DP1CzKmDrWi3RAxSBZoHg2OuL6fGk77_ Content-Type: text/plain; charset="utf-8" When tracing function validation, improve the reporting of alternative instruction by more clearly showing the different alternatives beginning and end. Signed-off-by: Alexandre Chartre --- tools/objtool/check.c | 64 ++++++++++++++++++++++++--- tools/objtool/include/objtool/trace.h | 33 ++++++++++++++ 2 files changed, 91 insertions(+), 6 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 8a51c871e1dc..43c88a5fd58a 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -3517,7 +3517,7 @@ static bool skip_alt_group(struct instruction *insn) =20 /* ANNOTATE_IGNORE_ALTERNATIVE */ if (insn->alt_group && insn->alt_group->ignore) { - TRACE_INSN(insn, "alt group ignored"); + TRACE_ALT(insn, "alt group ignored"); return true; } =20 @@ -3641,22 +3641,74 @@ static int validate_insn(struct objtool_file *file,= struct symbol *func, if (insn->alts) { int i, num_alts; =20 + /* + * Count the number of alternatives with an alt group. + * + * For a jump alternative, count is 0 and there is a single + * alternative (with no alt group). + * + * For a group alternative, count is at least 1. In addition + * there is an alternative that points to the code following + * the alternative. + */ num_alts =3D 0; - for (alt =3D insn->alts; alt; alt =3D alt->next) - num_alts++; + for (alt =3D insn->alts; alt; alt =3D alt->next) { + if (alt->insn->alt_group) + num_alts++; + } =20 i =3D 1; for (alt =3D insn->alts; alt; alt =3D alt->next) { - TRACE_INSN(insn, "alternative %d/%d", i, num_alts); + if (!num_alts) { + /* + * For a jump alternative, the non-default + * branch is validated first. So if the + * default instruction is a NOP then the + * branch is validated first (jump taken), + * otherwise the branch is not taken. Then + * the default alternative is validated. + */ + if (insn->type =3D=3D INSN_NOP) + TRACE_ALT_INFO(insn, "jump taken - begin"); + else + TRACE_ALT_INFO(insn, "jump not taken - begin"); + } else { + /* + * For a group alternative, the code after the + * alternative (alternative with no alt group) + * is validated first. Then each alternative + * is validated. Finally the default alternative + * is validated. + */ + if (alt->insn->alt_group) + TRACE_ALT_INFO(insn, "alt %d/%d - begin", i, num_alts); + else + TRACE_ALT_INFO(insn, "after alternative - begin"); + } + ret =3D validate_branch(file, func, alt->insn, *statep); + + if (!num_alts) { + if (insn->type =3D=3D INSN_NOP) + TRACE_ALT_INFO(insn, "jump taken - end"); + else + TRACE_ALT_INFO(insn, "jump not taken - end"); + } else { + if (alt->insn->alt_group) + TRACE_ALT_INFO_NOADDR(insn, "alt %d/%d - end", i, num_alts); + else + TRACE_ALT_INFO_NOADDR(insn, "after alternative - end"); + } + if (ret) { BT_INSN(insn, "(alt)"); return ret; } - i++; + if (alt->insn->alt_group) + i++; } =20 - TRACE_INSN(insn, "alternative orig"); + TRACE_ALT_INFO(insn, "default"); } =20 if (skip_alt_group(insn)) diff --git a/tools/objtool/include/objtool/trace.h b/tools/objtool/include/= objtool/trace.h index 5b8abdb9b09f..da3d41d6dedd 100644 --- a/tools/objtool/include/objtool/trace.h +++ b/tools/objtool/include/objtool/trace.h @@ -19,6 +19,21 @@ extern int trace_depth; fprintf(stderr, fmt, ##__VA_ARGS__); \ }) =20 +/* + * Print the instruction address and a message. The instruction + * itself is not printed. + */ +#define TRACE_ADDR(insn, fmt, ...) \ +({ \ + if (trace) { \ + disas_print_info(stderr, insn, trace_depth - 1, \ + fmt "\n", ##__VA_ARGS__); \ + } \ +}) + +/* + * Print the instruction address, the instruction and a message. + */ #define TRACE_INSN(insn, fmt, ...) \ ({ \ if (trace) { \ @@ -36,6 +51,20 @@ extern int trace_depth; trace_insn_state(insn, sprev, snext); \ }) =20 +#define TRACE_ALT_FMT(fmt) " " fmt + +#define TRACE_ALT(insn, fmt, ...) \ + TRACE_INSN(insn, TRACE_ALT_FMT(fmt), \ + (insn)->offset, ##__VA_ARGS__) + +#define TRACE_ALT_INFO(insn, fmt, ...) \ + TRACE_ADDR(insn, TRACE_ALT_FMT(fmt), \ + (insn)->offset, ##__VA_ARGS__) + +#define TRACE_ALT_INFO_NOADDR(insn, fmt, ...) \ + TRACE_ADDR(NULL, TRACE_ALT_FMT(fmt), \ + (insn)->offset, ##__VA_ARGS__) + static inline void trace_enable(void) { trace =3D true; @@ -65,8 +94,12 @@ void trace_insn_state(struct instruction *insn, struct i= nsn_state *sprev, #else /* DISAS */ =20 #define TRACE(fmt, ...) +#define TRACE_ADDR(insn, fmt, ...) #define TRACE_INSN(insn, fmt, ...) #define TRACE_INSN_STATE(insn, sprev, snext) +#define TRACE_ALT(insn, fmt, ...) +#define TRACE_ALT_INFO(insn, fmt, ...) +#define TRACE_ALT_INFO_NOADDR(insn, fmt, ...) =20 static inline void trace_enable(void) {} static inline void trace_disable(void) {} --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 CB94E28DB4A for ; Thu, 19 Jun 2025 14:57:23 +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=1750345045; cv=none; b=XcET29Ra4q+F0rN3z+++PsCxiKMbklhHCXRzi2HsMIIhJyHeij9LykRcyAt6Zuar1y5sd4N1QQ0n1/ze67ZNOn86XuWYsziKxKbcK0NTTr5OzXVdCznOfYj/74Rjrudnr8XWG+/yrjcaxrNPYIv+ZE0aU3fBNemeTGmAR0hsKSY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345045; c=relaxed/simple; bh=zQckDNelWG6CV1PJeKinn6jnwA7PvmhWytZ/b79m1IQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Ia8RH4sF6ho8ctZNQwlAL/Dcv2qEhbapM/vQdwZMmKGu/50902nPHpkhDXL2uPpPuzxpfqbaeAtmGzrdcxNnD73WrVXKGE/kqXgjgzoQO0Oy3InhnSHqM/QjEBlVqERNXRXFNVyzBaKZkOkPX65mW97ikzVMPnWJLOGg2p6X4jo= 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=WCcbaqUS; 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="WCcbaqUS" Received: from pps.filterd (m0333521.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 55JEMZ2D011343; Thu, 19 Jun 2025 14:57:21 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=fgAm9 hTnxGqHi2kf7mMzxwksSkxtw8Hfs9QzUIFInhA=; b=WCcbaqUSD8HjNS89dty/8 tUQi42mvan1HBBkum89jDrPyo5rAm3fmpZsAQEmGYkQs7QNWuh9gIy+akik9gFS4 E+rD7OFyDT32c5kCUFhK3kx3ZUfXsTaHZ1DacaCQBOMtrNo455AwIguTTtF1pdAq nviJ6NJimXoMi6Y57VGLAmmZxuHLFRzVHnKQductg6x7MESV1C0K0LMugjvSVfFc vDOWKxldQWb35mpaEWcOO8lSuAZKgBgIryUFCnkP+NXsuxwyuGOW3lR4j6kPz/aH JRa4z8zT+ju0QF6FkcxE/1AOFqe6Q8Hu/JtWIYks5/IW7OQ1Fqzb0NW31KxmpPpr Q== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 47900f23qt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:20 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDLxh0022869; Thu, 19 Jun 2025 14:57:19 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8e67-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:19 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0Jd008257; Thu, 19 Jun 2025 14:57:18 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-16; Thu, 19 Jun 2025 14:57:18 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 15/17] objtool: Do not validate IBT for .return_sites and .call_sites Date: Thu, 19 Jun 2025 16:56:57 +0200 Message-ID: <20250619145659.1377970-16-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=999 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfX1JFBVHVYfgao 72YIRqDdf6NiMtXgjhb/suWE/ovk/3bAbxrOfgnwgpTQDt0nKa9u3nL0cJhB091eW2p2lME8uDu zsOnhNchN+21Znzwx/vlp32ecvaCpyCNqubLfXlNmMt4AQ3Cvi1yOgvy9GMqUCVgZ2I8oNo1KqG 1Sv5Ji3JUeuBQb7NhbVTMXf+bCt24ESQWEPfv2zzygy9wBdCv+ebCK3EKEQn8Q5t6PNE9BriLpV tbs409FqXSQZDiEcTkI2EcBxRKgVrNSmbrApN/lJ6P3OwJK/r7JIt9oeQxLcazn+FIa6DKZKna5 507RLpdVsmoQCCzpQ9LlKE5mr8gCswF0Gjj/PTRjfW+KuW/ZNU6UGBV2zsMOzVlBPciPdS52P68 +TJ5GBiiQhLMCOecmy6tsAofgtMFjeVs8mbioriHjLoBiNywDcZErAr7pDv8il8nJtpzBPJl X-Proofpoint-ORIG-GUID: QoObeOXMPGK6QUfLZHfK8s48QLvgFD16 X-Authority-Analysis: v=2.4 cv=X/5SKHTe c=1 sm=1 tr=0 ts=68542550 b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=yvIqsss6GtJD96b7xZoA:9 cc=ntf awl=host:13207 X-Proofpoint-GUID: QoObeOXMPGK6QUfLZHfK8s48QLvgFD16 Content-Type: text/plain; charset="utf-8" The .return_sites and .call_sites sections reference text addresses, but not with the intent to indirect branch to them, so they don't need to be validated for IBT. This is useful when running objtool on object files which already have .return_sites or .call_sites sections, for example to re-run objtool after it has reported an error or a warning. Signed-off-by: Alexandre Chartre --- tools/objtool/check.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index 43c88a5fd58a..fecdf6f42358 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -4645,6 +4645,8 @@ static int validate_ibt(struct objtool_file *file) !strcmp(sec->name, ".llvm.call-graph-profile") || !strcmp(sec->name, ".llvm_bb_addr_map") || !strcmp(sec->name, "__tracepoints") || + !strcmp(sec->name, ".return_sites") || + !strcmp(sec->name, ".call_sites") || strstr(sec->name, "__patchable_function_entries")) continue; =20 --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 554522BF01B for ; Thu, 19 Jun 2025 14:57:28 +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=1750345050; cv=none; b=qSSes7dOlgI0YfMP716IsmBGq0GbnHQN0h5lVXN9+mUCo0SRBk6PCk89O5NrlohSlMQ/IyJTbcGlsnHkw6eckgHKkSw7xLjwUe6toZv2HV/wCkly4jef0sD0KH3lpKREdwD5NmaUQSpSmLDjYTUBf6Fb0+rNCaCabvoT/7ttaUw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345050; c=relaxed/simple; bh=0Ve5OciXTs/DgxXHyeH/Hw760EvX6jjzvIh5HDoxUeA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=NMwXPJhsY/Egv/peX36YU+E6XkYLgZk4lw0UzxsruU8fh/FOlk3QwOHNi0x0n6aBQO1mo118gbJXrs+BU+zpg+UgkQUsNxGk2YORKJlnatPQV1I5VyTTZl1zVW7SQgc9O/rPG07Tei3v1UR0o3s13MfZoOQbTdp9ySobDO/tMkU= 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=I0BDEIWc; 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="I0BDEIWc" 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 55JEMYSB025798; Thu, 19 Jun 2025 14:57:21 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=p1NR5 Uo9qxE/c+XYrd4u93UyzfRLfeM7J5KTXpPZ2rI=; b=I0BDEIWcJBFX3XY6cjlyN Fx13e7Q3fJ15C4s9QH0c6xyP/vlqk792aO2gRsxg0oofeiO0jX2AczwedydR7jKt mbB+m1b/JCFMsPkfEbnCBKKGdpGYk+98d/5a0UB+l/3Xy26wlUgD/x4ekPmpAV0b HM/dKmlIu9bDXok0v24WRPEBUKC6YqI7TYlLBm12uMum1KL0VYhMHAsMbCB43sWN MtWx+K04O/KboRz1ZxNr0mAFzuH3TpH70t8I9W+nS8rgp7A9zJdxRBXEMfb2k7s5 /Ee9tHKzgs3rnsBsJM4ty/2uC2aRT3sq2JGJ1tz/2fRboqbkP5tU6ORtXj+wrYbk Q== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 478yv5a0r3-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:21 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDJbWI022755; Thu, 19 Jun 2025 14:57:20 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8e6x-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:20 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0Jf008257; Thu, 19 Jun 2025 14:57:20 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-17; Thu, 19 Jun 2025 14:57:19 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 16/17] objtool: Add the --disas= action Date: Thu, 19 Jun 2025 16:56:58 +0200 Message-ID: <20250619145659.1377970-17-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=999 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyNCBTYWx0ZWRfXxd5PW7QJH39m PC1O2ZM0WGtPdzJXob7AgJiBXrm8rbJ9xTZcUaKUUSGzRs4x4Oal4DkidOpPVzvWRWBVGd8NsEP ivubBbrEHio6iYJxPp+dGcXOFTm2v8vRaRZIcH+5MMSISHV6BMtM9hA7nedz5632mv8RnQVCIex 6OB9JuoOtK2TRsKkrMJvWMwbTf8bEYhTvIff5Qc9HFDuLDkEQt5m9RCLON7OIrWY9hwzS0QaUko 7L/7qI2i86dH8qpyKhCFWxJGRt/k3dp/6vnyM33xl4zSO6l/LF9FjusLviVEZdmvZGzzKl6rijp QgrnuVRKbrKybWpMr87352HwFWQ0IbdYhOLm2HIfGjQXrOH+byRq0iDdVGAQYiI9HsXM6nf0UHX jJsHE0uI3haCKrfLIlQFSRURBESoKr08uA+qnRh7NCnK4tdZx+XeFl1Pd3mUTd9FZQ5HwZBk X-Proofpoint-GUID: JmF_Xw6DKI12uWtPLMo1cJod_Pc5eQ_B X-Proofpoint-ORIG-GUID: JmF_Xw6DKI12uWtPLMo1cJod_Pc5eQ_B X-Authority-Analysis: v=2.4 cv=W9c4VQWk c=1 sm=1 tr=0 ts=68542551 b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=20KFwNOVAAAA:8 a=Yos37rPc9-vhJleOp_oA:9 cc=ntf awl=host:13207 Content-Type: text/plain; charset="utf-8" Add the --disas=3D actions to disassemble the specified functions. The function pattern can be a single function name (e.g. --disas foo to disassemble the function with the name "foo"), or a shell wildcard pattern (e.g. --disas foo* to disassemble all functions with a name starting with "foo"). Signed-off-by: Alexandre Chartre --- tools/objtool/builtin-check.c | 4 ++- tools/objtool/check.c | 35 ++++++++++++++----------- tools/objtool/disas.c | 28 ++++++++++++++++++++ tools/objtool/include/objtool/builtin.h | 1 + tools/objtool/include/objtool/disas.h | 2 ++ 5 files changed, 53 insertions(+), 17 deletions(-) diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c index c53d738e4fb0..49b37da28b90 100644 --- a/tools/objtool/builtin-check.c +++ b/tools/objtool/builtin-check.c @@ -73,6 +73,7 @@ static int parse_hacks(const struct option *opt, const ch= ar *str, int unset) =20 static const struct option check_options[] =3D { OPT_GROUP("Actions:"), + OPT_STRING_OPTARG('d', "disas", &opts.disas, "function-pattern", "disas= semble functions", "*"), OPT_CALLBACK_OPTARG('h', "hacks", NULL, NULL, "jump_label,noinstr,skylake= ", "patch toolchain bugs/limitations", parse_hacks), OPT_BOOLEAN('i', "ibt", &opts.ibt, "validate and annotate IBT"), OPT_BOOLEAN('m', "mcount", &opts.mcount, "annotate mcount/fentry calls fo= r ftrace"), @@ -159,7 +160,8 @@ static bool opts_valid(void) return false; } =20 - if (opts.hack_jump_label || + if (opts.disas || + opts.hack_jump_label || opts.hack_noinstr || opts.ibt || opts.mcount || diff --git a/tools/objtool/check.c b/tools/objtool/check.c index fecdf6f42358..c7a70d47f104 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -2563,7 +2563,7 @@ static int decode_sections(struct objtool_file *file) * Must be before add_jump_destinations(), which depends on 'func' * being set for alternatives, to enable proper sibling call detection. */ - if (opts.stackval || opts.orc || opts.uaccess || opts.noinstr) { + if (opts.stackval || opts.orc || opts.uaccess || opts.noinstr || opts.dis= as) { ret =3D add_special_section_alts(file); if (ret) return ret; @@ -4766,14 +4766,15 @@ int check(struct objtool_file *file) int ret =3D 0, warnings =3D 0; =20 /* - * If the verbose or backtrace option is used then we need a - * disassembly context to disassemble instruction or function - * on warning or backtrace. + * Create a disassembly context if we might disassemble any + * instruction or function. */ - if (opts.verbose || opts.backtrace || opts.trace) { + if (opts.verbose || opts.backtrace || opts.trace || opts.disas) { disas_ctx =3D disas_context_create(file); - if (!disas_ctx) + if (!disas_ctx) { + opts.disas =3D false; opts.trace =3D false; + } objtool_disas_ctx =3D disas_ctx; } =20 @@ -4892,19 +4893,21 @@ int check(struct objtool_file *file) } =20 out: - if (!ret && !warnings) - return 0; - - if (opts.werror && warnings) - ret =3D 1; - - if (opts.verbose) { + if (ret || warnings) { if (opts.werror && warnings) - WARN("%d warning(s) upgraded to errors", warnings); - print_args(); - disas_warned_funcs(disas_ctx); + ret =3D 1; + + if (opts.verbose) { + if (opts.werror && warnings) + WARN("%d warning(s) upgraded to errors", warnings); + print_args(); + disas_warned_funcs(disas_ctx); + } } =20 + if (opts.disas) + disas_funcs(disas_ctx); + if (disas_ctx) { disas_context_destroy(disas_ctx); objtool_disas_ctx =3D NULL; diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index 376c7bedef47..97d506afdf45 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -3,6 +3,8 @@ * Copyright (C) 2015-2017 Josh Poimboeuf */ =20 +#include + #include #include #include @@ -399,3 +401,29 @@ void disas_warned_funcs(struct disas_context *dctx) disas_func(dctx, sym); } } + +void disas_funcs(struct disas_context *dctx) +{ + bool disas_all =3D !strcmp(opts.disas, "*"); + struct section *sec; + struct symbol *sym; + + for_each_sec(dctx->file, sec) { + + if (!(sec->sh.sh_flags & SHF_EXECINSTR)) + continue; + + sec_for_each_sym(sec, sym) { + /* + * If the function had a warning and the verbose + * option is used then the function was already + * disassemble. + */ + if (opts.verbose && sym->warned) + continue; + + if (disas_all || fnmatch(opts.disas, sym->name, 0) =3D=3D 0) + disas_func(dctx, sym); + } + } +} diff --git a/tools/objtool/include/objtool/builtin.h b/tools/objtool/includ= e/objtool/builtin.h index b3c84b6fdc5f..e41f3802d397 100644 --- a/tools/objtool/include/objtool/builtin.h +++ b/tools/objtool/include/objtool/builtin.h @@ -26,6 +26,7 @@ struct opts { bool uaccess; int prefix; bool cfi; + const char *disas; =20 /* options: */ bool backtrace; diff --git a/tools/objtool/include/objtool/disas.h b/tools/objtool/include/= objtool/disas.h index 5db75d06f219..5d2149ffac33 100644 --- a/tools/objtool/include/objtool/disas.h +++ b/tools/objtool/include/objtool/disas.h @@ -14,6 +14,7 @@ struct disassemble_info; struct disas_context *disas_context_create(struct objtool_file *file); void disas_context_destroy(struct disas_context *dctx); void disas_warned_funcs(struct disas_context *dctx); +void disas_funcs(struct disas_context *dctx); int disas_info_init(struct disassemble_info *dinfo, int arch, int mach32, int mach64, const char *options); @@ -37,6 +38,7 @@ static inline struct disas_context *disas_context_create(= struct objtool_file *fi =20 static inline void disas_context_destroy(struct disas_context *dctx) {} static inline void disas_warned_funcs(struct disas_context *dctx) {} +static inline void disas_funcs(struct disas_context *dctx) {} =20 static inline int disas_info_init(struct disassemble_info *dinfo, int arch, int mach32, int mach64, --=20 2.43.5 From nobody Thu Oct 9 06:06:38 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 CCCBA2BD003 for ; Thu, 19 Jun 2025 14:57:26 +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=1750345048; cv=none; b=sCJfeXUILbaAbKqJJgBzcchzdmxtrNPozAHmEptZ7TklShpvSAKvH/bLKH7p4Ni8W7OAw36JVAXIpaPgdLYQ0/AsJW00LhPdae9El36VrTSZUrzpQX05TNkjZgCJo3/OWFjw06WTnu5ioLhMr6zKp0dfjBRX4PTXa8vI72rTeEc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750345048; c=relaxed/simple; bh=xMgWuJgjZLKWrY1bhHBTjYqkbcAG5+bU5JiUnFxtCb8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ASZo2kum9lTALYafdvYD+sbWucEHebHtz8V6xRvbRDb7w8zaIyeHRR77nWWrK9uYbmaLiZ/aMloXPa1s4IwfSenmCggdIMGV0g5Xd5VMWo+hl7kyrcqt37KmmwLUsFael8sLUHWHIH4vz7iJ67B5YVt+s9ItGhk/904JpbrPN78= 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=VscYI59D; 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="VscYI59D" 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 55JEMa4N029324; Thu, 19 Jun 2025 14:57:23 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=kfy2u 1goXYdZwWeTcMaxTAxBZxMAdwIyKd3O6MkyOvw=; b=VscYI59De250uU29zaxyB 12ujQIMUduhuzBBvPrJYbSeVycswrGm/jAd/YDcPOzh3kPs1zHnuNQyte2nhTfwn ZpAVz3ccoWpcE6mXvZRmUHVdNdfWr2dO8g2tf8zxdzTET7ZtsI1BmaMUC+OwVWS6 c+mKiWQNxCnG284JXQ9OT08H/4iNoxaewmjcyuF4Ytb7bYT3ByOGhOcM5JCVBkub CgpWbnFmo1Q9SFiLwJLnP45YIdY24+0zDg5SNfeVmPreGtsFa5oR9+7puaeWpClZ ksr97587gFnJpGF9/foZ5hIsljoDCWkdeuhLn3QtRW7UWeMOYVBP5fVYTkapsJcY Q== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 47b23xwjy0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:23 +0000 (GMT) Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.18.1.2/8.18.1.2) with ESMTP id 55JDNbXB022764; Thu, 19 Jun 2025 14:57:21 GMT Received: from pps.reinject (localhost [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 478yhj8e7j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 19 Jun 2025 14:57:21 +0000 Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 55JEv0Jh008257; Thu, 19 Jun 2025 14:57:21 GMT Received: from laptop-dell-latitude7430.nl.oracle.com (dhcp-10-154-180-74.vpn.oracle.com [10.154.180.74]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTP id 478yhj8dta-18; Thu, 19 Jun 2025 14:57:21 +0000 From: Alexandre Chartre To: linux-kernel@vger.kernel.org, mingo@kernel.org, jpoimboe@kernel.org, peterz@infradead.org Cc: alexandre.chartre@oracle.com Subject: [RFC PATCH v2 17/17] objtool: Disassemble all alternatives when using --disas Date: Thu, 19 Jun 2025 16:56:59 +0200 Message-ID: <20250619145659.1377970-18-alexandre.chartre@oracle.com> X-Mailer: git-send-email 2.43.5 In-Reply-To: <20250619145659.1377970-1-alexandre.chartre@oracle.com> References: <20250619145659.1377970-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.1099,Hydra:6.0.736,FMLib:17.12.80.40 definitions=2025-06-19_05,2025-06-18_03,2025-03-28_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 spamscore=0 phishscore=0 adultscore=0 suspectscore=0 mlxscore=0 mlxlogscore=999 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2505160000 definitions=main-2506190124 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjUwNjE5MDEyMiBTYWx0ZWRfXyYnicvW0KAt0 ZtNIvMXbyiNFByzyDWmyjKq3nGMouo51l0e64eCXn1nlWPLHpZZv9zL+wUzOu7I+lk9nFbWnJNr TruNkZho8PooQafNhK8ehYeMHxIkvRB8oj8uh3GptjvyxQzAAj975MWSvzGoyXk21DkZ23KJbpQ nIdjd6fLMcFLp02CmYMqIYifmOudyzHVr/zS8h+X+S+CGxVbtHgfSDBBaFZjkrsZvjMyDTan34V RoknFEfq8kelOMre3cqt2hkpqjHHXjHnerncWfe8F3Appk8oGcitEZRIn79BPZnnbqiEL2kNA11 1YoJuYHu0Voox0YxwZGadkqOOaC/mpIH+4k6FcyVfWAyeHv+M1Rk/g+iKgTiJzxEQCr70BB3qN8 ajcefqMK+QnoQdBsYy3B0/3x8HkDFs4iH8QtHa1n8++wk8HMRFlspBmvnoGDrEjRQfVGKQnx X-Authority-Analysis: v=2.4 cv=DM2P4zNb c=1 sm=1 tr=0 ts=68542553 b=1 cx=c_pps a=qoll8+KPOyaMroiJ2sR5sw==:117 a=qoll8+KPOyaMroiJ2sR5sw==:17 a=6IFa9wvqVegA:10 a=yPCof4ZbAAAA:8 a=HvF_JEnCvTAsiACKIaMA:9 cc=ntf awl=host:13207 X-Proofpoint-GUID: _vVKwxYErInCcwWgDQeJ77wj7YcilGg- X-Proofpoint-ORIG-GUID: _vVKwxYErInCcwWgDQeJ77wj7YcilGg- Content-Type: text/plain; charset="utf-8" When using the --disas action, disassemble all code alternatives instead of only the default alternative. Signed-off-by: Alexandre Chartre --- tools/objtool/check.c | 8 -- tools/objtool/disas.c | 152 +++++++++++++++++++++++++- tools/objtool/include/objtool/check.h | 8 ++ 3 files changed, 154 insertions(+), 14 deletions(-) diff --git a/tools/objtool/check.c b/tools/objtool/check.c index c7a70d47f104..fa66c8c6bf21 100644 --- a/tools/objtool/check.c +++ b/tools/objtool/check.c @@ -25,11 +25,6 @@ #include #include =20 -struct alternative { - struct alternative *next; - struct instruction *insn; -}; - static unsigned long nr_cfi, nr_cfi_reused, nr_cfi_cache; =20 static struct cfi_init_state initial_func_cfi; @@ -131,9 +126,6 @@ static struct instruction *prev_insn_same_sym(struct ob= jtool_file *file, insn && insn->offset >=3D sym->offset; \ insn =3D prev_insn_same_sec(file, insn)) =20 -#define sec_for_each_insn_from(file, insn) \ - for (; insn; insn =3D next_insn_same_sec(file, insn)) - #define sec_for_each_insn_continue(file, insn) \ for (insn =3D next_insn_same_sec(file, insn); insn; \ insn =3D next_insn_same_sec(file, insn)) diff --git a/tools/objtool/disas.c b/tools/objtool/disas.c index 97d506afdf45..9c202feee493 100644 --- a/tools/objtool/disas.c +++ b/tools/objtool/disas.c @@ -266,6 +266,12 @@ char *disas_result(struct disas_context *dctx) #define DISAS_INSN_OFFSET_SPACE 10 #define DISAS_INSN_SPACE 60 =20 +#define DISAS_PRINFO(insn, depth, format, ...) \ + disas_print_info(stdout, insn, depth, format "\n", ##__VA_ARGS__) + +#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, @@ -345,6 +351,82 @@ void disas_print_insn(FILE *stream, struct disas_conte= xt *dctx, va_end(args); } =20 +static void disas_group_alt(struct disas_context *dctx, + struct instruction *orig_insn) +{ + struct instruction *insn; + struct alternative *alt; + struct symbol *func; + int i, count; + int alt_id; + + func =3D orig_insn->sym; + alt_id =3D orig_insn->offset; + + count =3D 0; + for (alt =3D orig_insn->alts; alt; alt =3D alt->next) { + if (!alt->insn->alt_group) + /* jump alternative */ + continue; + + if (func && alt->insn->sec =3D=3D func->sec) + /* exception handler */ + continue; + + /* count group alternatives, including fake nop */ + count++; + } + + i =3D 1; + for (alt =3D orig_insn->alts; alt; alt =3D alt->next) { + + if (!alt->insn->alt_group) + continue; + + /* + * If the alternative instruction is in the same section + * as the original instruction then that's an exception + * handling i.e. branch to the alternative instruction if + * there is an exception. + */ + if (func && alt->insn->sec =3D=3D func->sec) { + DISAS_PRINFO(NULL, 0, + " exception handler - begin", alt_id); + DISAS_PRINFO(orig_insn, 1, "jmp %lx <%s+0x%lx>", + alt->insn->offset, func->name, + alt->insn->offset - func->offset); + DISAS_PRINFO(NULL, 0, + " exception handler - end", alt_id); + continue; + } + + DISAS_PRINFO(NULL, 0, + " %d/%d - begin", alt_id, i, count); + + insn =3D alt->insn->alt_group->first_insn; + + sec_for_each_insn_from(dctx->file, insn) { + + if (insn->alts) { + DISAS_PRINFO(insn, 0, + "alt group: ignore nested alternative (not supported)"); + } + + DISAS_PRINSN(dctx, insn, 1); + + if (insn =3D=3D insn->alt_group->last_insn || + insn =3D=3D insn->alt_group->nop) + break; + + insn =3D next_insn_same_sec(dctx->file, insn); + } + + DISAS_PRINFO(NULL, 0, + " %d/%d end", alt_id, i, count); + i++; + } +} + /* * Disassemble a single instruction. Return the size of the instruction. */ @@ -367,21 +449,79 @@ size_t disas_insn(struct disas_context *dctx, struct = instruction *insn) return disasm(insn->offset, &dctx->info); } =20 +static void disas_jump_alt(struct disas_context *dctx, struct instruction = *insn) +{ + struct instruction *alt_insn; + struct symbol *func; + int alt_id; + + func =3D insn->sym; + alt_id =3D insn->offset; + + DISAS_PRINFO(NULL, 0, " default", alt_id); + DISAS_PRINSN(dctx, insn, 1); + + alt_insn =3D insn->alts->insn; + if (!alt_insn) { + WARN_INSN(insn, "no jump alternative"); + return; + } + + DISAS_PRINFO(NULL, 0, " else", alt_id); + + if (insn->type =3D=3D INSN_NOP) { + DISAS_PRINFO(insn, 1, "jmp %lx <%s+0x%lx>", + alt_insn->offset, func->name, + alt_insn->offset - func->offset); + } else { + DISAS_PRINFO(insn, 1, "nop%d", insn->len); + } + + DISAS_PRINFO(NULL, 0, " end", alt_id); + + if (insn->alts->next) + WARN_INSN(insn, "more than one jump alternatives\n"); +} + /* * Disassemble a function. */ static void disas_func(struct disas_context *dctx, struct symbol *func) { + struct instruction *alt =3D NULL; struct instruction *insn; - size_t addr; + int alt_id =3D 0; + int depth =3D 0; =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) { + if (alt) { + DISAS_PRINFO(insn, 0, + "alt default: ignore nested alternative (not supported)"); + } else if (insn->alt_group) { + alt =3D insn; + alt_id =3D alt->offset; + DISAS_PRINFO(NULL, 0, + " default - begin", alt_id); + depth =3D 1; + } else { + disas_jump_alt(dctx, insn); + continue; + } + } + + DISAS_PRINSN(dctx, insn, depth); + + if (alt && (alt->alt_group->last_insn =3D=3D insn || + alt->alt_group->nop =3D=3D insn)) { + DISAS_PRINFO(NULL, 0, + " default - end", alt_id); + disas_group_alt(dctx, alt); + alt =3D NULL; + depth =3D 0; + } } printf("\n"); } diff --git a/tools/objtool/include/objtool/check.h b/tools/objtool/include/= objtool/check.h index e5f97acb6252..748ee7631021 100644 --- a/tools/objtool/include/objtool/check.h +++ b/tools/objtool/include/objtool/check.h @@ -38,6 +38,11 @@ struct alt_group { bool ignore; }; =20 +struct alternative { + struct alternative *next; + struct instruction *insn; +}; + #define INSN_CHUNK_BITS 8 #define INSN_CHUNK_SIZE (1 << INSN_CHUNK_BITS) #define INSN_CHUNK_MAX (INSN_CHUNK_SIZE - 1) @@ -135,6 +140,9 @@ struct instruction *next_insn_same_sec(struct objtool_f= ile *file, struct instruc insn && insn->sec =3D=3D _sec; \ insn =3D next_insn_same_sec(file, insn)) =20 +#define sec_for_each_insn_from(file, insn) \ + for (; insn; insn =3D next_insn_same_sec(file, insn)) + #define sym_for_each_insn(file, sym, insn) \ for (insn =3D find_insn(file, sym->sec, sym->offset); \ insn && insn->offset < sym->offset + sym->len; \ --=20 2.43.5