From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 34501 invoked by alias); 6 Mar 2019 13:33:43 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 34410 invoked by uid 89); 6 Mar 2019 13:33:42 -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 autolearn=ham version=3.3.2 spammy=2486 X-HELO: EUR03-VE1-obe.outbound.protection.outlook.com Received: from mail-eopbgr50089.outbound.protection.outlook.com (HELO EUR03-VE1-obe.outbound.protection.outlook.com) (40.107.5.89) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 06 Mar 2019 13:33:40 +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=PpPH2NiFmuHUQFuK2Vzdi2wqq5NwQLAEarco5JVwP3Q=; b=cjRMaX47kNjjPSL7CmPHIni6Ljnb3v2nf5J755L1+nBlN7Q2Uc+pm3Tph/NtuWT5RQ+UMC0CjRfW7jHr6U7pRFERxtd96ioKHbbbNYHiRa2alYWQCM4f31spQYgD9YkXG8ed5FpluWrEi3bAE77x/TJ/hzMlQwojJ0C8yaYoEBw= Received: from DB6PR0802MB2133.eurprd08.prod.outlook.com (10.172.227.22) by DB6PR0802MB2406.eurprd08.prod.outlook.com (10.172.250.9) 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:37 +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:37 +0000 From: Alan Hayward To: "gdb-patches@sourceware.org" CC: nd , Alan Hayward Subject: [PATCH v2 6/8] AArch64: DWARF unwinder support for signed return addresses Date: Wed, 06 Mar 2019 13:33:00 -0000 Message-ID: <20190306133325.2531-7-alan.hayward@arm.com> References: <20190306133325.2531-1-alan.hayward@arm.com> In-Reply-To: <20190306133325.2531-1-alan.hayward@arm.com> authentication-results: spf=none (sender IP is ) smtp.mailfrom=Alan.Hayward@arm.com; received-spf: None (protection.outlook.com: arm.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-IsSubscribed: yes X-SW-Source: 2019-03/txt/msg00085.txt.bz2 Pauth address signing is enabled at binary compile time. When enabled the return addresses for functions may be mangled. This patch adds functionali= ty to restore the original address for use in the DWARF unwinder. DW_CFA_AARCH64_negate_ra_state in a binary indicates the toggling of address signing between enabled and disabled. Ensure the state is stored in the DW= ARF register ra_state. Ensure the pauth DWARF registers are initialised. gdb/ChangeLog: 2019-03-06 Alan Hayward Jiong Wang * aarch64-tdep.c (aarch64_frame_unmask_address): New function. (aarch64_dwarf2_prev_register): Unmask PC value. (aarch64_dwarf2_frame_init_reg): Init pauth registers. (aarch64_execute_dwarf_cfa_vendor_op): Check for DW_CFA_AARCH64_negate_ra_state. (aarch64_gdbarch_init): Add aarch64_execute_dwarf_cfa_vendor_op. --- gdb/aarch64-tdep.c | 87 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 2 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 01e98b7195..07430c0f25 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -34,6 +34,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" @@ -248,6 +249,26 @@ class instruction_reader : public abstract_instruction= _reader =20 } // namespace =20 +/* If address signing is enabled, mask off the signature bits from ADDR, u= sing + the register values in THIS_FRAME. */ + +static CORE_ADDR +aarch64_frame_unmask_address (struct gdbarch_tdep *tdep, + struct frame_info *this_frame, + CORE_ADDR addr) +{ + if (tdep->has_pauth () + && frame_unwind_register_unsigned (this_frame, + tdep->pauth_ra_state_regnum)) + { + int cmask_num =3D AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base); + CORE_ADDR cmask =3D frame_unwind_register_unsigned (this_frame, cmas= k_num); + addr =3D addr & ~cmask; + } + + return addr; +} + /* Analyze a prologue, looking for a recognizable stack frame and frame pointer. Scan until we encounter a store that could clobber the stack frame unexpectedly, or an unknown instruction. */ @@ -1013,12 +1034,14 @@ static struct value * aarch64_dwarf2_prev_register (struct frame_info *this_frame, void **this_cache, int regnum) { + struct gdbarch_tdep *tdep =3D gdbarch_tdep (get_frame_arch (this_frame)); CORE_ADDR lr; =20 switch (regnum) { case AARCH64_PC_REGNUM: lr =3D frame_unwind_register_unsigned (this_frame, AARCH64_LR_REGNUM= ); + lr =3D aarch64_frame_unmask_address (tdep, this_frame, lr); return frame_unwind_got_constant (this_frame, regnum, lr); =20 default: @@ -1027,6 +1050,9 @@ aarch64_dwarf2_prev_register (struct frame_info *this= _frame, } } =20 +static const unsigned char op_lit0 =3D DW_OP_lit0; +static const unsigned char op_lit1 =3D DW_OP_lit1; + /* Implement the "init_reg" dwarf2_frame_ops method. */ =20 static void @@ -1034,18 +1060,72 @@ aarch64_dwarf2_frame_init_reg (struct gdbarch *gdba= rch, int regnum, struct dwarf2_frame_state_reg *reg, struct frame_info *this_frame) { + struct gdbarch_tdep *tdep =3D gdbarch_tdep (gdbarch); + switch (regnum) { case AARCH64_PC_REGNUM: reg->how =3D DWARF2_FRAME_REG_FN; reg->loc.fn =3D aarch64_dwarf2_prev_register; - break; + return; + case AARCH64_SP_REGNUM: reg->how =3D DWARF2_FRAME_REG_CFA; - break; + return; + } + + /* Init pauth registers. */ + if (tdep->has_pauth ()) + { + if (regnum =3D=3D tdep->pauth_ra_state_regnum) + { + /* Initialize RA_STATE to zero. */ + reg->how =3D DWARF2_FRAME_REG_SAVED_VAL_EXP; + reg->loc.exp.start =3D &op_lit0; + reg->loc.exp.len =3D 1; + return; + } + else if (regnum =3D=3D AARCH64_PAUTH_DMASK_REGNUM (tdep->pauth_reg_b= ase) + || regnum =3D=3D AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base)) + { + reg->how =3D DWARF2_FRAME_REG_SAME_VALUE; + return; + } } } =20 +/* Implement the execute_dwarf_cfa_vendor_op method. */ + +static bool +aarch64_execute_dwarf_cfa_vendor_op (struct gdbarch *gdbarch, gdb_byte op, + struct dwarf2_frame_state *fs) +{ + struct gdbarch_tdep *tdep =3D gdbarch_tdep (gdbarch); + struct dwarf2_frame_state_reg *ra_state; + + if (tdep->has_pauth () && op =3D=3D DW_CFA_AARCH64_negate_ra_state) + { + /* Allocate RA_STATE column if it's not allocated yet. */ + fs->regs.alloc_regs (AARCH64_DWARF_PAUTH_RA_STATE + 1); + + /* Toggle the status of RA_STATE between 0 and 1. */ + ra_state =3D &(fs->regs.reg[AARCH64_DWARF_PAUTH_RA_STATE]); + ra_state->how =3D DWARF2_FRAME_REG_SAVED_VAL_EXP; + + if (ra_state->loc.exp.start =3D=3D nullptr + || ra_state->loc.exp.start =3D=3D &op_lit0) + ra_state->loc.exp.start =3D &op_lit1; + else + ra_state->loc.exp.start =3D &op_lit0; + + ra_state->loc.exp.len =3D 1; + + return true; + } + + return false; +} + /* When arguments must be pushed onto the stack, they go on in reverse order. The code below implements a FILO (stack) to do this. */ =20 @@ -3192,6 +3272,9 @@ aarch64_gdbarch_init (struct gdbarch_info info, struc= t gdbarch_list *arches) gdbarch_init_osabi (info, gdbarch); =20 dwarf2_frame_set_init_reg (gdbarch, aarch64_dwarf2_frame_init_reg); + /* Register DWARF CFA vendor handler. */ + set_gdbarch_execute_dwarf_cfa_vendor_op (gdbarch, + aarch64_execute_dwarf_cfa_vendor_op); =20 /* Add some default predicates. */ frame_unwind_append_unwinder (gdbarch, &aarch64_stub_unwind); --=20 2.17.2 (Apple Git-113)