* config/mips/linux.mh (TDEP_XML): New.

* features/mips-linux.xml, features/mips64-linux.xml: New files.
	* mips-linux-nat.c (mips_linux_register_addr): Handle
	MIPS_RESTART_REGNUM.
	(mips64_linux_register_addr): Likewise.
	(super_xfer_partial, mips_linux_xfer_partial): New.
	(_initialize_mips_linux_nat): Add them to the target_ops.
	* mips-linux-tdep.c (mips_supply_gregset): Handle MIPS_RESTART_REGNUM.
	(mips_fill_gregset, mips64_supply_gregset, mips64_fill_gregset)
	(mips_linux_o32_sigframe_init)
	(mips_linux_n32n64_sigframe_init): Likewise.
	(mips_linux_write_pc, mips_linux_restart_reg_p): New.
	(mips_linux_init_abi): Use mips_linux_write_pc.  Check for the
	"org.gnu.gdb.mips.linux" feature.
	* mips-linux-tdep.h (MIPS_RESTART_REGNUM): New constant.
	(mips_linux_restart_reg_p): New prototype.
	* mips-tdep.c (mips_gdbarch_init): Pass tdesc_data to the OS/ABI
	initialization routine.
	* Makefile.in (mips-linux-tdep.o, mips-linux-nat.o): Update.

	* gdb.texinfo (MIPS Features): Document org.gnu.gdb.mips.linux.
This commit is contained in:
Daniel Jacobowitz 2007-06-13 18:47:58 +00:00
parent f8b73d13b7
commit 822b65708d
11 changed files with 212 additions and 21 deletions

View file

@ -1,3 +1,25 @@
2007-06-13 Daniel Jacobowitz <dan@codesourcery.com>
* config/mips/linux.mh (TDEP_XML): New.
* features/mips-linux.xml, features/mips64-linux.xml: New files.
* mips-linux-nat.c (mips_linux_register_addr): Handle
MIPS_RESTART_REGNUM.
(mips64_linux_register_addr): Likewise.
(super_xfer_partial, mips_linux_xfer_partial): New.
(_initialize_mips_linux_nat): Add them to the target_ops.
* mips-linux-tdep.c (mips_supply_gregset): Handle MIPS_RESTART_REGNUM.
(mips_fill_gregset, mips64_supply_gregset, mips64_fill_gregset)
(mips_linux_o32_sigframe_init)
(mips_linux_n32n64_sigframe_init): Likewise.
(mips_linux_write_pc, mips_linux_restart_reg_p): New.
(mips_linux_init_abi): Use mips_linux_write_pc. Check for the
"org.gnu.gdb.mips.linux" feature.
* mips-linux-tdep.h (MIPS_RESTART_REGNUM): New constant.
(mips_linux_restart_reg_p): New prototype.
* mips-tdep.c (mips_gdbarch_init): Pass tdesc_data to the OS/ABI
initialization routine.
* Makefile.in (mips-linux-tdep.o, mips-linux-nat.o): Update.
2007-06-13 Daniel Jacobowitz <dan@codesourcery.com> 2007-06-13 Daniel Jacobowitz <dan@codesourcery.com>
* Makefile.in (mips-tdep.o): Update. * Makefile.in (mips-tdep.o): Update.

View file

