diff mbox

[RFC/RFT] Use core regset iterators on NetBSD/arm

Message ID 201411281619.sASGJbC8027851@d03av02.boulder.ibm.com
State New
Headers show

Commit Message

Ulrich Weigand Nov. 28, 2014, 4:19 p.m. UTC
Hello,

NetBSD/arm is another native target still does not use the new-style
iterate_over_regset_sections core file logic (allowing cross-debugging
of core files and core file generation).

The patch below provides iterate_over_regset_sections routines for
NetBSD/arm (both a.out and ELF core files -- not sure if a.out is
actually still relevant ...), copied mostly from the Linux version.

The patch is untested so far since I don't have access to a NetBSD/arm
system.  Testing by ARM maintainers would be much appreciated.

Bye,
Ulrich


gdb/

	* armnbsd-nat.c (struct md_core): Remove.
	(fetch_core_registers, fetch_elfcore_registers): Likewise.
	(arm_netbsd_core_fns, arm_netbsd_elfcore_fns): Likewise.
	(_initialize_arm_netbsd_nat): Do not call deprecated_add_core_fns.
	* armnbsd-tdep.c: Include "regcache.h" and "regset.h".
	(arm_apcs_32): Declare.
	(ARMNBSD_SIZEOF_GREGS, ARMNBSD_SIZEOF_FPAREGS): Define.
	(ARM_CPSR_GREGNUM): Define.
	(armnbsd_supply_gregset, armnbsd_supply_fparegset): New function.
	(armnbsd_aout_supply_gregset): Likewise.
	(armnbsd_gregset, armnbsd_fparegset): New variables.
	(armnbsd_aout_gregset): Likewise.
	(armnbsd_aout_iterate_over_regset_sections): New function.
	(arm_netbsd_aout_init_abi): Install it.
	(armnbsd_elf_iterate_over_regset_sections): New function.
	(arm_netbsd_elf_init_abi): Install it.
diff mbox

Patch

Index: binutils-gdb/gdb/armnbsd-nat.c
===================================================================
--- binutils-gdb.orig/gdb/armnbsd-nat.c	2014-11-11 16:31:24.273881172 +0100
+++ binutils-gdb/gdb/armnbsd-nat.c	2014-11-28 15:18:51.646317313 +0100
@@ -409,83 +409,6 @@  armnbsd_store_registers (struct target_o
     }
 }
 
-struct md_core
-{
-  struct reg intreg;
-  struct fpreg freg;
-};
-
-static void
-fetch_core_registers (struct regcache *regcache,
-		      char *core_reg_sect, unsigned core_reg_size,
-		      int which, CORE_ADDR ignore)
-{
-  struct md_core *core_reg = (struct md_core *) core_reg_sect;
-  int regno;
-  CORE_ADDR r_pc;
-
-  arm_supply_gregset (regcache, &core_reg->intreg);
-  arm_supply_fparegset (regcache, &core_reg->freg);
-}
-
-static void
-fetch_elfcore_registers (struct regcache *regcache,
-			 char *core_reg_sect, unsigned core_reg_size,
-			 int which, CORE_ADDR ignore)
-{
-  struct reg gregset;
-  struct fpreg fparegset;
-
-  switch (which)
-    {
-    case 0:	/* Integer registers.  */
-      if (core_reg_size != sizeof (struct reg))
-	warning (_("wrong size of register set in core file"));
-      else
-	{
-	  /* The memcpy may be unnecessary, but we can't really be sure
-	     of the alignment of the data in the core file.  */
-	  memcpy (&gregset, core_reg_sect, sizeof (gregset));
-	  arm_supply_gregset (regcache, &gregset);
-	}
-      break;
-
-    case 2:
-      if (core_reg_size != sizeof (struct fpreg))
-	warning (_("wrong size of FPA register set in core file"));
-      else
-	{
-	  /* The memcpy may be unnecessary, but we can't really be sure
-	     of the alignment of the data in the core file.  */
-	  memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
-	  arm_supply_fparegset (regcache, &fparegset);
-	}
-      break;
-
-    default:
-      /* Don't know what kind of register request this is; just ignore it.  */
-      break;
-    }
-}
-
-static struct core_fns arm_netbsd_core_fns =
-{
-  bfd_target_unknown_flavour,		/* core_flovour.  */
-  default_check_format,			/* check_format.  */
-  default_core_sniffer,			/* core_sniffer.  */
-  fetch_core_registers,			/* core_read_registers.  */
-  NULL
-};
-
-static struct core_fns arm_netbsd_elfcore_fns =
-{
-  bfd_target_elf_flavour,		/* core_flovour.  */
-  default_check_format,			/* check_format.  */
-  default_core_sniffer,			/* core_sniffer.  */
-  fetch_elfcore_registers,		/* core_read_registers.  */
-  NULL
-};
-
 void
 _initialize_arm_netbsd_nat (void)
 {
@@ -495,7 +418,4 @@  _initialize_arm_netbsd_nat (void)
   t->to_fetch_registers = armnbsd_fetch_registers;
   t->to_store_registers = armnbsd_store_registers;
   add_target (t);
-
-  deprecated_add_core_fns (&arm_netbsd_core_fns);
-  deprecated_add_core_fns (&arm_netbsd_elfcore_fns);
 }
