gdb/arm: Define MSP and PSP registers for M-Profile
authorChristophe Lyon <christophe.lyon@arm.com>
Fri, 1 Apr 2022 09:22:08 +0000 (10:22 +0100)
committerChristophe Lyon <christophe.lyon@arm.com>
Wed, 27 Apr 2022 14:18:18 +0000 (15:18 +0100)
This patch removes the hardcoded access to PSP in
arm_m_exception_cache() and relies on the definition with the XML
descriptions.

Signed-off-by: Christophe Lyon <christophe.lyon@foss.st.com>
Signed-off-by: Christophe Lyon <christophe.lyon@arm.com>
gdb/arch/arm.c
gdb/arch/arm.h
gdb/arm-tdep.c
gdb/arm-tdep.h
gdb/features/Makefile
gdb/features/arm/arm-m-system.c [new file with mode: 0644]
gdb/features/arm/arm-m-system.xml [new file with mode: 0644]

index 126e46a950a98c1821f755f1d822d882e9b63205..bc6e5ce3f09c008a8ba801140e872a0e62727be4 100644 (file)
@@ -28,6 +28,7 @@
 #include "../features/arm/arm-m-profile.c"
 #include "../features/arm/arm-m-profile-with-fpa.c"
 #include "../features/arm/arm-m-profile-mve.c"
+#include "../features/arm/arm-m-system.c"
 
 /* See arm.h.  */
 
@@ -446,6 +447,11 @@ arm_create_mprofile_target_description (arm_m_profile_type m_type)
       regnum = create_feature_arm_arm_m_profile_mve (tdesc, regnum);
       break;
 
+    case ARM_M_TYPE_SYSTEM:
+      regnum = create_feature_arm_arm_m_profile (tdesc, regnum);
+      regnum = create_feature_arm_arm_m_system (tdesc, regnum);
+      break;
+
     default:
       error (_("Invalid Arm M type: %d"), m_type);
     }
index 755391fe6fe4d362d3d581e0ac39ede57518ae27..0728bea1501f73161af3cd45a7308762f312ffd9 100644 (file)
@@ -105,6 +105,7 @@ enum arm_m_profile_type {
    ARM_M_TYPE_VFP_D16,
    ARM_M_TYPE_WITH_FPA,
    ARM_M_TYPE_MVE,
+   ARM_M_TYPE_SYSTEM,
    ARM_M_TYPE_INVALID
 };
 
