From patchwork Wed Sep 28 02:50:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Koudai Iwahori X-Patchwork-Id: 58099 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 849E43857C58 for ; Wed, 28 Sep 2022 02:52:21 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 849E43857C58 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1664333541; bh=gH8xxZ6lZv5f3bizdnRtW2Cxu6gMZFZtRvHRpr7sCS8=; h=Date:Subject:To:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=k0ZqeqCuqENAfAnRrP6/MPXc8Mt7QEtf/e5J6wY91kYd6/ggZZBLHBLeFJ3h+/GlV lRIgnG02tavdm97Tu5dEaZrJNuvBUNFOKpxw/8nnDMr5Yi/6NCIV1vaVxER1WxBfoX nzAVUJaCxJZCPMagM1YaMcY+sVY4J7V0gzGU+jqM= X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by sourceware.org (Postfix) with ESMTPS id CDFA3385828D for ; Wed, 28 Sep 2022 02:51:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CDFA3385828D Received: by mail-yb1-xb49.google.com with SMTP id i201-20020a253bd2000000b006b28b887dbaso10308659yba.13 for ; Tue, 27 Sep 2022 19:51:21 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date; bh=gH8xxZ6lZv5f3bizdnRtW2Cxu6gMZFZtRvHRpr7sCS8=; b=Whqyy3a/u+tbky7Y8ZyH05DDC8+IvCjvubIfjKj1z4/o4N9P2riyXeXE2KZHzOi5f2 W9Q6xWPrde0n6NcfP5XSBxmwzyL0g20mIyjTCcAowmAKyN0kH7g52pBQJLc2Bp0jFS88 mYRMr/5lRAkLsDB9A+LGyX6SVl0pGnal4V4Ya8wvBJuXVoIPy/+9zhvCmR2Y6vb1LqyJ kEii0fya61qHGrhcmLUsg58ygRdexrnEqCHVH7LpiJ0cE3W2EDX0q/ysXae/YrGESyw6 TMVilwtXWAi2AGZ/WJKYwtcgvP92JWz/2esV7SABlygrbAfvKmYQDSGics1dCFItkAx1 AmUA== X-Gm-Message-State: ACrzQf00dn5ZLya3A5oQmuu4ot8CrZT+qIxC7ngbD5EFvYDWvjxnYYp5 FveqGCl++Z0TQh4h+UKRmL1RUi4wddVGuQcEGCENj0IOnWbkC7tS+YrycM0o/scuoRGHQwjQKGq siK4gJqPMisUOG/PUolYZe02JTIAM3YHYLEnnkgEJW+4lXVgLxwtOhqdL2AboYJg3zow= X-Google-Smtp-Source: AMsMyM6vG8EXZgtsPM7CtzYY/oG/17CflzDfwOm8t2CCqkAEkZyJ0MVaEtzs9zRiuHdLyo2V9pnzdoxlQ3c= X-Received: from koudai.c.googlers.com ([fda3:e722:ac3:cc00:3:22c1:c0a8:1150]) (user=koudai job=sendgmr) by 2002:a25:4292:0:b0:6b6:368e:285c with SMTP id p140-20020a254292000000b006b6368e285cmr22349747yba.228.1664333480947; Tue, 27 Sep 2022 19:51:20 -0700 (PDT) Date: Wed, 28 Sep 2022 02:50:57 +0000 Mime-Version: 1.0 X-Mailer: git-send-email 2.37.3.998.g577e59143f-goog Message-ID: <20220928025057.188075-1-koudai@google.com> Subject: [PATCH] AArch64 pauth: Fix internal error when target supports extra regs To: gdb-patches@sourceware.org X-Spam-Status: No, score=-21.6 required=5.0 tests=BAYES_00, DKIMWL_WL_MED, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) 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: Koudai Iwahori via Gdb-patches From: Koudai Iwahori Reply-To: Koudai Iwahori Cc: Koudai Iwahori Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org Sender: "Gdb-patches" GDB crashes in aarch64_pseudo_register_type() when target supports pauth and extra registers. When the target supports pauth, GDB keeps a pseudo register `RA_STATE` and aarch64_gdbarch_tdep::ra_sign_state_regnum has the integer index of the register. aarch64_gdbarch_tdep::ra_sign_state_regnum is initialized to (# of reg) + (# of pseudo reg) right after GDB checking if the target supports the core/fpu/sve registers. However, the number of registers is updated in tdesc_use_registers() if the target can provide extra registers. In such cases, ra_sign_state_regnum does not have the right value and internal_error() in aarch64_pseudo_register_type() fires. I added ra_sign_state_pseudo_regnum field to aarch64_gdbarch_tdep for storing the pseudo register number and added get_ra_sign_state_regnum member function. --- gdb/aarch64-tdep.c | 23 ++++++++++++----------- gdb/aarch64-tdep.h | 8 +++++++- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 7229b53838e..87335ad22ae 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -254,7 +254,8 @@ aarch64_frame_unmask_lr (aarch64_gdbarch_tdep *tdep, { if (tdep->has_pauth () && frame_unwind_register_unsigned (this_frame, - tdep->ra_sign_state_regnum)) + tdep->get_ra_sign_state_regnum ( + get_frame_arch (this_frame)))) { int cmask_num = AARCH64_PAUTH_CMASK_REGNUM (tdep->pauth_reg_base); CORE_ADDR cmask = frame_unwind_register_unsigned (this_frame, cmask_num); @@ -542,7 +543,7 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch, if (tdep->has_pauth () && cache != nullptr) { - int regnum = tdep->ra_sign_state_regnum; + int regnum = tdep->get_ra_sign_state_regnum (gdbarch); cache->saved_regs[regnum].set_value (ra_state_val); } } @@ -882,7 +883,7 @@ aarch64_analyze_prologue_test (void) if (tdep->has_pauth ()) { - int regnum = tdep->ra_sign_state_regnum; + int regnum = tdep->get_ra_sign_state_regnum (gdbarch); SELF_CHECK (cache.saved_regs[regnum].is_value ()); } } @@ -1137,7 +1138,8 @@ aarch64_prologue_prev_register (struct frame_info *this_frame, lr = frame_unwind_register_unsigned (this_frame, AARCH64_LR_REGNUM); if (tdep->has_pauth () - && cache->saved_regs[tdep->ra_sign_state_regnum].is_value ()) + && cache->saved_regs[tdep->get_ra_sign_state_regnum (gdbarch)] + .is_value ()) lr = aarch64_frame_unmask_lr (tdep, this_frame, lr); return frame_unwind_got_constant (this_frame, prev_regnum, lr); @@ -1344,7 +1346,7 @@ aarch64_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum, /* Init pauth registers. */ if (tdep->has_pauth ()) { - if (regnum == tdep->ra_sign_state_regnum) + if (regnum == tdep->get_ra_sign_state_regnum (gdbarch)) { /* Initialize RA_STATE to zero. */ reg->how = DWARF2_FRAME_REG_SAVED_VAL_EXP; @@ -2255,7 +2257,7 @@ aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg) if (tdep->has_pauth ()) { if (reg == AARCH64_DWARF_RA_SIGN_STATE) - return tdep->ra_sign_state_regnum; + return tdep->get_ra_sign_state_regnum (gdbarch); } return -1; @@ -2662,7 +2664,7 @@ aarch64_pseudo_register_name (struct gdbarch *gdbarch, int 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->ra_sign_state_regnum) + if (tdep->has_pauth () && p_regnum == tdep->ra_sign_state_pseudo_regnum) return ""; internal_error (__FILE__, __LINE__, @@ -2698,7 +2700,7 @@ aarch64_pseudo_register_type (struct gdbarch *gdbarch, int regnum) && p_regnum < AARCH64_SVE_V0_REGNUM + AARCH64_V_REGS_NUM) return aarch64_vnv_type (gdbarch); - if (tdep->has_pauth () && regnum == tdep->ra_sign_state_regnum) + if (tdep->has_pauth () && p_regnum == tdep->ra_sign_state_pseudo_regnum) return builtin_type (gdbarch)->builtin_uint64; internal_error (__FILE__, __LINE__, @@ -2732,7 +2734,7 @@ aarch64_pseudo_register_reggroup_p (struct gdbarch *gdbarch, int 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->ra_sign_state_regnum) + if (tdep->has_pauth () && p_regnum == tdep->ra_sign_state_pseudo_regnum) return 0; return group == all_reggroup; @@ -3598,8 +3600,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->ra_sign_state_regnum = (feature_pauth == NULL) ? -1 - : ra_sign_state_offset + num_regs; + tdep->ra_sign_state_pseudo_regnum = ra_sign_state_offset; tdep->mte_reg_base = first_mte_regnum; tdep->tls_regnum = tls_regnum; diff --git a/gdb/aarch64-tdep.h b/gdb/aarch64-tdep.h index d8513023c37..acb69b2dc40 100644 --- a/gdb/aarch64-tdep.h +++ b/gdb/aarch64-tdep.h @@ -94,7 +94,13 @@ struct aarch64_gdbarch_tdep : gdbarch_tdep_base } int pauth_reg_base = 0; - int ra_sign_state_regnum = 0; + int ra_sign_state_pseudo_regnum = -1; + + int get_ra_sign_state_regnum (gdbarch *gdbarch) const + { + gdb_assert (ra_sign_state_pseudo_regnum >= 0); + return ra_sign_state_pseudo_regnum + gdbarch_num_regs (gdbarch); + } /* Returns true if the target supports pauth. */ bool has_pauth () const