diff mbox

[07/24] MIPS: Make Linux restart register more dynamic

Message ID 1467038991-6600-7-git-send-email-bhushan.attarde@imgtec.com
State New
Headers show

Commit Message

Bhushan Attarde June 27, 2016, 2:49 p.m. UTC
The Linux restart register has a fixed register number defined by
    MIPS_RESTART_REGNUM. The number of raw and pseudo registers is increased
    to MIPS_RESTART_REGNUM + 1 if it is safe to do so (if a target description
    is available) with an assert to ensure that the number of registers hasn't
    already exceeded MIPS_RESTART_REGNUM.

    This isn't conducive to adding more optional dynamic registers since
    MIPS_RESTART_REGNUM would keep needing to be updated to avoid the assert,
    so add a linux_restart register number to the struct mips_regnum and
    assign the register number dynamically.

    gdb/ChangeLog:

    	* mips-linux-nat.c (mips_linux_register_addr,
    	mips64_linux_register_addr): Use mips_regnum::linux_restart in
    	preference to mips_linux_restart_reg_p and MIPS_RESTART_REGNUM.
    	* mips-linux-tdep.c (mips_supply_gregset, mips_fill_gregset,
    	mips64_supply_gregset, mips64_fill_gregset,
    	mips_linux_o32_sigframe_init, mips_linux_n32n64_sigframe_init,
    	mips_linux_write_pc): Likewise.
    	(mips_linux_restart_reg_p): Remove.
    	(mips_linux_init_abi): Assign linux_restart register number
    	dynamically and only if the target provides it.
    	* mips-linux-tdep.h: Remove MIPS_RESTART_REGNUM enum value.
    	(mips_linux_restart_reg_p): Remove declaration.
    	* mips-tdep.c (mips_gdbarch_init): Initialise linux_restart register
    	number to -1.
    	* mips-tdep.h (struct mips_regnum): Add linux_restart member.
---
 gdb/mips-linux-nat.c  |  4 +--
 gdb/mips-linux-tdep.c | 80 ++++++++++++++++++++++++---------------------------
 gdb/mips-linux-tdep.h | 10 -------
 gdb/mips-tdep.c       |  1 +
 gdb/mips-tdep.h       |  1 +
 5 files changed, 42 insertions(+), 54 deletions(-)
diff mbox

Patch

diff --git a/gdb/mips-linux-nat.c b/gdb/mips-linux-nat.c
index 543cc36..fd1837f 100644
--- a/gdb/mips-linux-nat.c
+++ b/gdb/mips-linux-nat.c
@@ -117,7 +117,7 @@  mips_linux_register_addr (struct gdbarch *gdbarch, int regno, int store)
     regaddr = DSP_BASE + (regno - mips_regnum (gdbarch)->dspacc);
   else if (regno == mips_regnum (gdbarch)->dspctl)
     regaddr = DSP_CONTROL;
-  else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM)
+  else if (regno == mips_regnum (gdbarch)->linux_restart)
     regaddr = 0;
   else
     regaddr = (CORE_ADDR) -1;
@@ -158,7 +158,7 @@  mips64_linux_register_addr (struct gdbarch *gdbarch, int regno, int store)
     regaddr = DSP_BASE + (regno - mips_regnum (gdbarch)->dspacc);
   else if (regno == mips_regnum (gdbarch)->dspctl)
     regaddr = DSP_CONTROL;
-  else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM)
+  else if (regno == mips_regnum (gdbarch)->linux_restart)
     regaddr = 0;
   else
     regaddr = (CORE_ADDR) -1;
