[2/2] Nios2, gdb: Adjust to new coredump format

Message ID fm-32642-202404191039253f6027d3c5d2ac7a26-pulLwC@errorhandling.siemens-energy.com
State New
Headers
Series [1/2] Nios2, libbfd: Support new coredump .reg section |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Testing passed
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Testing passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Testing passed

Commit Message

Moritz Strübe April 19, 2024, 10:39 a.m. UTC
  Current kernels create their coredumps using ptrace. Adjust to this new
format.
---
 gdb/nios2-linux-tdep.c | 68 ++++++++++++++++++++----------------------
 1 file changed, 32 insertions(+), 36 deletions(-)
  

Comments

Tom Tromey April 19, 2024, 3:08 p.m. UTC | #1
>>>>> "Moritz" == Moritz Strübe <moritz.struebe@siemens-energy.com> writes:

Thank you for the patch.

Moritz> Current kernels create their coredumps using ptrace. Adjust to this new
Moritz> format.

Is there any need to support old coredumps as well; and if not, why not?

Moritz> +/* Registers not set by dump */
Moritz> +static std::set<int> notsetregs = {0, 24, 25, 30};

Should be const.

Moritz>  /* Implement the supply_regset hook for core files.  */
Moritz> -
Moritz>  static void

Spurious change.

Moritz> +  // If regno is 0 dump all registers
Moritz> +  if(regnum > 0 ){
Moritz> +    regcache->raw_supply (regnum, gregs + 4 * regnum);
Moritz> +  } else {

gdb doesn't use '//' comments and also uses a different formatting
style.

thanks,
Tom
  

Patch

diff --git a/gdb/nios2-linux-tdep.c b/gdb/nios2-linux-tdep.c
index fb9e88326fb..16581508688 100644
--- a/gdb/nios2-linux-tdep.c
+++ b/gdb/nios2-linux-tdep.c
@@ -32,46 +32,40 @@ 
 #include "gdbarch.h"
 
 /* Core file and register set support.  */
+/* See arch/nios2/kernel/ptrace.c */
 
-/* Map from the normal register enumeration order to the order that
-   registers appear in core files, which corresponds to the order
-   of the register slots in the kernel's struct pt_regs.  */
+#define NIOS2_GREGS_SIZE (4 * NIOS2_NUM_REGS)
 
-static const int reg_offsets[NIOS2_NUM_REGS] =
-{
-  -1,  8,  9, 10, 11, 12, 13, 14,	/* r0 - r7 */
-  0,  1,  2,  3,  4,  5,  6,  7,	/* r8 - r15 */
-  23, 24, 25, 26, 27, 28, 29, 30,	/* r16 - r23 */
-  -1, -1, 19, 18, 17, 21, -1, 16,	/* et bt gp sp fp ea sstatus ra */
-  21,					/* pc */
-  -1, 20, -1, -1, -1, -1, -1, -1,	/* status estatus ...  */
-  -1, -1, -1, -1, -1, -1, -1, -1
-};
-
-/* General register set size.  Should match sizeof (struct pt_regs) +
-   sizeof (struct switch_stack) from the NIOS2 Linux kernel patch.  */
-
-#define NIOS2_GREGS_SIZE (4 * 34)
+/* Registers not set by dump */
+static std::set<int> notsetregs = {0, 24, 25, 30};
 
 /* Implement the supply_regset hook for core files.  */
-
 static void
 nios2_supply_gregset (const struct regset *regset,
 		      struct regcache *regcache,
 		      int regnum, const void *gregs_buf, size_t len)
 {
   const gdb_byte *gregs = (const gdb_byte *) gregs_buf;
-  int regno;
-  static const gdb_byte zero_buf[4] = {0, 0, 0, 0};
-
-  for (regno = NIOS2_Z_REGNUM; regno <= NIOS2_MPUACC_REGNUM; regno++)
-    if (regnum == -1 || regnum == regno)
-      {
-	if (reg_offsets[regno] != -1)
-	  regcache->raw_supply (regno, gregs + 4 * reg_offsets[regno]);
-	else
-	  regcache->raw_supply (regno, zero_buf);
+  const uint32_t *regvals = (const uint32_t *) gregs_buf;
+
+  // If regno is 0 dump all registers
+  if(regnum > 0 ){
+    regcache->raw_supply (regnum, gregs + 4 * regnum);
+  } else {
+    for (auto regno = NIOS2_Z_REGNUM; regno < NIOS2_NUM_REGS; regno++){
+      // Only CPU registers are set by dump. Thus ignore everything above NIOS2_PC_REGNUM
+      if(notsetregs.find(regno) == notsetregs.end() && regno <= NIOS2_PC_REGNUM ) {
+        regcache->raw_supply(regno, gregs + 4 * regno);
+      } else {
+        // Print a warning in case the register is suddenly set in the future.
+        if(regvals[regno] != 0){
+          warning (_("'.reg': expected regno %d to be 0, but was 0x%08x."), regno, regvals[regno]);
+        }
+        // Registers not available should be set passing NULL.
+        regcache->raw_supply(regno, NULL);
       }
+    }
+  }
 }
 
 /* Implement the collect_regset hook for core files.  */
@@ -82,14 +76,16 @@  nios2_collect_gregset (const struct regset *regset,
 		       int regnum, void *gregs_buf, size_t len)
 {
   gdb_byte *gregs = (gdb_byte *) gregs_buf;
-  int regno;
-
-  for (regno = NIOS2_Z_REGNUM; regno <= NIOS2_MPUACC_REGNUM; regno++)
-    if (regnum == -1 || regnum == regno)
-      {
-	if (reg_offsets[regno] != -1)
-	  regcache->raw_collect (regno, gregs + 4 * reg_offsets[regno]);
+  // If regno is 0 dump all registers
+  if(regnum > 0 ){
+    regcache->raw_collect (regnum, gregs + 4 * regnum);
+  } else {
+    for (auto regno = NIOS2_Z_REGNUM; regno <= NIOS2_NUM_REGS; regno++){
+      if(notsetregs.find(regno) == notsetregs.end() && regno <= NIOS2_PC_REGNUM ) {
+        regcache->raw_collect(regno, gregs + 4 * regno);
       }
+    }
+  }
 }
 
 static const struct regset nios2_core_regset =