diff mbox

[RFC/RFT] Use core regset iterators on Linux/CRIS

Message ID 201411281547.sASFl86V028540@d03av02.boulder.ibm.com
State New
Headers show

Commit Message

Ulrich Weigand Nov. 28, 2014, 3:47 p.m. UTC
Hello,

the CRIS tdep file is unique in that it calls cris_elf_core_fns to install
a core file sniffer, which was really only ever intended for native targets.
(Not to mention that core file sniffers have long been obsolete.)

This is probably why CRIS was missed by Andreas Arnez' recent patch series
to move all Linux targets to the new iterate_over_regset_sections method.

This patch brings CRIS in line with the other Linux targets.  It is so far
untested since I don't have access to CRIS; I'd appreciate if any of the
CRIS maintainers could give it a go.

Since there is now a cris-linux-tdep.c file, it seemed appropriate to move
the cris_iterate_over_regset_sections function there.  This necessitated
moving a bunch of register number enums from cris-tdep.c to cris-tdep.h

Bye,
Ulrich


gdb/
	* cris-tdep.h (enum cris_num_regs, enum cris_regnums): Move from ...
	* cris-tdep.c (enum cris_num_regs, enum cris_regnums): ... here.
	(cris_elf_greg_t): Remove.
	(CRISV10_ELF_NGREG, cris_elf_gregset_t): Likewise.
	(CRISV32_ELF_NGREG, crisv32_elf_gregset_t): Likewise.
	(cris_supply_gregset, fetch_core_registers): Likewise.
	(cris_elf_core_fns): Likewise.
	(_initialize_cris_tdep): Do not call deprecated_add_core_fns.
	* cris-linux-tdep.c: Include "regcache.h" and "regset.h".
	(CRISV10_LINUX_SIZEOF_GREGSET): Define.
	(CRISV32_LINUX_SIZEOF_GREGSET): Define.
	(cris_linux_regmap): New variable.
	(crisv32_supply_gregset): New function.
	(crisv10_linux_gregset, crisv32_linux_gregset): New variables.
	(cris_iterate_over_regset_sections): New function.
	(cris_linux_init_abi): Install it.

Comments

Ricard Wanderlof Nov. 28, 2014, 4:06 p.m. UTC | #1
On Fri, 28 Nov 2014, Ulrich Weigand wrote:

> This patch brings CRIS in line with the other Linux targets.  It is so far
> untested since I don't have access to CRIS; I'd appreciate if any of the
> CRIS maintainers could give it a go.

Thanks Ulrich for your help. I'll try to have a go at testing this.

regards,

/Ricard
diff mbox

Patch

Index: binutils-gdb/gdb/cris-tdep.c
===================================================================
--- binutils-gdb.orig/gdb/cris-tdep.c	2014-11-11 16:31:24.896884689 +0100
+++ binutils-gdb/gdb/cris-tdep.c	2014-11-28 15:18:16.426081248 +0100
@@ -46,101 +46,6 @@ 
 
 #include "cris-tdep.h"
 