index 66e26e6e2126e9583515fea2293a0ce9a7652381..6b4b00993fa133aed66f19c5658b58abff0f8e4c 100644 (file)
@@ -3076,9 +3076,9 @@ arm_m_exception_cache (struct frame_info *this_frame)
 {
   struct gdbarch *gdbarch = get_frame_arch (this_frame);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  arm_gdbarch_tdep *tdep = (arm_gdbarch_tdep *) gdbarch_tdep (gdbarch);
   struct arm_prologue_cache *cache;
   CORE_ADDR lr;
-  CORE_ADDR sp;
   CORE_ADDR unwound_sp;
   LONGEST xpsr;
   uint32_t exc_return;
@@ -3094,7 +3094,6 @@ arm_m_exception_cache (struct frame_info *this_frame)
      to the exception and if FPU is used (causing extended stack frame).  */
 
   lr = get_frame_register_unsigned (this_frame, ARM_LR_REGNUM);
-  sp = get_frame_register_unsigned (this_frame, ARM_SP_REGNUM);
 
   /* Check EXC_RETURN indicator bits.  */
   exc_return = (((lr >> 28) & 0xf) == 0xf);
@@ -3103,37 +3102,13 @@ arm_m_exception_cache (struct frame_info *this_frame)
   process_stack_used = ((lr & (1 << 2)) != 0);
   if (exc_return && process_stack_used)
     {
-      /* Thread (process) stack used.
-        Potentially this could be other register defined by target, but PSP
-        can be considered a standard name for the "Process Stack Pointer".
-        To be fully aware of system registers like MSP and PSP, these could
-        be added to a separate XML arm-m-system-profile that is valid for
-        ARMv6-M and ARMv7-M architectures. Also to be able to debug eg a
-        corefile off-line, then these registers must be defined by GDB,
-        and also be included in the corefile regsets.  */
-
-      int psp_regnum = user_reg_map_name_to_regnum (gdbarch, "psp", -1);
-      if (psp_regnum == -1)
-       {
-         /* Thread (process) stack could not be fetched,
-            give warning and exit.  */
-
-         warning (_("no PSP thread stack unwinding supported."));
-
-         /* Terminate any further stack unwinding by refer to self.  */
-         cache->prev_sp = sp;
-         return cache;
-       }
-      else
-       {
-         /* Thread (process) stack used, use PSP as SP.  */
-         unwound_sp = get_frame_register_unsigned (this_frame, psp_regnum);
-       }
+      /* Thread (process) stack used, use PSP as SP.  */
+      unwound_sp = get_frame_register_unsigned (this_frame, tdep->m_profile_psp_regnum);
     }
   else
     {
       /* Main stack used, use MSP as SP.  */
-      unwound_sp = sp;
+      unwound_sp = get_frame_register_unsigned (this_frame, tdep->m_profile_msp_regnum);
     }
 
   /* The hardware saves eight 32-bit words, comprising xPSR,
@@ -9188,6 +9163,10 @@ arm_register_g_packet_guesses (struct gdbarch *gdbarch)
       register_remote_g_packet_guess (gdbarch, ARM_CORE_REGS_SIZE
                                      + ARM_VFP2_REGS_SIZE
                                      + ARM_INT_REGISTER_SIZE, tdesc);
+
+      /* M-profile system (stack pointers).  */
+      tdesc = arm_read_mprofile_description (ARM_M_TYPE_SYSTEM);
+      register_remote_g_packet_guess (gdbarch, 2 * ARM_INT_REGISTER_SIZE, tdesc);
     }
 
   /* Otherwise we don't have a useful guess.  */
@@ -9260,6 +9239,9 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   bool have_pacbti = false;
   int mve_vpr_regnum = -1;
   int register_count = ARM_NUM_REGS;
+  bool have_m_profile_msp = false;
+  int m_profile_msp_regnum = -1;
+  int m_profile_psp_regnum = -1;
 
   /* If we have an object to base this architecture on, try to determine
      its ABI.  */
@@ -9490,6 +9472,35 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
       if (!valid_p)
        return NULL;
 
+      if (is_m)
+       {
+         feature = tdesc_find_feature (tdesc,
+                                       "org.gnu.gdb.arm.m-system");
+         if (feature != nullptr)
+           {
+             /* MSP */
+             valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+                                                 register_count, "msp");
+             if (!valid_p)
+               {
+                 warning (_("M-profile m-system feature is missing required register msp."));
+                 return nullptr;
+               }
+             have_m_profile_msp = true;
+             m_profile_msp_regnum = register_count++;
+
+             /* PSP */
+             valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+                                                 register_count, "psp");
+             if (!valid_p)
+               {
+                 warning (_("M-profile m-system feature is missing required register psp."));
+                 return nullptr;
+               }
+             m_profile_psp_regnum = register_count++;
+           }
+       }
+
       feature = tdesc_find_feature (tdesc,
                                    "org.gnu.gdb.arm.fpa");
       if (feature != NULL)
@@ -9713,6 +9724,13 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Adjust the PACBTI feature settings.  */
   tdep->have_pacbti = have_pacbti;
 
+  /* Adjust the M-profile stack pointers settings.  */
+  if (have_m_profile_msp)
+    {
+      tdep->m_profile_msp_regnum = m_profile_msp_regnum;
+      tdep->m_profile_psp_regnum = m_profile_psp_regnum;
+    }
+
   arm_register_g_packet_guesses (gdbarch);
 
   /* Breakpoints.  */
