From patchwork Wed Mar 6 13:33:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alan Hayward X-Patchwork-Id: 31736 Received: (qmail 35793 invoked by alias); 6 Mar 2019 13:33:52 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 35715 invoked by uid 89); 6 Mar 2019 13:33:51 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS autolearn=ham version=3.3.2 spammy= X-HELO: EUR04-DB3-obe.outbound.protection.outlook.com Received: from mail-eopbgr60089.outbound.protection.outlook.com (HELO EUR04-DB3-obe.outbound.protection.outlook.com) (40.107.6.89) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 06 Mar 2019 13:33:48 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector1-arm-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=sVMdKiyCNvcRQ5GNpxZphBkhybp572n4dLKswI0G6gU=; b=GPk+ek7GiHoTJC/ygwTf0S9pAUvqAXGbhYe3WedIi2cYQYkLMaUOq8/SfxBaIcndhgU+nUjwfEh6SnthZSPgahFrcyi7uPYLUAoprDMkcNFniEJ5UiSdVIu77SgPGks+lzbzAPDC0sJLcViJJhWvr80a7Jwr87vSe8FIN/x9sdc= Received: from DB6PR0802MB2133.eurprd08.prod.outlook.com (10.172.227.22) by DB6PR0802MB2262.eurprd08.prod.outlook.com (10.172.227.19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1665.19; Wed, 6 Mar 2019 13:33:36 +0000 Received: from DB6PR0802MB2133.eurprd08.prod.outlook.com ([fe80::e974:35a7:c83c:e5b7]) by DB6PR0802MB2133.eurprd08.prod.outlook.com ([fe80::e974:35a7:c83c:e5b7%3]) with mapi id 15.20.1686.018; Wed, 6 Mar 2019 13:33:36 +0000 From: Alan Hayward To: "gdb-patches@sourceware.org" CC: nd , Alan Hayward Subject: [PATCH v2 5/8] AArch64: Add pauth DWARF registers Date: Wed, 6 Mar 2019 13:33:35 +0000 Message-ID: <20190306133325.2531-6-alan.hayward@arm.com> References: <20190306133325.2531-1-alan.hayward@arm.com> In-Reply-To: <20190306133325.2531-1-alan.hayward@arm.com> received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) authentication-results: spf=none (sender IP is ) smtp.mailfrom=Alan.Hayward@arm.com; x-ms-exchange-senderadcheck: 1 MIME-Version: 1.0 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-IsSubscribed: yes Map the pauth registers to DWARF. Add a new pseudo register ra_state and also map this to DWARF. This register is hidden from the user - prevent it from being read or written to. It will be used for the unmangling of addresses. 2019-03-06 Alan Hayward Jiong Wang * aarch64-tdep.c (aarch64_dwarf_reg_to_regnum): Check for pauth registers. (aarch64_pseudo_register_name): Likewise. (aarch64_pseudo_register_type): Likewise. (aarch64_pseudo_register_reggroup_p): Likewise. (aarch64_gdbarch_init): Add pauth registers. * aarch64-tdep.h (AARCH64_DWARF_PAUTH_RA_STATE): New define. (AARCH64_DWARF_PAUTH_DMASK): Likewise. (AARCH64_DWARF_PAUTH_CMASK): Likewise. (struct gdbarch_tdep): Add regnum for ra_state. --- gdb/aarch64-tdep.c | 94 ++++++++++++++++++++++++++++++---------------- gdb/aarch64-tdep.h | 4 ++ 2 files changed, 65 insertions(+), 33 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 66fdd7bf05..01e98b7195 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -1839,6 +1839,8 @@ aarch64_vnv_type (struct gdbarch *gdbarch) static int aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) { + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + if (reg >= AARCH64_DWARF_X0 && reg <= AARCH64_DWARF_X0 + 30) return AARCH64_X0_REGNUM + reg - AARCH64_DWARF_X0; @@ -1860,6 +1862,15 @@ aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) if (reg >= AARCH64_DWARF_SVE_Z0 && reg <= AARCH64_DWARF_SVE_Z0 + 15) return AARCH64_SVE_Z0_REGNUM + reg - AARCH64_DWARF_SVE_Z0; + if (tdep->has_pauth ()) + { + if (reg >= AARCH64_DWARF_PAUTH_DMASK && reg <= AARCH64_DWARF_PAUTH_CMASK) + return tdep->pauth_reg_base + reg - AARCH64_DWARF_PAUTH_DMASK; + + if (reg == AARCH64_DWARF_PAUTH_RA_STATE) + return tdep->pauth_ra_state_regnum; + } + return -1; } @@ -2215,22 +2226,22 @@ aarch64_pseudo_register_name (struct gdbarch *gdbarch, int regnum) "b28", "b29", "b30", "b31", }; - regnum -= gdbarch_num_regs (gdbarch); + int p_regnum = regnum - gdbarch_num_regs (gdbarch); - if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32) - return q_name[regnum - AARCH64_Q0_REGNUM]; + if (p_regnum >= AARCH64_Q0_REGNUM && p_regnum < AARCH64_Q0_REGNUM + 32) + return q_name[p_regnum - AARCH64_Q0_REGNUM]; - if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32) - return d_name[regnum - AARCH64_D0_REGNUM]; + if (p_regnum >= AARCH64_D0_REGNUM && p_regnum < AARCH64_D0_REGNUM + 32) + return d_name[p_regnum - AARCH64_D0_REGNUM]; - if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32) - return s_name[regnum - AARCH64_S0_REGNUM]; + if (p_regnum >= AARCH64_S0_REGNUM && p_regnum < AARCH64_S0_REGNUM + 32) + return s_name[p_regnum - AARCH64_S0_REGNUM]; - if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32) - return h_name[regnum - AARCH64_H0_REGNUM]; + if (p_regnum >= AARCH64_H0_REGNUM && p_regnum < AARCH64_H0_REGNUM + 32) + return h_name[p_regnum - AARCH64_H0_REGNUM]; - if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32) - return b_name[regnum - AARCH64_B0_REGNUM]; + if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32) + return b_name[p_regnum - AARCH64_B0_REGNUM]; if (tdep->has_sve ()) { @@ -2246,14 +2257,20 @@ aarch64_pseudo_register_name (struct gdbarch *gdbarch, int regnum) "v28", "v29", "v30", "v31", }; - if (regnum >= AARCH64_SVE_V0_REGNUM - && regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM) - return sve_v_name[regnum - AARCH64_SVE_V0_REGNUM]; + if (p_regnum >= AARCH64_SVE_V0_REGNUM + && p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM) + return sve_v_name[p_regnum - AARCH64_SVE_V0_REGNUM]; } + /* RA_STATE is used for unwinding only. Do not assign it a name - this + prevents it from being read by methods such as + mi_cmd_trace_frame_collected. */ + if (tdep->has_pauth () && regnum == tdep->pauth_ra_state_regnum) + return ""; + internal_error (__FILE__, __LINE__, _("aarch64_pseudo_register_name: bad register number %d"), - regnum); + p_regnum); } /* Implement the "pseudo_register_type" tdesc_arch_data method. */ @@ -2263,30 +2280,33 @@ aarch64_pseudo_register_type (struct gdbarch *gdbarch, int regnum) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - regnum -= gdbarch_num_regs (gdbarch); + int p_regnum = regnum - gdbarch_num_regs (gdbarch); - if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32) + if (p_regnum >= AARCH64_Q0_REGNUM && p_regnum < AARCH64_Q0_REGNUM + 32) return aarch64_vnq_type (gdbarch); - if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32) + if (p_regnum >= AARCH64_D0_REGNUM && p_regnum < AARCH64_D0_REGNUM + 32) return aarch64_vnd_type (gdbarch); - if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32) + if (p_regnum >= AARCH64_S0_REGNUM && p_regnum < AARCH64_S0_REGNUM + 32) return aarch64_vns_type (gdbarch); - if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32) + if (p_regnum >= AARCH64_H0_REGNUM && p_regnum < AARCH64_H0_REGNUM + 32) return aarch64_vnh_type (gdbarch); - if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32) + if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32) return aarch64_vnb_type (gdbarch); - if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM - && regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM) + if (tdep->has_sve () && p_regnum >= AARCH64_SVE_V0_REGNUM + && p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM) return aarch64_vnv_type (gdbarch); + if (tdep->has_pauth () && regnum == tdep->pauth_ra_state_regnum) + return builtin_type (gdbarch)->builtin_uint64; + internal_error (__FILE__, __LINE__, _("aarch64_pseudo_register_type: bad register number %d"), - regnum); + p_regnum); } /* Implement the "pseudo_register_reggroup_p" tdesc_arch_data method. */ @@ -2297,23 +2317,26 @@ aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int regnum, { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); - regnum -= gdbarch_num_regs (gdbarch); + int p_regnum = regnum - gdbarch_num_regs (gdbarch); - if (regnum >= AARCH64_Q0_REGNUM && regnum < AARCH64_Q0_REGNUM + 32) + if (p_regnum >= AARCH64_Q0_REGNUM && p_regnum < AARCH64_Q0_REGNUM + 32) return group == all_reggroup || group == vector_reggroup; - else if (regnum >= AARCH64_D0_REGNUM && regnum < AARCH64_D0_REGNUM + 32) + else if (p_regnum >= AARCH64_D0_REGNUM && p_regnum < AARCH64_D0_REGNUM + 32) return (group == all_reggroup || group == vector_reggroup || group == float_reggroup); - else if (regnum >= AARCH64_S0_REGNUM && regnum < AARCH64_S0_REGNUM + 32) + else if (p_regnum >= AARCH64_S0_REGNUM && p_regnum < AARCH64_S0_REGNUM + 32) return (group == all_reggroup || group == vector_reggroup || group == float_reggroup); - else if (regnum >= AARCH64_H0_REGNUM && regnum < AARCH64_H0_REGNUM + 32) + else if (p_regnum >= AARCH64_H0_REGNUM && p_regnum < AARCH64_H0_REGNUM + 32) return group == all_reggroup || group == vector_reggroup; - else if (regnum >= AARCH64_B0_REGNUM && regnum < AARCH64_B0_REGNUM + 32) + else if (p_regnum >= AARCH64_B0_REGNUM && p_regnum < AARCH64_B0_REGNUM + 32) return group == all_reggroup || group == vector_reggroup; - else if (tdep->has_sve () && regnum >= AARCH64_SVE_V0_REGNUM - && regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM) + else if (tdep->has_sve () && p_regnum >= AARCH64_SVE_V0_REGNUM + && p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM) return group == all_reggroup || group == vector_reggroup; + /* RA_STATE is used for unwinding only. Do not assign it to any groups. */ + if (tdep->has_pauth () && regnum == tdep->pauth_ra_state_regnum) + return 0; return group == all_reggroup; } @@ -2983,6 +3006,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) int num_regs = 0; int num_pseudo_regs = 0; int first_pauth_regnum = -1; + int pauth_ra_state_offset = -1; /* Ensure we always have a target description. */ if (!tdesc_has_registers (tdesc)) @@ -3051,7 +3075,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) if (feature_pauth != NULL) { first_pauth_regnum = num_regs; - + pauth_ra_state_offset = num_pseudo_regs; /* Validate the descriptor provides the mandatory PAUTH registers and allocate their numbers. */ for (i = 0; i < ARRAY_SIZE (aarch64_pauth_register_names); i++) @@ -3060,6 +3084,7 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) aarch64_pauth_register_names[i]); num_regs += i; + num_pseudo_regs += 1; /* Count RA_STATE pseudo register. */ } if (!valid_p) @@ -3096,6 +3121,9 @@ aarch64_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) tdep->jb_elt_size = 8; tdep->vq = aarch64_get_tdesc_vq (tdesc); tdep->pauth_reg_base = first_pauth_regnum; + tdep->pauth_ra_state_regnum = (feature_pauth == NULL) ? -1 + : pauth_ra_state_offset + num_regs; + set_gdbarch_push_dummy_call (gdbarch, aarch64_push_dummy_call); set_gdbarch_frame_align (gdbarch, aarch64_frame_align); diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h index f9fc8965f0..f73392d59b 100644 --- a/gdb/aarch64-tdep.h +++ b/gdb/aarch64-tdep.h @@ -31,6 +31,9 @@ struct regset; /* AArch64 Dwarf register numbering. */ #define AARCH64_DWARF_X0 0 #define AARCH64_DWARF_SP 31 +#define AARCH64_DWARF_PAUTH_RA_STATE 34 +#define AARCH64_DWARF_PAUTH_DMASK 35 +#define AARCH64_DWARF_PAUTH_CMASK 36 #define AARCH64_DWARF_V0 64 #define AARCH64_DWARF_SVE_VG 46 #define AARCH64_DWARF_SVE_FFR 47 @@ -89,6 +92,7 @@ struct gdbarch_tdep } int pauth_reg_base; + int pauth_ra_state_regnum; /* Returns true if the target supports pauth. */ bool has_pauth () const