Index: binutils-gdb/gdb/armnbsd-tdep.c
===================================================================
--- binutils-gdb.orig/gdb/armnbsd-tdep.c	2014-11-11 16:31:24.278881202 +0100
+++ binutils-gdb/gdb/armnbsd-tdep.c	2014-11-28 15:18:51.652317352 +0100
@@ -19,10 +19,142 @@ 
 
 #include "defs.h"
 #include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
 
 #include "arm-tdep.h"
 #include "solib-svr4.h"
 
+extern int arm_apcs_32;
+
+
+/* Core file support.  */
+
+#define ARMNBSD_SIZEOF_GREGS  (INT_REGISTER_SIZE * 17)
+#define ARMNBSD_SIZEOF_FPAREGS (INT_REGISTER_SIZE + FP_REGISTER_SIZE * 8)
+
+/* The index to access CSPR in struct reg.  */
+#define ARM_CPSR_GREGNUM 16
+
+static void
+armnbsd_supply_gregset (const struct regset *regset,
+			struct regcache *regcache,
+			int regnum, const void *gregs_buf, size_t len)
+{
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+  const gdb_byte *gregs = gregs_buf;
+  int regno;
+
+  gdb_assert (len >= ARMNBSD_SIZEOF_GREGS);
+
+  for (regno = ARM_A1_REGNUM; regno < ARM_PC_REGNUM; regno++)
+    if (regnum == -1 || regnum == regno)
+      regcache_raw_supply (regcache, regno,
+			   gregs + INT_REGISTER_SIZE * regno);
+
+  if (regnum == -1 || regnum == ARM_PS_REGNUM)
+    {
+      if (arm_apcs_32)
+	regcache_raw_supply (regcache, ARM_PS_REGNUM,
+			     gregs + INT_REGISTER_SIZE * ARM_CPSR_GREGNUM);
+      else
+	regcache_raw_supply (regcache, ARM_PS_REGNUM,
+			     gregs + INT_REGISTER_SIZE * ARM_PC_REGNUM);
+    }
+
+  if (regnum == -1 || regnum == ARM_PC_REGNUM)
+    {
+      gdb_byte pc_buf[INT_REGISTER_SIZE];
+      CORE_ADDR reg_pc;
+      reg_pc = extract_unsigned_integer ((gregs
+					  + INT_REGISTER_SIZE * ARM_PC_REGNUM),
+					 INT_REGISTER_SIZE, byte_order);
+      reg_pc = gdbarch_addr_bits_remove (gdbarch, reg_pc);
+      store_unsigned_integer (pc_buf, INT_REGISTER_SIZE, byte_order, reg_pc);
+      regcache_raw_supply (regcache, ARM_PC_REGNUM, pc_buf);
+    }
+}
+
+static void
+armnbsd_supply_fparegset (const struct regset *regset,
+			  struct regcache *regcache,
+			  int regnum, const void *regs_buf, size_t len)
+{
+  const gdb_byte *regs = regs_buf;
+  int regno;
+
+  gdb_assert (len >= ARMNBSD_SIZEOF_FPAREGS);
+
+  for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
+    if (regnum == -1 || regnum == regno)
+      regcache_raw_supply (regcache, regno,
+			   (regs + INT_REGISTER_SIZE
+			    + FP_REGISTER_SIZE * (regno - ARM_F0_REGNUM)));
+
+  if (regnum == -1 || regnum == ARM_FPS_REGNUM)
+    regcache_raw_supply (regcache, ARM_FPS_REGNUM, regs);
+}
+
+static void
+armnbsd_aout_supply_gregset (const struct regset *regset,
+			     struct regcache *regcache,
+			     int regnum, const void *regs_buf, size_t len)
+{
+  const gdb_byte *regs = regs_buf;
+
+  gdb_assert (len >= ARMNBSD_SIZEOF_GREGS + ARMNBSD_SIZEOF_FPAREGS);
+  armnbsd_supply_gregset (regset, regcache, regnum,
+			  regs, ARMNBSD_SIZEOF_GREGS);
+
+  regs += ARMNBSD_SIZEOF_GREGS;
+  armnbsd_supply_fparegset (regset, regcache, regnum,
+			    regs, ARMNBSD_SIZEOF_FPAREGS);
+}
+
+/* NetBSD/arm register sets.  */
+
+static struct regset armnbsd_gregset =
+{
+  NULL,
+  armnbsd_supply_gregset
+};
+
+static struct regset armnbsd_fparegset =
+{
+  NULL,
+  armnbsd_supply_fparegset
+};
+
+static struct regset armnbsd_aout_gregset =
+{
+  NULL,
+  armnbsd_aout_supply_gregset
+};
+
+/* Iterate over supported core file register note sections. */
+
+static void
+armnbsd_aout_iterate_over_regset_sections (struct gdbarch *gdbarch,
+					   iterate_over_regset_sections_cb *cb,
+					   void *cb_data,
+					   const struct regcache *regcache)
+{
+  cb (".reg", ARMNBSD_SIZEOF_GREGS + ARMNBSD_SIZEOF_FPAREGS,
+      &armnbsd_aout_gregset, NULL, cb_data);
+}
+
+static void
+armnbsd_elf_iterate_over_regset_sections (struct gdbarch *gdbarch,
+					  iterate_over_regset_sections_cb *cb,
+					  void *cb_data,
+					  const struct regcache *regcache)
+{
+  cb (".reg", ARMNBSD_SIZEOF_GREGS, &armnbsd_gregset, NULL, cb_data);
+  cb (".reg2", ARMNBSD_SIZEOF_FPAREGS, &armnbsd_fparegset, NULL, cb_data);
+}
+
+
 /* Description of the longjmp buffer.  */
 #define ARM_NBSD_JB_PC 24
 #define ARM_NBSD_JB_ELEMENT_SIZE INT_REGISTER_SIZE
@@ -78,6 +210,9 @@  arm_netbsd_aout_init_abi (struct gdbarch
   arm_netbsd_init_abi_common (info, gdbarch);
   if (tdep->fp_model == ARM_FLOAT_AUTO)
     tdep->fp_model = ARM_FLOAT_SOFT_FPA;
+
+  set_gdbarch_iterate_over_regset_sections
+    (gdbarch, armnbsd_aout_iterate_over_regset_sections);
 }
 
 static void
@@ -93,6 +228,9 @@  arm_netbsd_elf_init_abi (struct gdbarch_
   /* NetBSD ELF uses SVR4-style shared libraries.  */
   set_solib_svr4_fetch_link_map_offsets
     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+  set_gdbarch_iterate_over_regset_sections
+    (gdbarch, armnbsd_elf_iterate_over_regset_sections);
 }
 
 static enum gdb_osabi