From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by sourceware.org (Postfix) with ESMTPS id E68833854549 for ; Tue, 22 Nov 2022 16:01:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org E68833854549 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=oracle.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=oracle.com Received: from pps.filterd (m0246631.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 2AMFN49v010598 for ; Tue, 22 Nov 2022 16:01:08 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-transfer-encoding : content-type : mime-version; s=corp-2022-7-12; bh=24zOofGJ8vKDJ1Th7SoYziHTPYwilKeQaC+FGBs43Fw=; b=RlyW5oTS8RLMnxs2SoyUR/0yGiJATBC7V1AfA9adPdeKMANwLDMLrOtaVnCAkOuUkqSB uc52G330mzl94OfFNBLRyHZhyi+7HWnt313DEjrABiNwRbvuA/JeZswM4Kz0kdwPRH8W 3GSCF8oDYgxr6H6EFgDTc5j8UUovo+z82xXTuSk2/vaIOX40xN6MlPn7UPWhMXXKMh0k IO5K3Y5cCDbFW49gYdI/rHDPRBMxb8TaiL2kHeeornlv6RVTt47vs14ZM+4XH/RH1Rog It4yrEpxBXh0H5athTflZXKHC/JuE8iQoa0i/v+g9vdrKRqydslp/OZXyswnQK2UrsEW xQ== Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3kxrd80cs0-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Tue, 22 Nov 2022 16:01:08 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.5/8.17.1.5) with ESMTP id 2AMFHgJ8028938 for ; Tue, 22 Nov 2022 16:01:06 GMT Received: from nam11-dm6-obe.outbound.protection.outlook.com (mail-dm6nam11lp2169.outbound.protection.outlook.com [104.47.57.169]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id 3kxnkbcc72-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Tue, 22 Nov 2022 16:01:06 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=oGk+LoBN2jJiM49Glr2qo1evwTwVzDiJHvLCFyfmp7FVv2kCn+DzVkUO8gQztYDCz9tW7Lh5Tw/FhIwf5NEGlszPwboa1DS0SbFpfRQF4+FatTxS3y+Tjyn0Mfk7RXnO2eenHtgBxVpHbdfAQ1gB7m7lCUmluXCgP0wwkvVMogEeBE1DAPF/k0/DJ09Y9bnJggYfa0tr89tnoK2LL1JnHEYR/uETjjd4KGe7QRYGX8ObM8DKzbRgbxLhPm1x5tsUKVRJYnNcwCLbkpZ6xebbPAaHtj0GaQ3xZ45i39SxGZXcv25RvDorNYZedIqf9WJCJffOjk1I9+/rgBzPyKMelQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=24zOofGJ8vKDJ1Th7SoYziHTPYwilKeQaC+FGBs43Fw=; b=Qb8xzZJKRwE3AmvwnSL/3dzXmSd1KCRp42lEJWoGv7wJgW1RXxJXPUMr2VhEBd1trw12GyhSBFfOpseIXq+mjYOvwijWxBr01F71n9Ll1ocM0sSz7vutIFokVWes3Jej1vngMgm3AM7Z9qmL8LfZ/KIQc2De3Y89ydmQGAkErSqfErMJFuiq+EeeC/HMuwo+L5tblo6XgZ0gYJ4LC4zUsvsaGIqMkfOXMxX0rP+fjwMi6MxQlXX1/VUXm22U5AxAusJuszV/C3adeys6BieVQ+Z+b1BmqttLfRZKMefrEn00e99lLy1PyEwqFfcezN4x+KH4mrgeVE6tUf83TmpA5w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=24zOofGJ8vKDJ1Th7SoYziHTPYwilKeQaC+FGBs43Fw=; b=LeOXy8e16vLYN1YmmVkJaqfB5QXjWBDQQ2SOzUZHbZdT+Wmq2ATM0ctbSfL5c4EACCOvUNnszTMS7uhRi6Cay0N/J74K7GBTzW3cT+VC6Ww5VWAzrURCW9UYP4XDcvddx0z3XBSaiTJ/RE9vTRjY9lyTlrwVOI+fdPN2cYycBCE= Received: from MWHPR10MB1407.namprd10.prod.outlook.com (2603:10b6:300:23::20) by CH2PR10MB4277.namprd10.prod.outlook.com (2603:10b6:610:7b::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5834.15; Tue, 22 Nov 2022 16:00:58 +0000 Received: from MWHPR10MB1407.namprd10.prod.outlook.com ([fe80::1800:88c1:fae8:13b4]) by MWHPR10MB1407.namprd10.prod.outlook.com ([fe80::1800:88c1:fae8:13b4%10]) with mapi id 15.20.5834.015; Tue, 22 Nov 2022 16:00:58 +0000 From: "Guillermo E. Martinez" To: libabigail@sourceware.org Cc: "Guillermo E. Martinez" Subject: [PATCH v4] ELF based front-end readers fallback feature Date: Tue, 22 Nov 2022 10:00:50 -0600 Message-Id: <20221122160050.2031623-1-guillermo.e.martinez@oracle.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20221121185102.1163007-1-guillermo.e.martinez@oracle.com> References: <20221121185102.1163007-1-guillermo.e.martinez@oracle.com> Content-Transfer-Encoding: 8bit Content-Type: text/plain X-ClientProxiedBy: SN7PR04CA0215.namprd04.prod.outlook.com (2603:10b6:806:127::10) To MWHPR10MB1407.namprd10.prod.outlook.com (2603:10b6:300:23::20) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: MWHPR10MB1407:EE_|CH2PR10MB4277:EE_ X-MS-Office365-Filtering-Correlation-Id: a709c358-2a52-4c43-1feb-08dacca2bdad X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: YotQmZZ9HqbuyfupWqlv508L/ZjJjUpZV7kIW6aOrWr0RqnxAP/AZo8TcQxo6h7zJdcNIS3e1FnfX2biD1Hc5sTR0XdH5ntLgaYs4otBPAHEsfeJc7CNec4WRkWXHUT4b5D3+SpRJhaEgId3K91CNUejsjN9Hn1nFuAM2y6azm8PlfMrNnaBnK6TvpfIMbbb5w0SH3p8gkxu/QiEs3hQBEn5BMjhu6vlEE0et1sV6mHexuc784haIEoE2oG+K88Sieub4rLOKdl2nxAP1TPT71I2GujK6XzmTyzUUf6XMI3a9wVUUdKGQrFw5PmrzKE7Vm6jMa34B1PM0ATgfUufsHVJZ20YoRAy6MtfrWaVLRQQZw+/uKT6weCLJClDFHbdYFAB2F+hbCJG4LeMr6IylRlm++KpYoKYiF3IQdKvd4QdjldAxzBgP5oz+xRhIABIgX7hcxU/ZqNiaZDAcnDhSjLXpUfzBBI1q8mBOOrFr2UjXEnaQclRrsgzcVxVq/qx8Fl3h0oX8hEy1tE85HK5FJH2JMLwb6PGbqMgEXp+6CUGLQVsazjUMM+ibifqs8pNhv1lDwtHBYn3mfIFoI9wPUVC0gDJka4ueJanFaSSgWkOG2qYSI4j7QciKV0FJx4Fe5iH2R8Gn9EUMeJ5CElnPaZP9mw4WoHwj4uj2DbD/6SrgGJ2zV98XKGjY1qaRnx3i0oqayKWd1l/39clt6+ZtQ== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MWHPR10MB1407.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230022)(396003)(39860400002)(376002)(346002)(136003)(366004)(451199015)(38100700002)(86362001)(6506007)(8676002)(103116003)(186003)(107886003)(5660300002)(6666004)(6512007)(1076003)(316002)(6916009)(966005)(6486002)(66946007)(478600001)(66476007)(4326008)(2616005)(83380400001)(8936002)(30864003)(66556008)(2906002)(41300700001)(36756003)(559001)(579004);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?nPPrqFbZrfptqyFg62ylu3h4QWCEVQCXDzXQKtvKrDEFT7t0sqxJOMogfEu5?= =?us-ascii?Q?JqCoTRDQw4eTY8Fb29QyHvfL+x5KfgdG34JfOOErclSbBDattDqDJ+xYhQvC?= =?us-ascii?Q?ty8/Qpxn4UKVa15qFwwzOt8Xc4hAq7lOUOUssI6w4kKKITASZywZ9JTr+nOt?= =?us-ascii?Q?UZ6xGQKH5fcsVd9rAeCxHwIpRaSjDRrBY64ymTdg2ZeHuEvMQ04aXcvQjIU/?= =?us-ascii?Q?jUzopaHI7M+DT5RdLZC3wks9Dqymhel4of9sizijEutW8WVUhjIehNZ4VwQ2?= =?us-ascii?Q?hfqnFTEWxuG+htjTMm5uQU8aJQP/i5KHSgWCTF7dAZuy86S5U4eJplZIX5rs?= =?us-ascii?Q?HJzHslwTRDnqvfSIqwK9xfMsyXbR6uJXUz5HOQdhmCPaJ1nNLL8PREMm6vDJ?= =?us-ascii?Q?MQ0XheTLCV2Q7FwgV0KTxLVgW2YZuUqm4XHA0Bwqa4mIuvYcU6PcsT+lSRhK?= =?us-ascii?Q?kXWG/NBpQBPGibem+LUSGOysL2yackFdgxRQVhxoRXK4PDn48TnEUXAw8YEu?= =?us-ascii?Q?GU6iSDtmrqSXkV+PL7+XELzS6nvKZF3SGAdACnnRCZsQ3/PxB3baiAJrdWM+?= =?us-ascii?Q?wnym5vphSZkVd5lMnu3aflmHSDI5GAQ+5ovrm3noBm6bvnAxBrkGNDVylDRo?= =?us-ascii?Q?tS8leszQQqehCqgwD8UahAcPBwo25lhFCGxqsmIP9T/ko38gPAxvoDxIUrPs?= =?us-ascii?Q?8XT2SnRdxzKKYd6U9xMiApolaBWzcLCaJURVrTzNLacRmFlb5VsoAMepfd/9?= =?us-ascii?Q?vXgJ1Es18HI2+rkm/vZVheMub3e1wmilCsAHywAOzh8pb1m+SkMq595UxjpS?= =?us-ascii?Q?8kJIZ3cVfeL+i/1gDs0tBkTcSXQRB/Csqi6R8S3D0Z9D1AXDVOpisQesmc14?= =?us-ascii?Q?Bhs/o6i95r+n9hR5Fb0FMzBUWOlVtKBR5t2Mx7XVUkRUKAjsmkxxyyA9Gizq?= =?us-ascii?Q?288r6xP7HDjN/yb5Wt5YWcTWCbIuDDClsaPd4S9R2W96KYPGvYYvx2Czy1Qp?= =?us-ascii?Q?rE8qzOHVqED4xusooU3IzeZFogmrmWIgepRI0GJsTXSIaydFJ+EN6hZDSdnB?= =?us-ascii?Q?fo1GhYdDf2HitT71NoHLjuZwZxzfwLUaORAnOgruSi2CUpS8B+asvx+hDO7S?= =?us-ascii?Q?/ljRJ7XQhDiTxfm+b/KoQnueim8HBY+JqgaVV/LM7Vgx/qRAfVLVIyJusNTp?= =?us-ascii?Q?dyDKYzuwU2J3+Xv0dNNk8WX9LDCdRarjubVrRtrTwaNYYKnZ/yn2ygfuyAvl?= =?us-ascii?Q?K1Gf0udQo/k82FsEnpqJ5kgNlAj3VS9WYcGir7wE0Z+SyKHa9V87zJByIbj/?= =?us-ascii?Q?5dGEoUYiMIN0q35f3d8czYmb9nnnniAm6b1ZYx9L3J86vk5cC/3UnJR+rxzi?= =?us-ascii?Q?VKUBhzb8jz3ksS0zxD93yP9bE0tLsHgo/A6D11yZF9K9W+JkILDpfn32g/Bz?= =?us-ascii?Q?SQxwz8cXzrEriYk78owLTUlq6v5HTF4raw2TND153DOoC29T3Fh52MWYcleO?= =?us-ascii?Q?N+N/52Bqvz8UV2dQ+sGurmG972629z+3bfp4atOWArHPvYtoJzjDS7BTMqhM?= =?us-ascii?Q?IaAzKV3ElgOCJIjAQcDAgdrMxedxTeWVjXN0YXbN4hKwOSfGXrA2T2E92T4L?= =?us-ascii?Q?C4z4S9pmVc1hJ1cl9QYXJ7sbbQjRai/JjrA/QgLPdMuAPZiJ4G9dNLsfkt8t?= =?us-ascii?Q?RTPQRNURRzkZ14aIUN2Utx4gCEw=3D?= X-MS-Exchange-AntiSpam-ExternalHop-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-ExternalHop-MessageData-0: ssJd12jmcNd28DcuaetMg8lWJQWpoh2hSzTyLUlmVn0UZQUZ8Uak9cAQv1j+pZvdUP+T7VZrVO4zIWs9U0lGxjaZZu2Aqy0h47kz1eqR5VqXrovSVtiWfhjjhMaOjkRyXpKLrSo8uxMwW20vU4AuTOGNY40ZO5cWsrLMQKaxcl3aPCcB8S3fffGF6PpIbGmh6Utco+VneRLHdeLwtwGV4rBTvzVVrHRVkQCqN6rrRlvp9msrw/qm6+YjKZcRUz/6S3LeSARb/M4rzIkJDHEuUWlUkbJfo/EIODuYdFXcr91tB64XDgALfVVv9dZFYzPb9ErAit+myDo+y+rsoujYJSREXN/2vp3rE5Tggnxm+TgqQ5lX57BJT8J82wPwVLPGtYVC+Zya0tG8RKnPzNd+D9bmFc7DxQJF1gi/qTEJgN4KGS6JpEDcLrTMtBDAe5xBrbF6bqvIcMv3grxlpCaI1pKau97m1AxPKnAErXqNzU4tsc6RdFI5wDUJ1tWE3DBuhv4o6rTP/B/R1/zuHawJbcRTM+QqQpMqkFaztJ+XDTS6hO2KY+K8V7RKesfUsjPqM4L1MdTlGRJv9MoFIhD6NCK+1f8hG6znRzmCtwTVXh7+qsAFDnVtf+qlGZL0FmjOqWS6jvs0xJN/nGcRnedsaFhmWtmCsHY6KGfkCS/Afhlk2JvQd//1MjevIFYyqhojS0D1gQY4b9wguFq0wnOAr389JWmQ+aZ/fphvPgp9tA9Nj+s5RmIYAjhGEVDVfgwseIBmTKpSUKufDOa8SqPw4g== X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: a709c358-2a52-4c43-1feb-08dacca2bdad X-MS-Exchange-CrossTenant-AuthSource: MWHPR10MB1407.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Nov 2022 16:00:58.3790 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: PLNuWG6kTnq7IYFdAandb8b672FLmX9tyA7A18eKwN3Ck3pF7BAh/9DMyp3jMqXfvD50n+Sv+QnVbtKtc7hdt1Ym1G8C+g0kqwBsfkfcQjQ= X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH2PR10MB4277 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.219,Aquarius:18.0.895,Hydra:6.0.545,FMLib:17.11.122.1 definitions=2022-11-22_09,2022-11-18_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 malwarescore=0 phishscore=0 adultscore=0 suspectscore=0 spamscore=0 mlxlogscore=999 mlxscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2210170000 definitions=main-2211220121 X-Proofpoint-GUID: Y1L-6gad3lbixBFMxaXEMB_-Cbc873Kq X-Proofpoint-ORIG-GUID: Y1L-6gad3lbixBFMxaXEMB_-Cbc873Kq X-Spam-Status: No, score=-12.7 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,SPF_NONE,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: This patch-v4 to implement the fallback behaviour for CTF/DWARF front-ends. Changes from v3: * Add missing test inputs: tests/data/test-read-{ctf,dwarf}/test-fallback.o Please let me know your thoughts, they will be really appreciated!. Thanks in advanced, guillermo -- By default, `abidw', `abidiff', `abipkgdiff' and `kmidiff' tools use debug information in `DWARF` format, if present, otherwise now automatically the tools try to extract and build the IR using debug information in `CTF` format without use of `--ctf' option, if present, finally, if neither is found, they use only `ELF` symbols to extract, build, compare and report the binary IR. To force the use of CTF front-end the `--ctf' option should be pass to command line. It works for libraries and Linux kernel. The `--ctf' option is preserved to explicitly indicate to those tools that we want to use CTF support. By other hand, if tools use `--ctf' but binary doesn't have CTF debug information it looks for DWARF automatically. * doc/manuals/abidiff.rst: Adjust usage tool information to indicates fallback for CTF debug info when DWARF info is not present. * doc/manuals/abidw.rst: Likewise. * doc/manuals/abipkgdiff.rst: Likewise. * doc/manuals/kmidiff.rst: Likewise. * include/abg-elf-based-reader.h (initialize): Add member function. * include/abg-elf-reader.h (has_{dwarf,ctf}_debug_info): Add predicate functions. * include/abg-tools-utils.h (create_best_elf_based_reader): Add arguments. * src/abg-ctf-reader.cc (process_ctf_typedef, process_ctf_base_type) (process_ctf_function_type, process_ctf_sou_members, process_ctf_forward_type) (process_ctf_struct_type, process_ctf_union_type, process_ctf_array_type) (process_ctf_qualified_type, process_ctf_pointer_type, process_ctf_enum_type): Remove arguments. Using getters to access required information instead. (reader::cur_tu_): Add data member. (initialize): Add arguments. (cur_transl_unit): Add {get,set)ter. (slurp_elf_info): Clear `STATUS_DEBUG_INFO_NOT_FOUND' if corpus is `LINUX_KERNEL_BINARY_ORIGIN'. (reader::lookup_type): Remove. (reader::build_type): New member function. * src/abg-elf-reader.cc (reader::reader): Locate ctf debug info from binary file. (reader::reader): Reset base `fe_iface' constructor. (reader::has_{dwarf,ctf}_debug_info): New definitions. (reader::read_corpus): Set `STATUS_DEBUG_INFO_NOT_FOUND' according to corpus::origin. * src/abg-tools-utils.cc (dir_contains_ctf_archive): Define new member. (file_has_ctf_debug_info): Looks for kernel ctf debug information archive. (maybe_load_vmlinux_{dwarf,ctf}_corpus): Remove. (load_vmlinux_corpus): Define function to load IR from kernel regardless the corpus::origin. (build_corpus_group_from_kernel_dist_under): Make use of `create_best_elf_based_reader' to select the front-end. (create_best_elf_based_reader): Adjust to allow fallback behaviour for different front-ends. * tests/data/Makefile.am: Add tests. * tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt: Adjust. * tests/data/test-read-ctf/test-fallback.abi: New test case. * tests/data/test-read-ctf/test-fallback.c: Likewise. * tests/data/test-read-ctf/test-fallback.o: Likewise. * tests/data/test-read-dwarf/test-fallback.abi: Likewise. * tests/data/test-read-dwarf/test-fallback.c: Likewise. * tests/data/test-read-dwarf/test-fallback.o: Likewise. * tests/test-diff-pkg.cc: Adjust. * tests/test-read-common.cc (test_task::run_abidw): Use of `options:option' field. * tests/test-read-common.h (InOutSpec): Add new member. * tests/test-read-ctf.cc (in_out_specs): Add option field to test suite. Add new test case. * tests/test-read-dwarf.cc: Likewise. * tools/abidiff.cc (main): Use `create_best_elf_based_reader'. * tools/abidw.cc: Likewise. * tools/abipkgdiff.cc: Likewise. Signed-off-by: Guillermo E. Martinez --- doc/manuals/abidiff.rst | 15 +- doc/manuals/abidw.rst | 15 +- doc/manuals/abipkgdiff.rst | 13 +- doc/manuals/kmidiff.rst | 9 +- include/abg-elf-based-reader.h | 5 + include/abg-elf-reader.h | 6 + include/abg-tools-utils.h | 5 +- src/abg-ctf-reader.cc | 267 +++++++---------- src/abg-elf-reader.cc | 29 +- src/abg-tools-utils.cc | 281 +++++++++--------- tests/data/Makefile.am | 6 + .../test-diff-pkg-ctf/dirpkg-3-report-2.txt | 16 + tests/data/test-read-ctf/test-fallback.abi | 9 + tests/data/test-read-ctf/test-fallback.c | 8 + tests/data/test-read-ctf/test-fallback.o | Bin 0 -> 1216 bytes tests/data/test-read-dwarf/test-fallback.abi | 9 + tests/data/test-read-dwarf/test-fallback.c | 8 + tests/data/test-read-dwarf/test-fallback.o | Bin 0 -> 2424 bytes tests/test-diff-pkg.cc | 2 +- tests/test-read-common.cc | 5 +- tests/test-read-common.h | 1 + tests/test-read-ctf.cc | 93 ++++-- tests/test-read-dwarf.cc | 121 ++++++-- tools/abidiff.cc | 44 ++- tools/abidw.cc | 26 +- tools/abipkgdiff.cc | 43 ++- 26 files changed, 606 insertions(+), 430 deletions(-) create mode 100644 tests/data/test-read-ctf/test-fallback.abi create mode 100644 tests/data/test-read-ctf/test-fallback.c create mode 100644 tests/data/test-read-ctf/test-fallback.o create mode 100644 tests/data/test-read-dwarf/test-fallback.abi create mode 100644 tests/data/test-read-dwarf/test-fallback.c create mode 100644 tests/data/test-read-dwarf/test-fallback.o diff --git a/doc/manuals/abidiff.rst b/doc/manuals/abidiff.rst index c728b373..a8878d2c 100644 --- a/doc/manuals/abidiff.rst +++ b/doc/manuals/abidiff.rst @@ -12,11 +12,12 @@ This tool can also compare the textual representations of the ABI of two ELF binaries (as emitted by ``abidw``) or an ELF binary against a textual representation of another ELF binary. -For a comprehensive ABI change report that includes changes about -function and variable sub-types, the two input shared libraries must -be accompanied with their debug information in `DWARF`_ format. -Otherwise, only `ELF`_ symbols that were added or removed are -reported. +For a comprehensive ABI change report between two input shared +libraries that includes changes about function and variable sub-types, +``abidiff`` uses by default, debug information in `DWARF`_ format, if +present, otherwise it compares interfaces using debug information in +`CTF`_ format, if present, finally, if neither is found, it uses only +`ELF`_ symbols to report which of them were added or removed. .. include:: tools-use-libabigail.txt @@ -581,7 +582,7 @@ Options * ``--ctf`` - When comparing binaries, extract ABI information from CTF debug + When comparing binaries, extract ABI information from `CTF`_ debug information, if present. * ``--stats`` @@ -808,4 +809,4 @@ Usage examples .. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format .. _DWARF: http://www.dwarfstd.org - +.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/ctf-spec.pdf diff --git a/doc/manuals/abidw.rst b/doc/manuals/abidw.rst index a3055c7e..20948805 100644 --- a/doc/manuals/abidw.rst +++ b/doc/manuals/abidw.rst @@ -8,8 +8,7 @@ representation of its ABI to standard output. The emitted representation format, named ``ABIXML``, includes all the globally defined functions and variables, along with a complete representation of their types. It also includes a representation of the globally -defined ELF symbols of the file. The input shared library must -contain associated debug information in `DWARF`_ format. +defined ELF symbols of the file. When given the ``--linux-tree`` option, this program can also handle a `Linux kernel`_ tree. That is, a directory tree that contains both @@ -19,8 +18,13 @@ interface between the kernel and its module, to standard output. In this case, we don't call it an ABI, but a KMI (Kernel Module Interface). The emitted KMI includes all the globally defined functions and variables, along with a complete representation of their -types. The input binaries must contain associated debug information -in `DWARF`_ format. +types. + +To generate either ABI or KMI representation, by default ``abidw`` +uses debug information in `DWARF`_ format, if present, otherwise it +looks for debug information in `CTF`_ format, if present, finally, if +neither is found, it uses only `ELF`_ symbols to report which of them +were added or removed. .. include:: tools-use-libabigail.txt @@ -326,7 +330,7 @@ Options * ``--ctf`` - Extract ABI information from CTF debug information, if present in + Extract ABI information from `CTF`_ debug information, if present in the given object. * ``--annotate`` @@ -365,3 +369,4 @@ standard `here .. _DWARF: http://www.dwarfstd.org .. _GNU: http://www.gnu.org .. _Linux Kernel: https://kernel.org/ +.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/ctf-spec.pdf diff --git a/doc/manuals/abipkgdiff.rst b/doc/manuals/abipkgdiff.rst index 9114775a..771bb034 100644 --- a/doc/manuals/abipkgdiff.rst +++ b/doc/manuals/abipkgdiff.rst @@ -13,12 +13,18 @@ binaries. For a comprehensive ABI change report that includes changes about function and variable sub-types, the two input packages must be accompanied with their debug information packages that contain debug -information either in `DWARF`_ or in `CTF` formats. Please note +information either in `DWARF`_ or in `CTF`_ formats. Please note however that some packages contain binaries that embed the debug information directly in a section of said binaries. In those cases, obviously, no separate debug information package is needed as the tool will find the debug information inside the binaries. +By default, ``abipkgdiff`` uses debug information in `DWARF`_ format, +if present, otherwise it compares binaries interfaces using debug +information in `CTF`_ format, if present, finally, if neither is +found, it uses only `ELF`_ symbols to report which of them were added +or removed. + .. include:: tools-use-libabigail.txt .. _abipkgdiff_invocation_label: @@ -525,8 +531,8 @@ Options * ``--ctf`` - This is used to compare packages with CTF debug information, if - present. + This is used to compare packages with `CTF`_ debug information, + if present. .. _abipkgdiff_return_value_label: @@ -546,4 +552,5 @@ In the later case, the value of the exit code is the same as for the .. _Deb: https://en.wikipedia.org/wiki/Deb_%28file_format%29 .. _tar: https://en.wikipedia.org/wiki/Tar_%28computing%29 .. _DWARF: http://www.dwarfstd.org +.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/ctf-spec.pdf .. _Development Package: https://fedoraproject.org/wiki/Packaging:Guidelines?rd=Packaging/Guidelines#Devel_Packages diff --git a/doc/manuals/kmidiff.rst b/doc/manuals/kmidiff.rst index 53010189..a27d2456 100644 --- a/doc/manuals/kmidiff.rst +++ b/doc/manuals/kmidiff.rst @@ -74,6 +74,11 @@ functions and variables) between the Kernel and its modules. In practice, though, some users might want to compare a subset of the those interfaces. +By default, ``kmidiff`` uses debug information in `DWARF`_ format, +if present, otherwise it compares interfaces using debug information +in `CTF`_ format, if present, finally, if neither is found, it uses +only `ELF`_ symbols to report which were added or removed. + Users can then define a "white list" of the interfaces to compare. Such a white list is a just a file in the "INI" format that looks like: :: @@ -174,7 +179,7 @@ Options * ``--ctf`` - Extract ABI information from CTF debug information, if present in + Extract ABI information from `CTF`_ debug information, if present in the Kernel and Modules. * ``--impacted-interfaces | -i`` @@ -242,3 +247,5 @@ Options .. _ELF: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format .. _ksymtab: http://en.wikipedia.org/wiki/Executable_and_Linkable_Format .. _Linux Kernel: https://kernel.org +.. _DWARF: http://www.dwarfstd.org +.. _CTF: https://raw.githubusercontent.com/wiki/oracle/binutils-gdb/files/ctf-spec.pdf diff --git a/include/abg-elf-based-reader.h b/include/abg-elf-based-reader.h index cf0c719e..4fae055e 100644 --- a/include/abg-elf-based-reader.h +++ b/include/abg-elf-based-reader.h @@ -56,6 +56,11 @@ public: virtual ir::corpus_sptr read_and_add_corpus_to_group(ir::corpus_group& group, fe_iface::status& status); + virtual void + initialize(const string& elf_path, + const vector& debug_info_root_paths, + bool load_all_types, + bool linux_kernel_mode) = 0; };//end class elf_based_reader typedef std::shared_ptr elf_based_reader_sptr; diff --git a/include/abg-elf-reader.h b/include/abg-elf-reader.h index 86999ac1..42897a92 100644 --- a/include/abg-elf-reader.h +++ b/include/abg-elf-reader.h @@ -91,6 +91,12 @@ class reader : public fe_iface const Dwarf* dwarf_debug_info() const; + bool + has_dwarf_debug_info() const; + + bool + has_ctf_debug_info() const; + const Dwarf* alternate_dwarf_debug_info() const; diff --git a/include/abg-tools-utils.h b/include/abg-tools-utils.h index 9dc9b8d3..13d6ad75 100644 --- a/include/abg-tools-utils.h +++ b/include/abg-tools-utils.h @@ -322,7 +322,10 @@ build_corpus_group_from_kernel_dist_under(const string& root, elf_based_reader_sptr create_best_elf_based_reader(const string& elf_file_path, const vector& debug_info_root_paths, - environment& env); + environment& env, + bool use_ctf, + bool show_all_types, + bool linux_kernel_mode = false); }// end namespace tools_utils diff --git a/src/abg-ctf-reader.cc b/src/abg-ctf-reader.cc index 5fde94f3..fdefd3a6 100644 --- a/src/abg-ctf-reader.cc +++ b/src/abg-ctf-reader.cc @@ -51,15 +51,11 @@ class reader; static typedef_decl_sptr process_ctf_typedef(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); static type_decl_sptr process_ctf_base_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); @@ -69,63 +65,47 @@ build_ir_node_for_variadic_parameter_type(reader &rdr, static function_type_sptr process_ctf_function_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); static void process_ctf_sou_members(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type, class_or_union_sptr sou); static type_base_sptr process_ctf_forward_type(reader *rdr, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); static class_decl_sptr process_ctf_struct_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); static union_decl_sptr process_ctf_union_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); static array_type_def_sptr process_ctf_array_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); static type_base_sptr process_ctf_qualified_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); static pointer_type_def_sptr process_ctf_pointer_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); static enum_type_decl_sptr process_ctf_enum_type(reader *rdr, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type); @@ -161,6 +141,7 @@ class reader : public elf_based_reader ctf_sect_t ctf_sect; ctf_sect_t symtab_sect; ctf_sect_t strtab_sect; + translation_unit_sptr cur_tu_; public: @@ -263,17 +244,21 @@ public: { ctfa = nullptr; types_map.clear(); + cur_tu_.reset(); corpus_group().reset(); } /// Initializer of the reader. /// - /// /// @param elf_path the new path to the new ELF file to use. /// /// @param debug_info_root_paths a vector of paths to use to look /// for debug info that is split out into a separate file. /// + /// @param load_all_types currently not used. + /// + /// @param linux_kernel_mode currently not used. + /// /// This is useful to clear out the data used by the reader and get /// it ready to be used again. /// @@ -286,11 +271,32 @@ public: /// the environment. void initialize(const string& elf_path, - const vector& debug_info_root_paths) + const vector& debug_info_root_paths, + bool load_all_types = false, + bool linux_kernel_mode = false) { + load_all_types = load_all_types; + linux_kernel_mode = linux_kernel_mode; reset(elf_path, debug_info_root_paths); } + /// Setter of the current translation unit. + /// + /// @param tu the current translation unit being constructed. + void + cur_transl_unit(translation_unit_sptr tu) + { + if (tu) + cur_tu_ = tu; + } + + /// Getter of the current translation unit. + /// + /// @return the current translation unit being constructed. + const translation_unit_sptr& + cur_transl_unit() const + {return cur_tu_;} + /// Getter of the environment of the current CTF reader. /// /// @return the environment of the current CTF reader. @@ -349,27 +355,24 @@ public: // Read the ELF-specific parts of the corpus. elf::reader::read_corpus(status); - if ((status & STATUS_NO_SYMBOLS_FOUND) - || !(status & STATUS_OK)) - // Either we couldn't find ELF symbols or something went badly - // wrong. There is nothing we can do with this ELF file. Bail - // out. - return; - corpus_sptr corp = corpus(); if ((corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN) && corpus_group()) { - status |= fe_iface::STATUS_OK; + // Is expected not find debug information when we're building + // a kABI. + status &= static_cast + (~STATUS_DEBUG_INFO_NOT_FOUND); return; } - /* Get the raw ELF section contents for libctf. */ - if (!find_ctf_section()) - { - status |= fe_iface::STATUS_DEBUG_INFO_NOT_FOUND; - return; - } + if ((status & (STATUS_NO_SYMBOLS_FOUND | + STATUS_DEBUG_INFO_NOT_FOUND)) + || !(status & STATUS_OK)) + // Either we couldn't find ELF symbols or something went badly + // wrong. There is nothing we can do with this ELF file. Bail + // out. + return; GElf_Ehdr *ehdr, eh_mem; if (!(ehdr = gelf_getehdr(elf_handle(), &eh_mem))) @@ -402,16 +405,16 @@ public: /// Process a CTF archive and create libabigail IR for the types, /// variables and function declarations found in the archive, iterating /// over public symbols. The IR is added to the given corpus. - /// - /// @param corp the IR corpus to which add the new contents. void - process_ctf_archive(corpus_sptr corp) + process_ctf_archive() { + corpus_sptr corp = corpus(); /* We only have a translation unit. */ translation_unit_sptr ir_translation_unit = std::make_shared(env(), "", 64); ir_translation_unit->set_language(translation_unit::LANG_C); corp->add(ir_translation_unit); + cur_transl_unit(ir_translation_unit); int ctf_err; ctf_dict_t *ctf_dict, *dict_tmp; @@ -455,8 +458,7 @@ public: if (ctf_type_kind(ctf_dict, ctf_sym_type) != CTF_K_FUNCTION) { const char *var_name = sym_name.c_str(); - type_base_sptr var_type = lookup_type(corp, ir_translation_unit, - ctf_dict, ctf_sym_type); + type_base_sptr var_type = build_type(ctf_dict, ctf_sym_type); if (!var_type) /* Ignore variable if its type can't be sorted out. */ continue; @@ -477,8 +479,7 @@ public: { const char *func_name = sym_name.c_str(); ctf_id_t ctf_sym = ctf_sym_type; - type_base_sptr func_type = lookup_type(corp, ir_translation_unit, - ctf_dict, ctf_sym); + type_base_sptr func_type = build_type(ctf_dict, ctf_sym); if (!func_type) /* Ignore function if its type can't be sorted out. */ continue; @@ -508,8 +509,6 @@ public: /// Add a new type declaration to the given libabigail IR corpus CORP. /// - /// @param corp the libabigail IR corpus being constructed. - /// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -518,11 +517,11 @@ public: /// /// @return a shared pointer to the IR node for the type. type_base_sptr - process_ctf_type(corpus_sptr corp, - translation_unit_sptr tunit, - ctf_dict_t *ctf_dictionary, + process_ctf_type(ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp = corpus(); + translation_unit_sptr tunit = cur_transl_unit(); int type_kind = ctf_type_kind(ctf_dictionary, ctf_type); type_base_sptr result; @@ -538,21 +537,21 @@ public: case CTF_K_FLOAT: { type_decl_sptr type_decl - = process_ctf_base_type(this, corp, tunit, ctf_dictionary, ctf_type); + = process_ctf_base_type(this, ctf_dictionary, ctf_type); result = is_type(type_decl); break; } case CTF_K_TYPEDEF: { typedef_decl_sptr typedef_decl - = process_ctf_typedef(this, corp, tunit, ctf_dictionary, ctf_type); + = process_ctf_typedef(this, ctf_dictionary, ctf_type); result = is_type(typedef_decl); break; } case CTF_K_POINTER: { pointer_type_def_sptr pointer_type - = process_ctf_pointer_type(this, corp, tunit, ctf_dictionary, ctf_type); + = process_ctf_pointer_type(this, ctf_dictionary, ctf_type); result = pointer_type; break; } @@ -561,49 +560,45 @@ public: case CTF_K_RESTRICT: { type_base_sptr qualified_type - = process_ctf_qualified_type(this, corp, tunit, ctf_dictionary, ctf_type); + = process_ctf_qualified_type(this, ctf_dictionary, ctf_type); result = qualified_type; break; } case CTF_K_ARRAY: { array_type_def_sptr array_type - = process_ctf_array_type(this, corp, tunit, ctf_dictionary, ctf_type); + = process_ctf_array_type(this, ctf_dictionary, ctf_type); result = array_type; break; } case CTF_K_ENUM: { enum_type_decl_sptr enum_type - = process_ctf_enum_type(this, tunit, ctf_dictionary, ctf_type); + = process_ctf_enum_type(this, ctf_dictionary, ctf_type); result = enum_type; break; } case CTF_K_FUNCTION: { function_type_sptr function_type - = process_ctf_function_type(this, corp, tunit, ctf_dictionary, ctf_type); + = process_ctf_function_type(this, ctf_dictionary, ctf_type); result = function_type; break; } case CTF_K_STRUCT: { class_decl_sptr struct_decl - = process_ctf_struct_type(this, corp, tunit, ctf_dictionary, ctf_type); + = process_ctf_struct_type(this, ctf_dictionary, ctf_type); result = is_type(struct_decl); break; } case CTF_K_FORWARD: - { - result = process_ctf_forward_type(this, tunit, - ctf_dictionary, - ctf_type); - } + result = process_ctf_forward_type(this, ctf_dictionary, ctf_type); break; case CTF_K_UNION: { union_decl_sptr union_decl - = process_ctf_union_type(this, corp, tunit, ctf_dictionary, ctf_type); + = process_ctf_union_type(this, ctf_dictionary, ctf_type); result = is_type(union_decl); break; } @@ -622,11 +617,10 @@ public: return result; } - /// Given a CTF type id, lookup the corresponding libabigail IR type. - /// If the IR type hasn't been generated yet, generate it. + /// Given a CTF type id, build the corresponding libabigail IR type. + /// If the IR type has been generated it returns the corresponding + /// type. /// - /// @param corp the libabigail IR corpus being constructed. - /// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the looked type. /// @@ -635,14 +629,12 @@ public: /// /// @return a shared pointer to the IR node for the type. type_base_sptr - lookup_type(corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, - ctf_id_t ctf_type) + build_type(ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { type_base_sptr result = lookup_type(ctf_dictionary, ctf_type); if (!result) - result = process_ctf_type(corp, tunit, ctf_dictionary, ctf_type); + result = process_ctf_type(ctf_dictionary, ctf_type); return result; } @@ -664,13 +656,12 @@ public: origin |= corpus::CTF_ORIGIN; corp->set_origin(origin); - if (corpus_group()) - corpus_group()->add_corpus(corpus()); - slurp_elf_info(status); - if (!elf_helpers::is_linux_kernel(elf_handle()) - && ((status & fe_iface::STATUS_DEBUG_INFO_NOT_FOUND) | - (status & fe_iface::STATUS_NO_SYMBOLS_FOUND))) + if (status & fe_iface::STATUS_NO_SYMBOLS_FOUND) + return corpus_sptr(); + + if (!(origin & corpus::LINUX_KERNEL_BINARY_ORIGIN) + && (status & fe_iface::STATUS_DEBUG_INFO_NOT_FOUND)) return corp; int errp; @@ -697,7 +688,7 @@ public: status |= fe_iface::STATUS_DEBUG_INFO_NOT_FOUND; else { - process_ctf_archive(corp); + process_ctf_archive(); corpus()->sort_functions(); corpus()->sort_variables(); } @@ -719,8 +710,6 @@ typedef shared_ptr reader_sptr; /// Build and return a typedef libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -728,11 +717,11 @@ typedef shared_ptr reader_sptr; static typedef_decl_sptr process_ctf_typedef(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp = rdr->corpus(); + translation_unit_sptr tunit = rdr->cur_transl_unit(); typedef_decl_sptr result; ctf_id_t ctf_utype = ctf_type_reference(ctf_dictionary, ctf_type); @@ -744,14 +733,13 @@ process_ctf_typedef(reader *rdr, if (result = lookup_typedef_type(typedef_name, *corp)) return result; - type_base_sptr utype = rdr->lookup_type(corp, tunit, - ctf_dictionary, ctf_utype); + type_base_sptr utype = rdr->build_type(ctf_dictionary, ctf_utype); if (!utype) return result; - result = dynamic_pointer_cast(rdr->lookup_type(ctf_dictionary, - ctf_type)); + result = dynamic_pointer_cast + (rdr->lookup_type(ctf_dictionary, ctf_type)); if (result) return result; @@ -782,7 +770,6 @@ process_ctf_typedef(reader *rdr, /// IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -790,11 +777,11 @@ process_ctf_typedef(reader *rdr, static type_decl_sptr process_ctf_base_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp = rdr->corpus(); + translation_unit_sptr tunit = rdr->cur_transl_unit(); type_decl_sptr result; ssize_t type_alignment = ctf_type_align(ctf_dictionary, ctf_type); @@ -873,8 +860,6 @@ build_ir_node_for_variadic_parameter_type(reader &rdr, /// Build and return a function type libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -882,11 +867,11 @@ build_ir_node_for_variadic_parameter_type(reader &rdr, static function_type_sptr process_ctf_function_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp = rdr->corpus(); + translation_unit_sptr tunit = rdr->cur_transl_unit(); function_type_sptr result; /* Fetch the function type info from the CTF type. */ @@ -896,8 +881,7 @@ process_ctf_function_type(reader *rdr, /* Take care first of the result type. */ ctf_id_t ctf_ret_type = funcinfo.ctc_return; - type_base_sptr ret_type = rdr->lookup_type(corp, tunit, - ctf_dictionary, ctf_ret_type); + type_base_sptr ret_type = rdr->build_type(ctf_dictionary, ctf_ret_type); if (!ret_type) return result; @@ -912,8 +896,7 @@ process_ctf_function_type(reader *rdr, for (int i = 0; i < argc; i++) { ctf_id_t ctf_arg_type = argv[i]; - type_base_sptr arg_type = rdr->lookup_type(corp, tunit, - ctf_dictionary, ctf_arg_type); + type_base_sptr arg_type = rdr->build_type(ctf_dictionary, ctf_arg_type); if (!arg_type) return result; @@ -938,8 +921,8 @@ process_ctf_function_type(reader *rdr, function_parms.push_back(parm); } - result = dynamic_pointer_cast(rdr->lookup_type(ctf_dictionary, - ctf_type)); + result = dynamic_pointer_cast + (rdr->lookup_type(ctf_dictionary, ctf_type)); if (result) return result; @@ -964,20 +947,18 @@ process_ctf_function_type(reader *rdr, /// Add member information to a IR struct or union type. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @param sou the IR struct or union type to which add the members. static void process_ctf_sou_members(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type, class_or_union_sptr sou) { + corpus_sptr corp = rdr->corpus(); + translation_unit_sptr tunit = rdr->cur_transl_unit(); ssize_t member_size; ctf_next_t *member_next = NULL; const char *member_name = NULL; @@ -997,9 +978,8 @@ process_ctf_sou_members(reader *rdr, return; /* Build the IR for the member's type. */ - type_base_sptr member_type = rdr->lookup_type(corp, tunit, - ctf_dictionary, - member_ctf_type); + type_base_sptr member_type = rdr->build_type(ctf_dictionary, + member_ctf_type); if (!member_type) /* Ignore this member. */ continue; @@ -1024,17 +1004,16 @@ process_ctf_sou_members(reader *rdr, /// IR. /// /// @param rdr the read context. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @return the resulting IR node created. static type_base_sptr process_ctf_forward_type(reader *rdr, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + translation_unit_sptr tunit = rdr->cur_transl_unit(); decl_base_sptr result; std::string type_name = ctf_type_name_raw(ctf_dictionary, ctf_type); @@ -1083,8 +1062,6 @@ process_ctf_forward_type(reader *rdr, /// Build and return a struct type libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -1092,11 +1069,11 @@ process_ctf_forward_type(reader *rdr, static class_decl_sptr process_ctf_struct_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp = rdr->corpus(); + translation_unit_sptr tunit = rdr->cur_transl_unit(); class_decl_sptr result; std::string struct_type_name = ctf_type_name_raw(ctf_dictionary, ctf_type); @@ -1130,8 +1107,7 @@ process_ctf_struct_type(reader *rdr, /* Now add the struct members as specified in the CTF type description. This is C, so named types can only be defined in the global scope. */ - process_ctf_sou_members(rdr, corp, tunit, ctf_dictionary, ctf_type, - result); + process_ctf_sou_members(rdr, ctf_dictionary, ctf_type, result); return result; } @@ -1139,8 +1115,6 @@ process_ctf_struct_type(reader *rdr, /// Build and return an union type libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -1148,11 +1122,11 @@ process_ctf_struct_type(reader *rdr, static union_decl_sptr process_ctf_union_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp = rdr->corpus(); + translation_unit_sptr tunit = rdr->cur_transl_unit(); union_decl_sptr result; std::string union_type_name = ctf_type_name_raw(ctf_dictionary, ctf_type); @@ -1184,8 +1158,7 @@ process_ctf_union_type(reader *rdr, /* Now add the union members as specified in the CTF type description. This is C, so named types can only be defined in the global scope. */ - process_ctf_sou_members(rdr, corp, tunit, ctf_dictionary, ctf_type, - result); + process_ctf_sou_members(rdr, ctf_dictionary, ctf_type, result); return result; } @@ -1193,20 +1166,19 @@ process_ctf_union_type(reader *rdr, /// Build and return an array type libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. +/// /// @param ctf_dictionary the CTF dictionary being read. +/// /// @param ctf_type the CTF type ID of the source type. /// /// @return a shared pointer to the IR node for the array type. - static array_type_def_sptr process_ctf_array_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp = rdr->corpus(); + translation_unit_sptr tunit = rdr->cur_transl_unit(); array_type_def_sptr result; ctf_arinfo_t ctf_ainfo; bool is_infinite = false; @@ -1222,21 +1194,19 @@ process_ctf_array_type(reader *rdr, uint64_t nelems = ctf_ainfo.ctr_nelems; /* Make sure the element type is generated. */ - type_base_sptr element_type = rdr->lookup_type(corp, tunit, - ctf_dictionary, - ctf_element_type); + type_base_sptr element_type = rdr->build_type(ctf_dictionary, + ctf_element_type); if (!element_type) return result; /* Ditto for the index type. */ - type_base_sptr index_type = rdr->lookup_type(corp, tunit, - ctf_dictionary, - ctf_index_type); + type_base_sptr index_type = rdr->build_type(ctf_dictionary, + ctf_index_type); if (!index_type) return result; - result = dynamic_pointer_cast(rdr->lookup_type(ctf_dictionary, - ctf_type)); + result = dynamic_pointer_cast + (rdr->lookup_type(ctf_dictionary, ctf_type)); if (result) return result; @@ -1284,28 +1254,25 @@ process_ctf_array_type(reader *rdr, /// Build and return a qualified type libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. static type_base_sptr process_ctf_qualified_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp = rdr->corpus(); + translation_unit_sptr tunit = rdr->cur_transl_unit(); type_base_sptr result; int type_kind = ctf_type_kind(ctf_dictionary, ctf_type); ctf_id_t ctf_utype = ctf_type_reference(ctf_dictionary, ctf_type); - type_base_sptr utype = rdr->lookup_type(corp, tunit, - ctf_dictionary, ctf_utype); + type_base_sptr utype = rdr->build_type(ctf_dictionary, ctf_utype); if (!utype) return result; - result = dynamic_pointer_cast(rdr->lookup_type(ctf_dictionary, - ctf_type)); + result = dynamic_pointer_cast + (rdr->lookup_type(ctf_dictionary, ctf_type)); if (result) return result; @@ -1337,8 +1304,6 @@ process_ctf_qualified_type(reader *rdr, /// Build and return a pointer type libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -1346,24 +1311,23 @@ process_ctf_qualified_type(reader *rdr, static pointer_type_def_sptr process_ctf_pointer_type(reader *rdr, - corpus_sptr corp, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + corpus_sptr corp = rdr->corpus(); + translation_unit_sptr tunit = rdr->cur_transl_unit(); pointer_type_def_sptr result; ctf_id_t ctf_target_type = ctf_type_reference(ctf_dictionary, ctf_type); if (ctf_target_type == CTF_ERR) return result; - type_base_sptr target_type = rdr->lookup_type(corp, tunit, - ctf_dictionary, - ctf_target_type); + type_base_sptr target_type = rdr->build_type(ctf_dictionary, + ctf_target_type); if (!target_type) return result; - result = dynamic_pointer_cast(rdr->lookup_type(ctf_dictionary, - ctf_type)); + result = dynamic_pointer_cast + (rdr->lookup_type(ctf_dictionary, ctf_type)); if (result) return result; @@ -1383,8 +1347,6 @@ process_ctf_pointer_type(reader *rdr, /// Build and return an enum type libabigail IR. /// /// @param rdr the read context. -/// @param corp the libabigail IR corpus being constructed. -/// @param tunit the current IR translation unit. /// @param ctf_dictionary the CTF dictionary being read. /// @param ctf_type the CTF type ID of the source type. /// @@ -1392,10 +1354,10 @@ process_ctf_pointer_type(reader *rdr, static enum_type_decl_sptr process_ctf_enum_type(reader *rdr, - translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { + translation_unit_sptr tunit = rdr->cur_transl_unit(); enum_type_decl_sptr result; std::string enum_name = ctf_type_name_raw(ctf_dictionary, ctf_type); @@ -1430,6 +1392,7 @@ process_ctf_enum_type(reader *rdr, while ((ename = ctf_enum_next(ctf_dictionary, ctf_type, &enum_next, &evalue))) enms.push_back(enum_type_decl::enumerator(ename, evalue)); + if (ctf_errno(ctf_dictionary) != ECTF_NEXT_END) { fprintf(stderr, "ERROR from ctf_enum_next\n"); diff --git a/src/abg-elf-reader.cc b/src/abg-elf-reader.cc index eedeaf8e..3f191bda 100644 --- a/src/abg-elf-reader.cc +++ b/src/abg-elf-reader.cc @@ -459,6 +459,7 @@ reader::reader(const string& elf_path, { priv_->crack_open_elf_file(); priv_->locate_dwarf_debug_info(); + priv_->locate_ctf_debug_info(); } /// The destructor of the @ref elf::reader type. @@ -479,10 +480,13 @@ void reader::reset(const std::string& elf_path, const vector& debug_info_roots) { + fe_iface::options_type opts = options(); + fe_iface::reset(elf_path, opts.env); corpus_path(elf_path); priv_->initialize(debug_info_roots); priv_->crack_open_elf_file(); priv_->locate_dwarf_debug_info(); + priv_->locate_ctf_debug_info(); } /// Getter of the vector of directory paths to look into for split @@ -528,6 +532,15 @@ const Dwarf* reader::dwarf_debug_info() const {return priv_->dwarf_handle;} +bool +reader::has_dwarf_debug_info() const +{return ((priv_->dwarf_handle != nullptr) + || (priv_->alt_dwarf_handle != nullptr));} + +bool +reader::has_ctf_debug_info() const +{return (priv_->ctf_section != nullptr);} + /// Getter of the handle use to access DWARF information from the /// alternate split DWARF information. /// @@ -873,13 +886,15 @@ reader::read_corpus(status& status) corpus()->set_symtab(symtab()); // If we couldn't load debug info from the elf path, then say it. - if (dwarf_debug_info() == nullptr - && find_ctf_section() == nullptr) - status |= STATUS_DEBUG_INFO_NOT_FOUND; - - status |= STATUS_OK; - - return corpus(); + if ((origin & abigail::ir::corpus::DWARF_ORIGIN) + && !has_dwarf_debug_info()) + status |= STATUS_DEBUG_INFO_NOT_FOUND; + else if ((origin & abigail::ir::corpus::CTF_ORIGIN) + && !has_ctf_debug_info()) + status |= STATUS_DEBUG_INFO_NOT_FOUND; + + status |= STATUS_OK; + return corpus(); } /// Get the SONAME property of a designated ELF file. diff --git a/src/abg-tools-utils.cc b/src/abg-tools-utils.cc index 8898ef97..0a523b87 100644 --- a/src/abg-tools-utils.cc +++ b/src/abg-tools-utils.cc @@ -405,6 +405,23 @@ is_regular_file(const string& path) return false; } +/// Test if a directory contains a CTF archive. +/// +/// @param directory the directory to consider. +/// +/// @param archive_prefix the prefix of the archive file. +/// +/// @return true iff @p directory contains a CTF archive file. +bool +dir_contains_ctf_archive(const string& directory, + const string& archive_prefix) +{ + string ctf_archive = directory + "/" + archive_prefix + ".ctfa"; + if (file_exists(ctf_archive)) + return true; + return false; +} + /// Test if an ELF file has DWARF debug info. /// /// This function supports split debug info files as well. @@ -437,11 +454,29 @@ file_has_dwarf_debug_info(const string& elf_file_path, return false; } +/// Test if an ELF file has CTF debug info. +/// +/// This function supports split debug info files as well. +/// Linux Kernel with CTF debug information generates a CTF archive: +/// a special file containing debug information for vmlinux and its +/// modules (*.ko) files it is located by default in the Kernel build +/// directory as "vmlinux.ctfa". +/// +/// @param elf_file_path the path to the ELF file to consider. +/// +/// @param debug_info_root a vector of pointer to directory to look +/// for debug info, in case the file is associated to split debug +/// info. If there is no split debug info then this vector can be +/// empty. Note that convert_char_stars_to_char_star_stars() can be +/// used to ease the construction of this vector. +/// +/// @return true iff the ELF file at @elf_file_path is an ELF file +/// that contains debug info. bool file_has_ctf_debug_info(const string& elf_file_path, const vector& debug_info_root_paths) { - if (guess_file_type(elf_file_path) != FILE_TYPE_ELF) + if (guess_file_type(elf_file_path) != FILE_TYPE_ELF) return false; environment env; @@ -452,6 +487,20 @@ file_has_ctf_debug_info(const string& elf_file_path, if (r.find_ctf_section()) return true; + string vmlinux; + if (base_name(elf_file_path, vmlinux)) + { + string dirname; + if (dir_name(elf_file_path, dirname) + && dir_contains_ctf_archive(dirname, vmlinux)) + return true; + } + + // vmlinux.ctfa could be provided with --debug-info-dir + for (const auto& path : debug_info_root_paths) + if (dir_contains_ctf_archive(*path, vmlinux)) + return true; + return false; } @@ -2539,12 +2588,13 @@ get_binary_paths_from_kernel_dist(const string& dist_root, module_paths); } -/// If the @ref origin is DWARF_ORIGIN it build a @ref corpus_group -/// made of vmlinux kernel file and the linux kernel modules found -/// under @p root directory and under its sub-directories, recursively. +/// It builds a @ref corpus_group made of vmlinux kernel file and +/// the kernel modules found under @p root directory and under its +/// sub-directories, recursively. /// -/// @param origin the debug type information in vmlinux kernel and -/// the linux kernel modules to be used to build the corpora @p group. +/// @param rdr the raeder that should be used to extract the debug +/// infomation from the linux kernel and its modules used to build +/// the corpora @p group. /// /// @param the group @ref corpus_group to be built. /// @@ -2576,28 +2626,20 @@ get_binary_paths_from_kernel_dist(const string& dist_root, /// /// @param env the environment to create the corpus_group in. static void -maybe_load_vmlinux_dwarf_corpus(corpus::origin origin, - corpus_group_sptr& group, - const string& vmlinux, - vector& modules, - const string& root, - vector& di_roots, - vector& suppr_paths, - vector& kabi_wl_paths, - suppressions_type& supprs, - bool verbose, - timer& t, - environment& env) -{ - if (!(origin & corpus::DWARF_ORIGIN)) - return; - +load_vmlinux_corpus(elf_based_reader_sptr rdr, + corpus_group_sptr& group, + const string& vmlinux, + vector& modules, + const string& root, + vector& di_roots, + vector& suppr_paths, + vector& kabi_wl_paths, + suppressions_type& supprs, + bool verbose, + timer& t, + environment& env) +{ abigail::fe_iface::status status = abigail::fe_iface::STATUS_OK; - elf_based_reader_sptr rdr = - dwarf::create_reader(vmlinux, di_roots, env, - /*read_all_types=*/false, - /*linux_kernel_mode=*/true); - ABG_ASSERT(rdr); rdr->options().do_log = verbose; t.start(); @@ -2645,9 +2687,9 @@ maybe_load_vmlinux_dwarf_corpus(corpus::origin origin, << "/" << total_nb_modules << ") ... " << std::flush; - dwarf::reset_reader(*rdr, *m, di_roots, - /*read_all_types=*/false, - /*linux_kernel_mode=*/true); + rdr->initialize(*m, di_roots, + /*read_all_types=*/false, + /*linux_kernel_mode=*/true); load_generate_apply_suppressions(*rdr, suppr_paths, kabi_wl_paths, supprs); @@ -2665,101 +2707,6 @@ maybe_load_vmlinux_dwarf_corpus(corpus::origin origin, } } -/// If the @ref origin is CTF_ORIGIN it build a @ref corpus_group -/// made of vmlinux kernel file and the linux kernel modules found -/// under @p root directory and under its sub-directories, recursively. -/// -/// @param origin the debug type information in vmlinux kernel and -/// the linux kernel modules to be used to build the corpora @p group. -/// -/// @param group the @ref corpus_group to be built. -/// -/// @param vmlinux the path to the vmlinux binary. -/// -/// @param modules a vector with the paths to the linux kernel -/// modules. -/// -/// @param root the path of the directory under which the kernel -/// kernel modules were found. -/// -/// @param di_root the directory in aboslute path which debug -/// info is to be found for binaries under director @p root -/// -/// @param verbose true if the function has to emit some verbose -/// messages. -/// -/// @param t time to trace time spent in each step. -/// -/// @param env the environment to create the corpus_group in. -#ifdef WITH_CTF -static void -maybe_load_vmlinux_ctf_corpus(corpus::origin origin, - corpus_group_sptr& group, - const string& vmlinux, - vector& modules, - const string& root, - vector& di_roots, - bool verbose, - timer& t, - environment& env) -{ - if (!(origin & corpus::CTF_ORIGIN)) - return; - - abigail::fe_iface::status status = abigail::fe_iface::STATUS_OK; - elf_based_reader_sptr rdr = - ctf::create_reader(vmlinux, di_roots, env); - ABG_ASSERT(rdr); - - group.reset(new corpus_group(env, root)); - rdr->corpus_group(group); - - if (verbose) - std::cerr << "reading kernel binary '" - << vmlinux << "' ...\n" << std::flush; - - // Read the vmlinux corpus and add it to the group. - t.start(); - rdr->read_and_add_corpus_to_group(*group, status); - t.stop(); - - if (verbose) - std::cerr << vmlinux - << " reading DONE:" - << t << "\n"; - - if (group->is_empty()) - return; - - // Now add the corpora of the modules to the corpus group. - int total_nb_modules = modules.size(); - int cur_module_index = 1; - for (vector::const_iterator m = modules.begin(); - m != modules.end(); - ++m, ++cur_module_index) - { - if (verbose) - std::cerr << "reading module '" - << *m << "' (" - << cur_module_index - << "/" << total_nb_modules - << ") ... " << std::flush; - - ctf::reset_reader(*rdr, *m, di_roots); - rdr->corpus_group(group); - - t.start(); - rdr->read_and_add_corpus_to_group(*group, status); - t.stop(); - if (verbose) - std::cerr << "module '" - << *m - << "' reading DONE: " - << t << "\n"; - } -} -#endif - /// Walk a given directory and build an instance of @ref corpus_group /// from the vmlinux kernel binary and the linux kernel modules found /// under that directory and under its sub-directories, recursively. @@ -2836,15 +2783,22 @@ build_corpus_group_from_kernel_dist_under(const string& root, vector di_roots; di_roots.push_back(&di_root_ptr); - maybe_load_vmlinux_dwarf_corpus(origin, group, vmlinux, - modules, root, di_roots, - suppr_paths, kabi_wl_paths, - supprs, verbose, t, env); + abigail::elf_based_reader_sptr reader = + create_best_elf_based_reader(vmlinux, + di_roots, + env, #ifdef WITH_CTF - maybe_load_vmlinux_ctf_corpus(origin, group, vmlinux, - modules, root, di_roots, - verbose, t, env); + origin & corpus::CTF_ORIGIN, +#else + false, #endif + /*read_all_types=*/false, + /*linux_kernel_mode=*/true); + ABG_ASSERT(reader); + load_vmlinux_corpus(reader, group, vmlinux, + modules, root, di_roots, + suppr_paths, kabi_wl_paths, + supprs, verbose, t, env); } return group; @@ -2853,13 +2807,16 @@ build_corpus_group_from_kernel_dist_under(const string& root, /// Create the best elf based reader (or front-end), given an ELF file. /// /// This function looks into the ELF file. If it contains DWARF debug -/// info, then a DWARF Reader front-end is created and returned. -/// Otherwise, if it contains CTF debug info, then a CTF Reader -/// front-end is created and returned. +/// info, then a DWARF Reader front-end is created and returned, unless +/// that @ref use_ctf be true. Otherwise, if it contains CTF debug info, +/// then a CTF Reader front-end is created and returned. +/// +/// By other hand, it selects the DWARF front-end when @ref use_ctf is +/// true but ELF file doesn't have CTF debug information. /// /// Otherwise, if the file contains no debug info or if the king of -/// debug info is not yet recognized, a DWARF Reader front-end is -/// created and returned. +/// debug info is not yet recognized, a DWARF or CTF Reader front-end is +/// created and returned depending of @ref use_ctf parameter. /// /// @param elf_file_path a path to the ELF file to consider /// @@ -2868,32 +2825,62 @@ build_corpus_group_from_kernel_dist_under(const string& root, /// /// @param env the environment to use for the front-end. /// +/// @param use_ctf set to true if it's going to use CTF front-end. +/// +/// @param show_all_types option to be passed to elf based readers. +/// +/// @param linux_kernel_mode option to bed passed to elf based readers, +/// /// @return the ELF based Reader that is better adapted for the binary /// designated by @p elf_file_path. elf_based_reader_sptr create_best_elf_based_reader(const string& elf_file_path, const vector& debug_info_root_paths, - environment& env) + environment& env, + bool use_ctf, + bool show_all_types, + bool linux_kernel_mode) { elf_based_reader_sptr result; if (guess_file_type(elf_file_path) != FILE_TYPE_ELF) return result; - if (file_has_dwarf_debug_info(elf_file_path, debug_info_root_paths)) - result = dwarf::create_reader(elf_file_path, - debug_info_root_paths, - env); #ifdef WITH_CTF - else if (file_has_ctf_debug_info(elf_file_path, debug_info_root_paths)) - result = ctf::create_reader(elf_file_path, - debug_info_root_paths, - env); + if (!use_ctf) + { #endif + result = dwarf::create_reader(elf_file_path, + debug_info_root_paths, + env, + show_all_types, + linux_kernel_mode); +#ifdef WITH_CTF + if (!file_has_dwarf_debug_info(elf_file_path, + debug_info_root_paths) + && file_has_ctf_debug_info(elf_file_path, + debug_info_root_paths)) + result = ctf::create_reader(elf_file_path, + debug_info_root_paths, + env); + } else - result = dwarf::create_reader(elf_file_path, + { + result = ctf::create_reader(elf_file_path, debug_info_root_paths, env); + if (!file_has_ctf_debug_info(elf_file_path, + debug_info_root_paths) + && file_has_dwarf_debug_info(elf_file_path, + debug_info_root_paths)) + result = dwarf::create_reader(elf_file_path, + debug_info_root_paths, + env, + show_all_types, + linux_kernel_mode); + } +#endif + return result; } diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index 5ec33924..4b6e9305 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -607,6 +607,9 @@ test-read-dwarf/PR28584/PR28584-smv.clang.o.abi \ test-read-dwarf/PR29443-missing-xx.cc \ test-read-dwarf/PR29443-missing-xx.o \ test-read-dwarf/PR29443-missing-xx.o.abi \ +test-read-dwarf/test-fallback.abi \ +test-read-dwarf/test-fallback.c \ +test-read-dwarf/test-fallback.o \ \ test-read-ctf/test0 \ test-read-ctf/test0.abi \ @@ -698,6 +701,9 @@ test-read-ctf/test-anonymous-fields.o.abi \ test-read-ctf/test-linux-module.abi \ test-read-ctf/test-linux-module.c \ test-read-ctf/test-linux-module.ko \ +test-read-ctf/test-fallback.abi \ +test-read-ctf/test-fallback.c \ +test-read-ctf/test-fallback.o \ \ test-annotate/test0.abi \ test-annotate/test1.abi \ diff --git a/tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt b/tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt index e69de29b..4938d221 100644 --- a/tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt +++ b/tests/data/test-diff-pkg-ctf/dirpkg-3-report-2.txt @@ -0,0 +1,16 @@ +================ changes of 'libobj-v0.so'=============== + Functions changes summary: 0 Removed, 1 Changed (1 filtered out), 0 Added functions + Variables changes summary: 0 Removed, 0 Changed, 0 Added variable + + 1 function with some indirect sub-type change: + + [C] 'function void foo(S1*)' has some indirect sub-type changes: + parameter 1 of type 'S1*' has sub-type changes: + in pointed to type 'struct S1': + type size changed from 0 to 32 (in bits) + type alignment changed from 0 to 32 + 1 data member insertion: + 'int mem2', at offset 0 (in bits) + +================ end of changes of 'libobj-v0.so'=============== + diff --git a/tests/data/test-read-ctf/test-fallback.abi b/tests/data/test-read-ctf/test-fallback.abi new file mode 100644 index 00000000..e7d30594 --- /dev/null +++ b/tests/data/test-read-ctf/test-fallback.abi @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/tests/data/test-read-ctf/test-fallback.c b/tests/data/test-read-ctf/test-fallback.c new file mode 100644 index 00000000..e5019857 --- /dev/null +++ b/tests/data/test-read-ctf/test-fallback.c @@ -0,0 +1,8 @@ +/* gcc -gctf -c test-fallback.c -o test-fallback.o + + This test case is meant to test the fallback feature in + libabigail tools, so when those tools are executed without + the explicit use of `--ctf' option it should be use CTF + frond-end to build the IR. + */ +int a; diff --git a/tests/data/test-read-ctf/test-fallback.o b/tests/data/test-read-ctf/test-fallback.o new file mode 100644 index 0000000000000000000000000000000000000000..874368b667443493724183c51dc49e3c5c4bf104 GIT binary patch literal 1216 zcmbVLy-veG40fRWFCZ9@Si%Gda!Jbs1B!(B5khQ?43}^~M4F)F5Om@dcn2olf;VAi zgckt2@m;GcES%)C{rR(FyS=A_)59^(19LpsgMnvI)MEoX?wc{p!7O~ew`^o;K!Fz8 zB-1SOsC|@k6skYLLN;L7^T( zt!iC|mr~2V8B|JM2C2SkyepaKiA--r3UIW)zw56bot$nQj*PP-lL`0MKN zPE}b~65)a#EEs!e*eG5 z3MSHwlTLxy@r~>5YZU{84K~p*<3^3#ZvGlF=s)&XzTGQVa{VpD-I_#=>B95cD0{oy zHbw}GETb_#*xz(;lW+7c#*IBpUHT3Dg?oY+y*v8|xyUl-yM58Fh7Zx)T#6ra{xOqh lm}l~rhj4fI6nf_TMdlgBuyOGXjQ(~Md|~2+Wj2PJ{{yZRUq=7{ literal 0 HcmV?d00001 diff --git a/tests/data/test-read-dwarf/test-fallback.abi b/tests/data/test-read-dwarf/test-fallback.abi new file mode 100644 index 00000000..ebbae7ef --- /dev/null +++ b/tests/data/test-read-dwarf/test-fallback.abi @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/tests/data/test-read-dwarf/test-fallback.c b/tests/data/test-read-dwarf/test-fallback.c new file mode 100644 index 00000000..e5019857 --- /dev/null +++ b/tests/data/test-read-dwarf/test-fallback.c @@ -0,0 +1,8 @@ +/* gcc -gctf -c test-fallback.c -o test-fallback.o + + This test case is meant to test the fallback feature in + libabigail tools, so when those tools are executed without + the explicit use of `--ctf' option it should be use CTF + frond-end to build the IR. + */ +int a; diff --git a/tests/data/test-read-dwarf/test-fallback.o b/tests/data/test-read-dwarf/test-fallback.o new file mode 100644 index 0000000000000000000000000000000000000000..ab76098f2fff275b73cca9f627b95ff55de374ee GIT binary patch literal 2424 zcmbVNU2F_d6h1T4(so<=lTb=J1Z}ZncTrkeD-DhRic~zQ+3i@Z-D&MkW${oUK}Zu1 z9!UCtc&I1dNc^=Di8mtgDkNT-c<}Qgk(6_0?%9rOnkG(i?>Xl?-#Pc}{h1x!v3IAc zD8QmXJ4}0w0z597w&SiDhZ?AcX0(ezDIv(sTj~bIq?#Bij-gkoF|HLA_t_4ztCW@V zYC>9lU47+30CfXsC9Rf((YfzI!_DaDBi5Z~qr11}yY5#W>hFFX zyZGZ$`qR6qb>H7i#tx)jDE)Wi%b~NQqg8LjpU^Z*|J)xPqmH8(2d3ekD&xMR#oh9J z?i*==Lh&N__B$x3VI)X2m=gqp2BkCLp&9V9fO#ve3Hz0@Z;7s}c zJ45AUKZ=-KlX!8OP+C1zm}Tx-j8M&Zf#DfHRZsK1sYI7}{9f?0>`EKXa!m@Hb)(>Z zhlS}XncIb^j1h6nWdrC!vy!=cFc8%L6|te*C-qP7OzyuIF}Wr}@R}x++4ipoIYH~+ z7V96QA}F*zecj~s2N9$7BRKq`il#dKAllq3>vIB&aACpk5(HbyXBy{U<9vztToCv> z#$nE5eM97Pob@CV7!X>9?;%d-BCcD3{Z$aY* literal 0 HcmV?d00001 diff --git a/tests/test-diff-pkg.cc b/tests/test-diff-pkg.cc index e128ff63..8e510ca2 100644 --- a/tests/test-diff-pkg.cc +++ b/tests/test-diff-pkg.cc @@ -855,7 +855,7 @@ static InOutSpec in_out_specs[] = { // Just like the previous tests, but loc info is emitted. "data/test-diff-pkg-ctf/dirpkg-3-dir1", "data/test-diff-pkg-ctf/dirpkg-3-dir2", - "--no-default-suppression --no-abignore", + "--ctf --no-default-suppression --no-abignore", "data/test-diff-pkg-ctf/dirpkg-3.suppr", "", "", diff --git a/tests/test-read-common.cc b/tests/test-read-common.cc index b794a311..1d70b3d0 100644 --- a/tests/test-read-common.cc +++ b/tests/test-read-common.cc @@ -95,13 +95,14 @@ test_task::run_abidw(const string& extargs) { string abidw = string(get_build_dir()) + "/tools/abidw"; string drop_private_types; + string spec_options = spec.options ? spec.options : ""; set_in_abi_path(); if (!in_public_headers_path.empty()) drop_private_types += "--headers-dir " + in_public_headers_path + " --drop-private-types"; - string cmd = abidw + " " + drop_private_types + " --abidiff " + extargs + - in_elf_path; + string cmd = abidw + " " + spec_options + drop_private_types + + " --abidiff " + extargs + in_elf_path; if (system(cmd.c_str())) { error_message = string("ABIs differ:\n") diff --git a/tests/test-read-common.h b/tests/test-read-common.h index 4277896a..f00205b9 100644 --- a/tests/test-read-common.h +++ b/tests/test-read-common.h @@ -40,6 +40,7 @@ struct InOutSpec type_id_style_kind type_id_style; const char* in_abi_path; const char* out_abi_path; + const char* options; };// end struct InOutSpec /// The task that performs the tests. diff --git a/tests/test-read-ctf.cc b/tests/test-read-ctf.cc index 6dc2d53f..043032ff 100644 --- a/tests/test-read-ctf.cc +++ b/tests/test-read-ctf.cc @@ -43,7 +43,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test0.abi", - "output/test-read-ctf/test0.abi" + "output/test-read-ctf/test0.abi", + "--ctf" }, { "data/test-read-ctf/test0", @@ -51,7 +52,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test0.hash.abi", - "output/test-read-ctf/test0.hash.abi" + "output/test-read-ctf/test0.hash.abi", + "--ctf" }, { "data/test-read-ctf/test1.so", @@ -59,7 +61,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test1.so.abi", - "output/test-read-ctf/test1.so.abi" + "output/test-read-ctf/test1.so.abi", + "--ctf" }, { "data/test-read-ctf/test1.so", @@ -67,7 +70,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test1.so.hash.abi", - "output/test-read-ctf/test1.so.hash.abi" + "output/test-read-ctf/test1.so.hash.abi", + "--ctf" }, { "data/test-read-ctf/test2.so", @@ -75,7 +79,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test2.so.abi", - "output/test-read-ctf/test2.so.abi" + "output/test-read-ctf/test2.so.abi", + "--ctf" }, { "data/test-read-ctf/test2.so", @@ -83,7 +88,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test2.so.hash.abi", - "output/test-read-ctf/test2.so.hash.abi" + "output/test-read-ctf/test2.so.hash.abi", + "--ctf" }, { "data/test-read-common/test3.so", @@ -91,7 +97,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test3.so.abi", - "output/test-read-ctf/test3.so.abi" + "output/test-read-ctf/test3.so.abi", + "--ctf" }, { "data/test-read-common/test3.so", @@ -99,7 +106,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test3.so.hash.abi", - "output/test-read-ctf/test3.so.hash.abi" + "output/test-read-ctf/test3.so.hash.abi", + "--ctf" }, { "data/test-read-ctf/test-enum-many.o", @@ -107,7 +115,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test-enum-many.o.hash.abi", - "output/test-read-ctf/test-enum-many.o.hash.abi" + "output/test-read-ctf/test-enum-many.o.hash.abi", + "--ctf" }, { "data/test-read-ctf/test-ambiguous-struct-A.o", @@ -115,7 +124,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi", - "output/test-read-ctf/test-ambiguous-struct-A.o.hash.abi" + "output/test-read-ctf/test-ambiguous-struct-A.o.hash.abi", + "--ctf" }, { "data/test-read-ctf/test-ambiguous-struct-B.o", @@ -123,7 +133,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi", - "output/test-read-ctf/test-ambiguous-struct-B.o.hash.abi" + "output/test-read-ctf/test-ambiguous-struct-B.o.hash.abi", + "--ctf" }, { "data/test-read-ctf/test-conflicting-type-syms-a.o", @@ -131,7 +142,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi", - "output/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi" + "output/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi", + "--ctf" }, { "data/test-read-ctf/test-conflicting-type-syms-b.o", @@ -139,7 +151,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi", - "output/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi" + "output/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi", + "--ctf" }, { "data/test-read-common/test4.so", @@ -147,7 +160,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test4.so.abi", - "output/test-read-ctf/test4.so.abi" + "output/test-read-ctf/test4.so.abi", + "--ctf" }, { "data/test-read-common/test4.so", @@ -155,7 +169,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test4.so.hash.abi", - "output/test-read-ctf/test4.so.hash.abi" + "output/test-read-ctf/test4.so.hash.abi", + "--ctf" }, { "data/test-read-ctf/test5.o", @@ -163,7 +178,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test5.o.abi", - "output/test-read-ctf/test5.o.abi" + "output/test-read-ctf/test5.o.abi", + "--ctf" }, { "data/test-read-ctf/test7.o", @@ -171,7 +187,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test7.o.abi", - "output/test-read-ctf/test7.o.abi" + "output/test-read-ctf/test7.o.abi", + "--ctf" }, { "data/test-read-ctf/test8.o", @@ -179,7 +196,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test8.o.abi", - "output/test-read-ctf/test8.o.abi" + "output/test-read-ctf/test8.o.abi", + "--ctf" }, { "data/test-read-ctf/test9.o", @@ -187,7 +205,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test9.o.abi", - "output/test-read-ctf/test9.o.abi" + "output/test-read-ctf/test9.o.abi", + "--ctf" }, { "data/test-read-ctf/test-enum.o", @@ -195,7 +214,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-enum.o.abi", - "output/test-read-ctf/test-enum.o.abi" + "output/test-read-ctf/test-enum.o.abi", + "--ctf" }, { "data/test-read-ctf/test-enum-symbol.o", @@ -203,7 +223,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-ctf/test-enum-symbol.o.hash.abi", - "output/test-read-ctf/test-enum-symbol.o.hash.abi" + "output/test-read-ctf/test-enum-symbol.o.hash.abi", + "--ctf" }, { "data/test-read-ctf/test-dynamic-array.o", @@ -211,7 +232,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-dynamic-array.o.abi", - "output/test-read-ctf/test-dynamic-array.o.abi" + "output/test-read-ctf/test-dynamic-array.o.abi", + "--ctf" }, { "data/test-read-ctf/test-anonymous-fields.o", @@ -219,7 +241,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-anonymous-fields.o.abi", - "output/test-read-ctf/test-anonymous-fields.o.abi" + "output/test-read-ctf/test-anonymous-fields.o.abi", + "--ctf" }, { "data/test-read-common/PR27700/test-PR27700.o", @@ -228,6 +251,7 @@ static InOutSpec in_out_specs[] = HASH_TYPE_ID_STYLE, "data/test-read-ctf/PR27700/test-PR27700.abi", "output/test-read-ctf/PR27700/test-PR27700.abi", + "--ctf" }, { "data/test-read-ctf/test-callback.o", @@ -236,6 +260,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-callback.abi", "output/test-read-ctf/test-callback.abi", + "--ctf" }, { "data/test-read-ctf/test-array-of-pointers.o", @@ -244,6 +269,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-array-of-pointers.abi", "output/test-read-ctf/test-array-of-pointers.abi", + "--ctf" }, { "data/test-read-ctf/test-functions-declaration.o", @@ -252,6 +278,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-functions-declaration.abi", "output/test-read-ctf/test-functions-declaration.abi", + "--ctf" }, { "data/test-read-ctf/test-forward-type-decl.o", @@ -260,6 +287,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-forward-type-decl.abi", "output/test-read-ctf/test-forward-type-decl.abi", + "--ctf" }, { "data/test-read-ctf/test-list-struct.o", @@ -268,6 +296,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-list-struct.abi", "output/test-read-ctf/test-list-struct.abi", + "--ctf" }, { "data/test-read-common/test-PR26568-1.o", @@ -276,6 +305,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-PR26568-1.o.abi", "output/test-read-ctf/test-PR26568-1.o.abi", + "--ctf" }, { "data/test-read-common/test-PR26568-2.o", @@ -284,6 +314,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-PR26568-2.o.abi", "output/test-read-ctf/test-PR26568-2.o.abi", + "--ctf" }, { "data/test-read-ctf/test-callback2.o", @@ -292,6 +323,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-callback2.abi", "output/test-read-ctf/test-callback2.abi", + "--ctf" }, // out-of-tree kernel module. { @@ -301,9 +333,20 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-ctf/test-linux-module.abi", "output/test-read-ctf/test-linux-module.abi", + "--ctf" + }, + // CTF fallback feature. + { + "data/test-read-ctf/test-fallback.o", + "", + "", + SEQUENCE_TYPE_ID_STYLE, + "data/test-read-ctf/test-fallback.abi", + "output/test-read-ctf/test-fallback.abi", + NULL, }, // This should be the last entry. - {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL} + {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL, NULL} }; /// Task specialization to perform CTF tests. @@ -389,7 +432,7 @@ test_task_ctf::perform() if (!(is_ok = serialize_corpus(out_abi_path, corp))) return; - if (!(is_ok = run_abidw("--ctf "))) + if (!(is_ok = run_abidw())) return; if (!(is_ok = run_diff())) diff --git a/tests/test-read-dwarf.cc b/tests/test-read-dwarf.cc index 4b7bd14f..fbe3436b 100644 --- a/tests/test-read-dwarf.cc +++ b/tests/test-read-dwarf.cc @@ -43,7 +43,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test0.abi", - "output/test-read-dwarf/test0.abi" + "output/test-read-dwarf/test0.abi", + NULL, }, { "data/test-read-dwarf/test0", @@ -51,7 +52,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test0.hash.abi", - "output/test-read-dwarf/test0.hash.abi" + "output/test-read-dwarf/test0.hash.abi", + NULL, }, { "data/test-read-dwarf/test1", @@ -59,7 +61,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test1.abi", - "output/test-read-dwarf/test1.abi" + "output/test-read-dwarf/test1.abi", + NULL, }, { "data/test-read-dwarf/test1", @@ -67,7 +70,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test1.hash.abi", - "output/test-read-dwarf/test1.hash.abi" + "output/test-read-dwarf/test1.hash.abi", + NULL, }, { "data/test-read-dwarf/test2.so", @@ -75,7 +79,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test2.so.abi", - "output/test-read-dwarf/test2.so.abi" + "output/test-read-dwarf/test2.so.abi", + NULL, }, { "data/test-read-dwarf/test2.so", @@ -83,7 +88,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test2.so.hash.abi", - "output/test-read-dwarf/test2.so.hash.abi" + "output/test-read-dwarf/test2.so.hash.abi", + NULL, }, { "data/test-read-common/test3.so", @@ -91,7 +97,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test3.so.abi", - "output/test-read-dwarf/test3.so.abi" + "output/test-read-dwarf/test3.so.abi", + NULL, }, { "data/test-read-common/test3.so", @@ -99,7 +106,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test3.so.hash.abi", - "output/test-read-dwarf/test3.so.hash.abi" + "output/test-read-dwarf/test3.so.hash.abi", + NULL, }, // suppress all except the main symbol of a group of aliases { @@ -108,7 +116,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test3-alias-1.so.hash.abi", - "output/test-read-dwarf/test3-alias-1.so.hash.abi" + "output/test-read-dwarf/test3-alias-1.so.hash.abi", + NULL, }, // suppress the main symbol of a group of aliases { @@ -117,7 +126,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test3-alias-2.so.hash.abi", - "output/test-read-dwarf/test3-alias-2.so.hash.abi" + "output/test-read-dwarf/test3-alias-2.so.hash.abi", + NULL, }, // suppress all except one non main symbol of a group of aliases { @@ -126,7 +136,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test3-alias-3.so.hash.abi", - "output/test-read-dwarf/test3-alias-3.so.hash.abi" + "output/test-read-dwarf/test3-alias-3.so.hash.abi", + NULL, }, // suppress all symbols of a group of aliases { @@ -135,7 +146,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test3-alias-4.so.hash.abi", - "output/test-read-dwarf/test3-alias-4.so.hash.abi" + "output/test-read-dwarf/test3-alias-4.so.hash.abi", + NULL, }, // suppress the main symbols with alias (function+variable) in .o file { @@ -145,6 +157,7 @@ static InOutSpec in_out_specs[] = HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test-suppressed-alias.o.abi", "output/test-read-dwarf/test-suppressed-alias.o.abi", + NULL, }, { "data/test-read-common/test4.so", @@ -152,7 +165,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test4.so.abi", - "output/test-read-dwarf/test4.so.abi" + "output/test-read-dwarf/test4.so.abi", + NULL, }, { "data/test-read-common/test4.so", @@ -160,7 +174,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test4.so.hash.abi", - "output/test-read-dwarf/test4.so.hash.abi" + "output/test-read-dwarf/test4.so.hash.abi", + NULL, }, { "data/test-read-dwarf/test5.o", @@ -168,7 +183,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test5.o.abi", - "output/test-read-dwarf/test5.o.abi" + "output/test-read-dwarf/test5.o.abi", + NULL, }, { "data/test-read-dwarf/test5.o", @@ -176,7 +192,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test5.o.hash.abi", - "output/test-read-dwarf/test5.o.hash.abi" + "output/test-read-dwarf/test5.o.hash.abi", + NULL, }, { "data/test-read-dwarf/test6.so", @@ -184,7 +201,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test6.so.abi", - "output/test-read-dwarf/test6.so.abi" + "output/test-read-dwarf/test6.so.abi", + NULL, }, { "data/test-read-dwarf/test6.so", @@ -192,7 +210,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test6.so.hash.abi", - "output/test-read-dwarf/test6.so.hash.abi" + "output/test-read-dwarf/test6.so.hash.abi", + NULL, }, { "data/test-read-dwarf/test7.so", @@ -200,7 +219,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test7.so.abi", - "output/test-read-dwarf/test7.so.abi" + "output/test-read-dwarf/test7.so.abi", + NULL, }, { "data/test-read-dwarf/test7.so", @@ -208,7 +228,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test7.so.hash.abi", - "output/test-read-dwarf/test7.so.hash.abi" + "output/test-read-dwarf/test7.so.hash.abi", + NULL, }, { "data/test-read-dwarf/test8-qualified-this-pointer.so", @@ -216,7 +237,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test8-qualified-this-pointer.so.abi", - "output/test-read-dwarf/test8-qualified-this-pointer.so.abi" + "output/test-read-dwarf/test8-qualified-this-pointer.so.abi", + NULL, }, { "data/test-read-dwarf/test8-qualified-this-pointer.so", @@ -224,7 +246,8 @@ static InOutSpec in_out_specs[] = "", HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi", - "output/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi" + "output/test-read-dwarf/test8-qualified-this-pointer.so.hash.abi", + NULL, }, { "data/test-read-dwarf/test9-pr18818-clang.so", @@ -232,7 +255,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test9-pr18818-clang.so.abi", - "output/test-read-dwarf/test9-pr18818-clang.so.abi" + "output/test-read-dwarf/test9-pr18818-clang.so.abi", + NULL, }, { "data/test-read-dwarf/test10-pr18818-gcc.so", @@ -240,7 +264,8 @@ static InOutSpec in_out_specs[] = "", SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test10-pr18818-gcc.so.abi", - "output/test-read-dwarf/test10-pr18818-gcc.so.abi" + "output/test-read-dwarf/test10-pr18818-gcc.so.abi", + NULL, }, { "data/test-read-dwarf/test11-pr18828.so", @@ -249,6 +274,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test11-pr18828.so.abi", "output/test-read-dwarf/test11-pr18828.so.abi", + NULL, }, { "data/test-read-dwarf/test12-pr18844.so", @@ -257,6 +283,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test12-pr18844.so.abi", "output/test-read-dwarf/test12-pr18844.so.abi", + NULL, }, { "data/test-read-dwarf/test13-pr18894.so", @@ -265,6 +292,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test13-pr18894.so.abi", "output/test-read-dwarf/test13-pr18894.so.abi", + NULL, }, { "data/test-read-dwarf/test14-pr18893.so", @@ -273,6 +301,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test14-pr18893.so.abi", "output/test-read-dwarf/test14-pr18893.so.abi", + NULL, }, { "data/test-read-dwarf/test15-pr18892.so", @@ -281,6 +310,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test15-pr18892.so.abi", "output/test-read-dwarf/test15-pr18892.so.abi", + NULL, }, { "data/test-read-dwarf/test16-pr18904.so", @@ -289,6 +319,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test16-pr18904.so.abi", "output/test-read-dwarf/test16-pr18904.so.abi", + NULL, }, { "data/test-read-dwarf/test17-pr19027.so", @@ -297,6 +328,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test17-pr19027.so.abi", "output/test-read-dwarf/test17-pr19027.so.abi", + NULL, }, { "data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so", @@ -305,6 +337,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi", "output/test-read-dwarf/test18-pr19037-libvtkRenderingLIC-6.1.so.abi", + NULL, }, { "data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so", @@ -313,6 +346,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi", "output/test-read-dwarf/test19-pr19023-libtcmalloc_and_profiler.so.abi", + NULL, }, { "data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so", @@ -321,6 +355,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi", "output/test-read-dwarf/test20-pr19025-libvtkParallelCore-6.1.so.abi", + NULL, }, { "data/test-read-dwarf/test21-pr19092.so", @@ -329,6 +364,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test21-pr19092.so.abi", "output/test-read-dwarf/test21-pr19092.so.abi", + NULL, }, { "data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so", @@ -337,6 +373,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi", "output/test-read-dwarf/test22-pr19097-libstdc++.so.6.0.17.so.abi", + NULL, }, { "data/test-read-dwarf/libtest23.so", @@ -345,6 +382,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/libtest23.so.abi", "output/test-read-dwarf/libtest23.so.abi", + NULL, }, { "data/test-read-dwarf/libtest24-drop-fns.so", @@ -353,6 +391,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/libtest24-drop-fns.so.abi", "output/test-read-dwarf/libtest24-drop-fns.so.abi", + NULL, }, { "data/test-read-dwarf/libtest24-drop-fns.so", @@ -361,6 +400,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/libtest24-drop-fns-2.so.abi", "output/test-read-dwarf/libtest24-drop-fns-2.so.abi", + NULL, }, { "data/test-read-dwarf/PR22015-libboost_iostreams.so", @@ -369,6 +409,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR22015-libboost_iostreams.so.abi", "output/test-read-dwarf/PR22015-libboost_iostreams.so.abi", + NULL, }, { "data/test-read-dwarf/PR22122-libftdc.so", @@ -377,6 +418,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR22122-libftdc.so.abi", "output/test-read-dwarf/PR22122-libftdc.so.abi", + NULL, }, { "data/test-read-dwarf/PR24378-fn-is-not-scope.o", @@ -385,6 +427,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR24378-fn-is-not-scope.abi", "output/test-read-dwarf/PR24378-fn-is-not-scope.abi", + NULL, }, #if defined(HAVE_R_AARCH64_ABS64_MACRO) && defined(HAVE_R_AARCH64_PREL32_MACRO) { @@ -394,6 +437,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR25007-sdhci.ko.abi", "output/test-read-dwarf/PR25007-sdhci.ko.abi", + NULL, }, #endif #if defined HAVE_DW_FORM_strx @@ -404,6 +448,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi", "output/test-read-dwarf/PR25042-libgdbm-clang-dwarf5.so.6.0.0.abi", + NULL, }, #endif { @@ -413,6 +458,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, NULL, NULL, + NULL, }, { "data/test-read-dwarf/test26-bogus-binary.elf", @@ -421,6 +467,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, NULL, NULL, + NULL, }, { "data/test-read-dwarf/test27-bogus-binary.elf", @@ -429,6 +476,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, NULL, NULL, + NULL, }, { "data/test-read-common/PR26261/PR26261-exe", @@ -437,6 +485,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR26261/PR26261-exe.abi", "output/test-read-dwarf/PR26261/PR26261-exe.abi", + NULL, }, { "data/test-read-common/test-PR26568-1.o", @@ -445,6 +494,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test-PR26568-1.o.abi", "output/test-read-dwarf/test-PR26568-1.o.abi", + NULL, }, { "data/test-read-common/test-PR26568-2.o", @@ -453,6 +503,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/test-PR26568-2.o.abi", "output/test-read-dwarf/test-PR26568-2.o.abi", + NULL, }, { "data/test-read-dwarf/test-libandroid.so", @@ -461,6 +512,7 @@ static InOutSpec in_out_specs[] = HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test-libandroid.so.abi", "output/test-read-dwarf/test-libandroid.so.abi", + NULL, }, { "data/test-read-common/PR27700/test-PR27700.o", @@ -469,6 +521,7 @@ static InOutSpec in_out_specs[] = HASH_TYPE_ID_STYLE, "data/test-read-dwarf/PR27700/test-PR27700.abi", "output/test-read-dwarf/PR27700/test-PR27700.abi", + NULL, }, { "data/test-read-dwarf/test-libaaudio.so", @@ -477,6 +530,7 @@ static InOutSpec in_out_specs[] = HASH_TYPE_ID_STYLE, "data/test-read-dwarf/test-libaaudio.so.abi", "output/test-read-dwarf/test-libaaudio.so.abi", + NULL, }, { "data/test-read-dwarf/PR28584/PR28584-smv.clang.o", @@ -485,6 +539,7 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR28584/PR28584-smv.clang.o.abi", "output/test-read-dwarf/PR28584/PR28584-smv.clang.o.abi", + NULL, }, { "data/test-read-dwarf/PR29443-missing-xx.o", @@ -493,9 +548,25 @@ static InOutSpec in_out_specs[] = SEQUENCE_TYPE_ID_STYLE, "data/test-read-dwarf/PR29443-missing-xx.o.abi", "output/test-read-dwarf/PR29443-missing-xx.o.abi", + NULL, }, + // DWARF fallback feature. + { + "data/test-read-dwarf/test-fallback.o", + "", + "", + SEQUENCE_TYPE_ID_STYLE, + "data/test-read-dwarf/test-fallback.abi", + "output/test-read-dwarf/test-fallback.abi", +#ifdef WITH_CTF + "--ctf", +#else + NULL, +#endif + }, + // This should be the last entry. - {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL} + {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL, NULL} }; using abigail::suppr::suppression_sptr; diff --git a/tools/abidiff.cc b/tools/abidiff.cc index 7413b291..6cd948bf 100644 --- a/tools/abidiff.cc +++ b/tools/abidiff.cc @@ -55,6 +55,7 @@ using abigail::tools_utils::gen_suppr_spec_from_kernel_abi_whitelists; using abigail::tools_utils::load_default_system_suppressions; using abigail::tools_utils::load_default_user_suppressions; using abigail::tools_utils::abidiff_status; +using abigail::tools_utils::create_best_elf_based_reader; using namespace abigail; @@ -1196,21 +1197,17 @@ main(int argc, char* argv[]) case abigail::tools_utils::FILE_TYPE_ELF: // fall through case abigail::tools_utils::FILE_TYPE_AR: { - abigail::elf_based_reader_sptr rdr; + abigail::elf_based_reader_sptr rdr = + create_best_elf_based_reader(opts.file1, + opts.prepared_di_root_paths1, + env, #ifdef WITH_CTF - if (opts.use_ctf) - rdr = ctf::create_reader(opts.file1, - opts.prepared_di_root_paths1, - env); - else + opts.use_ctf, +#else + false, #endif - rdr = dwarf::create_reader(opts.file1, - opts.prepared_di_root_paths1, - env, - /*read_all_types=*/opts.show_all_types, - opts.linux_kernel_mode); - - assert(rdr); + opts.show_all_types); + ABG_ASSERT(rdr); rdr->options().show_stats = opts.show_stats; rdr->options().do_log = opts.do_log; @@ -1274,21 +1271,18 @@ main(int argc, char* argv[]) case abigail::tools_utils::FILE_TYPE_ELF: // Fall through case abigail::tools_utils::FILE_TYPE_AR: { - abigail::elf_based_reader_sptr rdr; + abigail::elf_based_reader_sptr rdr = + create_best_elf_based_reader(opts.file2, + opts.prepared_di_root_paths2, + env, #ifdef WITH_CTF - if (opts.use_ctf) - rdr = ctf::create_reader(opts.file2, - opts.prepared_di_root_paths2, - env); - else + opts.use_ctf, +#else + false, #endif - rdr = dwarf::create_reader (opts.file2, - opts.prepared_di_root_paths2, - env, - /*read_all_types=*/opts.show_all_types, - opts.linux_kernel_mode); + opts.show_all_types); + ABG_ASSERT(rdr); - assert(rdr); rdr->options().show_stats = opts.show_stats; rdr->options().do_log = opts.do_log; set_suppressions(*rdr, opts); diff --git a/tools/abidw.cc b/tools/abidw.cc index 7d520018..d711751f 100644 --- a/tools/abidw.cc +++ b/tools/abidw.cc @@ -48,6 +48,7 @@ using abigail::tools_utils::temp_file_sptr; using abigail::tools_utils::check_file; using abigail::tools_utils::build_corpus_group_from_kernel_dist_under; using abigail::tools_utils::timer; +using abigail::tools_utils::create_best_elf_based_reader; using abigail::ir::environment_sptr; using abigail::ir::environment; using abigail::corpus; @@ -101,7 +102,7 @@ struct options bool show_stats; bool noout; #ifdef WITH_CTF - bool use_ctf; + bool use_ctf; #endif bool show_locs; bool abidiff; @@ -554,19 +555,18 @@ load_corpus_and_write_abixml(char* argv[], fe_iface::status s = fe_iface::STATUS_UNKNOWN; // First of all, create a reader to read the ABI from the file // specfied in opts ... - abigail::elf_based_reader_sptr reader; + abigail::elf_based_reader_sptr reader = + create_best_elf_based_reader(opts.in_file_path, + opts.prepared_di_root_paths, + env, #ifdef WITH_CTF - if (opts.use_ctf) - reader = abigail::ctf::create_reader(opts.in_file_path, - opts.prepared_di_root_paths, - env); - else + opts.use_ctf, +#else + false, #endif - reader = abigail::dwarf::create_reader(opts.in_file_path, - opts.prepared_di_root_paths, - env, - opts.load_all_types, - opts.linux_kernel_mode); + opts.load_all_types, + opts.linux_kernel_mode); + ABG_ASSERT(reader); // ... then tune a bunch of "buttons" on the newly created reader ... reader->options().drop_undefined_syms = opts.drop_undefined_syms; @@ -819,7 +819,7 @@ load_kernel_corpus_group_and_write_abixml(char* argv[], global_timer.start(); t.start(); -corpus::origin origin = + corpus::origin origin = #ifdef WITH_CTF opts.use_ctf ? corpus::CTF_ORIGIN : #endif diff --git a/tools/abipkgdiff.cc b/tools/abipkgdiff.cc index adfe8b8e..ecdfb45f 100644 --- a/tools/abipkgdiff.cc +++ b/tools/abipkgdiff.cc @@ -136,6 +136,7 @@ using abigail::tools_utils::build_corpus_group_from_kernel_dist_under; using abigail::tools_utils::load_default_system_suppressions; using abigail::tools_utils::load_default_user_suppressions; using abigail::tools_utils::abidiff_status; +using abigail::tools_utils::create_best_elf_based_reader; using abigail::ir::corpus_sptr; using abigail::ir::corpus_group_sptr; using abigail::comparison::diff_context; @@ -1322,14 +1323,16 @@ compare(const elf_file& elf1, abigail::elf_based_reader_sptr reader; corpus_sptr corpus1; { + abigail::elf_based_reader_sptr reader = + create_best_elf_based_reader(elf1.path, + di_dirs1, + env, #ifdef WITH_CTF - if (opts.use_ctf) - reader = ctf::create_reader(elf1.path, di_dirs1, env); - else + opts.use_ctf, +#else + false, #endif - reader = dwarf::create_reader(elf1.path, di_dirs1, env, - /*load_all_types=*/opts.show_all_types); - + opts.show_all_types); ABG_ASSERT(reader); reader->add_suppressions(priv_types_supprs1); @@ -1420,13 +1423,17 @@ compare(const elf_file& elf1, corpus_sptr corpus2; { + abigail::elf_based_reader_sptr reader = + create_best_elf_based_reader(elf2.path, + di_dirs2, + env, #ifdef WITH_CTF - if (opts.use_ctf) - reader = ctf::create_reader(elf2.path, di_dirs2, env); - else + opts.use_ctf, +#else + false, #endif - reader = dwarf::create_reader(elf2.path, di_dirs2, env, - /*load_all_types=*/opts.show_all_types); + opts.show_all_types); + ABG_ASSERT(reader); reader->add_suppressions(priv_types_supprs2); if (!opts.kabi_suppressions.empty()) @@ -1582,13 +1589,17 @@ compare_to_self(const elf_file& elf, corpus_sptr corp; abigail::elf_based_reader_sptr reader; { + abigail::elf_based_reader_sptr reader = + create_best_elf_based_reader(elf.path, + di_dirs, + env, #ifdef WITH_CTF - if (opts.use_ctf) - reader = ctf::create_reader(elf.path, di_dirs, env); - else + opts.use_ctf, +#else + false, #endif - reader = dwarf::create_reader(elf.path, di_dirs, env, - /*read_all_types=*/opts.show_all_types); + opts.show_all_types); + ABG_ASSERT(reader); corp = reader->read_corpus(c_status); -- 2.35.1