]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
[Morello] Add support for Morello sigreturn/sigcontext frame
authorLuis Machado <luis.machado@arm.com>
Thu, 24 Sep 2020 18:09:24 +0000 (15:09 -0300)
committerLuis Machado <luis.machado@linaro.org>
Tue, 20 Oct 2020 18:06:07 +0000 (15:06 -0300)
This patch teaches GDB how to interpret the Morello sigcontext
structure in a sigreturn frame and allows GDB to read back the
correct values of the registers.

gdb/ChangeLog:

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

* aarch64-linux-tdep.c: Include arch/aarch64-insn.h.
(AARCH64_MORELLO_MAGIC, AARCH64_MORELLO_SIGCONTEXT_SIZE)
(AARCH64_MORELLO_SIGCONTEXT_C0_OFFSET): New constants.
(aarch64_linux_sigframe_init): Update to handle Morello
sigreturn/sigcontext frames.

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

index 7fbb4cf8e0a6f7e2b65c0433f87c9f94ee9bf208..d87129edd7fd6221e6fef0001e38e188bdba6f0a 100644 (file)
@@ -1,3 +1,11 @@
+2020-10-20  Luis Machado  <luis.machado@arm.com>
+
+       * aarch64-linux-tdep.c: Include arch/aarch64-insn.h.
+       (AARCH64_MORELLO_MAGIC, AARCH64_MORELLO_SIGCONTEXT_SIZE)
+       (AARCH64_MORELLO_SIGCONTEXT_C0_OFFSET): New constants.
+       (aarch64_linux_sigframe_init): Update to handle Morello
+       sigreturn/sigcontext frames.
+
 2020-10-20  Luis Machado  <luis.machado@arm.com>
 
        * aarch64-tdep.c (aarch64_addr_bits_remove): New function.
index 7492437e97ebfe680052547a743c789824bbfc2e..df91af217ed8438d1c269c98aab31f255e50bae7 100644 (file)
@@ -47,6 +47,9 @@
 
 #include "value.h"
 
+/* For aarch64_debug.  */
+#include "arch/aarch64-insn.h"
+
 /* Signal frame handling.
 
       +------------+  ^
 #define AARCH64_EXTRA_MAGIC                    0x45585401
 #define AARCH64_FPSIMD_MAGIC                   0x46508001
 #define AARCH64_SVE_MAGIC                      0x53564501
+#define AARCH64_MORELLO_MAGIC                  0x4d524c01
 
 /* Defines for the extra_context that follows an AARCH64_EXTRA_MAGIC.  */
 #define AARCH64_EXTRA_DATAP_OFFSET             8
 #define AARCH64_SVE_CONTEXT_SIZE(vq) \
   (AARCH64_SVE_CONTEXT_FFR_OFFSET (vq) + (vq * 2))
 
+/* Defines for the Morello sigcontext data, which is define in the kernel like
+   so:
+
+   struct morello_context
+   {
+     struct _aarch64_ctx head;
+     __u64 __pad;
+     __kernel_uintcap_t cregs[31];
+     __kernel_uintcap_t csp;
+     __kernel_uintcap_t rcsp;
+     __kernel_uintcap_t pcc;
+   };
+
+*/
+
+#define AARCH64_MORELLO_SIGCONTEXT_SIZE              (8 + 8 + 34 * 16)
+#define AARCH64_MORELLO_SIGCONTEXT_C0_OFFSET  16
 
 /* Read an aarch64_ctx, returning the magic value, and setting *SIZE to the
    size, or return 0 on error.  */
@@ -205,6 +226,11 @@ aarch64_linux_sigframe_init (const struct tramp_frame *self,
   bool extra_found = false;
   int num_regs = gdbarch_num_regs (gdbarch);
 
+  if (aarch64_debug)
+    {
+      debug_printf ("\naarch64: Entering aarch64_linux_sigframe_init\n");
+    }
+
   /* Read in the integer registers.  */
 
   for (int i = 0; i < 31; i++)
@@ -261,6 +287,54 @@ aarch64_linux_sigframe_init (const struct tramp_frame *self,
            break;
          }
 
+       case AARCH64_MORELLO_MAGIC:
+         {
+           if (aarch64_debug)
+             debug_printf ("aarch64: Found Morello section at %s.\n",
+                           paddress (gdbarch, section));
+
+           /* Handle Morello sigcontext.  */
+           if (!tdep->has_capability ())
+             break;
+
+           int regno = tdep->cap_reg_base;
+           CORE_ADDR offset = section + AARCH64_MORELLO_SIGCONTEXT_C0_OFFSET;
+           int reg_size = C_REGISTER_SIZE;
+
+           if (aarch64_debug)
+             {
+               debug_printf ("aarch64: Reading C registers from sigreturn "
+                             "frame.\n");
+             }
+
+           for (int i = 0; i < AARCH64_C_REGS_NUM; i++)
+             {
+               trad_frame_set_reg_addr (this_cache, regno + i,
+                                        offset + i * reg_size);
+             }
+
+           int pcc_regnum = tdep->cap_reg_base + 31;
+           int csp_regnum = tdep->cap_reg_base + 32;
+           int rcsp_regnum = tdep->cap_reg_base + 35;
+
+           if (aarch64_debug)
+             {
+               debug_printf ("aarch64: Reading PCC, CSP and RCSP registers "
+                             "from sigreturn frame at %s.\n",
+                             paddress (gdbarch, offset + 31 * reg_size));
+             }
+
+           trad_frame_set_reg_addr (this_cache, csp_regnum,
+                                    offset + 31 * reg_size);
+           trad_frame_set_reg_addr (this_cache, rcsp_regnum,
+                                    offset + 32 * reg_size);
+           trad_frame_set_reg_addr (this_cache, pcc_regnum,
+                                    offset + 33 * reg_size);
+
+           section += size;
+           break;
+         }
+
        case AARCH64_EXTRA_MAGIC:
          {
            /* Extra is always the last valid section in reserved and points to
@@ -359,6 +433,9 @@ aarch64_linux_sigframe_init (const struct tramp_frame *self,
     }
 
   trad_frame_set_id (this_cache, frame_id_build (sp, func));
+
+  if (aarch64_debug)
+    debug_printf ("aarch64: Exitting aarch64_linux_sigframe_init\n");
 }
 
 static const struct tramp_frame aarch64_linux_rt_sigframe =