@ -2337,12 +2337,14 @@ mips64obsd-tdep.o: mips64obsd-tdep.c $(defs_h) $(osabi_h) $(regcache_h) \
mips-irix-tdep.o: mips-irix-tdep.c $(defs_h) $(osabi_h) $(elf_bfd_h) mips-irix-tdep.o: mips-irix-tdep.c $(defs_h) $(osabi_h) $(elf_bfd_h)
mips-linux-nat.o: mips-linux-nat.c $(defs_h) $(mips_tdep_h) $(target_h) \ mips-linux-nat.o: mips-linux-nat.c $(defs_h) $(mips_tdep_h) $(target_h) \
$(regcache_h) $(linux_nat_h) $(gdb_proc_service_h) $(gregset_h) \ $(regcache_h) $(linux_nat_h) $(gdb_proc_service_h) $(gregset_h) \
$(mips_linux_tdep_h) $(inferior_h) $(mips_linux_tdep_h) $(inferior_h) $(target_descriptions_h) \
$(xml_support_h)
mips-linux-tdep.o: mips-linux-tdep.c $(defs_h) $(gdbcore_h) $(target_h) \ mips-linux-tdep.o: mips-linux-tdep.c $(defs_h) $(gdbcore_h) $(target_h) \
$(solib_svr4_h) $(osabi_h) $(mips_tdep_h) $(gdb_string_h) \ $(solib_svr4_h) $(osabi_h) $(mips_tdep_h) $(gdb_string_h) \
$(gdb_assert_h) $(frame_h) $(regcache_h) $(trad_frame_h) \ $(gdb_assert_h) $(frame_h) $(regcache_h) $(trad_frame_h) \
$(tramp_frame_h) $(gdbtypes_h) $(solib_h) $(symtab_h) \ $(tramp_frame_h) $(gdbtypes_h) $(solib_h) $(symtab_h) \
$(mips_linux_tdep_h) $(solist_h) $(solib_svr4_h) $(mips_linux_tdep_h) $(solist_h) $(solib_svr4_h) \
$(target_descriptions_h)
mipsnbsd-nat.o: mipsnbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \ mipsnbsd-nat.o: mipsnbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
$(target_h) $(mips_tdep_h) $(mipsnbsd_tdep_h) $(inf_ptrace_h) $(target_h) $(mips_tdep_h) $(mipsnbsd_tdep_h) $(inf_ptrace_h)
mipsnbsd-tdep.o: mipsnbsd-tdep.c $(defs_h) $(gdbcore_h) $(regcache_h) \ mipsnbsd-tdep.o: mipsnbsd-tdep.c $(defs_h) $(gdbcore_h) $(regcache_h) \

View file

@ -5,3 +5,12 @@ NATDEPFILES= inf-ptrace.o fork-child.o mips-linux-nat.o \
linux-nat.o linux-fork.o linux-nat.o linux-fork.o
LOADLIBES = -ldl -rdynamic LOADLIBES = -ldl -rdynamic
TDEP_XML = $(srcdir)/features/mips-cpu.xml \
$(srcdir)/features/mips-cp0.xml \
$(srcdir)/features/mips-fpu.xml \
$(srcdir)/features/mips-linux.xml \
$(srcdir)/features/mips64-cpu.xml \
$(srcdir)/features/mips64-cp0.xml \
$(srcdir)/features/mips64-fpu.xml \
$(srcdir)/features/mips64-linux.xml

View file

@ -1,3 +1,7 @@
2007-06-13 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.texinfo (MIPS Features): Document org.gnu.gdb.mips.linux.
2007-06-13 Daniel Jacobowitz <dan@codesourcery.com> 2007-06-13 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.texinfo (MIPS Features): New subsection. * gdb.texinfo (MIPS Features): New subsection.

View file

@ -25784,6 +25784,10 @@ it may be optional in a future version of @value{GDBN}. It should
contain registers @samp{f0} through @samp{f31}, @samp{fcsr}, and contain registers @samp{f0} through @samp{f31}, @samp{fcsr}, and
@samp{fir}. They may be 32-bit or 64-bit depending on the target. @samp{fir}. They may be 32-bit or 64-bit depending on the target.
The @samp{org.gnu.gdb.mips.linux} feature is optional. It should
contain a single register, @samp{restart}, which is used by the
Linux kernel to control restartable syscalls.
@include gpl.texi @include gpl.texi
@raisesections @raisesections

View file

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2007 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. -->
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<target>
<architecture>mips</architecture>
<xi:include href="mips-cpu.xml"/>
<xi:include href="mips-cp0.xml"/>
<xi:include href="mips-fpu.xml"/>
<feature name="org.gnu.gdb.mips.linux">
<reg name="restart" bitsize="32" group="system"/>
</feature>
</target>

View file

@ -0,0 +1,18 @@
<?xml version="1.0"?>
<!-- Copyright (C) 2007 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. -->
<!DOCTYPE target SYSTEM "gdb-target.dtd">
<target>
<architecture>mips</architecture>
<xi:include href="mips64-cpu.xml"/>
<xi:include href="mips64-cp0.xml"/>
<xi:include href="mips64-fpu.xml"/>
<feature name="org.gnu.gdb.mips.linux">
<reg name="restart" bitsize="64" group="system"/>
</feature>
</target>

View file