-enum cris_num_regs
-{
-  /* There are no floating point registers.  Used in gdbserver low-linux.c.  */
-  NUM_FREGS = 0,
-  
-  /* There are 16 general registers.  */
-  NUM_GENREGS = 16,
-  
-  /* There are 16 special registers.  */
-  NUM_SPECREGS = 16,
-
-  /* CRISv32 has a pseudo PC register, not noted here.  */
-  
-  /* CRISv32 has 16 support registers.  */
-  NUM_SUPPREGS = 16
-};
-
-/* Register numbers of various important registers.
-   CRIS_FP_REGNUM   Contains address of executing stack frame.
-   STR_REGNUM  Contains the address of structure return values.
-   RET_REGNUM  Contains the return value when shorter than or equal to 32 bits
-   ARG1_REGNUM Contains the first parameter to a function.
-   ARG2_REGNUM Contains the second parameter to a function.
-   ARG3_REGNUM Contains the third parameter to a function.
-   ARG4_REGNUM Contains the fourth parameter to a function.  Rest on stack.
-   gdbarch_sp_regnum Contains address of top of stack.
-   gdbarch_pc_regnum Contains address of next instruction.
-   SRP_REGNUM  Subroutine return pointer register.
-   BRP_REGNUM  Breakpoint return pointer register.  */
-
-enum cris_regnums
-{
-  /* Enums with respect to the general registers, valid for all 
-     CRIS versions.  The frame pointer is always in R8.  */
-  CRIS_FP_REGNUM = 8,
-  /* ABI related registers.  */
-  STR_REGNUM  = 9,
-  RET_REGNUM  = 10,
-  ARG1_REGNUM = 10,
-  ARG2_REGNUM = 11,
-  ARG3_REGNUM = 12,
-  ARG4_REGNUM = 13,
-  
-  /* Registers which happen to be common.  */
-  VR_REGNUM   = 17,
-  MOF_REGNUM  = 23,
-  SRP_REGNUM  = 27,
-
-  /* CRISv10 et al. specific registers.  */
-  P0_REGNUM   = 16,
-  P4_REGNUM   = 20,
-  CCR_REGNUM  = 21,
-  P8_REGNUM   = 24,
-  IBR_REGNUM  = 25,
-  IRP_REGNUM  = 26,
-  BAR_REGNUM  = 28,
-  DCCR_REGNUM = 29,
-  BRP_REGNUM  = 30,
-  USP_REGNUM  = 31,
-
-  /* CRISv32 specific registers.  */
-  ACR_REGNUM  = 15,
-  BZ_REGNUM   = 16,
-  PID_REGNUM  = 18,
-  SRS_REGNUM  = 19,
-  WZ_REGNUM   = 20,
-  EXS_REGNUM  = 21,
-  EDA_REGNUM  = 22,
-  DZ_REGNUM   = 24,
-  EBP_REGNUM  = 25,
-  ERP_REGNUM  = 26,
-  NRP_REGNUM  = 28,
-  CCS_REGNUM  = 29,
-  CRISV32USP_REGNUM  = 30, /* Shares name but not number with CRISv10.  */
-  SPC_REGNUM  = 31,
-  CRISV32PC_REGNUM   = 32, /* Shares name but not number with CRISv10.  */
-
-  S0_REGNUM = 33,
-  S1_REGNUM = 34,
-  S2_REGNUM = 35,
-  S3_REGNUM = 36,
-  S4_REGNUM = 37,
-  S5_REGNUM = 38,
-  S6_REGNUM = 39,
-  S7_REGNUM = 40,
-  S8_REGNUM = 41,
-  S9_REGNUM = 42,
-  S10_REGNUM = 43,
-  S11_REGNUM = 44,
-  S12_REGNUM = 45,
-  S13_REGNUM = 46,
-  S14_REGNUM = 47,
-  S15_REGNUM = 48,
-};
-
 extern const struct cris_spec_reg cris_spec_regs[];
 
 /* CRIS version, set via the user command 'set cris-version'.  Affects
@@ -3812,87 +3717,6 @@  cris_delayed_get_disassembler (bfd_vma a
   return print_insn (addr, info);
 }
 
-/* Originally from <asm/elf.h>.  */
-typedef unsigned char cris_elf_greg_t[4];
-
-/* Same as user_regs_struct struct in <asm/user.h>.  */
-#define CRISV10_ELF_NGREG 35
-typedef cris_elf_greg_t cris_elf_gregset_t[CRISV10_ELF_NGREG];
-
-#define CRISV32_ELF_NGREG 32
-typedef cris_elf_greg_t crisv32_elf_gregset_t[CRISV32_ELF_NGREG];
-
-/* Unpack a cris_elf_gregset_t into GDB's register cache.  */
-
-static void 
-cris_supply_gregset (struct regcache *regcache, cris_elf_gregset_t *gregsetp)
-{
-  struct gdbarch *gdbarch = get_regcache_arch (regcache);
-  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
-  int i;
-  cris_elf_greg_t *regp = *gregsetp;
-
-  /* The kernel dumps all 32 registers as unsigned longs, but supply_register
-     knows about the actual size of each register so that's no problem.  */
-  for (i = 0; i < NUM_GENREGS + NUM_SPECREGS; i++)
-    {
-      regcache_raw_supply (regcache, i, (char *)&regp[i]);
-    }
-
-  if (tdep->cris_version == 32)
-    {
-      /* Needed to set pseudo-register PC for CRISv32.  */
-      /* FIXME: If ERP is in a delay slot at this point then the PC will
-	 be wrong.  Issue a warning to alert the user.  */
-      regcache_raw_supply (regcache, gdbarch_pc_regnum (gdbarch),
-			   (char *)&regp[ERP_REGNUM]);
-
-      if (*(char *)&regp[ERP_REGNUM] & 0x1)
-	fprintf_unfiltered (gdb_stderr, "Warning: PC in delay slot\n");
-    }
-}
-
-/*  Use a local version of this function to get the correct types for
-    regsets, until multi-arch core support is ready.  */
-
-static void
-fetch_core_registers (struct regcache *regcache,
-		      char *core_reg_sect, unsigned core_reg_size,
-                      int which, CORE_ADDR reg_addr)
-{
-  cris_elf_gregset_t gregset;
-
-  switch (which)
-    {
-    case 0:
-      if (core_reg_size != sizeof (cris_elf_gregset_t)
-	  && core_reg_size != sizeof (crisv32_elf_gregset_t))
-        {
-          warning (_("wrong size gregset struct in core file"));
-        }
-      else
-        {
-          memcpy (&gregset, core_reg_sect, sizeof (gregset));
-          cris_supply_gregset (regcache, &gregset);
-        }
-
-    default:
-      /* We've covered all the kinds of registers we know about here,
-         so this must be something we wouldn't know what to do with
-         anyway.  Just ignore it.  */
-      break;
-    }
-}
-
-static struct core_fns cris_elf_core_fns =
-{
-  bfd_target_elf_flavour,               /* core_flavour */
-  default_check_format,                 /* check_format */
-  default_core_sniffer,                 /* core_sniffer */
-  fetch_core_registers,                 /* core_read_registers */
-  NULL                                  /* next */
-};
-
 extern initialize_file_ftype _initialize_cris_tdep; /* -Wmissing-prototypes */
 
 void
