From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR05-DB8-obe.outbound.protection.outlook.com (mail-db8eur05on2075.outbound.protection.outlook.com [40.107.20.75]) by sourceware.org (Postfix) with ESMTPS id D4E873858D1E for ; Tue, 21 Feb 2023 09:12:04 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org D4E873858D1E Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=arm.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=CjZ4NhoBpbLkaCSiL1jWiNTxIL334vPpBqBY0Aa4oxY=; b=lwmgNNa+4jTNWRR3Qlin37ZBaWuQ+M5V84a48YlgTnUnD6Bu0Vh612f4a9SlH1NtxupoArR2VZyATLIHxTu9mL0158nsVEcXjPLaFi2gdk+42MD/uzMch1kvTd99YqhwU6GOlRNrQ9bwqBHZjAFfuC99d3Prb2DUX50dDlo9eIo= Received: from DB9PR01CA0014.eurprd01.prod.exchangelabs.com (2603:10a6:10:1d8::19) by GV1PR08MB8283.eurprd08.prod.outlook.com (2603:10a6:150:a4::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6111.21; Tue, 21 Feb 2023 09:11:52 +0000 Received: from DBAEUR03FT009.eop-EUR03.prod.protection.outlook.com (2603:10a6:10:1d8:cafe::78) by DB9PR01CA0014.outlook.office365.com (2603:10a6:10:1d8::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6111.21 via Frontend Transport; Tue, 21 Feb 2023 09:11:51 +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; pr=C Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by DBAEUR03FT009.mail.protection.outlook.com (100.127.143.21) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6134.17 via Frontend Transport; Tue, 21 Feb 2023 09:11:51 +0000 Received: ("Tessian outbound baf1b7a96f25:v132"); Tue, 21 Feb 2023 09:11:51 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: bc3f55db8212032a X-CR-MTA-TID: 64aa7808 Received: from b167cc7e681e.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id 47ED9140-3AEC-4F06-B27D-3A3441ECF2C1.1; Tue, 21 Feb 2023 09:11:44 +0000 Received: from EUR04-DB3-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id b167cc7e681e.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Tue, 21 Feb 2023 09:11:44 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=mAJBPez+TX8DSwB36x3qd4oaNzw28FoCWAEcy0Lmaqb/Tx1TvWqfc2buHlYlobL5WiEcqJR+UpO4jefBvnbwW6Cp6ok4VO80YgmRz1Ro7KG07AtkanT6ZAEvq2IAoJMMP08fvrjlo1u50+muyF3/L3Rs6JyQq6X6sd9IBNYwKUwxrNFVSviQHXN6e6bYS7GXSIMxF91YEEtKYyboz/yPbv1ge8Cpbk4OI17xH+cQf+aMsMgg6MqWLGnUsR7r644DhKbb9TzBRdxjyhQkL6ScJvG6aTnl5LToskXZu/vnPDU6lYvuKjI0UgJ3c9GXnBjUiPh4/8qPDkNo0t7NhQAslw== 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=CjZ4NhoBpbLkaCSiL1jWiNTxIL334vPpBqBY0Aa4oxY=; b=UTdmwiD3onf5NhmMgaUlQCYzH5qjVPWmtwLW3mbIupwN/7zg61U8i2ndjKjunuPPgm0a4mPh6Y2q7PuWqHbCPayMvnBMABBEohwwdfTmgNO9Pm06FjHdiFXOoU5k851/KSba+/AzfUsdzispzt1QzjhvZyJbBJTg8eVMnVl9Pi7oUR5y/2NI0fHBc9ikFXs2fr4ycEVHcv4lqpCoq5G0mltIK7tGVk+PAEs6U+Ol2XZsR/r6GfqfGPfQkPy3Nul1aTwxusolPKNK/X4X6CfDjw1DxsDnKBlHwXcy6b76RlL/XvKyRfw1JR06oVXCyJg4aAOMnISCW5Un5bfvYnUgkg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=CjZ4NhoBpbLkaCSiL1jWiNTxIL334vPpBqBY0Aa4oxY=; b=lwmgNNa+4jTNWRR3Qlin37ZBaWuQ+M5V84a48YlgTnUnD6Bu0Vh612f4a9SlH1NtxupoArR2VZyATLIHxTu9mL0158nsVEcXjPLaFi2gdk+42MD/uzMch1kvTd99YqhwU6GOlRNrQ9bwqBHZjAFfuC99d3Prb2DUX50dDlo9eIo= Authentication-Results-Original: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; Received: from VI1PR08MB3919.eurprd08.prod.outlook.com (2603:10a6:803:c4::31) by VE1PR08MB5565.eurprd08.prod.outlook.com (2603:10a6:800:1b2::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6111.21; Tue, 21 Feb 2023 09:11:39 +0000 Received: from VI1PR08MB3919.eurprd08.prod.outlook.com ([fe80::bced:32a3:b77e:90a6]) by VI1PR08MB3919.eurprd08.prod.outlook.com ([fe80::bced:32a3:b77e:90a6%4]) with mapi id 15.20.6111.021; Tue, 21 Feb 2023 09:11:39 +0000 Message-ID: <99a54260-8ac8-215b-2f94-4f278f783d0c@arm.com> Date: Tue, 21 Feb 2023 09:11:31 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.7.1 Subject: Re: [PATCH] [AArch64] Enable pointer authentication support for aarch64 bare metal/kernel mode addresses Content-Language: en-US To: gdb-patches@sourceware.org Cc: jhb@FreeBSD.org, thiago.bauermann@linaro.org References: <20221216105722.1413765-1-luis.machado@arm.com> From: Luis Machado In-Reply-To: <20221216105722.1413765-1-luis.machado@arm.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-ClientProxiedBy: SA0PR13CA0012.namprd13.prod.outlook.com (2603:10b6:806:130::17) To VI1PR08MB3919.eurprd08.prod.outlook.com (2603:10a6:803:c4::31) MIME-Version: 1.0 X-MS-TrafficTypeDiagnostic: VI1PR08MB3919:EE_|VE1PR08MB5565:EE_|DBAEUR03FT009:EE_|GV1PR08MB8283:EE_ X-MS-Office365-Filtering-Correlation-Id: aa5c8347-9863-42bb-37a8-08db13ebab89 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: 4PgIqlwx0c5tFKWSsdTbkUt9Ce1bOzgWx1N+1l1wtX2k8u1QY6Is3KLFXVHdt4L7sRzjx+lJJAzjc8xFlys+gTQEA6Ka8MNwQJbAA6lRcY81zwAw+3LugDtCgQz2cVNFZ1f4G39izAMO5bhI+r5LntmYNZsN/cp2Gh+mQ5YytoV0auh9A8iHSnOSqJ8VQeKZkZZtVty8Wn8NWUf8eV5rIpjUosVgLKQiB1j9vu7zDAb9Tul+VSETpdt5GFGsxVsMckl+tXkybZga0uYlveDyK0DCiAtBTowHIWWsAK04bGgoW99Q5dOx8gWi7/W1weNwFsTx4OJw6aaVZOYnaeGbLQ+tvA94HUgi1GOYD6pCkKGiYpuCU7aNMzuBiqJ3dzMJxez3zJzvIUSvEU+LjaB11yxExkCRnmEbJbm0aqL6zV+ClUPD+gnPwTKHO5vNwSIoG/mGy1M7qrs9c2EbbBRl40LGNhMt5GG/p9H+azM8RVkm2HSc2EIsoa+KQxkNHevvX3W5wz/kHgdtIinZnLtslEXEX0tvPpL+k8xKlf+5NVeT8gZixUVi7j9amFWhnAjOc/k+f6Uoe13RRWESjXg9cF+4mIJwkhZTlKN/9jTsoXfmai3LZV5wbNwlIMN+tk4P4ZZXlMJM28L0rlvAm+XhlKlXQZgZIunWNYuEs9la9eFmxQJ6pHCBPoM0IOwlpvUD2p5UM7GdLTLcvg49Vfl9VQ== X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:VI1PR08MB3919.eurprd08.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230025)(4636009)(39860400002)(376002)(346002)(366004)(396003)(136003)(451199018)(316002)(478600001)(83380400001)(38100700002)(36756003)(44832011)(2906002)(86362001)(31696002)(30864003)(66946007)(66556008)(66476007)(8676002)(6916009)(4326008)(41300700001)(8936002)(5660300002)(53546011)(6506007)(6512007)(31686004)(66899018)(6666004)(6486002)(966005)(2616005)(26005)(186003)(45980500001)(43740500002);DIR:OUT;SFP:1101; X-MS-Exchange-Transport-CrossTenantHeadersStamped: VE1PR08MB5565 Original-Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: DBAEUR03FT009.eop-EUR03.prod.protection.outlook.com X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id-Prvs: d508135e-0701-49d4-bab3-08db13eba3e8 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: JPffPEcG5OivZjx+qn//yCxuN9iiFddPv1v/5gI1odF38xLvWXeYrMtJdPsG16Z3sEjjRgw4ClWBDW7QjngKAjjhSw31KvUYE3DWaQkqDgI3JPsOk6gVzmdwrMoCVtnbIgRpUzobPUREaUuGHnXsM7CVjGm3u+ltV2RFM4Iagio+kCHYnOp3fx8t/swev0TKgAOyW1f8VdAbI+oiagOFGydGbpQFMx2J4zcm99h/P5u6usCwc2tgZk51tq5AAGgIyBfZIpr4VdimNLq/sbVXxQDuMWlmBaYhw7aoAVLhlgJZoMYtxA5Gi17uhB0MyjiC9TimnLasrOsv9bI/tFAyLp6l6ypjShpPUBNYi47jYX9X1KK56G9ETyPiDoWk6nxNZGh+hXbiSVVdqKx03EMbASkdUxCWHrC8dWw1JlutmyxIOUr3TE76gAL+shSBFjZESkwFoQgst4FuNYWYDvG73nkJIKSva3RHDV26JSzIEbqF4q59D9VtGAcdLiTIa1tvrauqS0yJ+X8s+kvCnD4ixgVo+w4dUiaWHa2mktxc45iZOEg82Z30moN+fXB9OYMt8EEID5r5+Y88TMLsUexovenZGl3ec/km5u4T2+H0y5ANh8n0x3d4dp7/q4vtyuX4FmKFZfEkqNev2S7/4f/i8YDjmRnC/sgGs4YY0UkuOHS4XOslAGdkyrVkSZJITci1qz/JLbiezCsXMavZdEl89llyJ/fsGhWNO8mg32dpRw4= 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:(13230025)(4636009)(39860400002)(376002)(136003)(396003)(346002)(451199018)(46966006)(40470700004)(36840700001)(83380400001)(41300700001)(82310400005)(186003)(26005)(6512007)(53546011)(40460700003)(316002)(966005)(107886003)(86362001)(6486002)(40480700001)(478600001)(6666004)(31696002)(6506007)(36756003)(356005)(6916009)(336012)(2616005)(47076005)(8676002)(70586007)(70206006)(4326008)(36860700001)(2906002)(82740400003)(81166007)(31686004)(5660300002)(8936002)(44832011)(66899018)(30864003)(43740500002);DIR:OUT;SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Feb 2023 09:11:51.9039 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: aa5c8347-9863-42bb-37a8-08db13ebab89 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: DBAEUR03FT009.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: GV1PR08MB8283 X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,FORGED_SPF_HELO,GIT_PATCH_0,KAM_DMARC_NONE,NICE_REPLY_A,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_PASS,SPF_NONE,TXREP,UNPARSEABLE_RELAY autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: On 12/16/22 10:57, Luis Machado via Gdb-patches wrote: > At the moment GDB only handles pointer authentication (pauth) for userspace > addresses and if we're debugging a Linux-hosted program. > > The Linux Kernel can be configured to use pauth instructions for some > additional security hardening, but GDB doesn't handle this well. > > To overcome this limitation, GDB needs a couple things: > > 1 - The target needs to advertise pauth support. > 2 - The hook to remove non-address bits from a pointer needs to be registered > in aarch64-tdep.c as opposed to aarch64-linux-tdep.c. > > There is a patch for QEMU [1] that addresses the first point, and it makes > QEMU's gdbstub expose a couple more pauth mask registers, so overall we will > have up to 4 pauth masks (2 masks or 4 masks): > > pauth_dmask > pauth_cmask > pauth_dmask_high > pauth_cmask_high > > pauth_dmask and pauth_cmask are the masks used to remove pauth signatures > from userspace addresses. pauth_dmask_high and pauth_cmask_high masks are used > to remove pauth signatures from kernel addresses. > > The second point is easily addressed by moving code around. > > When debugging a Linux Kernel built with pauth with an unpatched GDB, we get > the following backtrace: > > #0 __fput (file=0xffff0000c17a6400) at /repos/linux/fs/file_table.c:296 > #1 0xffff8000082bd1f0 in ____fput (work=) at /repos/linux/fs/file_table.c:348 > #2 0x30008000080ade30 [PAC] in ?? () > #3 0x30d48000080ade30 in ?? () > Backtrace stopped: previous frame identical to this frame (corrupt stack?) > > With a patched GDB, we get something a lot more meaningful: > > #0 __fput (file=0xffff0000c1bcfa00) at /repos/linux/fs/file_table.c:296 > #1 0xffff8000082bd1f0 in ____fput (work=) at /repos/linux/fs/file_table.c:348 > #2 0xffff8000080ade30 [PAC] in task_work_run () at /repos/linux/kernel/task_work.c:179 > #3 0xffff80000801db90 [PAC] in resume_user_mode_work (regs=0xffff80000a96beb0) at /repos/linux/include/linux/resume_user_mode.h:49 > #4 do_notify_resume (regs=regs@entry=0xffff80000a96beb0, thread_flags=4) at /repos/linux/arch/arm64/kernel/signal.c:1127 > #5 0xffff800008fb9974 [PAC] in prepare_exit_to_user_mode (regs=0xffff80000a96beb0) at /repos/linux/arch/arm64/kernel/entry-common.c:137 > #6 exit_to_user_mode (regs=0xffff80000a96beb0) at /repos/linux/arch/arm64/kernel/entry-common.c:142 > #7 el0_svc (regs=0xffff80000a96beb0) at /repos/linux/arch/arm64/kernel/entry-common.c:638 > #8 0xffff800008fb9d34 [PAC] in el0t_64_sync_handler (regs=) at /repos/linux/arch/arm64/kernel/entry-common.c:655 > #9 0xffff800008011548 [PAC] in el0t_64_sync () at /repos/linux/arch/arm64/kernel/entry.S:586 > Backtrace stopped: Cannot access memory at address 0xffff80000a96c0c8 > > [1] https://gitlab.com/rth7680/qemu/-/commit/e440ce6de3e14bf19ee70935be9086c05359f07b > --- > gdb/aarch64-linux-tdep.c | 40 --------------- > gdb/aarch64-tdep.c | 103 ++++++++++++++++++++++++++++++++++----- > gdb/aarch64-tdep.h | 2 + > gdb/arch/aarch64.h | 6 +++ > 4 files changed, 100 insertions(+), 51 deletions(-) > > diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c > index 7e04bd9251f..1f091fbc540 100644 > --- a/gdb/aarch64-linux-tdep.c > +++ b/gdb/aarch64-linux-tdep.c > @@ -1980,40 +1980,6 @@ aarch64_linux_decode_memtag_section (struct gdbarch *gdbarch, > return tags; > } > > -/* AArch64 implementation of the remove_non_address_bits gdbarch hook. Remove > - non address bits from a pointer value. */ > - > -static CORE_ADDR > -aarch64_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR pointer) > -{ > - aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); > - > - /* By default, we assume TBI and discard the top 8 bits plus the VA range > - select bit (55). */ > - CORE_ADDR mask = AARCH64_TOP_BITS_MASK; > - > - if (tdep->has_pauth ()) > - { > - /* Fetch the PAC masks. These masks are per-process, so we can just > - fetch data from whatever thread we have at the moment. > - > - Also, we have both a code mask and a data mask. For now they are the > - same, but this may change in the future. */ > - struct regcache *regs = get_current_regcache (); > - CORE_ADDR cmask, dmask; > - > - if (regs->cooked_read (tdep->pauth_reg_base, &dmask) != REG_VALID) > - dmask = mask; > - > - if (regs->cooked_read (tdep->pauth_reg_base + 1, &cmask) != REG_VALID) > - cmask = mask; > - > - mask |= aarch64_mask_from_pac_registers (cmask, dmask); > - } > - > - return aarch64_remove_top_bits (pointer, mask); > -} > - > static void > aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > { > @@ -2066,12 +2032,6 @@ aarch64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) > /* Syscall record. */ > tdep->aarch64_syscall_record = aarch64_linux_syscall_record; > > - /* The top byte of a user space address known as the "tag", > - is ignored by the kernel and can be regarded as additional > - data associated with the address. */ > - set_gdbarch_remove_non_address_bits (gdbarch, > - aarch64_remove_non_address_bits); > - > /* MTE-specific settings and hooks. */ > if (tdep->has_mte ()) > { > diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c > index 024385a9fd8..d99c2b3e866 100644 > --- a/gdb/aarch64-tdep.c > +++ b/gdb/aarch64-tdep.c > @@ -133,10 +133,14 @@ static const char *const aarch64_sve_register_names[] = > > static const char *const aarch64_pauth_register_names[] = > { > - /* Authentication mask for data pointer. */ > + /* Authentication mask for data pointer, low half/user pointers. */ > "pauth_dmask", > - /* Authentication mask for code pointer. */ > - "pauth_cmask" > + /* Authentication mask for code pointer, low half/user pointers. */ > + "pauth_cmask", > + /* Authentication mask for data pointer, high half / kernel pointers. */ > + "pauth_dmask_high", > + /* Authentication mask for code pointer, high half / kernel pointers. */ > + "pauth_cmask_high" > }; > > static const char *const aarch64_mte_register_names[] = > @@ -222,9 +226,19 @@ aarch64_frame_unmask_lr (aarch64_gdbarch_tdep *tdep, > && frame_unwind_register_unsigned (this_frame, > tdep->ra_sign_state_regnum)) > { > - int cmask_num = AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base); > - CORE_ADDR cmask = frame_unwind_register_unsigned (this_frame, cmask_num); > - addr = addr & ~cmask; > + /* VA range select (bit 55) tells us whether to use the low half masks > + or the high half masks. */ > + int cmask_num; > + if (tdep->pauth_reg_count > 2 && addr & VA_RANGE_SELECT_BIT_MASK) > + cmask_num = AARCH64_PAUTH_CMASK_HIGH_REGNUM (tdep->pauth_reg_base); > + else > + cmask_num = AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base); > + > + /* By default, we assume TBI and discard the top 8 bits plus the VA range > + select bit (55). */ > + CORE_ADDR mask = AARCH64_TOP_BITS_MASK; > + mask |= frame_unwind_register_unsigned (this_frame, cmask_num); > + addr = aarch64_remove_top_bits (addr, mask); > > /* Record in the frame that the link register required unmasking. */ > set_frame_previous_pc_masked (this_frame); > @@ -1317,8 +1331,8 @@ aarch64_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, > reg->loc.exp.len = 1; > return; > } > - else if (regnum == AARCH64_PAUTH_DMASK_REGNUM (tdep->pauth_reg_base) > - || regnum == AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base)) > + else if (regnum >= tdep->pauth_reg_base > + && regnum < tdep->pauth_reg_base + tdep->pauth_reg_count) > { > reg->how = DWARF2_FRAME_REG_SAME_VALUE; > return; > @@ -3492,8 +3506,8 @@ aarch64_cannot_store_register (struct gdbarch *gdbarch, int regnum) > return 0; > > /* Pointer authentication registers are read-only. */ > - return (regnum == AARCH64_PAUTH_DMASK_REGNUM (tdep->pauth_reg_base) > - || regnum == AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base)); > + return (regnum >= tdep->pauth_reg_base > + && regnum < tdep->pauth_reg_base + tdep->pauth_reg_count); > } > > /* Implement the stack_frame_destroyed_p gdbarch method. */ > @@ -3521,6 +3535,51 @@ aarch64_stack_frame_destroyed_p (struct gdbarch *gdbarch, CORE_ADDR pc) > return streq (inst.opcode->name, "ret"); > } > > +/* AArch64 implementation of the remove_non_address_bits gdbarch hook. Remove > + non address bits from a pointer value. */ > + > +static CORE_ADDR > +aarch64_remove_non_address_bits (struct gdbarch *gdbarch, CORE_ADDR pointer) > +{ > + aarch64_gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); > + > + /* By default, we assume TBI and discard the top 8 bits plus the VA range > + select bit (55). */ > + CORE_ADDR mask = AARCH64_TOP_BITS_MASK; > + > + if (tdep->has_pauth ()) > + { > + /* Fetch the PAC masks. These masks are per-process, so we can just > + fetch data from whatever thread we have at the moment. > + > + Also, we have both a code mask and a data mask. For now they are the > + same, but this may change in the future. */ > + struct regcache *regs = get_current_regcache (); > + CORE_ADDR cmask, dmask; > + int dmask_regnum = AARCH64_PAUTH_DMASK_REGNUM (tdep->pauth_reg_base); > + int cmask_regnum = AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base); > + > + /* If we have a kernel address and we have kernel-mode address mask > + registers, use those instead. */ > + if (tdep->pauth_reg_count > 2 > + && pointer & VA_RANGE_SELECT_BIT_MASK) > + { > + dmask_regnum = AARCH64_PAUTH_DMASK_HIGH_REGNUM (tdep->pauth_reg_base); > + cmask_regnum = AARCH64_PAUTH_CMASK_HIGH_REGNUM (tdep->pauth_reg_base); > + } > + > + if (regs->cooked_read (dmask_regnum, &dmask) != REG_VALID) > + dmask = mask; > + > + if (regs->cooked_read (cmask_regnum, &cmask) != REG_VALID) > + cmask = mask; > + > + mask |= aarch64_mask_from_pac_registers (cmask, dmask); > + } > + > + return aarch64_remove_top_bits (pointer, mask); > +} > + > /* 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. > @@ -3659,19 +3718,35 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) > } > > /* Add the pauth registers. */ > + int pauth_masks = 0; > if (feature_pauth != NULL) > { > first_pauth_regnum = num_regs; > ra_sign_state_offset = num_pseudo_regs; > + > + /* Size of the expected register set with all 4 masks. */ > + int set_size = ARRAY_SIZE (aarch64_pauth_register_names); > + > + /* QEMU exposes a couple additional masks for the high half of the > + address. We should either have 2 registers or 4 registers. */ > + if (tdesc_unnumbered_register (feature_pauth, > + "pauth_dmask_high") == 0) > + { > + /* We did not find pauth_dmask_high, assume we only have > + 2 masks. We are not dealing with QEMU/Emulators then. */ > + set_size -= 2; > + } > + > /* Validate the descriptor provides the mandatory PAUTH registers and > allocate their numbers. */ > - for (i = 0; i < ARRAY_SIZE (aarch64_pauth_register_names); i++) > + for (i = 0; i < set_size; i++) > valid_p &= tdesc_numbered_register (feature_pauth, tdesc_data.get (), > first_pauth_regnum + i, > aarch64_pauth_register_names[i]); > > num_regs += i; > num_pseudo_regs += 1; /* Count RA_STATE pseudo register. */ > + pauth_masks = set_size; > } > > /* Add the MTE registers. */ > @@ -3706,6 +3781,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) > tdep->jb_elt_size = 8; > tdep->vq = vq; > tdep->pauth_reg_base = first_pauth_regnum; > + tdep->pauth_reg_count = pauth_masks; > tdep->ra_sign_state_regnum = -1; > tdep->mte_reg_base = first_mte_regnum; > tdep->tls_regnum_base = first_tls_regnum; > @@ -3822,6 +3898,11 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) > if (tdep->has_pauth ()) > tdep->ra_sign_state_regnum = ra_sign_state_offset + num_regs; > > + /* Architecture hook to remove bits of a pointer that are not part of the > + address, like memory tags (MTE) and pointer authentication signatures. */ > + set_gdbarch_remove_non_address_bits (gdbarch, > + aarch64_remove_non_address_bits); > + > /* Add standard register aliases. */ > for (i = 0; i < ARRAY_SIZE (aarch64_register_aliases); i++) > user_reg_add (gdbarch, aarch64_register_aliases[i].name, > diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h > index ff94c0a23b0..9fbb2b510aa 100644 > --- a/gdb/aarch64-tdep.h > +++ b/gdb/aarch64-tdep.h > @@ -94,6 +94,8 @@ struct aarch64_gdbarch_tdep : gdbarch_tdep_base > } > > int pauth_reg_base = 0; > + /* Number of pauth masks. */ > + int pauth_reg_count = 0; > int ra_sign_state_regnum = 0; > > /* Returns true if the target supports pauth. */ > diff --git a/gdb/arch/aarch64.h b/gdb/arch/aarch64.h > index 68048198b4d..4eeb9f8aa2c 100644 > --- a/gdb/arch/aarch64.h > +++ b/gdb/arch/aarch64.h > @@ -132,6 +132,12 @@ enum aarch64_regnum > > #define AARCH64_PAUTH_DMASK_REGNUM(pauth_reg_base) (pauth_reg_base) > #define AARCH64_PAUTH_CMASK_REGNUM(pauth_reg_base) (pauth_reg_base + 1) > +/* The high versions of these masks are used for bare metal/kernel-mode pointer > + authentication support. */ > +#define AARCH64_PAUTH_DMASK_HIGH_REGNUM(pauth_reg_base) (pauth_reg_base + 2) > +#define AARCH64_PAUTH_CMASK_HIGH_REGNUM(pauth_reg_base) (pauth_reg_base + 3) > + > +/* This size is only meant for Linux, not bare metal. QEMU exposes 4 masks. */ > #define AARCH64_PAUTH_REGS_SIZE (16) > > #define AARCH64_X_REGS_NUM 31 Pushed now.