]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[Morello] Unwinding: Restore CLR and PCC properly
authorLuis Machado <luis.machado@arm.com>
Fri, 9 Oct 2020 16:50:17 +0000 (13:50 -0300)
committerLuis Machado <luis.machado@linaro.org>
Tue, 20 Oct 2020 18:06:50 +0000 (15:06 -0300)
This patch teaches GDB how to handle restoring CLR and PCC values properly.

gdb/ChangeLog:

2020-10-20  Luis Machado  <luis.machado@arm.com>

* aarch64-tdep.c (aarch64_prologue_prev_register): Use LR or CLR
depending on the request.
(aarch64_dwarf_reg_to_regnum): Redirect CLR to LR temporarily.
* aarch64-tdep.h (AARCH64_DWARF_CLR): New constant.

gdb/ChangeLog
gdb/aarch64-tdep.c
gdb/aarch64-tdep.h

index 1db787a233a523671a6d7f64afa0b242e7237f0d..6df56cc91e78447f283a111e3bebe9c85558db35 100644 (file)
@@ -1,3 +1,10 @@
+2020-10-20  Luis Machado  <luis.machado@arm.com>
+
+       * aarch64-tdep.c (aarch64_prologue_prev_register): Use LR or CLR
+       depending on the request.
+       (aarch64_dwarf_reg_to_regnum): Redirect CLR to LR temporarily.
+       * aarch64-tdep.h (AARCH64_DWARF_CLR): New constant.
+
 2020-10-20  Luis Machado  <luis.machado@arm.com>
 
        * aarch64-tdep.c (aarch64_prologue_prev_register): Handle the PCC and
index 20b84c376491e94a3daaa7079da1ee9b7cef2d2d..b28ed42a9d0b29af76a310fc6c6cb1bb853e06e8 100644 (file)
@@ -1238,21 +1238,49 @@ aarch64_prologue_prev_register (struct frame_info *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.  */
+     frame's prologue, not the next frame's resume location.
+
+     We do the same for PCC and CLR.  */
   if (prev_regnum == AARCH64_PC_REGNUM || prev_regnum == pcc_regnum)
     {
       CORE_ADDR lr;
       struct gdbarch *gdbarch = get_frame_arch (this_frame);
+      enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
-      lr = frame_unwind_register_unsigned (this_frame, AARCH64_LR_REGNUM);
+      /* Fetch LR or CLR depending on the ABI.  */
+      int lr_regnum;
+      if (prev_regnum == AARCH64_PC_REGNUM)
+       lr_regnum = AARCH64_LR_REGNUM;
+      else
+       lr_regnum = tdep->cap_reg_base + 30;
+
+      struct value *lr_value = frame_unwind_register_value (this_frame,
+                                                           lr_regnum);
+
+      /* Extract only the bottom 8 bytes of CLR.  This truncates the capability
+        to 8 bytes.  For LR, this gets us the whole register.  */
+      lr = extract_unsigned_integer (value_contents_all (lr_value), 8,
+                                    byte_order);
 
       if (tdep->has_pauth ()
          && trad_frame_value_p (cache->saved_regs,
                                 tdep->pauth_ra_state_regnum))
        lr = aarch64_frame_unmask_lr (tdep, this_frame, lr);
 
+      /* Remove any potential LSB's in the address.  */
       lr = gdbarch_addr_bits_remove (gdbarch, lr);
-      return frame_unwind_got_constant (this_frame, prev_regnum, lr);
+
+      struct value *lr_value_adjusted
+         = frame_unwind_got_constant (this_frame, prev_regnum, lr);
+
+      /* Copy the capability tag over, if it exists.  */
+      if (prev_regnum == pcc_regnum && value_tagged (lr_value))
+       {
+         set_value_tagged (lr_value_adjusted, 1);
+         set_value_tag (lr_value_adjusted, value_tag (lr_value));
+       }
+
+      return lr_value_adjusted;
     }
 
   /* SP is generally not saved to the stack, but this frame is
@@ -2377,6 +2405,10 @@ aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
 
   if (tdep->has_capability ())
     {
+      /* FIXME-Morello: Redirect CLR to LR for now.  */
+      if (reg == AARCH64_DWARF_CLR)
+       return AARCH64_LR_REGNUM;
+
       if (reg >= AARCH64_DWARF_C0 && reg <= AARCH64_DWARF_C0 + 30)
        return tdep->cap_reg_base + (reg - AARCH64_DWARF_C0);
 
index c7238207c0ec72a130bd571f376fe25fcc95dc37..a9d89c0d8b7f6f0254c2b63b3d64e8f2b4fe3d46 100644 (file)
@@ -41,6 +41,7 @@ struct regset;
 #define AARCH64_DWARF_SVE_P0   48
 #define AARCH64_DWARF_SVE_Z0   96
 #define AARCH64_DWARF_C0  198
+#define AARCH64_DWARF_CLR 228
 #define AARCH64_DWARF_CSP 229
 #define AARCH64_DWARF_PCC 230
 #define AARCH64_DWARF_DDC 231