@@ -9998,6 +10016,10 @@ arm_dump_tdep (struct gdbarch *gdbarch, struct ui_file *file)
              tdep->mve_pseudo_base);
   gdb_printf (file, _("arm_dump_tdep: mve_pseudo_count = %i\n"),
              tdep->mve_pseudo_count);
+  gdb_printf (file, _("arm_dump_tdep: m_profile_msp_regnum = %i\n"),
+             tdep->m_profile_msp_regnum);
+  gdb_printf (file, _("arm_dump_tdep: m_profile_psp_regnum = %i\n"),
+             tdep->m_profile_psp_regnum);
   gdb_printf (file, _("arm_dump_tdep: Lowest pc = 0x%lx\n"),
              (unsigned long) tdep->lowest_pc);
   gdb_printf (file, _("arm_dump_tdep: have_pacbti = %s\n"),
index ae32fffcabf093d0cb3d79fe6ab0599773b28a45..40170673fde8086778be10caef1084494cdd5fa8 100644 (file)
@@ -125,6 +125,9 @@ struct arm_gdbarch_tdep : gdbarch_tdep
                                   register.  */
   int pacbti_pseudo_count = 0; /* Total number of PACBTI pseudo registers.  */
 
+  int m_profile_msp_regnum = 0;        /* M-profile MSP register number.  */
+  int m_profile_psp_regnum = 0;        /* M-profile PSP register number.  */
+
   bool is_m = false;           /* Does the target follow the "M" profile.  */
   CORE_ADDR lowest_pc = 0;     /* Lowest address at which instructions
                                   will appear.  */
index a2bb2a5922f62817ae32ae4336e882eb69c13a3d..737d9cbd3dbe3a6e4922d3bfa9caba78c7b9e166 100644 (file)
@@ -206,6 +206,7 @@ FEATURE_XMLFILES = aarch64-core.xml \
        arm/arm-fpa.xml \
        arm/arm-m-profile.xml \
        arm/arm-m-profile-mve.xml \
+       arm/arm-m-system.xml \
        arm/arm-m-profile-with-fpa.xml \
        arm/arm-vfpv2.xml \
        arm/arm-vfpv3.xml \
diff --git a/gdb/features/arm/arm-m-system.c b/gdb/features/arm/arm-m-system.c
new file mode 100644 (file)
index 0000000..3fb20a5
--- /dev/null
@@ -0,0 +1,15 @@
+/* THIS FILE IS GENERATED.  -*- buffer-read-only: t -*- vi:set ro:
+  Original: arm-m-system.xml */
+
+#include "gdbsupport/tdesc.h"
+
+static int
+create_feature_arm_arm_m_system (struct target_desc *result, long regnum)
+{
+  struct tdesc_feature *feature;
+
+  feature = tdesc_create_feature (result, "org.gnu.gdb.arm.m-system");
+  tdesc_create_reg (feature, "msp", regnum++, 1, NULL, 32, "data_ptr");
+  tdesc_create_reg (feature, "psp", regnum++, 1, NULL, 32, "data_ptr");
+  return regnum;
+}
diff --git a/gdb/features/arm/arm-m-system.xml b/gdb/features/arm/arm-m-system.xml
new file mode 100644 (file)
index 0000000..eb167ad
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!-- Copyright (C) 2022 Free Software Foundation, Inc.
+
+     Copying and distribution of this file, with or without modification,
+     are permitted in any medium without royalty provided the copyright
+     notice and this notice are preserved.  -->
+
+<!DOCTYPE feature SYSTEM "gdb-target.dtd">
+<feature name="org.gnu.gdb.arm.m-system">
+  <reg name="msp" bitsize="32" type="data_ptr"/>
+  <reg name="psp" bitsize="32" type="data_ptr"/>
+</feature>