@ -27,10 +27,13 @@
#include "regcache.h" #include "regcache.h"
#include "linux-nat.h" #include "linux-nat.h"
#include "mips-linux-tdep.h" #include "mips-linux-tdep.h"
#include "target-descriptions.h"
#include "xml-support.h"
#include "gdb_proc_service.h" #include "gdb_proc_service.h"
#include "gregset.h" #include "gregset.h"
#include <sgidefs.h>
#include <sys/ptrace.h> #include <sys/ptrace.h>
#ifndef PTRACE_GET_THREAD_AREA #ifndef PTRACE_GET_THREAD_AREA
@ -81,6 +84,8 @@ mips_linux_register_addr (struct gdbarch *gdbarch, int regno, int store)
regaddr = FPC_CSR; regaddr = FPC_CSR;
else if (regno == mips_regnum (gdbarch)->fp_implementation_revision) else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
regaddr = store? (CORE_ADDR) -1 : FPC_EIR; regaddr = store? (CORE_ADDR) -1 : FPC_EIR;
else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM)
regaddr = 0;
else else
regaddr = (CORE_ADDR) -1; regaddr = (CORE_ADDR) -1;
@ -114,6 +119,8 @@ mips64_linux_register_addr (struct gdbarch *gdbarch, int regno, int store)
regaddr = MIPS64_FPC_CSR; regaddr = MIPS64_FPC_CSR;
else if (regno == mips_regnum (gdbarch)->fp_implementation_revision) else if (regno == mips_regnum (gdbarch)->fp_implementation_revision)
regaddr = store? (CORE_ADDR) -1 : MIPS64_FPC_EIR; regaddr = store? (CORE_ADDR) -1 : MIPS64_FPC_EIR;
else if (mips_linux_restart_reg_p (gdbarch) && regno == MIPS_RESTART_REGNUM)
regaddr = 0;
else else
regaddr = (CORE_ADDR) -1; regaddr = (CORE_ADDR) -1;
@ -335,6 +342,36 @@ mips_linux_register_u_offset (struct gdbarch *gdbarch, int regno, int store_p)
return mips_linux_register_addr (gdbarch, regno, store_p); return mips_linux_register_addr (gdbarch, regno, store_p);
} }
static LONGEST (*super_xfer_partial) (struct target_ops *, enum target_object,
const char *, gdb_byte *, const gdb_byte *,
ULONGEST, LONGEST);
static LONGEST
mips_linux_xfer_partial (struct target_ops *ops,
enum target_object object,
const char *annex,
gdb_byte *readbuf, const gdb_byte *writebuf,
ULONGEST offset, LONGEST len)
{
if (object == TARGET_OBJECT_AVAILABLE_FEATURES)
{
if (annex != NULL && strcmp (annex, "target.xml") == 0)
{
/* Report that target registers are a size we know for sure
that we can get from ptrace. */
if (_MIPS_SIM == _ABIO32)
annex = "mips-linux.xml";
else
annex = "mips64-linux.xml";
}
return xml_builtin_xfer_partial (annex, readbuf, writebuf, offset, len);
}
return super_xfer_partial (ops, object, annex, readbuf, writebuf,
offset, len);
}
void _initialize_mips_linux_nat (void); void _initialize_mips_linux_nat (void);
void void
@ -348,5 +385,9 @@ _initialize_mips_linux_nat (void)
t->to_fetch_registers = mips64_linux_fetch_registers; t->to_fetch_registers = mips64_linux_fetch_registers;
t->to_store_registers = mips64_linux_store_registers; t->to_store_registers = mips64_linux_store_registers;
/* Override the default to_xfer_partial. */
super_xfer_partial = t->to_xfer_partial;
t->to_xfer_partial = mips_linux_xfer_partial;
linux_nat_add_target (t); linux_nat_add_target (t);
} }

View file