@@ -3935,8 +3759,6 @@  Makes GDB use the NRP register instead o
 			   NULL, /* FIXME: i18n: Usage of Dwarf-2 CFI
 				    for CRIS is %d.  */
 			   &setlist, &showlist);
-
-  deprecated_add_core_fns (&cris_elf_core_fns);
 }
 
 /* Prints out all target specific values.  */
Index: binutils-gdb/gdb/cris-linux-tdep.c
===================================================================
--- binutils-gdb.orig/gdb/cris-linux-tdep.c	2014-11-11 16:31:24.891884659 +0100
+++ binutils-gdb/gdb/cris-linux-tdep.c	2014-11-28 15:18:16.430081275 +0100
@@ -26,9 +26,74 @@ 
 #include "linux-tdep.h"
 #include "solib-svr4.h"
 #include "symtab.h"
+#include "regcache.h"
+#include "regset.h"
 
 #include "cris-tdep.h"
 
+/* Core file support.  */
+
+#define CRISV10_LINUX_SIZEOF_GREGSET (35 * 4)
+#define CRISV32_LINUX_SIZEOF_GREGSET (32 * 4)
+
+static const struct regcache_map_entry cris_linux_regmap[] =
+  {
+    { NUM_GENREGS + NUM_SPECREGS, 0, 4 },
+    { 0 }
+  };
+
+static void
+crisv32_supply_gregset (const struct regset *regset,
+			struct regcache *regcache,
+			int regnum, const void *regs, size_t len)
+{
+  regcache_supply_regset (regset, regcache, regnum, regs, len);
+
+  /* Needed to set pseudo-register PC for CRISv32.  */
+  /* FIXME: If ERP is in a delay slot at this point then the PC will
+      be wrong.  Issue a warning to alert the user.  */
+  if (regnum == -1 || regnum == CRISV32PC_REGNUM)
+    {
+      const gdb_byte *regp = regs;
+      ULONGEST pc;
+
+      regcache_raw_supply (regcache, CRISV32PC_REGNUM, regp + 4 * ERP_REGNUM);
+
+      regcache_raw_read_unsigned (regcache, CRISV32PC_REGNUM, &pc);
+      if (pc & 0x1)
+	fprintf_unfiltered (gdb_stderr, "Warning: PC in delay slot\n");
+    }
+}
+
+static const struct regset crisv10_linux_gregset =
+{
+  cris_linux_regmap,
+  regcache_supply_regset, regcache_collect_regset
+};
+
+static const struct regset crisv32_linux_gregset =
+{
+  cris_linux_regmap,
+  crisv32_supply_gregset, regcache_collect_regset
+};
+
+static void
+cris_iterate_over_regset_sections (struct gdbarch *gdbarch,
+				   iterate_over_regset_sections_cb *cb,
+				   void *cb_data,
+				   const struct regcache *regcache)
+{
+  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+  if (tdep->cris_version == 32)
+    cb (".reg", CRISV32_LINUX_SIZEOF_GREGSET,
+	&crisv32_linux_gregset, NULL, cb_data);
+  else
+    cb (".reg", CRISV10_LINUX_SIZEOF_GREGSET,
+	&crisv10_linux_gregset, NULL, cb_data);
+}
+
+
 static void
 cris_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 {
@@ -44,6 +109,8 @@  cris_linux_init_abi (struct gdbarch_info
   set_solib_svr4_fetch_link_map_offsets (gdbarch,
 					 svr4_ilp32_fetch_link_map_offsets);
 
+  set_gdbarch_iterate_over_regset_sections (gdbarch,
+					    cris_iterate_over_regset_sections);
 }
 
 /* Provide a prototype to silence -Wmissing-prototypes.  */
Index: binutils-gdb/gdb/cris-tdep.h
===================================================================
--- binutils-gdb.orig/gdb/cris-tdep.h	2014-11-11 16:31:24.899884704 +0100
+++ binutils-gdb/gdb/cris-tdep.h	2014-11-28 15:18:16.434081301 +0100
@@ -31,4 +31,99 @@  struct gdbarch_tdep
   int cris_dwarf2_cfi;
 };
 