diff --git a/gdb/mips-linux-tdep.c b/gdb/mips-linux-tdep.c
index 6b9743b..82b8127 100644
--- a/gdb/mips-linux-tdep.c
+++ b/gdb/mips-linux-tdep.c
@@ -141,8 +141,9 @@  mips_supply_gregset (struct regcache *regcache,
   for (regi = EF_REG0 + 1; regi <= EF_REG31; regi++)
     supply_32bit_reg (regcache, regi - EF_REG0, regp + regi);
 
-  if (mips_linux_restart_reg_p (gdbarch))
-    supply_32bit_reg (regcache, MIPS_RESTART_REGNUM, regp + EF_REG0);
+  if (mips_regnum (gdbarch)->linux_restart >= 0)
+    supply_32bit_reg (regcache, mips_regnum (gdbarch)->linux_restart,
+		      regp + EF_REG0);
 
   supply_32bit_reg (regcache, mips_regnum (gdbarch)->lo, regp + EF_LO);
   supply_32bit_reg (regcache, mips_regnum (gdbarch)->hi, regp + EF_HI);
@@ -191,7 +192,9 @@  mips_fill_gregset (const struct regcache *regcache,
       mips_fill_gregset (regcache, gregsetp, mips_regnum (gdbarch)->badvaddr);
       mips_fill_gregset (regcache, gregsetp, MIPS_PS_REGNUM);
       mips_fill_gregset (regcache, gregsetp, mips_regnum (gdbarch)->cause);
-      mips_fill_gregset (regcache, gregsetp, MIPS_RESTART_REGNUM);
+      if (mips_regnum (gdbarch)->linux_restart >= 0)
+	mips_fill_gregset (regcache, gregsetp,
+			   mips_regnum (gdbarch)->linux_restart);
       return;
    }
 
@@ -214,8 +217,7 @@  mips_fill_gregset (const struct regcache *regcache,
     regaddr = EF_CP0_STATUS;
   else if (regno == mips_regnum (gdbarch)->cause)
     regaddr = EF_CP0_CAUSE;
-  else if (mips_linux_restart_reg_p (gdbarch)
-	   && regno == MIPS_RESTART_REGNUM)
+  else if (regno == mips_regnum (gdbarch)->linux_restart)
     regaddr = EF_REG0;
   else
     regaddr = -1;
@@ -388,8 +390,8 @@  mips64_supply_gregset (struct regcache *regcache,
     supply_64bit_reg (regcache, regi - MIPS64_EF_REG0,
 		      (const gdb_byte *) (regp + regi));
 
-  if (mips_linux_restart_reg_p (gdbarch))
-    supply_64bit_reg (regcache, MIPS_RESTART_REGNUM,
+  if (mips_regnum (gdbarch)->linux_restart >= 0)
+    supply_64bit_reg (regcache, mips_regnum (gdbarch)->linux_restart,
 		      (const gdb_byte *) (regp + MIPS64_EF_REG0));
 
   supply_64bit_reg (regcache, mips_regnum (gdbarch)->lo,
@@ -444,7 +446,8 @@  mips64_fill_gregset (const struct regcache *regcache,
 			   mips_regnum (gdbarch)->badvaddr);
       mips64_fill_gregset (regcache, gregsetp, MIPS_PS_REGNUM);
       mips64_fill_gregset (regcache, gregsetp,  mips_regnum (gdbarch)->cause);
-      mips64_fill_gregset (regcache, gregsetp, MIPS_RESTART_REGNUM);
+      mips64_fill_gregset (regcache, gregsetp,
+			   mips_regnum (gdbarch)->linux_restart);
       return;
    }
 
@@ -462,8 +465,7 @@  mips64_fill_gregset (const struct regcache *regcache,
     regaddr = MIPS64_EF_CP0_STATUS;
   else if (regno == mips_regnum (gdbarch)->cause)
     regaddr = MIPS64_EF_CP0_CAUSE;
-  else if (mips_linux_restart_reg_p (gdbarch)
-	   && regno == MIPS_RESTART_REGNUM)
+  else if (regno == mips_regnum (gdbarch)->linux_restart)
     regaddr = MIPS64_EF_REG0;
   else
     regaddr = -1;
@@ -1094,9 +1096,9 @@  mips_linux_o32_sigframe_init (const struct tramp_frame *self,
   else
     regs_base = sigcontext_base;
 
-  if (mips_linux_restart_reg_p (gdbarch))
+  if (mips_regnum (gdbarch)->linux_restart >= 0)
     trad_frame_set_reg_addr (this_cache,
-			     (MIPS_RESTART_REGNUM
+			     (mips_regnum (gdbarch)->linux_restart
 			      + gdbarch_num_regs (gdbarch)),
 			     regs_base + SIGCONTEXT_REGS);
 
@@ -1286,9 +1288,9 @@  mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
   else
     sigcontext_base = frame_sp + N64_SIGFRAME_SIGCONTEXT_OFFSET;
 
-  if (mips_linux_restart_reg_p (gdbarch))
+  if (mips_regnum (gdbarch)->linux_restart >= 0)
     trad_frame_set_reg_addr (this_cache,
-			     (MIPS_RESTART_REGNUM
+			     (mips_regnum (gdbarch)->linux_restart
 			      + gdbarch_num_regs (gdbarch)),
 			     sigcontext_base + N64_SIGCONTEXT_REGS);
 
@@ -1387,23 +1389,9 @@  mips_linux_write_pc (struct regcache *regcache, CORE_ADDR pc)
   mips_write_pc (regcache, pc);
 
   /* Clear the syscall restart flag.  */
-  if (mips_linux_restart_reg_p (gdbarch))
-    regcache_cooked_write_unsigned (regcache, MIPS_RESTART_REGNUM, 0);
-}
-
-/* Return 1 if MIPS_RESTART_REGNUM is usable.  */
-
-int
-mips_linux_restart_reg_p (struct gdbarch *gdbarch)
-{
-  /* If we do not have a target description with registers, then
-     MIPS_RESTART_REGNUM will not be included in the register set.  */
-  if (!tdesc_has_registers (gdbarch_target_desc (gdbarch)))
-    return 0;
-
-  /* If we do, then MIPS_RESTART_REGNUM is safe to check; it will
-     either be GPR-sized or missing.  */
-  return register_size (gdbarch, MIPS_RESTART_REGNUM) > 0;
+  if (mips_regnum (gdbarch)->linux_restart >= 0)
+    regcache_cooked_write_unsigned (regcache,
+				    mips_regnum (gdbarch)->linux_restart, 0);
 }
 
 /* When FRAME is at a syscall instruction, return the PC of the next
@@ -1743,19 +1731,27 @@  mips_linux_init_abi (struct gdbarch_info info,
     {
       const struct tdesc_feature *feature;
 
-      /* If we have target-described registers, then we can safely
-	 reserve a number for MIPS_RESTART_REGNUM (whether it is
-	 described or not).  */
-      gdb_assert (gdbarch_num_regs (gdbarch) <= MIPS_RESTART_REGNUM);
-      set_gdbarch_num_regs (gdbarch, MIPS_RESTART_REGNUM + 1);
-      set_gdbarch_num_pseudo_regs (gdbarch, MIPS_RESTART_REGNUM + 1);
-
-      /* If it's present, then assign it to the reserved number.  */
+      /* If "restart" is present in the target register description,
+	 then assign it to a new register number.  */
       feature = tdesc_find_feature (info.target_desc,
 				    "org.gnu.gdb.mips.linux");
-      if (feature != NULL)
-	tdesc_numbered_register (feature, (((struct gdbarch_tdep_info*)(info.tdep_info))->tdesc_data),
-				 MIPS_RESTART_REGNUM, "restart");
+      if (feature != NULL
+	  && tdesc_unnumbered_register (feature, "restart"))
+	{
+	  int restart_regnum;
+	  /* We cast away const'ness in order to set linux_restart.
+	     */
+	  struct mips_regnum *regnum =
+			(struct mips_regnum *)mips_regnum (gdbarch);
+
+	  restart_regnum = gdbarch_num_regs (gdbarch);
+	  regnum->linux_restart = restart_regnum;
+	  set_gdbarch_num_regs (gdbarch, restart_regnum + 1);
+	  set_gdbarch_num_pseudo_regs (gdbarch, restart_regnum + 1);
+
+	  tdesc_numbered_register (feature, (((struct gdbarch_tdep_info*)(info.tdep_info))->tdesc_data),
+				   restart_regnum, "restart");
+	}
     }
 }
 
diff --git a/gdb/mips-linux-tdep.h b/gdb/mips-linux-tdep.h
index e8a69fb..4537fcd 100644
--- a/gdb/mips-linux-tdep.h
+++ b/gdb/mips-linux-tdep.h
@@ -95,13 +95,3 @@  void mips64_supply_fpregset (struct regcache *,
 			     const mips64_elf_fpregset_t *);
 void mips64_fill_fpregset (const struct regcache *,
 			   mips64_elf_fpregset_t *, int);
-
-enum {
-  /* The Linux kernel stores an error code from any interrupted
-     syscall in a "register" (in $0's save slot).  */
-  MIPS_RESTART_REGNUM = 79
-};
-
-/* Return 1 if MIPS_RESTART_REGNUM is usable.  */
-
-int mips_linux_restart_reg_p (struct gdbarch *gdbarch);
diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c
index 28cfb57..61b560c 100644
--- a/gdb/mips-tdep.c
+++ b/gdb/mips-tdep.c
@@ -8261,6 +8261,7 @@  mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
 
   /* Fill in the OS dependent register numbers and names.  */
   mips_regnum.config5 = -1;
+  mips_regnum.linux_restart = -1;
   if (info.osabi == GDB_OSABI_IRIX)
     {
       mips_regnum.fp0 = 32;
diff --git a/gdb/mips-tdep.h b/gdb/mips-tdep.h
index 39af72b..97bfab3 100644
--- a/gdb/mips-tdep.h
+++ b/gdb/mips-tdep.h
@@ -70,6 +70,7 @@  struct mips_regnum
   int lo;		/* ...  */
   int dspacc;		/* SmartMIPS/DSP accumulators.  */
   int dspctl;		/* DSP control.  */
+  int linux_restart;
 };
 extern const struct mips_regnum *mips_regnum (struct gdbarch *gdbarch);