From patchwork Mon Mar 28 13:04:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luis Machado X-Patchwork-Id: 554814 Delivered-To: patch@linaro.org Received: by 2002:a05:7000:1248:0:0:0:0 with SMTP id z8csp8467719mag; Mon, 28 Mar 2022 06:05:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzJanEr+QxonR/U6OeJpk3/AzgCP7aIYAag+5dKWLn798rtM93V+9Hm2NrLNF24EHgEu5Kq X-Received: by 2002:a17:906:2699:b0:6d0:9f3b:a6a7 with SMTP id t25-20020a170906269900b006d09f3ba6a7mr26654078ejc.397.1648472706552; Mon, 28 Mar 2022 06:05:06 -0700 (PDT) Return-Path: Received: from sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id w20-20020a056402129400b00418c2b5bdcbsi14054669edv.173.2022.03.28.06.05.06 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Mar 2022 06:05:06 -0700 (PDT) Received-SPF: pass (google.com: domain of gdb-patches-bounces+patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=EISZAqt0; arc=fail (signature failed); spf=pass (google.com: domain of gdb-patches-bounces+patch=linaro.org@sourceware.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gdb-patches-bounces+patch=linaro.org@sourceware.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 5B356385803D for ; Mon, 28 Mar 2022 13:05:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5B356385803D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1648472705; bh=2YhWn9FDYGsPBF/WmEO1GHM+BDHkKZZBYOD/03hFAjs=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=EISZAqt0M/ftQAieWYx6mZAJgRNfQtclc0I3i1rU3M3xvf4CT5TF4wB3TwoFfsYPg KSHURHWoYFdHHPjOqjmpeJZIAWwXgtP7HOkTdYiy8kkV8+eJcU1dvxYAl2WvOQ5cpo D/uLvSmqr8OZERpZunvVVtTrtQVX+zJiHarMxf4I= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-eopbgr80085.outbound.protection.outlook.com [40.107.8.85]) by sourceware.org (Postfix) with ESMTPS id 99CE43858C56 for ; Mon, 28 Mar 2022 13:04:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 99CE43858C56 Received: from DB6PR0802CA0037.eurprd08.prod.outlook.com (2603:10a6:4:a3::23) by AM0PR08MB4513.eurprd08.prod.outlook.com (2603:10a6:208:147::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5102.16; Mon, 28 Mar 2022 13:04:31 +0000 Received: from DB5EUR03FT035.eop-EUR03.prod.protection.outlook.com (2603:10a6:4:a3:cafe::b8) by DB6PR0802CA0037.outlook.office365.com (2603:10a6:4:a3::23) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4844.15 via Frontend Transport; Mon, 28 Mar 2022 13:04:31 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by DB5EUR03FT035.mail.protection.outlook.com (10.152.20.65) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5102.18 via Frontend Transport; Mon, 28 Mar 2022 13:04:31 +0000 Received: ("Tessian outbound 1f399c739551:v113"); Mon, 28 Mar 2022 13:04:31 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: bd5cb9556416287f X-CR-MTA-TID: 64aa7808 Received: from 55ac475fa67d.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id E6996B12-23DF-4710-A9AC-05133D5ED869.1; Mon, 28 Mar 2022 13:04:24 +0000 Received: from EUR05-VI1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 55ac475fa67d.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Mon, 28 Mar 2022 13:04:24 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=FNrocODJ4CFGAdWDSML9yn7qdXt37fHhw+WMqiz0EIypHmJK2vXz9fMCdQRp6EXP8WuTlFq4RgfxCvVNmu76N28dwEJXo1vmHvoDHRYcSQXi7of9STtCjaMBAJgLW1PnvtQFnH+Ot5825BFh3GdXZnnaBeFwDywuJm8s/N/Jx4Wuw5K7lNh1TuyZ6zLCZqGJBUotnFdkr4d3v80ZhZE/1Tq2XvYl0+F1Us+6nJdplzlBIh/eUN3jKBw33cm1myFnk9SKOBuToc4JVJHfo1lQXzPoNiTFA2Nnam89XfGPvWQBXWrgoPj1Hxssbe3ZlCenZw6wOFvKgitbLspVuDjj/A== 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=2YhWn9FDYGsPBF/WmEO1GHM+BDHkKZZBYOD/03hFAjs=; b=hbsqY5VyRzN/lGDc3rn3EuPrOwvd2UPXvDWpfL5nPHO2FR+PBYu4ke3qSGWGTVW7qkwYRKRDyqWCjlpWnsBAV8YY2Xoj6OgY1KG9Xeltiqaxtom+jcY4aIecYWiGqgE4rWTd21SHfKCRcYllLO+BU7b5sesuLM3f79TRT7G1LHkDcXjdQ+rTSKqLB/OuWxcUtd82M0gIJ4uWqgRfijyN6P4n0BRRAyIidNf7MNCek8joE20LZ/Fln3Fu0Bhvk2v/TVnPeW/tHKiEKofHs8MnCXLOoAgHnjiTrdTnKZDlRk3fGmWF/cn8QuUPzRyiriwWevW3Ip45JNnApXYmblzcmg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass (sender ip is 40.67.248.234) smtp.rcpttodomain=sourceware.org smtp.mailfrom=arm.com; dmarc=pass (p=none sp=none pct=100) action=none header.from=arm.com; dkim=none (message not signed); arc=none Received: from AS8P189CA0013.EURP189.PROD.OUTLOOK.COM (2603:10a6:20b:31f::22) by PR3PR08MB5628.eurprd08.prod.outlook.com (2603:10a6:102:8e::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5102.18; Mon, 28 Mar 2022 13:04:23 +0000 Received: from AM5EUR03FT023.eop-EUR03.prod.protection.outlook.com (2603:10a6:20b:31f:cafe::c) by AS8P189CA0013.outlook.office365.com (2603:10a6:20b:31f::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.5102.16 via Frontend Transport; Mon, 28 Mar 2022 13:04:23 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 40.67.248.234) smtp.mailfrom=arm.com; dkim=none (message not signed) header.d=none;dmarc=pass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 40.67.248.234 as permitted sender) receiver=protection.outlook.com; client-ip=40.67.248.234; helo=nebula.arm.com; Received: from nebula.arm.com (40.67.248.234) by AM5EUR03FT023.mail.protection.outlook.com (10.152.16.169) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.20.5102.18 via Frontend Transport; Mon, 28 Mar 2022 13:04:23 +0000 Received: from AZ-NEU-EX01.Emea.Arm.com (10.251.26.4) by AZ-NEU-EX04.Arm.com (10.251.24.32) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.2308.27; Mon, 28 Mar 2022 13:04:26 +0000 Received: from AZ-NEU-EX04.Arm.com (10.251.24.32) by AZ-NEU-EX01.Emea.Arm.com (10.251.26.4) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.2308.27; Mon, 28 Mar 2022 13:04:21 +0000 Received: from e129171.cambridge.arm.com (10.2.80.38) by mail.arm.com (10.251.24.32) with Microsoft SMTP Server id 15.1.2308.27 via Frontend Transport; Mon, 28 Mar 2022 13:04:25 +0000 To: Subject: [PATCH] [ARM] Enable ARMv8.1-m PACBTI support Date: Mon, 28 Mar 2022 14:04:06 +0100 Message-ID: <20220328130406.1594505-1-luis.machado@arm.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-EOPAttributedMessage: 1 X-MS-Office365-Filtering-Correlation-Id: 9ad73ee8-0464-4a9c-e4ea-08da10bb7f9d X-MS-TrafficTypeDiagnostic: PR3PR08MB5628:EE_|DB5EUR03FT035:EE_|AM0PR08MB4513:EE_ X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true NoDisclaimer: true X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: hBswqqoZjU5kBDBFNfgi6BqBjQcquV/rsyw/DimSvn5754Ar5DYKqABKFIT+nF8Sz9PbmuqpqAxJxc605pIot++LdmwpmUceZ6x96nuERV0lNASeDe3hH9fPvMa5jP0KGJPI8JzxaiZXObpkjcoe1kNFkHXs6HGzlppbxkmogxJetQGWYPMkda0PKJyi3MMyldAE83ni394RA2Os2DJ94GAVjDjkM9pe+1ycU+fT7A9Es+rZood+iHQtyEIestqAai3KenJwfepzNUTdnBj9xmY1t5Wx/9TtoUd5oYS1zLQ8lfZ0Efc6jBuYupjjaXrv5ux2DMy7W3RtUSVbC1ZVn4sXsz3+LDi6oTpM1eVPkCIMrNbZsO+7dPwC+/4CBS+5skRJWK72pwmhVGkV23wZ5yFEQUGrz0Y0KkhrE8sq9kbyf/HyU28Y4ipbxM0apq6UHX7hJcWRkx4zOxijjJuLAQnbwByoZzYVV9uxRDjxBaUg2Y+rKDSAKD8jzS/s0/bRqaaaAa7vTDW6OSHBnDj5/820a+m0ZlQ8FCG7Kkd3936ECUZkgRo9sdsZFLzHTLnuxp+YCozjgJTpFum2UYox/2NlV0TDukgLDb6kvPCQrhHmTwVBxZoxemuq6HHGkENB/AssAI1J05S4fg1k77FnR8wCWhdlSaESN0ZR/FnhFfK9hnzRUI4NbZyoSkGpgwuorduLVxW+MuXiUlMkIQBdgyapOjXe1QhRYFXhJlfA5FNySgfH16R0QPpEqEZTgOMa/t7Q1KicbNyJgBN1181+N+Qnofajc9IH9RL33irw0JoOVH922Bue53BWD2/G5CRdYVweXQCBuwJOwZbiaNPjNg== X-Forefront-Antispam-Report-Untrusted: CIP:40.67.248.234; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:nebula.arm.com; PTR:InfoDomainNonexistent; CAT:NONE; SFS:(13230001)(4636009)(46966006)(36840700001)(40470700004)(86362001)(26005)(316002)(2906002)(30864003)(40460700003)(36756003)(8936002)(508600001)(7696005)(83380400001)(1076003)(2616005)(6916009)(426003)(5660300002)(186003)(45080400002)(336012)(44832011)(8676002)(4326008)(70586007)(36860700001)(47076005)(966005)(70206006)(81166007)(82310400004)(6666004)(356005)(36900700001); DIR:OUT; SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: PR3PR08MB5628 X-MS-Exchange-Transport-CrossTenantHeadersStripped: DB5EUR03FT035.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: 8bee8304-542d-41c8-e090-08da10bb7ad8 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: p/VgxfKgsORZ8eGv2Fytwib6SBdDX1OfOiTigAmnhjWo/YHqwDaUi2lCJ1htyI/pP2pFAei80g0ura5w90zTC87ikR8YS/hf3xoIAn4q2MkMVpHEpHL7sQFwzDPhw/IcwdVElMVIe9JSjtqUSb5U8VxPPpXI+7m50PCKj+8dGUYIX++9S23K4s5SWHgc8JmCFnbxlJ8HlRaWaYipPGBDyuMS6mZq8nBPiv+zY5MxzwR9Nv1lHf/RmSEWd3ZMn+1iZyHLt2PWVEFzHOvLf5YA3ttf30eHEmy9M4AcqlnJWVV6Z9TtLz9w9ylnXCxyKFmkBFxDc0Ux0gC0lDSVnvjfGg7zbc8eQQpqHyuSGKhDDsYDVS0UYIrtRP8okRrKSV1XVfakgmk3DTsB9NvCXZY6QkGLnOiYYqge2Ijc5aQxKbQ7Tm984t8f2h0to3/4tXfauyUxmavM6+lEURDx8a45zZETsZFe4rE2sZfMbOcK7aF+4THX7uXssp2m1yYjnkKrbTl0XE/0Hel8QT3VD+5M+nYPmxumCyLzs87kTQhgkDfEzezDiTL7uvCYtv+exyTpIEEUjgXLmG4zFf7qrtQw4n1x/SuzrXeTiFmOh5XGDYwqw60hcUqskC6LJJHaH4vOojB3/vu+rpEf3HwRSuKf0J3gM+2td5S8J9LXcr70XbqSHVMnjuCyLlyuGcFfL9Tf5oBD7pyG+RRbjZWn3AnET8+LW3ra+7ImEu2GyQWXMFLJw28hG744Eu1WK7NE65S6gk4c23C6SsmCnyLiu6hZv82PBw6hSXI391iHAVb5l6Y= X-Forefront-Antispam-Report: CIP:63.35.35.123; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:64aa7808-outbound-1.mta.getcheckrecipient.com; PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com; CAT:NONE; SFS:(13230001)(4636009)(36840700001)(40470700004)(46966006)(36860700001)(36756003)(47076005)(30864003)(6666004)(70206006)(44832011)(2906002)(86362001)(40460700003)(316002)(1076003)(8936002)(6916009)(82310400004)(508600001)(4326008)(81166007)(45080400002)(26005)(83380400001)(186003)(426003)(966005)(336012)(8676002)(5660300002)(70586007)(7696005)(2616005); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Mar 2022 13:04:31.2229 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 9ad73ee8-0464-4a9c-e4ea-08da10bb7f9d X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[63.35.35.123]; Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: DB5EUR03FT035.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR08MB4513 X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, LIKELY_SPAM_BODY, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_PASS, TXREP, T_SCC_BODY_TEXT_LINE, UNPARSEABLE_RELAY 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: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Luis Machado via Gdb-patches From: Luis Machado Reply-To: Luis Machado Errors-To: gdb-patches-bounces+patch=linaro.org@sourceware.org Sender: "Gdb-patches" From: Luis Machado This set of changes enable support for the ARMv8.1-m PACBTI extensions [1]. The goal of the PACBTI extensions is similar in scope to that of a-profile PAC/BTI (aarch64 only), but the underlying implementation is different. One important difference is that the pointer authentication code is stored in a separate register, thus we don't need to mask/unmask the return address from a function in order to produce a correct backtrace. The patch introduces the following modifications: - Extend the prologue analyser for 32-bit ARM to handle some instructions from ARMv8.1-m PACBTI: pac, aut, pacg, autg and bti. Also keep track of return address signing/authentication instructions. - Adds code to identify object file attributes that indicate the presence of ARMv8.1-m PACBTI (Tag_PAC_extension, Tag_BTI_extension, Tag_PACRET_use and Tag_BTI_use). - Adds support for DWARF pseudo-register RA_AUTH_CODE, as described in the aadwarf32 [2]. - Extends the dwarf unwinder to track the value of RA_AUTH_CODE. - Decorates backtraces with the "[PAC]" identifier when a frame has signed the return address. - Makes GDB aware of a new XML feature "org.gnu.gdb.arm.m-profile-pacbti". This feature is not included as an XML file on GDB's side because it is only supported for bare metal targets. - Additional documentation. [1] https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/armv8-1-m-pointer-authentication-and-branch-target-identification-extension [2] https://github.com/ARM-software/abi-aa/blob/main/aadwarf32/aadwarf32.rst --- gdb/arch/arm.h | 13 +++ gdb/arm-tdep.c | 241 ++++++++++++++++++++++++++++++++++++++++---- gdb/arm-tdep.h | 6 ++ gdb/doc/gdb.texinfo | 7 ++ 4 files changed, 247 insertions(+), 20 deletions(-) diff --git a/gdb/arch/arm.h b/gdb/arch/arm.h index f75470e7572..755391fe6fe 100644 --- a/gdb/arch/arm.h +++ b/gdb/arch/arm.h @@ -21,6 +21,19 @@ #include "gdbsupport/tdesc.h" +/* Prologue helper macros for ARMv8.1-m PACBTI. */ +#define IS_PAC(instruction) (instruction == 0xf3af801d) +#define IS_PACBTI(instruction) (instruction == 0xf3af800d) +#define IS_BTI(instruction) (instruction == 0xf3af800f) +#define IS_PACG(instruction) ((instruction & 0xfff0f0f0) == 0xfb60f000) +#define IS_AUT(instruction) (instruction == 0xf3af802d) +#define IS_AUTG(instruction) ((instruction & 0xfff00ff0) == 0xfb500f00) + +/* DWARF register numbers according to the AADWARF32 document. */ +enum arm_dwarf_regnum { + ARM_DWARF_RA_AUTH_CODE = 143 +}; + /* Register numbers of various important registers. */ enum gdb_regnum { diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index d216d1daff7..96aa213f6f5 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -38,6 +38,7 @@ #include "frame-base.h" #include "trad-frame.h" #include "objfiles.h" +#include "dwarf2.h" #include "dwarf2/frame.h" #include "gdbtypes.h" #include "prologue-value.h" @@ -286,6 +287,9 @@ struct arm_prologue_cache /* The register used to hold the frame pointer for this frame. */ int framereg; + /* True if the return address is signed, false otherwise. */ + gdb::optional ra_signed_state; + /* Saved register offsets. */ trad_frame_saved_reg *saved_regs; }; @@ -713,6 +717,7 @@ thumb_analyze_prologue (struct gdbarch *gdbarch, while (start < limit) { unsigned short insn; + gdb::optional ra_signed_state; insn = read_code_unsigned_integer (start, 2, byte_order_for_code); @@ -847,6 +852,7 @@ thumb_analyze_prologue (struct gdbarch *gdbarch, inst2 = read_code_unsigned_integer (start + 2, 2, byte_order_for_code); + uint32_t whole_insn = (insn << 16) | inst2; if ((insn & 0xf800) == 0xf000 && (inst2 & 0xe800) == 0xe800) { @@ -1100,7 +1106,37 @@ thumb_analyze_prologue (struct gdbarch *gdbarch, constant = read_memory_unsigned_integer (loc + 4, 4, byte_order); regs[bits (inst2, 8, 11)] = pv_constant (constant); } - + /* Start of ARMv8.1-m PACBTI extension instructions. */ + else if (IS_PAC (whole_insn)) + { + /* LR and SP are input registers. PAC is in R12. LR is + signed from this point onwards. NOP space. */ + ra_signed_state = true; + } + else if (IS_PACBTI (whole_insn)) + { + /* LR and SP are input registers. PAC is in R12 and PC is a + valid BTI landing pad. LR is signed from this point onwards. + NOP space. */ + ra_signed_state = true; + } + else if (IS_BTI (whole_insn)) + { + /* Valid BTI landing pad. NOP space. */ + } + else if (IS_PACG (whole_insn)) + { + /* Sign Rn using Rm and store the PAC in Rd. Rd is signed from + this point onwards. */ + ra_signed_state = true; + } + else if (IS_AUT (whole_insn) || IS_AUTG (whole_insn)) + { + /* These instructions appear close to the epilogue, when signed + pointers are getting authenticated. */ + ra_signed_state = false; + } + /* End of ARMv8.1-m PACBTI extension instructions */ else if (thumb2_instruction_changes_pc (insn, inst2)) { /* Don't scan past anything that might change control flow. */ @@ -1113,6 +1149,21 @@ thumb_analyze_prologue (struct gdbarch *gdbarch, unrecognized_pc = start; } + arm_gdbarch_tdep *tdep + = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch); + + /* Make sure we are dealing with a target that supports ARMv8.1-m + PACBTI. */ + if (cache != nullptr && tdep->have_pacbti + && ra_signed_state.has_value ()) + { + arm_debug_printf ("Found pacbti instruction at %s", + paddress (gdbarch, start)); + arm_debug_printf ("RA is %s", + *ra_signed_state? "signed" : "not signed"); + cache->ra_signed_state = ra_signed_state; + } + start += 2; } else if (thumb_instruction_changes_pc (insn)) @@ -1988,6 +2039,13 @@ arm_prologue_prev_register (struct frame_info *this_frame, *this_cache = arm_make_prologue_cache (this_frame); cache = (struct arm_prologue_cache *) *this_cache; + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch); + + /* If this frame has signed the return address, mark it as so. */ + if (tdep->have_pacbti && cache->ra_signed_state.has_value () + && *cache->ra_signed_state) + set_frame_previous_pc_masked (this_frame); + /* If we are asked to unwind the PC, then we need to return the LR instead. The prologue may save PC, but it will point into this frame's prologue, not the next frame's resume location. Also @@ -3216,6 +3274,7 @@ arm_dwarf2_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { struct gdbarch * gdbarch = get_frame_arch (this_frame); + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch); CORE_ADDR lr, cpsr; ULONGEST t_bit = arm_psr_thumb_bit (gdbarch); @@ -3226,6 +3285,18 @@ arm_dwarf2_prev_register (struct frame_info *this_frame, void **this_cache, describes saves of LR. However, that version may have an extra bit set to indicate Thumb state. The bit is not part of the PC. */ + + /* Record in the frame whether the return address was signed. */ + if (tdep->have_pacbti) + { + CORE_ADDR ra_auth_code + = frame_unwind_register_unsigned (this_frame, + tdep->pacbti_pseudo_base); + + if (ra_auth_code != 0) + set_frame_previous_pc_masked (this_frame); + } + lr = frame_unwind_register_unsigned (this_frame, ARM_LR_REGNUM); return frame_unwind_got_constant (this_frame, regnum, arm_addr_bits_remove (gdbarch, lr)); @@ -3246,24 +3317,6 @@ arm_dwarf2_prev_register (struct frame_info *this_frame, void **this_cache, } } -static void -arm_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, - struct dwarf2_frame_state_reg *reg, - struct frame_info *this_frame) -{ - switch (regnum) - { - case ARM_PC_REGNUM: - case ARM_PS_REGNUM: - reg->how = DWARF2_FRAME_REG_FN; - reg->loc.fn = arm_dwarf2_prev_register; - break; - case ARM_SP_REGNUM: - reg->how = DWARF2_FRAME_REG_CFA; - break; - } -} - /* Implement the stack_frame_destroyed_p gdbarch method. */ static int @@ -4193,6 +4246,25 @@ is_mve_pseudo (struct gdbarch *gdbarch, int regnum) return false; } +/* Return true if REGNUM is a PACBTI pseudo register (ra_auth_code). Return + false otherwise. + + REGNUM is the raw register number and not a pseudo-relative register + number. */ + +static bool +is_pacbti_pseudo (struct gdbarch *gdbarch, int regnum) +{ + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch); + + if (tdep->have_pacbti + && regnum >= tdep->pacbti_pseudo_base + && regnum < tdep->pacbti_pseudo_base + tdep->pacbti_pseudo_count) + return true; + + return false; +} + /* Return the GDB type object for the "standard" data type of data in register N. */ @@ -4210,6 +4282,9 @@ arm_register_type (struct gdbarch *gdbarch, int regnum) if (is_mve_pseudo (gdbarch, regnum)) return builtin_type (gdbarch)->builtin_int16; + if (is_pacbti_pseudo (gdbarch, regnum)) + return builtin_type (gdbarch)->builtin_uint32; + /* If the target description has register information, we are only in this function so that we can override the types of double-precision registers for NEON. */ @@ -4272,6 +4347,17 @@ arm_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) if (reg >= 112 && reg <= 127) return ARM_WR0_REGNUM + reg - 112; + /* PACBTI register containing the Pointer Authentication Code. */ + if (reg == ARM_DWARF_RA_AUTH_CODE) + { + arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch); + + if (tdep->have_pacbti) + return tdep->pacbti_pseudo_base; + + return -1; + } + if (reg >= 192 && reg <= 199) return ARM_WC0_REGNUM + reg - 192; @@ -4337,6 +4423,35 @@ arm_register_sim_regno (struct gdbarch *gdbarch, int regnum) internal_error (__FILE__, __LINE__, _("Bad REGNUM %d"), regnum); } +static const unsigned char op_lit0 = DW_OP_lit0; + +static void +arm_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, + struct dwarf2_frame_state_reg *reg, + struct frame_info *this_frame) +{ + if (is_pacbti_pseudo (gdbarch, regnum)) + { + /* Initialize RA_AUTH_CODE to zero. */ + reg->how = DWARF2_FRAME_REG_SAVED_VAL_EXP; + reg->loc.exp.start = &op_lit0; + reg->loc.exp.len = 1; + return; + } + + switch (regnum) + { + case ARM_PC_REGNUM: + case ARM_PS_REGNUM: + reg->how = DWARF2_FRAME_REG_FN; + reg->loc.fn = arm_dwarf2_prev_register; + break; + case ARM_SP_REGNUM: + reg->how = DWARF2_FRAME_REG_CFA; + break; + } +} + /* Given BUF, which is OLD_LEN bytes ending at ENDADDR, expand the buffer to be NEW_LEN bytes ending at ENDADDR. Return NULL if an error occurs. BUF is freed. */ @@ -8683,6 +8798,10 @@ arm_register_name (struct gdbarch *gdbarch, int i) if (is_mve_pseudo (gdbarch, i)) return "p0"; + /* RA_AUTH_CODE is used for unwinding only. Do not assign it a name. */ + if (is_pacbti_pseudo (gdbarch, i)) + return ""; + if (i >= ARRAY_SIZE (arm_register_names)) /* These registers are only supported on targets which supply an XML description. */ @@ -9073,6 +9192,17 @@ arm_gnu_triplet_regexp (struct gdbarch *gdbarch) return gdbarch_bfd_arch_info (gdbarch)->arch_name; } +/* Implement the "get_pc_address_flags" gdbarch method. */ + +static std::string +arm_get_pc_address_flags (frame_info *frame, CORE_ADDR pc) +{ + if (get_frame_pc_masked (frame)) + return "PAC"; + + return ""; +} + /* Initialize the current architecture based on INFO. If possible, re-use an architecture from ARCHES, which is a list of architectures already created during this debugging session. @@ -9098,6 +9228,7 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) const struct target_desc *tdesc = info.target_desc; bool have_vfp = false; bool have_mve = false; + bool have_pacbti = false; int mve_vpr_regnum = -1; int register_count = ARM_NUM_REGS; @@ -9220,6 +9351,31 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) || attr_arch == TAG_CPU_ARCH_V8_1M_MAIN || attr_profile == 'M')) is_m = true; + + /* Look for attributes that indicate support for ARMv8.1-m + PACBTI. */ + if (!tdesc_has_registers (tdesc) && is_m) + { + int attr_pac_extension + = bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_PROC, + Tag_PAC_extension); + + int attr_bti_extension + = bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_PROC, + Tag_BTI_extension); + + int attr_pacret_use + = bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_PROC, + Tag_PACRET_use); + + int attr_bti_use + = bfd_elf_get_obj_attr_int (info.abfd, OBJ_ATTR_PROC, + Tag_BTI_use); + + if (attr_pac_extension != 0 || attr_bti_extension != 0 + || attr_pacret_use != 0 || attr_bti_use != 0) + have_pacbti = true; + } #endif } @@ -9446,6 +9602,22 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (have_vfp) have_q_pseudos = true; } + + /* Do we have the ARMv8.1-m PACBTI feature? */ + feature = tdesc_find_feature (tdesc, + "org.gnu.gdb.arm.m-profile-pacbti"); + if (feature != nullptr) + { + /* By advertising this feature, the target acknowledges the + presence of the ARMv8.1-m PACBTI extensions. + + We don't care for any particular registers in this group, so + the target is free to include whatever it deems appropriate. + + The expectation is for this feature to include the PAC + keys. */ + have_pacbti = true; + } } } @@ -9472,6 +9644,11 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (is_m != tdep->is_m) continue; + /* Also check for ARMv8.1-m PACBTI support, since it might come from + the binary. */ + if (have_pacbti != tdep->have_pacbti) + continue; + /* Found a match. */ break; } @@ -9504,6 +9681,9 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->mve_vpr_regnum = mve_vpr_regnum; } + /* Adjust the PACBTI feature settings. */ + tdep->have_pacbti = have_pacbti; + arm_register_g_packet_guesses (gdbarch); /* Breakpoints. */ @@ -9672,6 +9852,11 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double); } + /* Hook used to decorate frames with signed return addresses, only available + for ARMv8.1-m PACBTI. */ + if (is_m && have_pacbti) + set_gdbarch_get_pc_address_flags (gdbarch, arm_get_pc_address_flags); + if (tdesc_data != nullptr) { set_tdesc_pseudo_register_name (gdbarch, arm_register_name); @@ -9715,8 +9900,16 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) num_pseudos += tdep->mve_pseudo_count; } + /* Do we have any ARMv8.1-m PACBTI pseudo registers. */ + if (have_pacbti) + { + tdep->pacbti_pseudo_base = register_count + num_pseudos; + tdep->pacbti_pseudo_count = 1; + num_pseudos += tdep->pacbti_pseudo_count; + } + /* Set some pseudo register hooks, if we have pseudo registers. */ - if (tdep->have_s_pseudos || have_mve) + if (tdep->have_s_pseudos || have_mve || have_pacbti) { set_gdbarch_num_pseudo_regs (gdbarch, num_pseudos); set_gdbarch_pseudo_register_read (gdbarch, arm_pseudo_read); @@ -9776,6 +9969,14 @@ arm_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file) tdep->mve_pseudo_base); fprintf_filtered (file, _("arm_dump_tdep: mve_pseudo_count = %i\n"), tdep->mve_pseudo_count); + fprintf_filtered (file, _("arm_dump_tdep: have_pacbti = %s\n"), + tdep->have_pacbti? "yes" : "no"); + fprintf_filtered (file, _("arm_dump_tdep: pacbti_pseudo_base = %i\n"), + tdep->pacbti_pseudo_base); + fprintf_filtered (file, _("arm_dump_tdep: pacbti_pseudo_count = %i\n"), + tdep->pacbti_pseudo_count); + fprintf_filtered (file, _("arm_dump_tdep: is_m = %s\n"), + tdep->is_m? "yes" : "no"); fprintf_filtered (file, _("arm_dump_tdep: Lowest pc = 0x%lx\n"), (unsigned long) tdep->lowest_pc); } diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h index 8a9f618539f..ae32fffcabf 100644 --- a/gdb/arm-tdep.h +++ b/gdb/arm-tdep.h @@ -119,6 +119,12 @@ struct arm_gdbarch_tdep : gdbarch_tdep int mve_pseudo_base = 0; /* Number of the first MVE pseudo register. */ int mve_pseudo_count = 0; /* Total number of MVE pseudo registers. */ + bool have_pacbti = false; /* True if we have the ARMv8.1-m PACBTI + extensions. */ + int pacbti_pseudo_base = 0; /* Number of the first PACBTI pseudo + register. */ + int pacbti_pseudo_count = 0; /* Total number of PACBTI pseudo registers. */ + bool is_m = false; /* Does the target follow the "M" profile. */ CORE_ADDR lowest_pc = 0; /* Lowest address at which instructions will appear. */ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index 729f9d79a93..3b9245d5075 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -25369,6 +25369,7 @@ target process. @subsubsection AArch64 Pointer Authentication. @cindex AArch64 Pointer Authentication. +@anchor{AArch64 PAC} When @value{GDBN} is debugging the AArch64 architecture, and the program is using the v8.3-A feature Pointer Authentication (PAC), then whenever the link @@ -46522,6 +46523,12 @@ quad-precision registers from pairs of double-precision registers. If this feature is present, @samp{org.gnu.gdb.arm.vfp} must also be present and include 32 double-precision registers. +The @samp{org.gnu.gdb.arm.m-profile-pacbti} feature is optional, and +acknowledges support for the ARMv8.1-m PACBTI extensions. @value{GDBN} +will track return address signing states and will decorate backtraces using +the [PAC] marker, similar to AArch64's PAC extension. +@xref{AArch64 PAC}. + @node i386 Features @subsection i386 Features @cindex target descriptions, i386 features