From patchwork Fri Apr 29 14:16:58 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: 53359 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 5012B385736D for ; Fri, 29 Apr 2022 14:17:25 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5012B385736D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1651241845; bh=6vq9Pd9LVBqVcraQDKSWUrgEDheNRKVS7um+Ev9kif4=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Help:List-Subscribe:From:Reply-To:From; b=PmLU3gV2eZ0qbnNPx8gWJcdBthYcGrFMBCk/5eiFabZwJBw0RxAHsNxONhm688LeL IAFC4aGt93wM2jxnGeenduiFKXKG3ijkyF0Bhs6DA5XWuxkYo6teIYUBvcZlwFluDB 8y5Oq3xG5m3iTeoD/X51f0xm2InQ9CV1kF1uxJzo= X-Original-To: libabigail@sourceware.org Delivered-To: libabigail@sourceware.org Received: from mx0b-00069f02.pphosted.com (mx0b-00069f02.pphosted.com [205.220.177.32]) by sourceware.org (Postfix) with ESMTPS id 570D0385803E for ; Fri, 29 Apr 2022 14:17:15 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 570D0385803E Received: from pps.filterd (m0246632.ppops.net [127.0.0.1]) by mx0b-00069f02.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 23TBL81w011361 for ; Fri, 29 Apr 2022 14:17:15 GMT Received: from iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (iadpaimrmta02.appoci.oracle.com [147.154.18.20]) by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 3fmaw4q0jn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 29 Apr 2022 14:17:14 +0000 Received: from pps.filterd (iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1]) by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (8.16.1.2/8.16.1.2) with SMTP id 23TEGGaj008687 for ; Fri, 29 Apr 2022 14:17:13 GMT Received: from nam12-dm6-obe.outbound.protection.outlook.com (mail-dm6nam12lp2177.outbound.protection.outlook.com [104.47.59.177]) by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com with ESMTP id 3fm7w82k1g-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK) for ; Fri, 29 Apr 2022 14:17:12 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=BDxIO1JkI7DkvryhvBXUJh2h74BJyPERw6+N9TiuETqEjBhFdue+zqQDHIrew935ygxdMAMFaWMgxPiqfYluLf/klF/k0t2jIfvmD+0GtTI9jCHLrAjyyx6yY8RayBfhY5yRbdA9/KI9hqT9xMiKaKMGpaLmGHDUUuygTAeOaPX4xwwrTuf8KPFQeEobuThtH3MuIETtmixnaL+86ulLzHUGL4RIRsvG/8RYinsTaafy7AqgidKSZBqnfIGCMUT2paN9YvMzVHIeDy7N9nddxoIIGKbeMO6OAAGQSTh3WJvQ5FQuN6/en6pFkkrVPEy4l5QXi7FhoFDFOdlcIatLDw== 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=6vq9Pd9LVBqVcraQDKSWUrgEDheNRKVS7um+Ev9kif4=; b=MdfQ5C5ydXhuIUFc3Ufb8JstnCU5fgJv9Mbf5RTnp4NVgn16irlCJo8Y+Gy3DQyH9s8x84M8u9vTnKuXV1B3Z+tQqwdnc2b3x8E8QDfJwkSithQb10QaV/5BL7Oulq+5f39OJQeN0SBeYVy+FYKyeNk4jszZZGr4AgJBW1JWcXz9kFG8gLUaSoD/DybsJzhEMajOtTQr1J4QNXSu8huIjUcGpi4qgkS7pmajQ9MTryGT6UAlqhs8Sw0SdYa6/ip1RE9HoKtX0i75YXB1M4/XJlVC3jrn/zjhLPW9AjzDNYyvB7uvjl9ZJAK6UwJsKYkHABGaCDcmfqqddyO6+xrbwA== 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 SN6PR10MB2703.namprd10.prod.outlook.com (2603:10b6:805:4f::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5186.14; Fri, 29 Apr 2022 14:17:08 +0000 Received: from MWHPR10MB1407.namprd10.prod.outlook.com ([fe80::107d:de35:fa5f:3cc0]) by MWHPR10MB1407.namprd10.prod.outlook.com ([fe80::107d:de35:fa5f:3cc0%7]) with mapi id 15.20.5206.014; Fri, 29 Apr 2022 14:17:08 +0000 To: libabigail@sourceware.org Subject: [PATCH v2] ctf-reader: Add support to read CTF information from Linux kernel Date: Fri, 29 Apr 2022 09:16:58 -0500 Message-Id: <20220429141658.260012-1-guillermo.e.martinez@oracle.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220330153531.2769612-1-guillermo.e.martinez@oracle.com> References: <20220330153531.2769612-1-guillermo.e.martinez@oracle.com> X-ClientProxiedBy: SA0PR11CA0178.namprd11.prod.outlook.com (2603:10b6:806:1bb::33) 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: 4a5dadb1-2035-4c72-398e-08da29eaf185 X-MS-TrafficTypeDiagnostic: SN6PR10MB2703: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: eJ6xw0gAtbERCK7WzcqbyYF9+lrKyRjHJDE9dJJ9MjEEX4YLvWwaOGF6aQ8W7nKEAJBCZ+zZDpukbF3Q0EydnDJMftV7XR7k/rPzSWuRwOOsVRl7zhfCwmSIYUmOZg8LIynAzG8LV6S0cDe6LbfNoOkMPZ2UVVDwQAMebyr1S1fmD5khzARQmBu7omCjwX58AC+zqfnqVxRoghd/y+IO/2n40eKigjlncIePpcEJBMVW48tWO8JWYZDrO/IMUHTOPWLu1pHRLE6AoB/y5DbPLZvID+0BlQo0dtJdY/wpkwDCzwnhB+efCrmQkSJVfuIrgU9/jUftIwOpdrF7yLaEVrHc2DUpJXL1oJvGafYDOI8Kccrig6pXDjUwDCIPk2Oo3KbHeQx3sFtDrm1VlfASFMOUIvG9paefLicIoxjMGdlyF0t7C+/ins5ErKwWCt3m3m5ZA+22vdFQhFBJ7HZm+TYsm22PV0sAA6invDAgTgwTnredjw8gJ5CcKL/46WeuWgIymXkyk1GqgtaukIsRhxY1ZFcFtjnH9sR4ymmqNDIj2uJWAF4Z/jX7fkIssr/hbZwQ8VUVLaNldNThX7po0yyWZD+fyloofFMW2Q9zdOzWmHkuKGb+5XyiKM7Ob7Koao143dh1UP63llZfze17tCe6+jRiaMvihM+lbedMRYI0C3Vnrpr6RuqY5hVH9q268RH7u5O1rGZTqV+WY38lvu0HXSouA6K9avhoZuxTOHfxV1ej8eJ1fT2ZrP4MfXlQLI++qaZa4I6FgnNhCr+xIZSWYtS/l4nELa98irIFNIY= 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)(1076003)(6916009)(186003)(19627235002)(2616005)(316002)(66946007)(66476007)(66556008)(8676002)(52116002)(6666004)(36756003)(6506007)(6512007)(103116003)(86362001)(4326008)(5660300002)(38350700002)(38100700002)(26005)(8936002)(30864003)(2906002)(6486002)(83380400001)(508600001)(107886003)(966005)(579004)(559001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: F43IdqsN0pvYmt73Dm3044oVTJQM6KS8ZyxjIFHXKscj+LoA8usm5ZFuvjuZrvGNn5UGepBKsHYHF1iDfxrwo0e+N3B9qksc9VM4jhxkLkssE4O4D4Nm8Le5J6+KGFgeBUK+Y+/K/3zMcsj0mFEEe1jyiMEDxjl7/38lGthLzjHek6f7y3bnHo6uSTScbUHZi5gP2BYjXcXGFkXQuzaPuHkFQrPt9E0CWaCN+bcirO/1bajv0U9petuA+zSp+oosjV3vFNcN9Rt+Umr7l7JPOnRzDKASA0OlcxRvbo7TO3XkQoAvfQFx1dvkGQEn5CzAYbLI10SX9D+s6i/vENu8E3zBYa2PA8hucvLHsCHskX2EbifvjymMXnlVFVNL7Aer0uXLVt9WM5fo1L9OC/xGpwqlOtZEQjejyDS9AKKRIik0gdU43XDmdhOCrXv6bFVuwFa7yH/Kgt+iWZ8V0tTtFxxTGOxTt5RJiHZVmWn8XRVMfO9amkb+xQLkafu2qvd7izQ+50b0IZvA2VEKjDT/O+qWVZ+p6EHFHDu6zA3mVjRfbrHoNPkV8xxhOxFrrY1yrBFmI7NC4+tZv84UTQE54tQDy3Mp3m1qZD4LB5ep/0vVKWn76lpCLgWQea+pz0dtlk8c6U1o3mBFkGdEM+XiRum50ELtG6vqE9DKim0bPQu/gkv6LDXBC5VI/sgBxXHclXNiJSXNXzVozhPwkIkekpbpamB36CX+tH7+txs2yBIwFjHX7w2zPupwX/oQtIhWPJjHkkeI1dPCASDWMd9ryZ6m6vUg0ZW0YH0oowz5GqSmuI1y4wL/PwTATWnXdygQ+myyTJnxm7C95fQM3Rti/lE4rE7ku231zjgP4bb6fm1pX9CnhG4S5CAoYOQEuyFqL7x8TS2/2exKnAQNIXRjHptHWVtMpucX2of93tn+DGypg8AYo/6Y1Q+Br+bB+edtj18zftBAjlrHLZHyUQUU8tj2FT8lC4w3bI4sUOD3SwTPB3H6GsMELdX/Q9kIRUL2djx2NL14+uhk9ABPE8eS1Y5Of7B8PHwpBbCZi/2MXsi5A4n2sooFRVMCjNhLaNyjl7phm83yEEV+4eGUVParlN4/ZNFeB+hqdu+bdeoK1AyJ//14GJfuLbGYTSec5Z6JN+qF0b4f3IPVvMQnj9h1YnKlBKJYg94/zMZIphF1P0saM84owOVuuVwk6Yl+Bz2FFdKLAe/qbottTrF2U9dCfDFyN4o1g26h1YB9Kej4sV8zMElK0Mx7kUR6r0ZCibjgV7F/B305rJmk3f3qn2xOkkbjMEzOlg/G+60tCYRhtunBBcRTG84uc4wa0ZN6Dfq44fC5iQ7jt5CM+3SWIBq6bd8Jy/f3MPlRpewYpOnSHUT9zqta043wrM+nWEcm1oLl8BTgAXWPA+Tt4+Lr0BdQF3lCdp9PTmkQ2abgKy9WCNEBwXeO3tenh3Q3tG6wBdwlrNfhDi20KxYsfsuOF5rjpsEqTX+vxnSDtWC6raRuIVfyXbfp+UfnOMEhwE7F7+CrZyRjEzcJ7/2UO4DyXGJh25iyaA0aVsbnFsGTr4sNhGrqJpYJXB/7yTLTYRb4J3yvAaLugplHNJns//3dKITHOBodsUDTOLV3qSE3zVWiwv61R2dWzWpX+4KoItcf+erbyXFbRSAvEZCZGIRCtbdRSd5b8SmQpVliKW7RVUYxcKlo0ZjqdtopkGVe46T9tpxIyZjPpYIfBvSr1N166zDMnM3ShhovYzzoSpAnLDXfFykCyCy22o7Bm91ep0wIG6yH X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 4a5dadb1-2035-4c72-398e-08da29eaf185 X-MS-Exchange-CrossTenant-AuthSource: MWHPR10MB1407.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 29 Apr 2022 14:17:08.2159 (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: iVAIzkjMkQ7S55G/Flv15QQqs1/yXOS62FdYGO+W/2YPhND1wftKmSwz8lCF0NE7NChPsX9ueH18hYidrMBxXSJ4QRHsvC/h/TVEd7gcofo= X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN6PR10MB2703 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.486, 18.0.858 definitions=2022-04-29_05:2022-04-28, 2022-04-29 signatures=0 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 spamscore=0 mlxlogscore=999 malwarescore=0 mlxscore=0 phishscore=0 bulkscore=0 adultscore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2202240000 definitions=main-2204290080 X-Proofpoint-GUID: VdkII3CqV-EuPhMpoO_QWaGfW5Biz2iB X-Proofpoint-ORIG-GUID: VdkII3CqV-EuPhMpoO_QWaGfW5Biz2iB X-Spam-Status: No, score=-12.2 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 autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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 v2 patch meant to read CTF information from Linux. Changes from v1: * rebase and update from its dependency: https://sourceware.org/pipermail/libabigail/2022q2/004308.html Please take a look and let me know your comments, I'll really appreciate them. Kind regards, Guillermo This patch is meant to extract ABI information from CTF stored in Linux kernel build directory it depends on: vmlinux.ctfa file. In order to generate CTF information in Linux kernel must be able to support 'make ctf', which cause the compiler to be run with -gctf emitting CTF information on the kernel. The target 'ctf' in Linux Makefile generate a 'vmlinux.ctfa', that will be used for ctf reader in libabigail. 'vmlinux.ctfa' has multiple 'ctf dictionaries' called: CTF archive members one for built-in kernel modules (`vmlinux') and one for each out-of-tree kernel module organized in a parent-child hierarchy. In vmlinux.ctfa file there is a CTF archive member: `shared_ctf' it is a parent dictionary, containing share symbols and CTF types used by more than one kernel object. These common types are stored in 'types_map' in ctf reader, ignoring the ctf dictionary name, CTF API has the machinery to looking for a share type in parent dictionary referred in a child dictionary. This CTF layout can be dumped by using objdump tool. The basic algorithm used to generate the Linux corpus follow: 1. Looking for: vmlinux, *.ko objects, and vmlinux.ctfa files. The first files are used to extract the ELF symbols, and the last one contains the CTF type information for non-static variables and functions symbols. 2. `process_ctf_archive' iterates on public symbols for vmlinux and its modules, using the name of the symbol, ctf reader search for CTF information in its dictionary, if the information was found it builds a `var_decl' or `function_decl' depending of `ctf_type_kind' result. This algorithm is also applied to ELF files (exec, dyn, rel), so instead of iterating on all ctf_types it uses public symbols as main loop. * abg-elf-reader-common.h: Include ctf-api.h file. (read_and_add_corpus_to_group_from_elf, set_read_context_corpus_group) (reset_read_context, set_vmlinux_ctfa_path, dic_type_key): Declare new member functions. * include/abg-ir.h (environment::debug_format_type): Add new enum type. (environment::debug_format_): Add new member variable. (environment::{get_debug_format_type,set_debug_format_type): Add new member functions. * src/abg-ctf-reader.cc: Include map, algorithms header files. (read_context::vmlinux_ctfa_path_): Add new member variable to store location of `vmlinux.ctfa'. (read_context::type_map): Change from unordered_map to std::map storing ctf dictionary name as part of the key. (read_context::is_elf_exec): Add new member variable. (read_context::{cur_corpus_, cur_corpus_group_}): Likewise. (read_context::unknown_types_set): Likewise. (read_context::{current_corpus_group, main_corpus_from_current_group, has_corpus_group, current_corpus_is_main_corpus_from_current_group, should_reuse_type_from_corpus_group}): Add new member functions. (read_context::{add_unknown_type, lookup_unknown_type, initialize}): Likewise. (read_context::{add_type, lookup_type}): Add new `ctf_dict_t' type argument. (ctf_reader::{process_ctf_typedef, process_ctf_base_type, process_ctf_function_type, process_ctf_forward_type, process_ctf_struct_type, process_ctf_union_type, process_ctf_array_type, process_ctf_qualified_type, process_ctf_enum_type}): Add code to `reuse' types already registered in main corpus. Replace function calls to the new ctf interface. Add verifier to not build types duplicated by recursive calling chain. (ctf_reader::process_ctf_type): Add code to return immediately if the ctf type is unknown. Add unknown types to `unknown_types_set'. (ctf_reader::process_ctf_archive): Change comment. Add code to iterate over global symbols, searching by symbol name in the ctf dictionary using `ctf_lookup_{variable,by_symbol_name}' depending of the ELF file type and corpus type, creating a `{var,fuc}_decl' using the return type of `ctf_type_kind'. Also close the ctf dict and call `canonicalize_all_types'. (slurp_elf_info): Set `is_elf_exec' depending of ELF type. Also return success if corpus origin is Linux and symbol table was read. (ctf_reader::read_corpus): Add current corpus. Set corpus origin to `LINUX_KERNEL_BINARY_ORIGIN' or `CTF_ORIGIN'. Use `is_linux_kernel' to verify the ctf reader status, now the ctf archive is 'opened' using `ctf_arc{open,bufopen}' depending of corpus origin value, `sort_{function,variables}' is call after extract ctf information and `ctf_close' is called. (read:context::{set_read_context_corpus_group, reset_read_context, read_and_add_corpus_to_group_from_elf, set_vmlinux_ctfa_path, dic_type_key): Add new member function implementation. * src/abg-ir.cc (environment::environment): Add default value `DWARF_FORMAT_TYPE' for `debug_format_'. (environment::{get_debug_format_type, set_debug_format_type}): Add new member function implementation. * src/abg-tools-utils.cc: Use `abg-ctf-reader.h' file. (is_vmlinux): Add new argument. (find_vmlinux_and_module_paths): Change to use new `is_vmlinux' signature. (find_vmlinux_path): Add new argument. Also change to use new `is_vmlinux' signature. (get_vmlinux_path_from_kernel_dist): Change to use `find_vmlinux_path' signature. (get_vmlinux_ctfa_path_from_kernel_dist): Add new function definition. (build_corpus_group_from_kernel_dist_under): Add conditional use of `debug_format_' if it is `CTF_FORMAT_TYPE' looks for `vmlinux.ctfa', re-organise the code to process both debug formats: `{DWARF,CTF}_FORMAT_TYPE. * tools/abidw.cc (main): Use of --ctf argument to set format debug. * tests/test-read-ctf.cc: Add new tests to harness. * tests/data/test-read-ctf/test-PR27700.abi: New test expected result. * tests/data/test-read-ctf/test-anonymous-fields.o.abi: Likewise. * tests/data/test-read-ctf/test-enum-many-ctf.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-enum-many.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-enum-symbol-ctf.o.hash.abi: Likewise. * tests/data/test-read-common/test-PR26568-2.o: Adjust. * tests/data/test-read-ctf/test-PR26568-1.o.abi: Likewise. * tests/data/test-read-ctf/test-PR26568-2.o.abi: Likewise. * tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-ambiguous-struct-B.c: Likewise. * tests/data/test-read-ctf/test-ambiguous-struct-B.o: Likewise. * tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-array-of-pointers.abi: Likewise. * tests/data/test-read-ctf/test-callback.abi: Likewise. * tests/data/test-read-ctf/test-callback2.abi: Likewise. * tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-dynamic-array.o.abi: Likewise. * tests/data/test-read-ctf/test-enum-ctf.o.abi: Likewise. * tests/data/test-read-ctf/test-enum-symbol.o.hash.abi: Likewise. * tests/data/test-read-ctf/test-enum.o.abi: Likewise. * tests/data/test-read-ctf/test-forward-type-decl.abi: Likewise. * tests/data/test-read-ctf/test-functions-declaration.abi: Likewise. * tests/data/test-read-ctf/test-list-struct.abi: Likewise. * tests/data/test-read-ctf/test0: Likewise. * tests/data/test-read-ctf/test0.abi: Likewise. * tests/data/test-read-ctf/test0.c: Likewise. * tests/data/test-read-ctf/test0.hash.abi: Likewise. * tests/data/test-read-ctf/test1.so.abi: Likewise. * tests/data/test-read-ctf/test1.so.hash.abi: Likewise. * tests/data/test-read-ctf/test2.so.abi: Likewise. * tests/data/test-read-ctf/test2.so.hash.abi: Likewise. * tests/data/test-read-ctf/test3.so.abi: Likewise. * tests/data/test-read-ctf/test3.so.hash.abi: Likewise. * tests/data/test-read-ctf/test4.so.abi: Likewise. * tests/data/test-read-ctf/test4.so.hash.abi: Likewise. * tests/data/test-read-ctf/test5.o.abi: Likewise. * tests/data/test-read-ctf/test7.o.abi: Likewise. * tests/data/test-read-ctf/test8.o.abi: Likewise. * tests/data/test-read-ctf/test9.o.abi: Likewise. --- include/abg-ctf-reader.h | 19 + include/abg-ir.h | 14 + src/abg-ctf-reader.cc | 467 ++++++++++++++---- src/abg-ir.cc | 17 +- src/abg-tools-utils.cc | 272 +++++++--- tests/data/test-read-common/test-PR26568-2.o | Bin 3048 -> 3488 bytes .../test-read-ctf/PR27700/test-PR27700.abi | 3 +- tests/data/test-read-ctf/test-PR26568-1.o.abi | 34 +- tests/data/test-read-ctf/test-PR26568-2.o.abi | 22 +- tests/data/test-read-ctf/test-PR27700.abi | 21 + .../test-ambiguous-struct-A.o.hash.abi | 3 +- .../test-read-ctf/test-ambiguous-struct-B.c | 2 +- .../test-read-ctf/test-ambiguous-struct-B.o | Bin 1344 -> 1344 bytes .../test-ambiguous-struct-B.o.hash.abi | 5 +- .../test-read-ctf/test-anonymous-fields.o.abi | 18 +- .../test-read-ctf/test-array-of-pointers.abi | 2 +- tests/data/test-read-ctf/test-callback.abi | 30 +- tests/data/test-read-ctf/test-callback2.abi | 2 +- .../test-conflicting-type-syms-a.o.hash.abi | 4 +- .../test-conflicting-type-syms-b.o.hash.abi | 4 +- .../test-read-ctf/test-dynamic-array.o.abi | 2 +- tests/data/test-read-ctf/test-enum-ctf.o.abi | 24 + .../test-enum-many-ctf.o.hash.abi | 69 +++ .../test-read-ctf/test-enum-many.o.hash.abi | 6 +- .../test-enum-symbol-ctf.o.hash.abi | 16 + .../test-read-ctf/test-enum-symbol.o.hash.abi | 3 +- tests/data/test-read-ctf/test-enum.o.abi | 6 +- .../test-read-ctf/test-forward-type-decl.abi | 2 +- .../test-functions-declaration.abi | 4 +- tests/data/test-read-ctf/test-list-struct.abi | 4 +- tests/data/test-read-ctf/test0 | Bin 16656 -> 16896 bytes tests/data/test-read-ctf/test0.abi | 30 +- tests/data/test-read-ctf/test0.c | 6 + tests/data/test-read-ctf/test0.hash.abi | 18 +- tests/data/test-read-ctf/test1.so.abi | 11 +- tests/data/test-read-ctf/test1.so.hash.abi | 7 +- tests/data/test-read-ctf/test2.so.abi | 8 + tests/data/test-read-ctf/test2.so.hash.abi | 8 + tests/data/test-read-ctf/test3.so.abi | 4 + tests/data/test-read-ctf/test3.so.hash.abi | 4 + tests/data/test-read-ctf/test4.so.abi | 6 + tests/data/test-read-ctf/test4.so.hash.abi | 6 + tests/data/test-read-ctf/test5.o.abi | 36 +- tests/data/test-read-ctf/test7.o.abi | 43 +- tests/data/test-read-ctf/test8.o.abi | 2 +- tests/data/test-read-ctf/test9.o.abi | 2 +- tests/test-read-ctf.cc | 20 +- tools/abidw.cc | 5 + 48 files changed, 933 insertions(+), 358 deletions(-) create mode 100644 tests/data/test-read-ctf/test-PR27700.abi create mode 100644 tests/data/test-read-ctf/test-enum-ctf.o.abi create mode 100644 tests/data/test-read-ctf/test-enum-many-ctf.o.hash.abi create mode 100644 tests/data/test-read-ctf/test-enum-symbol-ctf.o.hash.abi diff --git a/include/abg-ctf-reader.h b/include/abg-ctf-reader.h index 3343f0d8..827d1bc2 100644 --- a/include/abg-ctf-reader.h +++ b/include/abg-ctf-reader.h @@ -19,6 +19,8 @@ #include "abg-suppression.h" #include "abg-elf-reader-common.h" +#include "ctf-api.h" + namespace abigail { namespace ctf_reader @@ -32,8 +34,25 @@ create_read_context(const std::string& elf_path, ir::environment *env); corpus_sptr read_corpus(read_context *ctxt, elf_reader::status& status); + corpus_sptr read_corpus(const read_context_sptr &ctxt, elf_reader::status &status); + +corpus_sptr +read_and_add_corpus_to_group_from_elf(read_context*, corpus_group&, elf_reader::status&); + +void +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, + ir::environment* environment); +void +set_vmlinux_ctfa_path(read_context& ctxt, + const string& filename); +std::string +dic_type_key(ctf_dict_t *dic, ctf_id_t ctf_type); } // end namespace ctf_reader } // end namespace abigail diff --git a/include/abg-ir.h b/include/abg-ir.h index a2f4e1a7..033e3708 100644 --- a/include/abg-ir.h +++ b/include/abg-ir.h @@ -136,7 +136,16 @@ class environment public: struct priv; std::unique_ptr priv_; + /// The possible debug format types. Default is DWARF_FORMAT_TYPE + enum debug_format_type + { + DWARF_FORMAT_TYPE, +#ifdef WITH_CTF + CTF_FORMAT_TYPE, +#endif + }; + debug_format_type debug_format_; /// A convenience typedef for a map of canonical types. The key is /// the pretty representation string of a particular type and the /// value is the vector of canonical types that have the same pretty @@ -236,6 +245,11 @@ public: uintptr_t get_canonical_type_from_type_id(const char*); #endif + debug_format_type + get_debug_format_type() const; + + void + set_debug_format_type(debug_format_type d); friend class class_or_union; friend class class_decl; diff --git a/src/abg-ctf-reader.cc b/src/abg-ctf-reader.cc index 2c6839cb..dcc65d4e 100644 --- a/src/abg-ctf-reader.cc +++ b/src/abg-ctf-reader.cc @@ -16,6 +16,8 @@ #include /* For open(3) */ #include #include +#include +#include #include "ctf-api.h" @@ -56,15 +58,25 @@ public: /// be read from the file then this is NULL. ctf_archive_t *ctfa; + /// The name of the vmlinux file from which the CTF archive got + /// extracted. + string vmlinux_ctfa_path_; + /// A map associating CTF type ids with libabigail IR types. This /// is used to reuse already generated types. - unordered_map types_map; + std::map types_map; + + /// A set associating unknown CTF type ids + std::set unknown_types_set; /// libelf handler for the ELF file from which we read the CTF data, /// and the corresponding file descriptor. Elf *elf_handler; int elf_fd; + /// set when ELF is ET_EXEC + bool is_elf_exec; + /// The symtab read from the ELF file. symtab_reader::symtab_sptr symtab; @@ -74,26 +86,109 @@ public: ctf_sect_t symtab_sect; ctf_sect_t strtab_sect; + corpus_sptr cur_corpus_; + corpus_group_sptr cur_corpus_group_; + + /// Getter of the current corpus group being constructed. + /// + /// @return current the current corpus being constructed, if any, or + /// nil. + const corpus_group_sptr + current_corpus_group() const + {return cur_corpus_group_;} + + /// Test if there is a corpus group being built. + /// + /// @return if there is a corpus group being built, false otherwise. + bool + has_corpus_group() const + {return bool(cur_corpus_group_);} + + /// Return the main corpus from the current corpus group, if any. + /// + /// @return the main corpus of the current corpus group, if any, nil + /// if no corpus group is being constructed. + corpus_sptr + main_corpus_from_current_group() + { + if (cur_corpus_group_) + return cur_corpus_group_->get_main_corpus(); + return corpus_sptr(); + } + + /// Test if the current corpus being built is the main corpus of the + /// current corpus group. + /// + /// @return return true iff the current corpus being built is the + /// main corpus of the current corpus group. + bool + current_corpus_is_main_corpus_from_current_group() + { + corpus_sptr main_corpus = main_corpus_from_current_group(); + + if (main_corpus && main_corpus.get() == cur_corpus_.get()) + return true; + + return false; + } + + /// Return true if the current corpus is part of a corpus group + /// being built and if it's not the main corpus of the group. + /// + /// For instance, this would return true if we are loading a linux + /// kernel *module* that is part of the current corpus group that is + /// being built. In this case, it means we should re-use types + /// coming from the "vmlinux" binary that is the main corpus of the + /// group. + /// + /// @return the corpus group the current corpus belongs to, if the + /// current corpus is part of a corpus group being built. Nil otherwise. + corpus_sptr + should_reuse_type_from_corpus_group() + { + if (has_corpus_group()) + if (corpus_sptr main_corpus = main_corpus_from_current_group()) + if (!current_corpus_is_main_corpus_from_current_group()) + return current_corpus_group(); + + return corpus_sptr(); + } + /// Associate a given CTF type ID with a given libabigail IR type. - void add_type(ctf_id_t ctf_type, type_base_sptr type) + void add_type(ctf_dict_t *dic, ctf_id_t ctf_type, type_base_sptr type) { - types_map.insert(std::make_pair(ctf_type, type)); + string key = dic_type_key(dic, ctf_type); + types_map.insert(std::make_pair(key, type)); + } + + /// Insert a given CTF unknown type ID. + /// + /// @param ctf_type the unknown type ID to be added. + void add_unknown_type(ctf_id_t ctf_type) + { + unknown_types_set.insert(ctf_type); } /// Lookup a given CTF type ID in the types map. /// /// @param ctf_type the type ID of the type to lookup. - type_base_sptr lookup_type(ctf_id_t ctf_type) + type_base_sptr lookup_type(ctf_dict_t *dic, ctf_id_t ctf_type) { type_base_sptr result; + std::string key = dic_type_key(dic, ctf_type); - auto search = types_map.find(ctf_type); + auto search = types_map.find(key); if (search != types_map.end()) result = search->second; return result; } + /// Lookup a given CTF unknown type ID in the unknown set. + /// @param ctf_type the unknown type ID to lookup. + bool lookup_unknown_type(ctf_id_t ctf_type) + { return unknown_types_set.find(ctf_type) != unknown_types_set.end(); } + /// Canonicalize all the types stored in the types map. void canonicalize_all_types(void) { @@ -105,19 +200,22 @@ public: /// /// @param elf_path the path to the ELF file. read_context(const string& elf_path, ir::environment *env) + { + initialize(elf_path, env); + } + + void initialize(const string& elf_path, ir::environment *env) { types_map.clear(); filename = elf_path; ir_env = env; elf_handler = NULL; elf_fd = -1; + is_elf_exec = false; ctfa = NULL; - } - - /// Destructor of the @ref read_context type. - ~read_context() - { - ctf_close(ctfa); + vmlinux_ctfa_path_ = ""; + symtab.reset(); + cur_corpus_group_.reset(); } }; // end class read_context. @@ -153,13 +251,18 @@ process_ctf_typedef(read_context *ctxt, return result; const char *typedef_name = ctf_type_name_raw(ctf_dictionary, ctf_type); + if (corpus_sptr corp = ctxt->should_reuse_type_from_corpus_group()) + if (result = lookup_typedef_type(typedef_name, *corp)) + return result; + type_base_sptr utype = lookup_type(ctxt, corp, tunit, ctf_dictionary, ctf_utype); if (!utype) return result; - result = dynamic_pointer_cast(ctxt->lookup_type(ctf_type)); + result = dynamic_pointer_cast(ctxt->lookup_type(ctf_dictionary, + ctf_type)); if (result) return result; @@ -180,7 +283,7 @@ process_ctf_typedef(read_context *ctxt, if (result) { add_decl_to_scope(result, tunit->get_global_scope()); - ctxt->add_type(ctf_type, result); + ctxt->add_type(ctf_dictionary, ctf_type, result); } return result; @@ -225,9 +328,20 @@ process_ctf_base_type(read_context *ctxt, type_base_sptr void_type = ctxt->ir_env->get_void_type(); decl_base_sptr type_declaration = get_type_declaration(void_type); result = is_type_decl(type_declaration); + canonicalize(result); } else { + if (corpus_sptr corp = ctxt->should_reuse_type_from_corpus_group()) + { + string normalized_type_name = type_name; + integral_type int_type; + if (parse_integral_type(type_name, int_type)) + normalized_type_name = int_type.to_string(); + if (result = lookup_basic_type(normalized_type_name, *corp)) + return result; + } + result = lookup_basic_type(type_name, *corp); if (!result) result.reset(new type_decl(ctxt->ir_env, @@ -242,7 +356,7 @@ process_ctf_base_type(read_context *ctxt, if (result) { add_decl_to_scope(result, tunit->get_global_scope()); - ctxt->add_type(ctf_type, result); + ctxt->add_type(ctf_dictionary, ctf_type, result); } return result; @@ -303,7 +417,8 @@ process_ctf_function_type(read_context *ctxt, function_parms.push_back(parm); } - result = dynamic_pointer_cast(ctxt->lookup_type(ctf_type)); + result = dynamic_pointer_cast(ctxt->lookup_type(ctf_dictionary, + ctf_type)); if (result) return result; @@ -319,7 +434,7 @@ process_ctf_function_type(read_context *ctxt, result->set_is_artificial(true); decl_base_sptr function_type_decl = get_type_declaration(result); add_decl_to_scope(function_type_decl, tunit->get_global_scope()); - ctxt->add_type(ctf_type, result); + ctxt->add_type(ctf_dictionary, ctf_type, result); } return result; @@ -419,6 +534,11 @@ process_ctf_forward_type(read_context *ctxt, } else { + if (!type_is_anonymous) + if (corpus_sptr corp = ctxt->should_reuse_type_from_corpus_group()) + if (result = lookup_class_type(type_name, *corp)) + return is_type(result); + class_decl_sptr struct_fwd(new class_decl(ctxt->ir_env, type_name, /*alignment=*/0, /*size=*/0, @@ -434,7 +554,7 @@ process_ctf_forward_type(read_context *ctxt, return is_type(result); add_decl_to_scope(result, tunit->get_global_scope()); - ctxt->add_type(ctf_type, is_type(result)); + ctxt->add_type(ctf_dictionary, ctf_type, is_type(result)); return is_type(result); } @@ -458,9 +578,14 @@ process_ctf_struct_type(read_context *ctxt, { class_decl_sptr result; std::string struct_type_name = ctf_type_name_raw(ctf_dictionary, - ctf_type); + ctf_type); bool struct_type_is_anonymous = (struct_type_name == ""); + if (!struct_type_is_anonymous) + if (corpus_sptr corp = ctxt->should_reuse_type_from_corpus_group()) + if (result = lookup_class_type(struct_type_name, *corp)) + return result; + /* The libabigail IR encodes C struct types in `class' IR nodes. */ result.reset(new class_decl(ctxt->ir_env, struct_type_name, @@ -479,7 +604,7 @@ process_ctf_struct_type(read_context *ctxt, at this point even if the members haven't been added to the IR node yet. */ add_decl_to_scope(result, tunit->get_global_scope()); - ctxt->add_type(ctf_type, result); + ctxt->add_type(ctf_dictionary, ctf_type, result); /* 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 @@ -512,6 +637,11 @@ process_ctf_union_type(read_context *ctxt, ctf_type); bool union_type_is_anonymous = (union_type_name == ""); + if (!union_type_is_anonymous) + if (corpus_sptr corp = ctxt->should_reuse_type_from_corpus_group()) + if (result = lookup_union_type(union_type_name, *corp)) + return result; + /* Create the corresponding libabigail union IR node. */ result.reset(new union_decl(ctxt->ir_env, union_type_name, @@ -528,7 +658,7 @@ process_ctf_union_type(read_context *ctxt, at this point even if the members haven't been added to the IR node yet. */ add_decl_to_scope(result, tunit->get_global_scope()); - ctxt->add_type(ctf_type, result); + ctxt->add_type(ctf_dictionary, ctf_type, result); /* 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 @@ -584,7 +714,8 @@ process_ctf_array_type(read_context *ctxt, if (!index_type) return result; - result = dynamic_pointer_cast(ctxt->lookup_type(ctf_type)); + result = dynamic_pointer_cast(ctxt->lookup_type(ctf_dictionary, + ctf_type)); if (result) return result; @@ -623,7 +754,7 @@ process_ctf_array_type(read_context *ctxt, { decl_base_sptr array_type_decl = get_type_declaration(result); add_decl_to_scope(array_type_decl, tunit->get_global_scope()); - ctxt->add_type(ctf_type, result); + ctxt->add_type(ctf_dictionary, ctf_type, result); } return result; @@ -652,6 +783,11 @@ process_ctf_qualified_type(read_context *ctxt, if (!utype) return result; + result = dynamic_pointer_cast(ctxt->lookup_type(ctf_dictionary, + ctf_type)); + if (result) + return result; + qualified_type_def::CV qualifiers = qualified_type_def::CV_NONE; if (type_kind == CTF_K_CONST) qualifiers |= qualified_type_def::CV_CONST; @@ -668,7 +804,7 @@ process_ctf_qualified_type(read_context *ctxt, { decl_base_sptr qualified_type_decl = get_type_declaration(result); add_decl_to_scope(qualified_type_decl, tunit->get_global_scope()); - ctxt->add_type(ctf_type, result); + ctxt->add_type(ctf_dictionary, ctf_type, result); } return result; @@ -702,7 +838,8 @@ process_ctf_pointer_type(read_context *ctxt, if (!target_type) return result; - result = dynamic_pointer_cast(ctxt->lookup_type(ctf_type)); + result = dynamic_pointer_cast(ctxt->lookup_type(ctf_dictionary, + ctf_type)); if (result) return result; @@ -713,7 +850,7 @@ process_ctf_pointer_type(read_context *ctxt, if (result) { add_decl_to_scope(result, tunit->get_global_scope()); - ctxt->add_type(ctf_type, result); + ctxt->add_type(ctf_dictionary, ctf_type, result); } return result; @@ -736,6 +873,12 @@ process_ctf_enum_type(read_context *ctxt, ctf_id_t ctf_type) { enum_type_decl_sptr result; + std::string enum_name = ctf_type_name_raw(ctf_dictionary, ctf_type); + + if (!enum_name.empty()) + if (corpus_sptr corp = ctxt->should_reuse_type_from_corpus_group()) + if (result = lookup_enum_type(enum_name, *corp)) + return result; /* Build a signed integral type for the type of the enumerators, aka the underlying type. The size of the enumerators in bytes is @@ -769,13 +912,12 @@ process_ctf_enum_type(read_context *ctxt, return result; } - const char *enum_name = ctf_type_name_raw(ctf_dictionary, ctf_type); - result.reset(new enum_type_decl(enum_name, location(), - utype, enms, enum_name)); + result.reset(new enum_type_decl(enum_name.c_str(), location(), + utype, enms, enum_name.c_str())); if (result) { add_decl_to_scope(result, tunit->get_global_scope()); - ctxt->add_type(ctf_type, result); + ctxt->add_type(ctf_dictionary, ctf_type, result); } return result; @@ -804,7 +946,10 @@ process_ctf_type(read_context *ctxt, int type_kind = ctf_type_kind(ctf_dictionary, ctf_type); type_base_sptr result; - if ((result = ctxt->lookup_type(ctf_type))) + if (ctxt->lookup_unknown_type(ctf_type)) + return nullptr; + + if ((result = ctxt->lookup_type(ctf_dictionary, ctf_type))) return result; switch (type_kind) @@ -889,7 +1034,10 @@ process_ctf_type(read_context *ctxt, } if (!result) - fprintf(stderr, "NOT PROCESSED TYPE %lu\n", ctf_type); + { + fprintf(stderr, "NOT PROCESSED TYPE %lu\n", ctf_type); + ctxt->add_unknown_type(ctf_type); + } return result; } @@ -913,7 +1061,7 @@ lookup_type(read_context *ctxt, corpus_sptr corp, translation_unit_sptr tunit, ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type) { - type_base_sptr result = ctxt->lookup_type(ctf_type); + type_base_sptr result = ctxt->lookup_type(ctf_dictionary, ctf_type); if (!result) result = process_ctf_type(ctxt, corp, tunit, ctf_dictionary, ctf_type); @@ -921,8 +1069,8 @@ lookup_type(read_context *ctxt, corpus_sptr corp, } /// Process a CTF archive and create libabigail IR for the types, -/// variables and function declarations found in the archive. The IR -/// is added to the given corpus. +/// variables and function declarations found in the archive, iterating +/// over public symbols. The IR is added to the given corpus. /// /// @param ctxt the read context containing the CTF archive to /// process. @@ -937,43 +1085,49 @@ process_ctf_archive(read_context *ctxt, corpus_sptr corp) ir_translation_unit->set_language(translation_unit::LANG_C); corp->add(ir_translation_unit); - /* Iterate over the CTF dictionaries in the archive. */ int ctf_err; ctf_dict_t *ctf_dict; - ctf_next_t *dict_next = NULL; - const char *archive_name; + const auto symtab = ctxt->symtab; + symtab_reader::symtab_filter filter = symtab->make_filter(); + filter.set_public_symbols(); + std::string dict_name; - while ((ctf_dict = ctf_archive_next(ctxt->ctfa, &dict_next, &archive_name, - 0 /* skip_parent */, &ctf_err)) != NULL) + if (corp->get_origin() == corpus::LINUX_KERNEL_BINARY_ORIGIN) { - /* Iterate over the CTF types stored in this archive. */ - ctf_id_t ctf_type; - int type_flag; - ctf_next_t *type_next = NULL; + tools_utils::base_name(ctxt->filename, dict_name); - while ((ctf_type = ctf_type_next(ctf_dict, &type_next, &type_flag, - 1 /* want_hidden */)) != CTF_ERR) - { - process_ctf_type(ctxt, corp, ir_translation_unit, - ctf_dict, ctf_type); - } - if (ctf_errno(ctf_dict) != ECTF_NEXT_END) - fprintf(stderr, "ERROR from ctf_type_next\n"); + if (dict_name != "vmlinux") + // remove .ko suffix + dict_name.erase(dict_name.length() - 3, 3); - /* Canonicalize all the types generated above. This must be - done "a posteriori" because the processing of types may - require other related types to not be already - canonicalized. */ - ctxt->canonicalize_all_types(); + std::replace(dict_name.begin(), dict_name.end(), '-', '_'); + } - /* Iterate over the CTF variables stored in this archive. */ + if ((ctf_dict = ctf_dict_open(ctxt->ctfa, + dict_name.empty() ? NULL : dict_name.c_str(), + &ctf_err)) == NULL) + { + fprintf(stderr, "ERROR dictionary not found\n"); + abort(); + } + + for (const auto& symbol : symtab_reader::filtered_symtab(*symtab, filter)) + { + std::string sym_name = symbol->get_name(); ctf_id_t ctf_var_type; - ctf_next_t *var_next = NULL; - const char *var_name; - while ((ctf_var_type = ctf_variable_next(ctf_dict, &var_next, &var_name)) - != CTF_ERR) + if (corp->get_origin() == corpus::LINUX_KERNEL_BINARY_ORIGIN + || ctxt->is_elf_exec) + ctf_var_type= ctf_lookup_variable (ctf_dict, sym_name.c_str()); + else + ctf_var_type = ctf_lookup_by_symbol_name(ctf_dict, sym_name.c_str()); + + if (ctf_var_type == (ctf_id_t) -1) + continue; + + if (ctf_type_kind (ctf_dict, ctf_var_type) != CTF_K_FUNCTION) { + const char *var_name = sym_name.c_str(); type_base_sptr var_type = lookup_type(ctxt, corp, ir_translation_unit, ctf_dict, ctf_var_type); if (!var_type) @@ -986,50 +1140,38 @@ process_ctf_archive(read_context *ctxt, corpus_sptr corp) location(), var_name)); + var_declaration->set_symbol(symbol); add_decl_to_scope(var_declaration, - ir_translation_unit->get_global_scope()); + ir_translation_unit->get_global_scope()); } - if (ctf_errno(ctf_dict) != ECTF_NEXT_END) - fprintf(stderr, "ERROR from ctf_variable_next\n"); - - /* Iterate over the CTF functions stored in this archive. */ - ctf_next_t *func_next = NULL; - const char *func_name = NULL; - ctf_id_t ctf_sym; + else + { + const char *func_name = sym_name.c_str(); + ctf_id_t ctf_sym = ctf_var_type; + type_base_sptr func_type = lookup_type(ctxt, corp, ir_translation_unit, + ctf_dict, ctf_sym); + if (!func_type) + /* Ignore function if its type can't be sorted out. */ + continue; - while ((ctf_sym = ctf_symbol_next(ctf_dict, &func_next, &func_name, - 1 /* functions symbols only */) != CTF_ERR)) - { - ctf_id_t ctf_func_type = ctf_lookup_by_name(ctf_dict, func_name); - type_base_sptr func_type = lookup_type(ctxt, corp, ir_translation_unit, - ctf_dict, ctf_func_type); - if (!func_type) - /* Ignore function if its type can't be sorted out. */ - continue; - - elf_symbols func_elf_symbols = ctxt->symtab->lookup_symbol(func_name); - if (func_elf_symbols.size() == 0 - || func_elf_symbols[0]->get_binding() == elf_symbol::LOCAL_BINDING) - /* Ignore local functions. */ - continue; - - function_decl_sptr func_declaration; - func_declaration.reset(new function_decl(func_name, - func_type, - 0 /* is_inline */, - location())); - - add_decl_to_scope(func_declaration, - ir_translation_unit->get_global_scope()); - } - if (ctf_errno(ctf_dict) != ECTF_NEXT_END) - fprintf(stderr, "ERROR from ctf_symbol_next\n"); + function_decl_sptr func_declaration; + func_declaration.reset(new function_decl(func_name, + func_type, + 0 /* is_inline */, + location())); - ctf_dict_close(ctf_dict); + func_declaration->set_symbol(symbol); + add_decl_to_scope(func_declaration, + ir_translation_unit->get_global_scope()); + } } - if (ctf_err != ECTF_NEXT_END) - fprintf(stderr, "ERROR from ctf_archive_next\n"); + ctf_dict_close(ctf_dict); + /* Canonicalize all the types generated above. This must be + done "a posteriori" because the processing of types may + require other related types to not be already + canonicalized. */ + ctxt->canonicalize_all_types(); } /// Open the ELF file described by the given read context. @@ -1113,6 +1255,7 @@ slurp_elf_info(read_context *ctxt, corpus_sptr corp) /* Set the ELF architecture. */ GElf_Ehdr eh_mem; GElf_Ehdr *ehdr = gelf_getehdr(ctxt->elf_handler, &eh_mem); + ctxt->is_elf_exec = (ehdr->e_type == ET_EXEC); 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. */ @@ -1121,6 +1264,9 @@ slurp_elf_info(read_context *ctxt, corpus_sptr corp) 0 /* No suppressions. */); corp->set_symtab(ctxt->symtab); + if (corp->get_origin() == corpus::LINUX_KERNEL_BINARY_ORIGIN) + return 1; + /* Get the raw ELF section contents for libctf. */ Elf_Scn *ctf_scn = elf_helpers::find_section(ctxt->elf_handler, ".ctf", SHT_PROGBITS); Elf_Scn *symtab_scn = elf_helpers::find_symbol_table_section(ctxt->elf_handler); @@ -1167,6 +1313,7 @@ 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; @@ -1177,27 +1324,45 @@ read_corpus(read_context *ctxt, elf_reader::status &status) return corp; } + bool is_linux_kernel = elf_helpers::is_linux_kernel(ctxt->elf_handler); /* Set some properties of the corpus first. */ - corp->set_origin(corpus::CTF_ORIGIN); - if (!slurp_elf_info(ctxt, corp)) + if (is_linux_kernel) + corp->set_origin(corpus::LINUX_KERNEL_BINARY_ORIGIN); + else + corp->set_origin(corpus::CTF_ORIGIN); + + 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; return corp; } - /* Build the ctfa from the contents of the relevant ELF sections, - and process the CTF archive in the read context, if any. - Information about the types, variables, functions, etc contained - in the archive are added to the given corpus. */ int errp; - ctxt->ctfa = ctf_arc_bufopen(&ctxt->ctf_sect, &ctxt->symtab_sect, - &ctxt->strtab_sect, &errp); + if (corp->get_origin() == corpus::LINUX_KERNEL_BINARY_ORIGIN) + ctxt->ctfa = ctf_arc_open(ctxt->vmlinux_ctfa_path_.c_str(), &errp); + else + /* Build the ctfa from the contents of the relevant ELF sections, + and process the CTF archive in the read context, if any. + Information about the types, variables, functions, etc contained + in the archive are added to the given corpus. */ + ctxt->ctfa = ctf_arc_bufopen(&ctxt->ctf_sect, &ctxt->symtab_sect, + &ctxt->strtab_sect, &errp); + + ctxt->ir_env->canonicalization_is_done(false); if (ctxt->ctfa == NULL) status = elf_reader::STATUS_DEBUG_INFO_NOT_FOUND; else process_ctf_archive(ctxt, corp); + ctxt->ir_env->canonicalization_is_done(true); + ctxt->cur_corpus_->sort_functions(); + ctxt->cur_corpus_->sort_variables(); + /* Cleanup and return. */ + ctf_close(ctxt->ctfa); close_elf_handler(ctxt); return corp; } @@ -1216,5 +1381,93 @@ corpus_sptr read_corpus(const read_context_sptr &ctxt, elf_reader::status &status) {return read_corpus(ctxt.get(), status);} +/// Set the @ref corpus_group being created to the current read context. +/// +/// @param ctxt the read_context to consider. +/// +/// @param group the @ref corpus_group to set. +void +set_read_context_corpus_group(read_context& ctxt, + corpus_group_sptr& group) +{ + ctxt.cur_corpus_group_ = group; +} +// +/// Read a corpus and add it to a given @ref corpus_group. +/// +/// @param ctxt the reading context to consider. +/// +/// @param group the @ref corpus_group to add the new corpus to. +/// +/// @param status output parameter. The status of the read. It is set +/// by this function upon its completion. +corpus_sptr +read_and_add_corpus_to_group_from_elf(read_context* ctxt, + corpus_group& group, + elf_reader::status& status) +{ + corpus_sptr result; + corpus_sptr corp = read_corpus(ctxt, status); + if (status & elf_reader::STATUS_OK) + { + if (!corp->get_group()) + group.add_corpus(corp); + result = corp; + } + + return result; +} + +/// Re-initialize a read_context so that it can re-used to read +/// another binary. +/// +/// @param ctxt the context to re-initialize. +/// +/// @param elf_path the path to the elf file the context is to be used +/// for. +/// +/// @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 +/// that ABI artifacts that are to be compared all need to be created +/// within the same environment. +/// +/// Please also note that the life time of this environment object +/// must be greater than the life time of the resulting @ref +/// read_context the context uses resources that are allocated in the +/// environment. +void +reset_read_context(read_context_sptr &ctxt, + const std::string& elf_path, + ir::environment* environment) +{ + if (ctxt) + ctxt->initialize(elf_path, environment); +} + +/// Set the @ref filename being assigned to the current read context. +/// +/// @param ctxt the read_context to consider. +/// +/// @param filename the @ref vmlinux CTFA filename to set. +void +set_vmlinux_ctfa_path(read_context& ctxt, + const string& filename) +{ + ctxt.vmlinux_ctfa_path_ = filename; +} + +std::string +dic_type_key(ctf_dict_t *dic, ctf_id_t ctf_type) +{ + std::stringstream key; + + if (ctf_type_isparent (dic, ctf_type)) + key << std::hex << ctf_type; + else + key << std::hex << ctf_type << '-' << ctf_cuname(dic); + return key.str(); +} + } // End of namespace ctf_reader } // End of namespace abigail diff --git a/src/abg-ir.cc b/src/abg-ir.cc index 0ef5e8b2..5eebcfa3 100644 --- a/src/abg-ir.cc +++ b/src/abg-ir.cc @@ -3165,7 +3165,8 @@ typedef unordered_map // diff --git a/src/abg-tools-utils.cc b/src/abg-tools-utils.cc index e94c3003..b73786a8 100644 --- a/src/abg-tools-utils.cc +++ b/src/abg-tools-utils.cc @@ -44,6 +44,9 @@ #include #include "abg-dwarf-reader.h" +#ifdef WITH_CTF +#include "abg-ctf-reader.h" +#endif #include "abg-internal.h" #include "abg-regex.h" @@ -2234,9 +2237,11 @@ load_generate_apply_suppressions(dwarf_reader::read_context &read_ctxt, /// /// @param entry the FTSENT to consider. /// +/// @param filename the name of file. +/// /// @return true iff @p entry is for a vmlinux binary. static bool -is_vmlinux(const FTSENT *entry) +is_vmlinux(const FTSENT *entry, const string &filename) { if (entry == NULL || (entry->fts_info != FTS_F && entry->fts_info != FTS_SL) @@ -2246,7 +2251,7 @@ is_vmlinux(const FTSENT *entry) string fname = entry->fts_name; - if (fname == "vmlinux") + if (fname == filename) { string dirname; dir_name(entry->fts_path, dirname); @@ -2317,7 +2322,7 @@ find_vmlinux_and_module_paths(const string& from, continue; } - if (!found_vmlinux && is_vmlinux(entry)) + if (!found_vmlinux && is_vmlinux(entry, "vmlinux")) { vmlinux_path = entry->fts_path; found_vmlinux = true; @@ -2337,10 +2342,13 @@ find_vmlinux_and_module_paths(const string& from, /// /// @param vmlinux_path output parameter /// +/// @param vmlinux_name output parameter +/// /// return true iff the vmlinux binary was found static bool find_vmlinux_path(const string& from, - string &vmlinux_path) + string &vmlinux_path, + const string &vmlinux_name) { char* path[] = {const_cast(from.c_str()), 0}; @@ -2359,7 +2367,7 @@ find_vmlinux_path(const string& from, continue; } - if (!found_vmlinux && is_vmlinux(entry)) + if (!found_vmlinux && is_vmlinux(entry, vmlinux_name)) { vmlinux_path = entry->fts_path; found_vmlinux = true; @@ -2456,12 +2464,37 @@ get_vmlinux_path_from_kernel_dist(const string& from, dist_root += "/lib/modules"; bool found = false; - if (find_vmlinux_path(dist_root, vmlinux_path)) + if (find_vmlinux_path(dist_root, vmlinux_path, "vmlinux")) found = true; return found; } +/// Get the paths of the CTF vmlinux archive under given directory. +/// +/// @param from the directory under which to look for. +/// +/// @param vmlinux_path output parameter. The path of the CTF vmlinux +/// binary that was found. +/// +/// @return true if at least the path to the vmlinux.ctfa binary was found. +#ifdef WITH_CTF +bool +get_vmlinux_ctfa_path_from_kernel_dist(const string& from, + string& vmlinux_ctfa_path) +{ + if (!dir_exists(from)) + return false; + + string dist_root = from; + bool found = false; + if (find_vmlinux_path(dist_root, vmlinux_ctfa_path, "vmlinux.ctfa")) + found = true; + + return found; +} +#endif + /// Get the paths of the vmlinux and kernel module binaries under /// given directory. /// @@ -2543,12 +2576,21 @@ build_corpus_group_from_kernel_dist_under(const string& root, t.start(); bool got_binary_paths = get_binary_paths_from_kernel_dist(root, debug_info_root, vmlinux, modules); +#ifdef WITH_CTF + string vmlinux_ctfa; + if (got_binary_paths && + env->get_debug_format_type() == environment::CTF_FORMAT_TYPE) + { + got_binary_paths = get_vmlinux_ctfa_path_from_kernel_dist(root, vmlinux_ctfa); + ABG_ASSERT(!vmlinux_ctfa.empty()); + } +#endif + t.stop(); if (verbose) std::cerr << "DONE: " << t << "\n"; - dwarf_reader::read_context_sptr ctxt; if (got_binary_paths) { shared_ptr di_root = @@ -2558,81 +2600,149 @@ build_corpus_group_from_kernel_dist_under(const string& root, di_roots.push_back(&di_root_ptr); abigail::elf_reader::status status = abigail::elf_reader::STATUS_OK; corpus_group_sptr group; - if (!vmlinux.empty()) - { - ctxt = - dwarf_reader::create_read_context(vmlinux, di_roots ,env.get(), - /*read_all_types=*/false, - /*linux_kernel_mode=*/true); - dwarf_reader::set_do_log(*ctxt, verbose); - - t.start(); - load_generate_apply_suppressions(*ctxt, suppr_paths, - kabi_wl_paths, supprs); - t.stop(); - - if (verbose) - std::cerr << "loaded white list and generated suppr spec in: " - << t - << "\n"; - - group.reset(new corpus_group(env.get(), root)); - - set_read_context_corpus_group(*ctxt, group); - - if (verbose) - std::cerr << "reading kernel binary '" - << vmlinux << "' ...\n" << std::flush; - - // Read the vmlinux corpus and add it to the group. - t.start(); - read_and_add_corpus_to_group_from_elf(*ctxt, *group, status); - t.stop(); - - if (verbose) - std::cerr << vmlinux - << " reading DONE:" - << t << "\n"; - } - if (!group->is_empty()) - { - // 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; - - reset_read_context(ctxt, *m, di_roots, env.get(), - /*read_all_types=*/false, - /*linux_kernel_mode=*/true); - - load_generate_apply_suppressions(*ctxt, suppr_paths, - kabi_wl_paths, supprs); - - set_read_context_corpus_group(*ctxt, group); - - t.start(); - read_and_add_corpus_to_group_from_elf(*ctxt, - *group, status); - t.stop(); - if (verbose) - std::cerr << "module '" - << *m - << "' reading DONE: " - << t << "\n"; - } - - result = group; - } + if (env->get_debug_format_type() == environment::DWARF_FORMAT_TYPE) + { + dwarf_reader::read_context_sptr ctxt; + if (!vmlinux.empty()) + { + ctxt = + dwarf_reader::create_read_context(vmlinux, di_roots, env.get(), + /*read_all_types=*/false, + /*linux_kernel_mode=*/true); + dwarf_reader::set_do_log(*ctxt, verbose); + + t.start(); + load_generate_apply_suppressions(*ctxt, suppr_paths, + kabi_wl_paths, supprs); + t.stop(); + + if (verbose) + std::cerr << "loaded white list and generated suppr spec in: " + << t + << "\n"; + + group.reset(new corpus_group(env.get(), root)); + + set_read_context_corpus_group(*ctxt, group); + + if (verbose) + std::cerr << "reading kernel binary '" + << vmlinux << "' ...\n" << std::flush; + + // Read the vmlinux corpus and add it to the group. + t.start(); + read_and_add_corpus_to_group_from_elf(*ctxt, *group, status); + t.stop(); + + if (verbose) + std::cerr << vmlinux + << " reading DONE:" + << t << "\n"; + } + + if (!group->is_empty()) + { + // 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; + + reset_read_context(ctxt, *m, di_roots, env.get(), + /*read_all_types=*/false, + /*linux_kernel_mode=*/true); + + load_generate_apply_suppressions(*ctxt, suppr_paths, + kabi_wl_paths, supprs); + + set_read_context_corpus_group(*ctxt, group); + + t.start(); + read_and_add_corpus_to_group_from_elf(*ctxt, + *group, status); + t.stop(); + if (verbose) + std::cerr << "module '" + << *m + << "' reading DONE: " + << t << "\n"; + } + + result = group; + } + } +#ifdef WITH_CTF + else if (env->get_debug_format_type() == environment::CTF_FORMAT_TYPE) + { + ctf_reader::read_context_sptr ctxt; + if (!vmlinux.empty()) + { + ctxt = + ctf_reader::create_read_context(vmlinux, env.get()); + set_vmlinux_ctfa_path(*ctxt, vmlinux_ctfa); + + group.reset(new corpus_group(env.get(), root)); + set_read_context_corpus_group(*ctxt, group); + + if (verbose) + std::cerr << "reading kernel binary '" + << vmlinux << "' ...\n" << std::flush; + + // Read the vmlinux corpus and add it to the group. + t.start(); + read_and_add_corpus_to_group_from_elf(ctxt.get(), *group, status); + t.stop(); + + if (verbose) + std::cerr << vmlinux + << " reading DONE:" + << t << "\n"; + } + + if (!group->is_empty()) + { + // 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; + + reset_read_context(ctxt, *m, env.get()); + set_vmlinux_ctfa_path(*ctxt, vmlinux_ctfa); + set_read_context_corpus_group(*ctxt, group); + + t.start(); + read_and_add_corpus_to_group_from_elf(ctxt.get(), + *group, status); + t.stop(); + if (verbose) + std::cerr << "module '" + << *m + << "' reading DONE: " + << t << "\n"; + } + + result = group; + } + } +#endif } return result; diff --git a/tests/data/test-read-common/test-PR26568-2.o b/tests/data/test-read-common/test-PR26568-2.o index b192d52132766d4f95136e23f93de43a64d8cc2e..a6706e8cf508ab89927b0fccecd0268d27111ed9 100644 GIT binary patch delta 1078 zcmZuwJ#Q015Z%3R+XNC4+rf~Wtw;eB%$Z17uE08YF6d0W;^l$g=#T(agS?dAmD%_cwibb#Nn{HP|`IVN_-* zmVAHz`rg0aiWKFRqCj{BJsEYAeL@S+bhImI1kPB7YSeJW7>OZA(1_29CDoC}EE<7w zsFR{tqeK}CFQZ3+WdmmP^q!2X1vG>5tjC(Z*T_=XXAjt} z?^ap8>oM!4->O-aex+~uZQE(qtWMjpnr_9exDDHF=DRzcpk1?DR#58%`Hoe!1A7!B zTg^LutL1wmVsmS~c(+)}uitjUGkmTeaY###a!yds<{P6;&yUgdUU~i-FRVO%A=#X( z@LEpFGSh{RlZR`{0vyU3p8->G4^#sN$`0Q;=IRA5qc9}2U+_o!rrts&jvez*)(zKAJj1W*_wN`>n^!NiJ zq)4A4oum?*^gRLR*Bo;Ows%V+A&PrWJgIxNM)g7wIC4r-B9=BEzkjHoMKyJa; z<6cR+1v3%uzsx3bA#*GVy9i8=??;51BwYL=&_9GWa+XVTN^Gm4YI*z;4a-&P3c6OF z-$aI)G!!Gly?9nJ)bP(1&@Cd)j_$-e(ZWJ_ae b7pX1XF9?zz{8U!i*07e^pjUb2Nd)`?0Gw2F diff --git a/tests/data/test-read-ctf/PR27700/test-PR27700.abi b/tests/data/test-read-ctf/PR27700/test-PR27700.abi index 62df1017..fe3a897d 100644 --- a/tests/data/test-read-ctf/PR27700/test-PR27700.abi +++ b/tests/data/test-read-ctf/PR27700/test-PR27700.abi @@ -11,9 +11,8 @@ - - + diff --git a/tests/data/test-read-ctf/test-PR26568-1.o.abi b/tests/data/test-read-ctf/test-PR26568-1.o.abi index d62474ec..832dc1bd 100644 --- a/tests/data/test-read-ctf/test-PR26568-1.o.abi +++ b/tests/data/test-read-ctf/test-PR26568-1.o.abi @@ -7,47 +7,29 @@ - - - - - - - - - - - - - + - + - + - + - - + + - - - - - - - + - + diff --git a/tests/data/test-read-ctf/test-PR26568-2.o.abi b/tests/data/test-read-ctf/test-PR26568-2.o.abi index a934d15b..70e0772f 100644 --- a/tests/data/test-read-ctf/test-PR26568-2.o.abi +++ b/tests/data/test-read-ctf/test-PR26568-2.o.abi @@ -3,34 +3,28 @@ - + - + - + - + - - + + - - - - - - - + - + diff --git a/tests/data/test-read-ctf/test-PR27700.abi b/tests/data/test-read-ctf/test-PR27700.abi new file mode 100644 index 00000000..fe3a897d --- /dev/null +++ b/tests/data/test-read-ctf/test-PR27700.abi @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi b/tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi index 922a1daf..12050a5b 100644 --- a/tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi +++ b/tests/data/test-read-ctf/test-ambiguous-struct-A.o.hash.abi @@ -30,7 +30,6 @@ - - + diff --git a/tests/data/test-read-ctf/test-ambiguous-struct-B.c b/tests/data/test-read-ctf/test-ambiguous-struct-B.c index 95a93469..e592529b 100644 --- a/tests/data/test-read-ctf/test-ambiguous-struct-B.c +++ b/tests/data/test-read-ctf/test-ambiguous-struct-B.c @@ -2,4 +2,4 @@ struct A; struct B { struct A *a; }; struct A { struct B b; int foo; struct B b2; }; -static struct A a __attribute__((__used__)); +struct A a __attribute__((__used__)); diff --git a/tests/data/test-read-ctf/test-ambiguous-struct-B.o b/tests/data/test-read-ctf/test-ambiguous-struct-B.o index 06bd0f502a874ad4a10c4beb5788eaace44c2bf9..40a11fcbd4ae19b78a943812f69606cdc6c9fc15 100644 GIT binary patch delta 20 ccmX@Wb%1Nb8%9RK&2Jg^GchtvUdu8W08_UIfB*mh delta 20 ccmX@Wb%1Nb8%9RP&2Jg^GchtxUdu8W08;!1aR2}S diff --git a/tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi b/tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi index 28291eb5..83d21919 100644 --- a/tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi +++ b/tests/data/test-read-ctf/test-ambiguous-struct-B.o.hash.abi @@ -1,4 +1,7 @@ + + + @@ -18,6 +21,6 @@ - + diff --git a/tests/data/test-read-ctf/test-anonymous-fields.o.abi b/tests/data/test-read-ctf/test-anonymous-fields.o.abi index 0419c29c..2134a86d 100644 --- a/tests/data/test-read-ctf/test-anonymous-fields.o.abi +++ b/tests/data/test-read-ctf/test-anonymous-fields.o.abi @@ -3,14 +3,14 @@ - + - + - + - + @@ -18,16 +18,16 @@ - + - + - + - - + + diff --git a/tests/data/test-read-ctf/test-array-of-pointers.abi b/tests/data/test-read-ctf/test-array-of-pointers.abi index 920da28b..195361df 100644 --- a/tests/data/test-read-ctf/test-array-of-pointers.abi +++ b/tests/data/test-read-ctf/test-array-of-pointers.abi @@ -31,6 +31,6 @@ - + diff --git a/tests/data/test-read-ctf/test-callback.abi b/tests/data/test-read-ctf/test-callback.abi index 704c4971..7f9b6c5f 100644 --- a/tests/data/test-read-ctf/test-callback.abi +++ b/tests/data/test-read-ctf/test-callback.abi @@ -4,28 +4,16 @@ - - - - - - - - - - - + + + + - - - - + + + + - - - - - - + diff --git a/tests/data/test-read-ctf/test-callback2.abi b/tests/data/test-read-ctf/test-callback2.abi index bdd4ad33..ddc3e493 100644 --- a/tests/data/test-read-ctf/test-callback2.abi +++ b/tests/data/test-read-ctf/test-callback2.abi @@ -11,7 +11,7 @@ - + diff --git a/tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi b/tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi index 03dd56b3..8d5c3e36 100644 --- a/tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi +++ b/tests/data/test-read-ctf/test-conflicting-type-syms-a.o.hash.abi @@ -8,7 +8,7 @@ - - + + diff --git a/tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi b/tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi index 35bcac7a..992b669d 100644 --- a/tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi +++ b/tests/data/test-read-ctf/test-conflicting-type-syms-b.o.hash.abi @@ -7,7 +7,7 @@ - - + + diff --git a/tests/data/test-read-ctf/test-dynamic-array.o.abi b/tests/data/test-read-ctf/test-dynamic-array.o.abi index 02b22811..a9849d49 100644 --- a/tests/data/test-read-ctf/test-dynamic-array.o.abi +++ b/tests/data/test-read-ctf/test-dynamic-array.o.abi @@ -21,7 +21,7 @@ - + diff --git a/tests/data/test-read-ctf/test-enum-ctf.o.abi b/tests/data/test-read-ctf/test-enum-ctf.o.abi new file mode 100644 index 00000000..f36f3fad --- /dev/null +++ b/tests/data/test-read-ctf/test-enum-ctf.o.abi @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/test-read-ctf/test-enum-many-ctf.o.hash.abi b/tests/data/test-read-ctf/test-enum-many-ctf.o.hash.abi new file mode 100644 index 00000000..67a958a7 --- /dev/null +++ b/tests/data/test-read-ctf/test-enum-many-ctf.o.hash.abi @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/test-read-ctf/test-enum-many.o.hash.abi b/tests/data/test-read-ctf/test-enum-many.o.hash.abi index 26bc048c..116325f9 100644 --- a/tests/data/test-read-ctf/test-enum-many.o.hash.abi +++ b/tests/data/test-read-ctf/test-enum-many.o.hash.abi @@ -61,9 +61,7 @@ - - - - + + diff --git a/tests/data/test-read-ctf/test-enum-symbol-ctf.o.hash.abi b/tests/data/test-read-ctf/test-enum-symbol-ctf.o.hash.abi new file mode 100644 index 00000000..fea6eb8b --- /dev/null +++ b/tests/data/test-read-ctf/test-enum-symbol-ctf.o.hash.abi @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/tests/data/test-read-ctf/test-enum-symbol.o.hash.abi b/tests/data/test-read-ctf/test-enum-symbol.o.hash.abi index d128b5b1..f4911bc4 100644 --- a/tests/data/test-read-ctf/test-enum-symbol.o.hash.abi +++ b/tests/data/test-read-ctf/test-enum-symbol.o.hash.abi @@ -10,7 +10,6 @@ - - + diff --git a/tests/data/test-read-ctf/test-enum.o.abi b/tests/data/test-read-ctf/test-enum.o.abi index 88e6ad61..bd3a55be 100644 --- a/tests/data/test-read-ctf/test-enum.o.abi +++ b/tests/data/test-read-ctf/test-enum.o.abi @@ -16,9 +16,7 @@ - - - - + + diff --git a/tests/data/test-read-ctf/test-forward-type-decl.abi b/tests/data/test-read-ctf/test-forward-type-decl.abi index 21bb45c8..026e7d32 100644 --- a/tests/data/test-read-ctf/test-forward-type-decl.abi +++ b/tests/data/test-read-ctf/test-forward-type-decl.abi @@ -24,6 +24,6 @@ - + diff --git a/tests/data/test-read-ctf/test-functions-declaration.abi b/tests/data/test-read-ctf/test-functions-declaration.abi index 9ef05e44..7eb57d26 100644 --- a/tests/data/test-read-ctf/test-functions-declaration.abi +++ b/tests/data/test-read-ctf/test-functions-declaration.abi @@ -7,11 +7,11 @@ - + - + diff --git a/tests/data/test-read-ctf/test-list-struct.abi b/tests/data/test-read-ctf/test-list-struct.abi index 196a79a1..deb6a4a1 100644 --- a/tests/data/test-read-ctf/test-list-struct.abi +++ b/tests/data/test-read-ctf/test-list-struct.abi @@ -14,7 +14,7 @@ - - + + diff --git a/tests/data/test-read-ctf/test0 b/tests/data/test-read-ctf/test0 index aca7fbacdfff7ad2caf0142390710373a8da72a1..90aa8a39a2e1326a5cb5faaa9e854fc344caaa52 100755 GIT binary patch delta 1886 zcmah~L2MgE6rEkWZra+(ZUVNWHnG!6kSdbB4pp+Tz+NFxdrBKokUdjHSN zd;ibh8SlFBwsHP~(HKr_=EVc^gezjg69eK-2CcCEMV+OqRCA^GGli z>$IIInx!!1vl-J3)7k7`$O(J&cW80VdGA07&*>>?n$G1?dj~K!MU=jF68%x}p%rjS z05{6)U9bt^c>!xMeHzgay_Cwy+>9NtOp13EYtzZxal@iZxop2JP89yD`B7>5=r>fb zh1bE}QKfpQXEf3Ou)y|eu3azM=tbv6uyK*>U=M?}M4WuEG4X9jZ%4t}B0(RIW{o)g ztb7~FZu}sEUGyzq8AHp?loq0|C=(`#L0t= ziZq}62-7#gTIleuVkf!(1I*r0l@pXYCiitZD&s=c)13s1jE+0)4%m&AW2eoP6DW8M z#YTYVF^&Uo0S^IJ033+;4u}FRzy@vsG2nMVHgpf@15DJ|i#Q9wBJy?hfI+OoBJ$AE zfW>o!M+8J>1BIT%j+a|`ugcxKkG z@NnLrnX6Z8!FmlTwV7$AUiW7!^_kf!nG;V(UzuCX%-8(+YOTJ!;Z5u_=v3a?pA31b z!(@og=Eq_#Pt`|*rb2yd1#4go3VCqy`K6Uuq`pW}M4Nf*sJtrq(reWctCsk?m6WNl z2)<~Em8USe-){R_tv?$LRv%JYs5#2Z+HI4V$jjCF>%7}K=gV%S$-WIh=W`c_#dBDc zT3uj^3v6)#m(Jx=D=$IO-qj|)R9F$h;WtdTr=zZ>a7=LG}|x;{%$4|A?CKm#GDRmFz;%xK2~> zKT)&rXuoVnnyx1Q4W#`-Eog3$T`U^6X$t;NYQq0TE%+MHB?NX;F)iHf3#0R0<+&`XH#N z(X+7HWF#?*pbraz7G=z0T7=Llf`~Sev~ZQw#_8Pq&Mlh@@7#Cp?|;rc_r81Ih07v$ zQRF(B-Cp?H6r>;w3O2y{34c@fpbUuZSF_NeK15HRd0r~=v_CP~SN%(4YQLO`PfHC2 z))b`DgHVvzD%CR0Z0;czm#Y9qZ%2;=KSb0iFR-GCVZnQo?w zM4LdVfC|Qks25O=(WH)z)d!RzTs73i{^UMUhf~RT#D)ER|7+eGO#^~_0WX(y5ph|=Z!6qvKGJ# zX3?Kgw`)90e2dGB;s#tDZMemYF`NSzSNTYD%N*l%`)3(An{=ha|p{q4Cp{Y@X2Z zKvtWF|SZbxhr*YaTI5E z4Ajm9!%#>4BXm<;;w?@7v0jCP#lT8}D(v$MO4FtoK82j*aIk+F=h3YOPIRulgV-Na3b*bo>A*N-N5o z=4qx`Wq%CzhhekX{xHQauZYice4gVy;<}ZW8H~biI6-gvjM#)lPEh0o30B$y%GL?P znBC=zGdM@~Jc>SFT*3_5>zE~b2j|E>K;ir1F=oiV!mPhJVwYvJ=@Y110q02b4u$f? o2h5QDh*`3qagOXa6q%?P!TXsgs!WGy#gmz#s - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/data/test-read-ctf/test0.c b/tests/data/test-read-ctf/test0.c index eb702312..fdefd57c 100644 --- a/tests/data/test-read-ctf/test0.c +++ b/tests/data/test-read-ctf/test0.c @@ -1,3 +1,9 @@ +/* + * ELF EXEC files must use -Wl,--ctf-variables -Bdynimic options + * to export an ABI and store CTF symbols information. + * + * ctf-gcc -gctf -Wl,--ctf-variables -Bdynamic test0.c -o test0 + */ #include diff --git a/tests/data/test-read-ctf/test0.hash.abi b/tests/data/test-read-ctf/test0.hash.abi index b58520ab..eff32228 100644 --- a/tests/data/test-read-ctf/test0.hash.abi +++ b/tests/data/test-read-ctf/test0.hash.abi @@ -39,16 +39,26 @@ - - - - + + + + + + + + + + + + + + diff --git a/tests/data/test-read-ctf/test1.so.abi b/tests/data/test-read-ctf/test1.so.abi index 5b3caf63..416bd39d 100644 --- a/tests/data/test-read-ctf/test1.so.abi +++ b/tests/data/test-read-ctf/test1.so.abi @@ -16,8 +16,13 @@ - - - + + + + + + + + diff --git a/tests/data/test-read-ctf/test1.so.hash.abi b/tests/data/test-read-ctf/test1.so.hash.abi index 8019cb54..b3620e75 100644 --- a/tests/data/test-read-ctf/test1.so.hash.abi +++ b/tests/data/test-read-ctf/test1.so.hash.abi @@ -16,8 +16,13 @@ - + + + + + + diff --git a/tests/data/test-read-ctf/test2.so.abi b/tests/data/test-read-ctf/test2.so.abi index eb6aff3e..67f802f9 100644 --- a/tests/data/test-read-ctf/test2.so.abi +++ b/tests/data/test-read-ctf/test2.so.abi @@ -20,6 +20,14 @@ + + + + + + + + diff --git a/tests/data/test-read-ctf/test2.so.hash.abi b/tests/data/test-read-ctf/test2.so.hash.abi index 6e57333b..6bbf347e 100644 --- a/tests/data/test-read-ctf/test2.so.hash.abi +++ b/tests/data/test-read-ctf/test2.so.hash.abi @@ -20,6 +20,14 @@ + + + + + + + + diff --git a/tests/data/test-read-ctf/test3.so.abi b/tests/data/test-read-ctf/test3.so.abi index 9d55fec5..3d2f6326 100644 --- a/tests/data/test-read-ctf/test3.so.abi +++ b/tests/data/test-read-ctf/test3.so.abi @@ -8,5 +8,9 @@ + + + + diff --git a/tests/data/test-read-ctf/test3.so.hash.abi b/tests/data/test-read-ctf/test3.so.hash.abi index 9d55fec5..1c69e2e1 100644 --- a/tests/data/test-read-ctf/test3.so.hash.abi +++ b/tests/data/test-read-ctf/test3.so.hash.abi @@ -8,5 +8,9 @@ + + + + diff --git a/tests/data/test-read-ctf/test4.so.abi b/tests/data/test-read-ctf/test4.so.abi index b8e0ead3..dc18e191 100644 --- a/tests/data/test-read-ctf/test4.so.abi +++ b/tests/data/test-read-ctf/test4.so.abi @@ -10,5 +10,11 @@ + + + + + + diff --git a/tests/data/test-read-ctf/test4.so.hash.abi b/tests/data/test-read-ctf/test4.so.hash.abi index dbe34d9c..dc428592 100644 --- a/tests/data/test-read-ctf/test4.so.hash.abi +++ b/tests/data/test-read-ctf/test4.so.hash.abi @@ -10,5 +10,11 @@ + + + + + + diff --git a/tests/data/test-read-ctf/test5.o.abi b/tests/data/test-read-ctf/test5.o.abi index eb30cf6a..f7bcdeb1 100644 --- a/tests/data/test-read-ctf/test5.o.abi +++ b/tests/data/test-read-ctf/test5.o.abi @@ -17,34 +17,32 @@ - - - - - - - - - - + + + + + + + + - + - + - + - + - + - + - + - + - + diff --git a/tests/data/test-read-ctf/test7.o.abi b/tests/data/test-read-ctf/test7.o.abi index b744fac5..a13af174 100644 --- a/tests/data/test-read-ctf/test7.o.abi +++ b/tests/data/test-read-ctf/test7.o.abi @@ -3,40 +3,31 @@ - - + - + - + - + - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - + + - + diff --git a/tests/data/test-read-ctf/test8.o.abi b/tests/data/test-read-ctf/test8.o.abi index 68b3af06..b6996c29 100644 --- a/tests/data/test-read-ctf/test8.o.abi +++ b/tests/data/test-read-ctf/test8.o.abi @@ -4,7 +4,7 @@ - + diff --git a/tests/data/test-read-ctf/test9.o.abi b/tests/data/test-read-ctf/test9.o.abi index 746dd77b..08704d79 100644 --- a/tests/data/test-read-ctf/test9.o.abi +++ b/tests/data/test-read-ctf/test9.o.abi @@ -49,7 +49,7 @@ - + diff --git a/tests/test-read-ctf.cc b/tests/test-read-ctf.cc index fdf49e90..215ed8d6 100644 --- a/tests/test-read-ctf.cc +++ b/tests/test-read-ctf.cc @@ -269,20 +269,28 @@ static InOutSpec in_out_specs[] = "output/test-read-ctf/test-list-struct.abi", }, { - "data/test-read-ctf/test-callback2.o", + "data/test-read-common/test-PR26568-1.o", "", "", SEQUENCE_TYPE_ID_STYLE, - "data/test-read-ctf/test-callback2.abi", - "output/test-read-ctf/test-callback2.abi", + "data/test-read-ctf/test-PR26568-1.o.abi", + "output/test-read-ctf/test-PR26568-1.o.abi", }, { - "data/test-read-ctf/test-forward-undefine-type-decl.o", + "data/test-read-common/test-PR26568-2.o", "", "", SEQUENCE_TYPE_ID_STYLE, - "data/test-read-ctf/test-forward-undefine-type-decl.abi", - "output/test-read-ctf/test-forward-undefine-type-decl.abi", + "data/test-read-ctf/test-PR26568-2.o.abi", + "output/test-read-ctf/test-PR26568-2.o.abi", + }, + { + "data/test-read-ctf/test-callback2.o", + "", + "", + SEQUENCE_TYPE_ID_STYLE, + "data/test-read-ctf/test-callback2.abi", + "output/test-read-ctf/test-callback2.abi", }, // This should be the last entry. {NULL, NULL, NULL, SEQUENCE_TYPE_ID_STYLE, NULL, NULL} diff --git a/tools/abidw.cc b/tools/abidw.cc index f7a8937d..f9287b47 100644 --- a/tools/abidw.cc +++ b/tools/abidw.cc @@ -958,6 +958,11 @@ main(int argc, char* argv[]) environment_sptr env(new environment); int exit_code = 0; +#ifdef WITH_CTF + if (opts.use_ctf) + env->set_debug_format_type(environment::CTF_FORMAT_TYPE); +#endif + if (tools_utils::is_regular_file(opts.in_file_path)) exit_code = load_corpus_and_write_abixml(argv, env, opts); else