]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[Morello] Enable DWARF unwinding with C registers
authorLuis Machado <luis.machado@arm.com>
Wed, 9 Sep 2020 16:09:47 +0000 (13:09 -0300)
committerLuis Machado <luis.machado@linaro.org>
Tue, 20 Oct 2020 18:06:45 +0000 (15:06 -0300)
Adjust unwinding functions to cope with the presence of C registers.

gdb/ChangeLog:

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

* aarch64-tdep.c (aarch64_prologue_prev_register): Handle the PCC and
CSP registers. Remove the LSB.
(aarch64_dwarf2_prev_register): Handle CSP, PCC and remove the LSB
from CLR.
(aarch64_dwarf2_frame_init_reg): Handle PCC and CSP.
(aarch64_dwarf_reg_to_regnum): Handle C registers.

gdb/ChangeLog
gdb/aarch64-tdep.c

index f15af2c4552b97ec536400c775c23e8b16b920ca..1db787a233a523671a6d7f64afa0b242e7237f0d 100644 (file)
@@ -1,3 +1,12 @@
+2020-10-20  Luis Machado  <luis.machado@arm.com>
+
+       * aarch64-tdep.c (aarch64_prologue_prev_register): Handle the PCC and
+       CSP registers. Remove the LSB.
+       (aarch64_dwarf2_prev_register): Handle CSP, PCC and remove the LSB
+       from CLR.
+       (aarch64_dwarf2_frame_init_reg): Handle PCC and CSP.
+       (aarch64_dwarf_reg_to_regnum): Handle C registers.
+
 2020-10-20  Luis Machado  <luis.machado@arm.com>
 
        * dwarf2/frame.c (struct dwarf2_cie) <pure_cap>: New field.
index 72adec05884ebca0a0b0e68a7ce49455bf276fd2..20b84c376491e94a3daaa7079da1ee9b7cef2d2d 100644 (file)
@@ -1233,14 +1233,16 @@ aarch64_prologue_prev_register (struct frame_info *this_frame,
   struct aarch64_prologue_cache *cache
     = aarch64_make_prologue_cache (this_frame, this_cache);
 
+  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
+  int pcc_regnum = tdep->cap_reg_base + 31;
+
   /* 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.  */
-  if (prev_regnum == AARCH64_PC_REGNUM)
+  if (prev_regnum == AARCH64_PC_REGNUM || prev_regnum == pcc_regnum)
     {
       CORE_ADDR lr;
       struct gdbarch *gdbarch = get_frame_arch (this_frame);
-      struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
       lr = frame_unwind_register_unsigned (this_frame, AARCH64_LR_REGNUM);
 
@@ -1249,6 +1251,7 @@ aarch64_prologue_prev_register (struct frame_info *this_frame,
                                 tdep->pauth_ra_state_regnum))
        lr = aarch64_frame_unmask_lr (tdep, this_frame, lr);
 
+      lr = gdbarch_addr_bits_remove (gdbarch, lr);
       return frame_unwind_got_constant (this_frame, prev_regnum, lr);
     }
 
@@ -1267,7 +1270,9 @@ aarch64_prologue_prev_register (struct frame_info *this_frame,
          |          |
          |          |<- SP
          +----------+  */
-  if (prev_regnum == AARCH64_SP_REGNUM)
+  int csp_regnum = tdep->cap_reg_base + 32;
+
+  if (prev_regnum == AARCH64_SP_REGNUM || prev_regnum == csp_regnum)
     return frame_unwind_got_constant (this_frame, prev_regnum,
                                      cache->prev_sp);
 
@@ -1407,20 +1412,21 @@ static struct value *
 aarch64_dwarf2_prev_register (struct frame_info *this_frame,
                              void **this_cache, int regnum)
 {
-  struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (this_frame));
+  struct gdbarch *gdbarch = get_frame_arch (this_frame);
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   CORE_ADDR lr;
 
-  switch (regnum)
+  int pcc_regnum = tdep->cap_reg_base + 31;
+
+  if (regnum == AARCH64_PC_REGNUM || regnum == pcc_regnum)
     {
-    case AARCH64_PC_REGNUM:
       lr = frame_unwind_register_unsigned (this_frame, AARCH64_LR_REGNUM);
       lr = aarch64_frame_unmask_lr (tdep, this_frame, lr);
+      lr = gdbarch_addr_bits_remove (gdbarch, lr);
       return frame_unwind_got_constant (this_frame, regnum, lr);
-
-    default:
-      internal_error (__FILE__, __LINE__,
-                     _("Unexpected register %d"), regnum);
     }
+
+  internal_error (__FILE__, __LINE__, _("Unexpected register %d"), regnum);
 }
 
 static const unsigned char op_lit0 = DW_OP_lit0;
@@ -1434,15 +1440,18 @@ aarch64_dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
                               struct frame_info *this_frame)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+  int pcc_regnum = tdep->cap_reg_base + 31;
+  int csp_regnum = tdep->cap_reg_base + 32;
 
-  switch (regnum)
+  if (regnum == AARCH64_PC_REGNUM || regnum == pcc_regnum)
     {
-    case AARCH64_PC_REGNUM:
       reg->how = DWARF2_FRAME_REG_FN;
       reg->loc.fn = aarch64_dwarf2_prev_register;
       return;
+    }
 
-    case AARCH64_SP_REGNUM:
+  if (regnum == AARCH64_SP_REGNUM || regnum == csp_regnum)
+    {
       reg->how = DWARF2_FRAME_REG_CFA;
       return;
     }
@@ -2366,6 +2375,15 @@ aarch64_dwarf_reg_to_regnum (struct gdbarch *gdbarch, int reg)
        return tdep->pauth_ra_state_regnum;
     }
 
+  if (tdep->has_capability ())
+    {
+      if (reg >= AARCH64_DWARF_C0 && reg <= AARCH64_DWARF_C0 + 30)
+       return tdep->cap_reg_base + (reg - AARCH64_DWARF_C0);
+
+      if (reg == AARCH64_DWARF_CSP)
+       return tdep->cap_reg_base + 32;
+    }
+
   return -1;
 }