From patchwork Mon May 16 18:32:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Guillermo E. Martinez" X-Patchwork-Id: 54045 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id CC11E3857350 for ; Mon, 16 May 2022 18:33:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org CC11E3857350 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1652725996; bh=OH5yCOmOP4GN06/ikmlCKBPzvc/mhTnAYGnGsmuNT/U=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:From; b=hXuVCcZD/8UTPg2tojpw8mjP5HYeWizlPVhP7ED+WuyJnmwP5LZ8WP5hkXFmW2RZZ sdn2ZDRsmRFQSJZVcFbSynIa04Nmep8i1pBvUM1Zu7f5Vuer1NvKSCy3HJilcoAhHq da1OrISlXWUTjAJ+UKeFMRdll/U1vIh8bv7L9XtY= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mx0a-00069f02.pphosted.com (mx0a-00069f02.pphosted.com [205.220.165.32]) by sourceware.org (Postfix) with ESMTPS id 75B7D3858D3C for ; Mon, 16 May 2022 18:33:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 75B7D3858D3C Received: from pps.filterd (m0246627.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 24GHU77L009881 for ; Mon, 16 May 2022 18:33:08 GMT Received: from iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta03.appoci.oracle.com [130.35.103.27]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3g2310m7ck-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Mon, 16 May 2022 18:33:08 +0000 Received: from pps.filterd (iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com (8.16.1.2/8.16.1.2) with SMTP id 24GIOvQk015364 for ; Mon, 16 May 2022 18:33:06 GMT Received: from nam12-dm6-obe.outbound.protection.outlook.com (mail-dm6nam12lp2172.outbound.protection.outlook.com [104.47.59.172]) by iadpaimrmta03.imrmtpd1.prodappiadaev1.oraclevcn.com with ESMTP id 3g22v27mrr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Mon, 16 May 2022 18:33:06 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=RkcV1+ZOOT63VxwPWEugaIwVKzVCLtjsvrgUCp6Pl3rJ1Hk3c7JqbSbrdEXCvpiqMIF8N0lbatc3gZdKLnOs5yj3T6q34DYSLHqFwxPpAXOCgdM3Ku6Xq6Ft1hAF6jV0YyT6GsWXnI4RfVdTdfpx4viDueVL/iG5JDXAyxSefP0FAfK6yyH0pNPM1D2oDbUdxSOJshkzuxTcfkEhUDY1QTOSygTd9CPvr217G4fRXnludu3o6YhCsXe52KwFjtPvhSEvGStBo/U/qUbEToQWfPv0q1cla7tik2RPCcU4PRNkkgFvZrON+byLOaEouRJUofSwclhj8dV1xMu/dib5yw== 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=OH5yCOmOP4GN06/ikmlCKBPzvc/mhTnAYGnGsmuNT/U=; b=fYGmzG/27AHYWb4K7UP9o/Fr3tSZQxwAdBZZfo2sslv2FAP+v1kMFuJ1bJXbk70pGpXTcxAhHvMm8QVLZYltDm63xGK5SpKLT/jgKIdjw9a/USTHdZy7PSP0o+j+hqsEgY5pmXDUiNIxbg6sIqsdwlbY5RsDLaFywCtFyYyTOC8XhjGb3t+zAeg1XklCrMUMmPZUENMHHmMJTof/L+mHGdMyhqYxpxQ87yX9mZw5kDETkMkmrafAhdRiZ3VvVvu2pba0dRAzUeteVW3nWQl8j8SUEmKazzcQQAYBS0R+iE/DkpHlM6GA9iSojM2W4fPUpC6/P6Y61gPmSAYH66GZrw== 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 Received: from MWHPR10MB1407.namprd10.prod.outlook.com (2603:10b6:300:23::20) by BN6PR10MB1411.namprd10.prod.outlook.com (2603:10b6:404:3d::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5250.13; Mon, 16 May 2022 18:33:04 +0000 Received: from MWHPR10MB1407.namprd10.prod.outlook.com ([fe80::c88b:fab4:f199:fc1b]) by MWHPR10MB1407.namprd10.prod.outlook.com ([fe80::c88b:fab4:f199:fc1b%4]) with mapi id 15.20.5250.018; Mon, 16 May 2022 18:33:04 +0000 To: libabigail@sourceware.org Subject: [PATCH v2] ctf-reader: add support to looking debug information in external path Date: Mon, 16 May 2022 13:32:54 -0500 Message-Id: <20220516183254.2042821-1-guillermo.e.martinez@oracle.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <87k0apvc7m.fsf@seketeli.org> References: <87k0apvc7m.fsf@seketeli.org> X-ClientProxiedBy: SJ0PR13CA0122.namprd13.prod.outlook.com (2603:10b6:a03:2c6::7) To MWHPR10MB1407.namprd10.prod.outlook.com (2603:10b6:300:23::20) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 4aee7c36-740d-4323-5cee-08da376a8379 X-MS-TrafficTypeDiagnostic: BN6PR10MB1411:EE_ X-Microsoft-Antispam-PRVS: X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: e3EgVq+AqnQEv3O2I7rqMs/3ss9M73++r+ct4z6l+v8F2blwUkWucz5fB2B6AgeA/EpAC/2XWD7Pj8k2I5yc3Lrt2WjSLR3es80rtIaR3edLzGjszYl5pb1a7yY4DWfuxS3/1xHP11sFxSR4JRaCJSrYr8BGDBm9vpAFEeEygpr8TpaBRE7Xzt8no2pvjyKpGFyDs3cOxdek002NEefx9Q3fQwRwMyQ0FkzfY4cplzE1l0PtGmXw+dnrkYt1HPlKEiZN/GBCe353jR8T50wOkKsSfCpQl8crfTr052pszhhDbn/cvU7i5F6VSLymeBv3XC1HQ1sD3MJu8XfQQkJl1Awha6swpYoiGs7n67Av5utiADJFWqRG+Hsihug5iKeEfYOy5pNu+fVUycFH186Vj1ijbQwCwnOUFeDQFRRIUbY6NvmZPtIWBjswKmMtW1JsGrw/FUWUo6k9zcqAiZB22SGizqbpdMOyVV4J1Zh9i7hibx0R1Bh7e/w2/8HQbzt/qTvKTKfW3k/KPX9FEdMkxe4BPLbIljlAQBxKd3g7dgaJZPsnWAbyedOQZhYVYEQsmoPY12iEnRTfUFUM7TzL9q/j2mMv3wE6sh76giTVNB2gocQXBatsX+OVpdLhM3vSkuCrin8hey8ECc6m26P3dQ== 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:(13230001)(366004)(5660300002)(66946007)(508600001)(30864003)(8936002)(4326008)(66476007)(66556008)(8676002)(86362001)(103116003)(6486002)(1076003)(186003)(6506007)(36756003)(2616005)(107886003)(2906002)(6666004)(38100700002)(83380400001)(52116002)(6512007)(6916009)(316002); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 2 X-MS-Exchange-AntiSpam-MessageData-0: IBLjjreIQcWcdTia2w5DRS+u4CAl/zw6E46z/yjVhOC6rC1SxucDM2q5ZMcGZe7OOmhbuWtCQE3Bd4BE+4XvIAmxSDNV/LyzYfY7Ox2dmn/0cR1HO5rqjrsLLQIXOrcP3PeTA12SK/yg/FmeMKrz69lFZmnar8xaJhQq/5TW/bV4flwa6LWu9mAFoRzvrSLf6u9rjzmd/fkV1YM9f4gd7t0W8I19/h3NYNy3xe+WUN+lvlZ1KBK5Thjy4/a6xsDvqytd4sDR795UIKUhpBGWYxhdijIAzvlotBplpnLGXXclTFcQyyOfaKVDDP7gsQW72vzy+G57o2ZiGOKnOhwiI9zyAMse72xm4gYhYpg7sf1aoOdR+IfehFTN309rKiqRIBAU8yHOW4c7dtsqfNXACG+CBOUpIotYdytmwO/QNqTYPaib5fIvpmHmJ0rE8txbGZ/cGcW1dYGWqPEgGcVUeiFUjC+5ln0zgCd0VIsjQVfl11SJR+XLfg4wFD77CU9TqIhNosVMha+JPc3I9h85wBPcDElSZpuPIQrc4jrFRC4fWDfzrjfsM/2IdomSKFQy9xr7wRiTYc1Oi+kpPF4k2k8aRTYx1rDAW12TuuYrOx6PqO4Eg/D0sASXjayw6SscoG5EgQR0Nlj8BbNodsTfMZBuk6tpowKQ/bDV5O0rr6SUEId0/e3Mfl2ne/4wImick2QJp3Pp7nW+18tUGoUi5qTTL/9LEXBOEvBMKuoFiLNUEiRYtIOOejIwIf2x1/xfXS9VgySsshOTywy6vbWQe6W8IJgaqL6gsY14DXpD/+3gQw781TfJzXJiBORP7RN7rhXp+53SYT1jdtAGFFx/L4K5N+totP7tdmrctPde7ginoeDO4IlG4Xb7w3Djdl0/9kjQrMWFOYAghWF7LXQbJsRFTzr/WWXpQ3/mCEceFS9gNMp7Luk0AVBU8JLHqGwP3BY8cYTtjyEhQgJe5KTyuJel9Mr44sOkV/WPGtwk7TQTnjZTsadsCe+8JjdF2NJS4/LHyCoNM0nfT779DvXqv1IZoTw6CoAtGTOF760OhRP4lPXosxBfGAN3YfwJ+Ory2U6p0TQJDbph5JU3tBvO44PePbnhaiYztD+dm3Xe3rFxD7lhHLj5QYuJPE3LPMbIDSrZCl6vA0aQzU5co8xWasVHV2uSey8nGqK2Lmx4cGEJJq4yK5vKNsbamSmhkKxGFoBlXJJ4rgcESmhIAOs7iLzbZokHiv00DUzuThFko+l8atooEgt1Z1jK1vy+O8gceOlAVXGOusffoFjHgvTaOug8n/vSCENHpNeDzQcza3sFjVBmGb/sQ0h/lRmx8KhfueTT2RWqbv2zsDhaTW0jHmp+kUL8fYWUpHprVICYB0gy1C6GWCUhBZkR+eklgwsdjPxl/Jv2nUxJZwvWgKTgNPYHWnmcerEj8bLW37w2/J0BvSVXTNAoNBhYX3PeZgyTG/77iS5w/wBQ6qqKuLWreu8Rw39gFv4MN2s1MfjKwspSYE7ecvKG1t9t224Fh4nOM6BVODJ8dFI7uCd9hH/faN60W3JX+AuAdFynTvmpOtJJFTrTvvCKBIj3snZ2XHJXcVAvRcjlfQ/7mXiRdiUF7OGejCn1LcrPgkZrAD87ZaG4tkVeqsQybRgxb/nilTfQwqsikt22KQfvd5xPhlvY/WGEX974ks6BZA3vd41Uhb8WVQDGd0n4TqKvWyXsK3GrlVVLziUvjSxpt6rU3oXpjuxFRceVy0G3Q5myUtqtJ/xTO/r51uG8Sj0PX+2Kvx9Adsm826qx X-MS-Exchange-AntiSpam-MessageData-1: 5p7QtbBe7m2QaA== X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4aee7c36-740d-4323-5cee-08da376a8379 X-MS-Exchange-CrossTenant-AuthSource: MWHPR10MB1407.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 May 2022 18:33:04.1301 (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: ITZxHnf4om+fKUYrl14BlagMotXwjFgNxYvfQaa5Af096Tn4XEIV29jYptUkJPZ7VVOtL0tiHrMfHDxgdsbapiJzTga1bXwOnquly2YMCnM= X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN6PR10MB1411 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.486, 18.0.858 definitions=2022-05-16_15:2022-05-16, 2022-05-16 signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxscore=0 malwarescore=0 suspectscore=0 mlxlogscore=964 adultscore=0 phishscore=0 spamscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2202240000 definitions=main-2205160100 X-Proofpoint-ORIG-GUID: umfYmQXD3mfM0JH9e9eA1lyW8DonrlMb X-Proofpoint-GUID: umfYmQXD3mfM0JH9e9eA1lyW8DonrlMb X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libabigail@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Mailing list of the Libabigail project List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-Patchwork-Original-From: "Guillermo E. Martinez via Libabigail" From: "Guillermo E. Martinez" Reply-To: "Guillermo E. Martinez" Errors-To: libabigail-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libabigail" Hello libabigail team, This is the patch v2 to add support for looking debug information in external path(s) in CTF reader. Changes from v1: * Rebase from master branch Comments will be welcomed! Kinds regards, Guillermo When an ELF `stripped' file is used to get CTF debug information the ELF symbols used by ctf reader (`symtab_reader::symtab') is split in a separate file and even though CTF was designed to be in ELF file after be `stripped' this .ctf section can be 'loaded' from and external .debug file, for instance the script `find-debuginfo' used to generate RPM debug packages split debug information in .debug files. The location of such files is pass as a standard argument from libabigail tools and the name of the file is gathering from the `.gnu_debuglink' section. * include/abg-ctf-reader.h (ctf_reader::create_read_context): Add `debug_info_root_paths' argument. (ctf_reader::reset_read_context): Likewise. * src/abg-ctf-reader.cc: Add `read_context::elf_{handler,fd}_dbg', data members. (read_context::read_context): Add new `debug_info_root_paths' argument. (read_context::initialize): Likewise. (ctf_reader::create_read_context): Likewise. (ctf_reader::close_elf_handler): Release `read_context::elf_{handler,fd}_dbg' members. (ctf_reader::find_alt_debuginfo): Add new function. (ctf_reader::slurp_elf_info): Add new argument `status'. Use `find_alt_debuginfo' and `elf_helpers::find_section_by_name' to read the symtab and ctf information from an external .debug file, the `status' reference is updated. (ctf_reader::read_corpus): Verify `status' after `slurp_elf_info'. (ctf_reader::reset_read_context): Add new `debug_info_root_path' argument. * src/abg-elf-helpers.cc (elf_helpers::find_section_by_name): Update comment. * src/abg-tools-utils.cc (maybe_load_vmlinux_ctf_corpus): Adjust `ctf_reader::{create,reset}_read_context'. * tests/test-read-ctf.cc: Likewise. * tools/abidiff.cc (display_usage): Add `--ctf' command line option. (main): Adjust `ctf_reader::create_read_context'. Likewise. * tools/abidw.cc (load_corpus_and_write_abixml): Adjust `ctf_reader::create_read_context'. * tools/abilint.cc: Likewise. Signed-off-by: Guillermo E. Martinez Signed-off-by: Guillermo E. Martinez Signed-off-by: Dodji Seketeli --- include/abg-ctf-reader.h | 2 + src/abg-ctf-reader.cc | 176 ++++++++++++++++++++++++++++++--------- src/abg-elf-helpers.cc | 2 + src/abg-tools-utils.cc | 11 ++- tests/test-read-ctf.cc | 3 + tools/abidiff.cc | 6 +- tools/abidw.cc | 6 +- tools/abilint.cc | 7 +- 8 files changed, 165 insertions(+), 48 deletions(-) diff --git a/include/abg-ctf-reader.h b/include/abg-ctf-reader.h index ba7289aa..60f3623d 100644 --- a/include/abg-ctf-reader.h +++ b/include/abg-ctf-reader.h @@ -31,6 +31,7 @@ typedef shared_ptr read_context_sptr; read_context_sptr create_read_context(const std::string& elf_path, + const vector& debug_info_root_paths, ir::environment *env); corpus_sptr read_corpus(read_context *ctxt, elf_reader::status& status); @@ -47,6 +48,7 @@ set_read_context_corpus_group(read_context& ctxt, corpus_group_sptr& group); void reset_read_context(read_context_sptr &ctxt, const std::string& elf_path, + const vector& debug_info_root_path, ir::environment* environment); std::string dic_type_key(ctf_dict_t *dic, ctf_id_t ctf_type); diff --git a/src/abg-ctf-reader.cc b/src/abg-ctf-reader.cc index 89dea276..2bb3d924 100644 --- a/src/abg-ctf-reader.cc +++ b/src/abg-ctf-reader.cc @@ -70,6 +70,10 @@ public: Elf *elf_handler; int elf_fd; + /// libelf handler for the ELF file from which we read the CTF data, + /// and the corresponding file descriptor found in external .debug file + Elf *elf_handler_dbg; + int elf_fd_dbg; /// The symtab read from the ELF file. symtab_reader::symtab_sptr symtab; @@ -83,6 +87,8 @@ public: corpus_sptr cur_corpus_; corpus_group_sptr cur_corpus_group_; corpus::exported_decls_builder* exported_decls_builder_; + // The set of directories under which to look for debug info. + vector debug_info_root_paths_; /// Setter of the exported decls builder object. /// @@ -253,15 +259,20 @@ public: /// /// @param elf_path the path to the ELF file. /// - /// @param environment the environment used by the current context. + /// @param debug_info_root_paths vector with the paths + /// to directories where .debug file is located. + /// + /// @param env the environment used by the current context. /// This environment contains resources needed by the reader and by /// the types and declarations that are to be created later. Note /// that ABI artifacts that are to be compared all need to be /// created within the same environment. - read_context(const string& elf_path, ir::environment *env) : - ctfa(NULL) + read_context(const string& elf_path, + const vector& debug_info_root_paths, + ir::environment *env) : + ctfa(NULL) { - initialize(elf_path, env); + initialize(elf_path, debug_info_root_paths, env); } /// Initializer of read_context. @@ -269,6 +280,9 @@ public: /// @param elf_path the path to the elf file the context is to be /// used for. /// + /// @param debug_info_root_paths vector with the paths + /// to directories where .debug file is located. + /// /// @param environment the environment used by the current context. /// This environment contains resources needed by the reader and by /// the types and declarations that are to be created later. Note @@ -279,16 +293,22 @@ public: /// must be greater than the life time of the resulting @ref /// read_context the context uses resources that are allocated in /// the environment. - void initialize(const string& elf_path, ir::environment *env) + void + initialize(const string& elf_path, + const vector& debug_info_root_paths, + ir::environment *env) { types_map.clear(); filename = elf_path; ir_env = env; elf_handler = NULL; + elf_handler_dbg = NULL; elf_fd = -1; + elf_fd_dbg = -1; symtab.reset(); cur_corpus_group_.reset(); exported_decls_builder_ = 0; + debug_info_root_paths_ = debug_info_root_paths; } ~read_context() @@ -1332,6 +1352,10 @@ close_elf_handler (read_context *ctxt) /* Finish the ELF handler and close the associated file. */ elf_end(ctxt->elf_handler); close(ctxt->elf_fd); + + /* Finish the ELF handler and close the associated debug file. */ + elf_end(ctxt->elf_handler_dbg); + close(ctxt->elf_fd_dbg); } /// Fill a CTF section description with the information in a given ELF @@ -1358,38 +1382,113 @@ fill_ctf_section(Elf_Scn *elf_section, ctf_sect_t *ctf_section) ctf_section->cts_entsize = section_header->sh_entsize; } +/// Find a CTF section and debug symbols in a given ELF using +/// .gnu_debuglink section. +/// +/// @param ctxt the read context. +/// @param ctf_dbg_section the CTF section to fill with the raw data. +static void +find_alt_debuginfo(read_context *ctxt, Elf_Scn **ctf_dbg_scn) +{ + std::string name; + Elf_Data *data; + + Elf_Scn *section = elf_helpers::find_section + (ctxt->elf_handler, ".gnu_debuglink", SHT_PROGBITS); + + if (section + && (data = elf_getdata(section, NULL)) + && data->d_size != 0) + name = (char *) data->d_buf; + + int fd = -1; + Elf *hdlr = NULL; + *ctf_dbg_scn = NULL; + + if (!name.empty()) + for (vector::const_iterator i = ctxt->debug_info_root_paths_.begin(); + i != ctxt->debug_info_root_paths_.end(); + ++i) + { + std::string file_path; + if (!tools_utils::find_file_under_dir(**i, name, file_path)) + continue; + + if ((fd = open(file_path.c_str(), O_RDONLY)) == -1) + continue; + + if ((hdlr = elf_begin(fd, ELF_C_READ, NULL)) == NULL) + { + close(fd); + continue; + } + + ctxt->symtab = + symtab_reader::symtab::load(hdlr, ctxt->ir_env, nullptr); + + // unlikely .ctf was designed to be present in stripped file + *ctf_dbg_scn = + elf_helpers::find_section(hdlr, ".ctf", SHT_PROGBITS); + break; + + elf_end(hdlr); + close(fd); + } + + // If we don't have a symbol table, use current one in ELF file + if (!ctxt->symtab) + ctxt->symtab = + symtab_reader::symtab::load(ctxt->elf_handler, ctxt->ir_env, nullptr); + + ctxt->elf_handler_dbg = hdlr; + ctxt->elf_fd_dbg = fd; +} + /// Slurp certain information from the ELF file described by a given /// read context and install it in a libabigail corpus. /// /// @param ctxt the read context /// @param corp the libabigail corpus in which to install the info. -/// -/// @return 0 if there is an error. -/// @return 1 otherwise. - -static int -slurp_elf_info(read_context *ctxt, corpus_sptr corp) +/// @param status the resulting status flags. +static void +slurp_elf_info(read_context *ctxt, + corpus_sptr corp, + elf_reader::status& status) { + /* Set the ELF architecture. */ + GElf_Ehdr *ehdr, eh_mem; Elf_Scn *symtab_scn; - Elf_Scn *ctf_scn; + Elf_Scn *ctf_scn, *ctf_dbg_scn; Elf_Scn *strtab_scn; - GElf_Ehdr eh_mem; - GElf_Ehdr *ehdr = gelf_getehdr(ctxt->elf_handler, &eh_mem); - /* Set the ELF architecture. */ + if (!(ehdr = gelf_getehdr(ctxt->elf_handler, &eh_mem))) + return; + corp->set_architecture_name(elf_helpers::e_machine_to_string(ehdr->e_machine)); - /* Read the symtab from the ELF file and set it in the corpus. */ - ctxt->symtab = - symtab_reader::symtab::load(ctxt->elf_handler, ctxt->ir_env, - 0 /* No suppressions. */); + find_alt_debuginfo(ctxt, &ctf_dbg_scn); + ABG_ASSERT(ctxt->symtab); corp->set_symtab(ctxt->symtab); if (corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN) - return 1; + { + status |= elf_reader::STATUS_OK; + return; + } /* Get the raw ELF section contents for libctf. */ - ctf_scn = elf_helpers::find_section(ctxt->elf_handler, ".ctf", SHT_PROGBITS); + const char *ctf_name = ".ctf"; + ctf_scn = elf_helpers::find_section_by_name(ctxt->elf_handler, ctf_name); + if (ctf_scn == NULL) + { + if (ctf_dbg_scn) + ctf_scn = ctf_dbg_scn; + else + { + status |= elf_reader::STATUS_DEBUG_INFO_NOT_FOUND; + return; + } + } // ET_{EXEC,DYN} needs .dyn{sym,str} in ctf_arc_bufopen const char *symtab_name = ".dynsym"; @@ -1403,15 +1502,17 @@ slurp_elf_info(read_context *ctxt, corpus_sptr corp) symtab_scn = elf_helpers::find_section_by_name(ctxt->elf_handler, symtab_name); strtab_scn = elf_helpers::find_section_by_name(ctxt->elf_handler, strtab_name); - - if (ctf_scn == NULL || symtab_scn == NULL || strtab_scn == NULL) - return 0; + if (symtab_scn == NULL || strtab_scn == NULL) + { + status |= elf_reader::STATUS_NO_SYMBOLS_FOUND; + return; + } fill_ctf_section(ctf_scn, &ctxt->ctf_sect); fill_ctf_section(symtab_scn, &ctxt->symtab_sect); fill_ctf_section(strtab_scn, &ctxt->strtab_sect); - return 1; + status |= elf_reader::STATUS_OK; } /// Create and return a new read context to process CTF information @@ -1422,9 +1523,12 @@ slurp_elf_info(read_context *ctxt, corpus_sptr corp) read_context_sptr create_read_context(const std::string& elf_path, + const vector& debug_info_root_paths, ir::environment *env) { - read_context_sptr result(new read_context(elf_path, env)); + read_context_sptr result(new read_context(elf_path, + debug_info_root_paths, + env)); return result; } @@ -1443,17 +1547,12 @@ read_corpus(read_context *ctxt, elf_reader::status &status) { corpus_sptr corp = std::make_shared(ctxt->ir_env, ctxt->filename); - ctxt->cur_corpus_ = corp; - /* Be optimist. */ - status = elf_reader::STATUS_OK; + status = elf_reader::STATUS_UNKNOWN; /* Open the ELF file. */ if (!open_elf_handler(ctxt)) - { - status = elf_reader::STATUS_DEBUG_INFO_NOT_FOUND; return corp; - } bool is_linux_kernel = elf_helpers::is_linux_kernel(ctxt->elf_handler); corpus::origin origin = corpus::CTF_ORIGIN; @@ -1465,11 +1564,11 @@ read_corpus(read_context *ctxt, elf_reader::status &status) if (ctxt->cur_corpus_group_) ctxt->cur_corpus_group_->add_corpus(ctxt->cur_corpus_); - if (!slurp_elf_info(ctxt, corp) && !is_linux_kernel) - { - status = elf_reader::STATUS_NO_SYMBOLS_FOUND; + slurp_elf_info(ctxt, corp, status); + if (!is_linux_kernel + && ((status & elf_reader::STATUS_DEBUG_INFO_NOT_FOUND) | + (status & elf_reader::STATUS_NO_SYMBOLS_FOUND))) return corp; - } // Set the set of exported declaration that are defined. ctxt->exported_decls_builder @@ -1496,7 +1595,7 @@ read_corpus(read_context *ctxt, elf_reader::status &status) ctxt->ir_env->canonicalization_is_done(false); if (ctxt->ctfa == NULL) - status = elf_reader::STATUS_DEBUG_INFO_NOT_FOUND; + status |= elf_reader::STATUS_DEBUG_INFO_NOT_FOUND; else { process_ctf_archive(ctxt, corp); @@ -1583,10 +1682,11 @@ read_and_add_corpus_to_group_from_elf(read_context* ctxt, void reset_read_context(read_context_sptr &ctxt, const std::string& elf_path, + const vector& debug_info_root_path, ir::environment* environment) { if (ctxt) - ctxt->initialize(elf_path, environment); + ctxt->initialize(elf_path, debug_info_root_path, environment); } /// Returns a key to be use in types_map dict conformed by diff --git a/src/abg-elf-helpers.cc b/src/abg-elf-helpers.cc index a1fd4e6c..c41e339e 100644 --- a/src/abg-elf-helpers.cc +++ b/src/abg-elf-helpers.cc @@ -300,6 +300,8 @@ e_machine_to_string(GElf_Half e_machine) /// /// @param elf_handle the elf handle to use. /// +/// @param name the section name. +/// /// @return the section found, nor nil if none was found. Elf_Scn* find_section_by_name(Elf* elf_handle, const std::string& name) diff --git a/src/abg-tools-utils.cc b/src/abg-tools-utils.cc index f30c3f1d..7ea7ecb7 100644 --- a/src/abg-tools-utils.cc +++ b/src/abg-tools-utils.cc @@ -2633,6 +2633,9 @@ maybe_load_vmlinux_dwarf_corpus(corpus::origin origin, /// @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. /// @@ -2646,6 +2649,7 @@ maybe_load_vmlinux_ctf_corpus(corpus::origin origin, const string& vmlinux, vector& modules, const string& root, + vector& di_roots, bool verbose, timer& t, environment_sptr& env) @@ -2655,7 +2659,7 @@ maybe_load_vmlinux_ctf_corpus(corpus::origin origin, abigail::elf_reader::status status = abigail::elf_reader::STATUS_OK; ctf_reader::read_context_sptr ctxt; - ctxt = ctf_reader::create_read_context(vmlinux, env.get()); + ctxt = ctf_reader::create_read_context(vmlinux, di_roots, env.get()); group.reset(new corpus_group(env.get(), root)); set_read_context_corpus_group(*ctxt, group); @@ -2690,7 +2694,7 @@ maybe_load_vmlinux_ctf_corpus(corpus::origin origin, << "/" << total_nb_modules << ") ... " << std::flush; - reset_read_context(ctxt, *m, env.get()); + reset_read_context(ctxt, *m, di_roots, env.get()); set_read_context_corpus_group(*ctxt, group); t.start(); @@ -2788,7 +2792,8 @@ build_corpus_group_from_kernel_dist_under(const string& root, supprs, verbose, t, env); #ifdef WITH_CTF maybe_load_vmlinux_ctf_corpus(origin, group, vmlinux, - modules, root, verbose, t, env); + modules, root, di_roots, + verbose, t, env); #endif } diff --git a/tests/test-read-ctf.cc b/tests/test-read-ctf.cc index 215ed8d6..1f31e90c 100644 --- a/tests/test-read-ctf.cc +++ b/tests/test-read-ctf.cc @@ -22,6 +22,7 @@ using std::string; using std::cerr; +using std::vector; using abigail::tests::read_common::InOutSpec; using abigail::tests::read_common::test_task; @@ -346,9 +347,11 @@ test_task_ctf::perform() env.reset(new abigail::ir::environment); abigail::elf_reader::status status = abigail::elf_reader::STATUS_UNKNOWN; + vector di_roots; ABG_ASSERT(abigail::tools_utils::file_exists(in_elf_path)); read_context_sptr ctxt = create_read_context(in_elf_path, + di_roots, env.get()); ABG_ASSERT(ctxt); diff --git a/tools/abidiff.cc b/tools/abidiff.cc index 763f084e..37a273ad 100644 --- a/tools/abidiff.cc +++ b/tools/abidiff.cc @@ -247,7 +247,9 @@ display_usage(const string& prog_name, ostream& out) << " --dump-diff-tree emit a debug dump of the internal diff tree to " "the error output stream\n" << " --stats show statistics about various internal stuff\n" - << " --ctf use CTF instead of DWARF in ELF files\n" +#ifdef WITH_CTF + << " --ctf use CTF instead of DWARF in ELF files\n" +#endif #ifdef WITH_DEBUG_SELF_COMPARISON << " --debug debug the process of comparing an ABI corpus against itself" #endif @@ -1184,6 +1186,7 @@ main(int argc, char* argv[]) { abigail::ctf_reader::read_context_sptr ctxt = abigail::ctf_reader::create_read_context(opts.file1, + opts.prepared_di_root_paths1, env.get()); ABG_ASSERT(ctxt); c1 = abigail::ctf_reader::read_corpus(ctxt.get(), @@ -1267,6 +1270,7 @@ main(int argc, char* argv[]) { abigail::ctf_reader::read_context_sptr ctxt = abigail::ctf_reader::create_read_context(opts.file2, + opts.prepared_di_root_paths2, env.get()); ABG_ASSERT(ctxt); c2 = abigail::ctf_reader::read_corpus(ctxt.get(), diff --git a/tools/abidw.cc b/tools/abidw.cc index 32d055f5..1ca642bb 100644 --- a/tools/abidw.cc +++ b/tools/abidw.cc @@ -540,9 +540,9 @@ load_corpus_and_write_abixml(char* argv[], if (opts.use_ctf) { abigail::ctf_reader::read_context_sptr ctxt - = abigail::ctf_reader::create_read_context (opts.in_file_path, - env.get()); - + = abigail::ctf_reader::create_read_context(opts.in_file_path, + opts.prepared_di_root_paths, + env.get()); assert (ctxt); t.start(); corp = abigail::ctf_reader::read_corpus (ctxt, s); diff --git a/tools/abilint.cc b/tools/abilint.cc index 4883b557..b45cad19 100644 --- a/tools/abilint.cc +++ b/tools/abilint.cc @@ -782,9 +782,10 @@ main(int argc, char* argv[]) #ifdef WITH_CTF if (opts.use_ctf) { - abigail::ctf_reader::read_context_sptr ctxt - = abigail::ctf_reader::create_read_context(opts.file_path, - env.get()); + abigail::ctf_reader::read_context_sptr ctxt = + abigail::ctf_reader::create_read_context(opts.file_path, + di_roots, + env.get()); ABG_ASSERT(ctxt); corp = abigail::ctf_reader::read_corpus(ctxt.get(), s); }