This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[PATCH 07/24] MIPS: Make Linux restart register more dynamic
- From: Bhushan Attarde <bhushan dot attarde at imgtec dot com>
- To: <gdb-patches at sourceware dot org>
- Cc: <Maciej dot Rozycki at imgtec dot com>, <Matthew dot Fortune at imgtec dot com>, <James dot Hogan at imgtec dot com>, <Andrew dot Bennett at imgtec dot com>, <Jaydeep dot Patil at imgtec dot com>, Bhushan Attarde <bhushan dot attarde at imgtec dot com>
- Date: Mon, 27 Jun 2016 20:19:34 +0530
- Subject: [PATCH 07/24] MIPS: Make Linux restart register more dynamic
- Authentication-results: sourceware.org; auth=none
- References: <1467038991-6600-1-git-send-email-bhushan dot attarde at imgtec dot com>
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 --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);
--
1.9-rc2