@ -37,6 +37,7 @@
#include "solib-svr4.h" #include "solib-svr4.h"
#include "solist.h" #include "solist.h"
#include "symtab.h" #include "symtab.h"
#include "target-descriptions.h"
#include "mips-linux-tdep.h" #include "mips-linux-tdep.h"
static struct target_so_ops mips_svr4_so_ops; static struct target_so_ops mips_svr4_so_ops;
@ -96,9 +97,12 @@ mips_supply_gregset (struct regcache *regcache,
memset (zerobuf, 0, MAX_REGISTER_SIZE); memset (zerobuf, 0, MAX_REGISTER_SIZE);
for (regi = EF_REG0; regi <= EF_REG31; regi++) for (regi = EF_REG0 + 1; regi <= EF_REG31; regi++)
supply_32bit_reg (regcache, regi - EF_REG0, regp + regi); supply_32bit_reg (regcache, regi - EF_REG0, regp + regi);
if (mips_linux_restart_reg_p (current_gdbarch))
supply_32bit_reg (regcache, MIPS_RESTART_REGNUM, regp + EF_REG0);
supply_32bit_reg (regcache, mips_regnum (current_gdbarch)->lo, supply_32bit_reg (regcache, mips_regnum (current_gdbarch)->lo,
regp + EF_LO); regp + EF_LO);
supply_32bit_reg (regcache, mips_regnum (current_gdbarch)->hi, supply_32bit_reg (regcache, mips_regnum (current_gdbarch)->hi,
@ -113,9 +117,10 @@ mips_supply_gregset (struct regcache *regcache,
regp + EF_CP0_CAUSE); regp + EF_CP0_CAUSE);
/* Fill inaccessible registers with zero. */ /* Fill inaccessible registers with zero. */
regcache_raw_supply (regcache, MIPS_ZERO_REGNUM, zerobuf);
regcache_raw_supply (regcache, MIPS_UNUSED_REGNUM, zerobuf); regcache_raw_supply (regcache, MIPS_UNUSED_REGNUM, zerobuf);
for (regi = MIPS_FIRST_EMBED_REGNUM; for (regi = MIPS_FIRST_EMBED_REGNUM;
regi < MIPS_LAST_EMBED_REGNUM; regi <= MIPS_LAST_EMBED_REGNUM;
regi++) regi++)
regcache_raw_supply (regcache, regi, zerobuf); regcache_raw_supply (regcache, regi, zerobuf);
} }
@ -133,7 +138,7 @@ mips_fill_gregset (const struct regcache *regcache,
if (regno == -1) if (regno == -1)
{ {
memset (regp, 0, sizeof (mips_elf_gregset_t)); memset (regp, 0, sizeof (mips_elf_gregset_t));
for (regi = 0; regi < 32; regi++) for (regi = 1; regi < 32; regi++)
mips_fill_gregset (regcache, gregsetp, regi); mips_fill_gregset (regcache, gregsetp, regi);
mips_fill_gregset (regcache, gregsetp, mips_fill_gregset (regcache, gregsetp,
mips_regnum (current_gdbarch)->lo); mips_regnum (current_gdbarch)->lo);
@ -146,10 +151,11 @@ mips_fill_gregset (const struct regcache *regcache,
mips_fill_gregset (regcache, gregsetp, MIPS_PS_REGNUM); mips_fill_gregset (regcache, gregsetp, MIPS_PS_REGNUM);
mips_fill_gregset (regcache, gregsetp, mips_fill_gregset (regcache, gregsetp,
mips_regnum (current_gdbarch)->cause); mips_regnum (current_gdbarch)->cause);
mips_fill_gregset (regcache, gregsetp, MIPS_RESTART_REGNUM);
return; return;
} }
if (regno < 32) if (regno > 0 && regno < 32)
{ {
dst = regp + regno + EF_REG0; dst = regp + regno + EF_REG0;
regcache_raw_collect (regcache, regno, dst); regcache_raw_collect (regcache, regno, dst);
@ -168,6 +174,9 @@ mips_fill_gregset (const struct regcache *regcache,
regaddr = EF_CP0_STATUS; regaddr = EF_CP0_STATUS;
else if (regno == mips_regnum (current_gdbarch)->cause) else if (regno == mips_regnum (current_gdbarch)->cause)
regaddr = EF_CP0_CAUSE; regaddr = EF_CP0_CAUSE;
else if (mips_linux_restart_reg_p (current_gdbarch)
&& regno == MIPS_RESTART_REGNUM)
regaddr = EF_REG0;
else else
regaddr = -1; regaddr = -1;
@ -294,10 +303,14 @@ mips64_supply_gregset (struct regcache *regcache,
memset (zerobuf, 0, MAX_REGISTER_SIZE); memset (zerobuf, 0, MAX_REGISTER_SIZE);
for (regi = MIPS64_EF_REG0; regi <= MIPS64_EF_REG31; regi++) for (regi = MIPS64_EF_REG0 + 1; regi <= MIPS64_EF_REG31; regi++)
supply_64bit_reg (regcache, regi - MIPS64_EF_REG0, supply_64bit_reg (regcache, regi - MIPS64_EF_REG0,
(const gdb_byte *)(regp + regi)); (const gdb_byte *)(regp + regi));
if (mips_linux_restart_reg_p (current_gdbarch))
supply_64bit_reg (regcache, MIPS_RESTART_REGNUM,
(const gdb_byte *)(regp + MIPS64_EF_REG0));
supply_64bit_reg (regcache, mips_regnum (current_gdbarch)->lo, supply_64bit_reg (regcache, mips_regnum (current_gdbarch)->lo,
(const gdb_byte *) (regp + MIPS64_EF_LO)); (const gdb_byte *) (regp + MIPS64_EF_LO));
supply_64bit_reg (regcache, mips_regnum (current_gdbarch)->hi, supply_64bit_reg (regcache, mips_regnum (current_gdbarch)->hi,
@ -313,9 +326,10 @@ mips64_supply_gregset (struct regcache *regcache,
(const gdb_byte *) (regp + MIPS64_EF_CP0_CAUSE)); (const gdb_byte *) (regp + MIPS64_EF_CP0_CAUSE));
/* Fill inaccessible registers with zero. */ /* Fill inaccessible registers with zero. */
regcache_raw_supply (regcache, MIPS_ZERO_REGNUM, zerobuf);
regcache_raw_supply (regcache, MIPS_UNUSED_REGNUM, zerobuf); regcache_raw_supply (regcache, MIPS_UNUSED_REGNUM, zerobuf);
for (regi = MIPS_FIRST_EMBED_REGNUM; for (regi = MIPS_FIRST_EMBED_REGNUM;
regi < MIPS_LAST_EMBED_REGNUM; regi <= MIPS_LAST_EMBED_REGNUM;
regi++) regi++)
regcache_raw_supply (regcache, regi, zerobuf); regcache_raw_supply (regcache, regi, zerobuf);
} }
@ -333,7 +347,7 @@ mips64_fill_gregset (const struct regcache *regcache,
if (regno == -1) if (regno == -1)
{ {
memset (regp, 0, sizeof (mips64_elf_gregset_t)); memset (regp, 0, sizeof (mips64_elf_gregset_t));
for (regi = 0; regi < 32; regi++) for (regi = 1; regi < 32; regi++)
mips64_fill_gregset (regcache, gregsetp, regi); mips64_fill_gregset (regcache, gregsetp, regi);
mips64_fill_gregset (regcache, gregsetp, mips64_fill_gregset (regcache, gregsetp,
mips_regnum (current_gdbarch)->lo); mips_regnum (current_gdbarch)->lo);
@ -346,10 +360,11 @@ mips64_fill_gregset (const struct regcache *regcache,
mips64_fill_gregset (regcache, gregsetp, MIPS_PS_REGNUM); mips64_fill_gregset (regcache, gregsetp, MIPS_PS_REGNUM);
mips64_fill_gregset (regcache, gregsetp, mips64_fill_gregset (regcache, gregsetp,
mips_regnum (current_gdbarch)->cause); mips_regnum (current_gdbarch)->cause);
mips64_fill_gregset (regcache, gregsetp, MIPS_RESTART_REGNUM);
return; return;
} }
if (regno < 32) if (regno > 0 && regno < 32)
regaddr = regno + MIPS64_EF_REG0; regaddr = regno + MIPS64_EF_REG0;
else if (regno == mips_regnum (current_gdbarch)->lo) else if (regno == mips_regnum (current_gdbarch)->lo)
regaddr = MIPS64_EF_LO; regaddr = MIPS64_EF_LO;
@ -363,6 +378,9 @@ mips64_fill_gregset (const struct regcache *regcache,
regaddr = MIPS64_EF_CP0_STATUS; regaddr = MIPS64_EF_CP0_STATUS;
else if (regno == mips_regnum (current_gdbarch)->cause) else if (regno == mips_regnum (current_gdbarch)->cause)
regaddr = MIPS64_EF_CP0_CAUSE; regaddr = MIPS64_EF_CP0_CAUSE;
else if (mips_linux_restart_reg_p (current_gdbarch)
&& regno == MIPS_RESTART_REGNUM)
regaddr = MIPS64_EF_REG0;
else else
regaddr = -1; regaddr = -1;
@ -838,11 +856,11 @@ mips_linux_o32_sigframe_init (const struct tramp_frame *self,
else else
regs_base = sigcontext_base; regs_base = sigcontext_base;
#if 0 if (mips_linux_restart_reg_p (current_gdbarch))
trad_frame_set_reg_addr (this_cache, ORIG_ZERO_REGNUM trad_frame_set_reg_addr (this_cache,
+ gdbarch_num_regs (current_gdbarch), (MIPS_RESTART_REGNUM
regs_base + SIGCONTEXT_REGS); + gdbarch_num_regs (current_gdbarch)),
#endif regs_base + SIGCONTEXT_REGS);
for (ireg = 1; ireg < 32; ireg++) for (ireg = 1; ireg < 32; ireg++)
trad_frame_set_reg_addr (this_cache, trad_frame_set_reg_addr (this_cache,
@ -988,12 +1006,11 @@ mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
else else
sigcontext_base += N64_SIGFRAME_SIGCONTEXT_OFFSET; sigcontext_base += N64_SIGFRAME_SIGCONTEXT_OFFSET;
#if 0 if (mips_linux_restart_reg_p (current_gdbarch))
trad_frame_set_reg_addr (this_cache, trad_frame_set_reg_addr (this_cache,
ORIG_ZERO_REGNUM (MIPS_RESTART_REGNUM
+ gdbarch_num_regs (current_gdbarch), + gdbarch_num_regs (current_gdbarch)),
sigcontext_base + N64_SIGCONTEXT_REGS); sigcontext_base + N64_SIGCONTEXT_REGS);
#endif
for (ireg = 1; ireg < 32; ireg++) for (ireg = 1; ireg < 32; ireg++)
trad_frame_set_reg_addr (this_cache, trad_frame_set_reg_addr (this_cache,
@ -1036,6 +1053,30 @@ mips_linux_n32n64_sigframe_init (const struct tramp_frame *self,
func)); func));
} }
static void
mips_linux_write_pc (CORE_ADDR pc, ptid_t ptid)
{
write_register_pid (PC_REGNUM, pc, ptid);
/* Clear the syscall restart flag. */
if (mips_linux_restart_reg_p (current_gdbarch))
write_register_pid (MIPS_RESTART_REGNUM, 0, ptid);
}
/* 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;
}
/* Initialize one of the GNU/Linux OS ABIs. */ /* Initialize one of the GNU/Linux OS ABIs. */
@ -1045,6 +1086,7 @@ mips_linux_init_abi (struct gdbarch_info info,
{ {
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
enum mips_abi abi = mips_abi (gdbarch); enum mips_abi abi = mips_abi (gdbarch);
struct tdesc_arch_data *tdesc_data = (void *) info.tdep_info;
switch (abi) switch (abi)
{ {
@ -1105,6 +1147,26 @@ mips_linux_init_abi (struct gdbarch_info info,
= mips_linux_in_dynsym_resolve_code; = mips_linux_in_dynsym_resolve_code;
} }
set_solib_ops (gdbarch, &mips_svr4_so_ops); set_solib_ops (gdbarch, &mips_svr4_so_ops);
set_gdbarch_write_pc (gdbarch, mips_linux_write_pc);
if (tdesc_data)
{
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);
/* If it's present, then assign it to the reserved number. */
feature = tdesc_find_feature (info.target_desc,
"org.gnu.gdb.mips.linux");
if (feature != NULL)
tdesc_numbered_register (feature, tdesc_data, MIPS_RESTART_REGNUM,
"restart");
}
} }
void void

View file

@ -92,3 +92,13 @@ void mips64_supply_gregset (struct regcache *, const mips64_elf_gregset_t *);
void mips64_fill_gregset (const struct regcache *, mips64_elf_gregset_t *, int); void mips64_fill_gregset (const struct regcache *, mips64_elf_gregset_t *, int);
void mips64_supply_fpregset (struct regcache *, const mips64_elf_fpregset_t *); void mips64_supply_fpregset (struct regcache *, const mips64_elf_fpregset_t *);
void mips64_fill_fpregset (const struct regcache *, mips64_elf_fpregset_t *, int); 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 = MIPS_LAST_EMBED_REGNUM + 1
};
/* Return 1 if MIPS_RESTART_REGNUM is usable. */
int mips_linux_restart_reg_p (struct gdbarch *gdbarch);

View file

@ -5457,6 +5457,7 @@ mips_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
mips_register_g_packet_guesses (gdbarch); mips_register_g_packet_guesses (gdbarch);
/* Hook in OS ABI-specific overrides, if they have been registered. */ /* Hook in OS ABI-specific overrides, if they have been registered. */
info.tdep_info = (void *) tdesc_data;
gdbarch_init_osabi (info, gdbarch); gdbarch_init_osabi (info, gdbarch);
/* Unwind the frame. */ /* Unwind the frame. */