+enum cris_num_regs
+{
+  /* There are no floating point registers.  Used in gdbserver low-linux.c.  */
+  NUM_FREGS = 0,
+
+  /* There are 16 general registers.  */
+  NUM_GENREGS = 16,
+
+  /* There are 16 special registers.  */
+  NUM_SPECREGS = 16,
+
+  /* CRISv32 has a pseudo PC register, not noted here.  */
+
+  /* CRISv32 has 16 support registers.  */
+  NUM_SUPPREGS = 16
+};
+
+/* Register numbers of various important registers.
+   CRIS_FP_REGNUM   Contains address of executing stack frame.
+   STR_REGNUM  Contains the address of structure return values.
+   RET_REGNUM  Contains the return value when shorter than or equal to 32 bits
+   ARG1_REGNUM Contains the first parameter to a function.
+   ARG2_REGNUM Contains the second parameter to a function.
+   ARG3_REGNUM Contains the third parameter to a function.
+   ARG4_REGNUM Contains the fourth parameter to a function.  Rest on stack.
+   gdbarch_sp_regnum Contains address of top of stack.
+   gdbarch_pc_regnum Contains address of next instruction.
+   SRP_REGNUM  Subroutine return pointer register.
+   BRP_REGNUM  Breakpoint return pointer register.  */
+
+enum cris_regnums
+{
+  /* Enums with respect to the general registers, valid for all
+     CRIS versions.  The frame pointer is always in R8.  */
+  CRIS_FP_REGNUM = 8,
+  /* ABI related registers.  */
+  STR_REGNUM  = 9,
+  RET_REGNUM  = 10,
+  ARG1_REGNUM = 10,
+  ARG2_REGNUM = 11,
+  ARG3_REGNUM = 12,
+  ARG4_REGNUM = 13,
+
+  /* Registers which happen to be common.  */
+  VR_REGNUM   = 17,
+  MOF_REGNUM  = 23,
+  SRP_REGNUM  = 27,
+
+  /* CRISv10 et al. specific registers.  */
+  P0_REGNUM   = 16,
+  P4_REGNUM   = 20,
+  CCR_REGNUM  = 21,
+  P8_REGNUM   = 24,
+  IBR_REGNUM  = 25,
+  IRP_REGNUM  = 26,
+  BAR_REGNUM  = 28,
+  DCCR_REGNUM = 29,
+  BRP_REGNUM  = 30,
+  USP_REGNUM  = 31,
+
+  /* CRISv32 specific registers.  */
+  ACR_REGNUM  = 15,
+  BZ_REGNUM   = 16,
+  PID_REGNUM  = 18,
+  SRS_REGNUM  = 19,
+  WZ_REGNUM   = 20,
+  EXS_REGNUM  = 21,
+  EDA_REGNUM  = 22,
+  DZ_REGNUM   = 24,
+  EBP_REGNUM  = 25,
+  ERP_REGNUM  = 26,
+  NRP_REGNUM  = 28,
+  CCS_REGNUM  = 29,
+  CRISV32USP_REGNUM  = 30, /* Shares name but not number with CRISv10.  */
+  SPC_REGNUM  = 31,
+  CRISV32PC_REGNUM   = 32, /* Shares name but not number with CRISv10.  */
+
+  S0_REGNUM = 33,
+  S1_REGNUM = 34,
+  S2_REGNUM = 35,
+  S3_REGNUM = 36,
+  S4_REGNUM = 37,
+  S5_REGNUM = 38,
+  S6_REGNUM = 39,
+  S7_REGNUM = 40,
+  S8_REGNUM = 41,
+  S9_REGNUM = 42,
+  S10_REGNUM = 43,
+  S11_REGNUM = 44,
+  S12_REGNUM = 45,
+  S13_REGNUM = 46,
+  S14_REGNUM = 47,
+  S15_REGNUM = 48,
+};
+
 #endif /* CRIS_TDEP_H */