* Makefile.in (XMLFILES): Include $(TDEP_XML).

(filenames_h): New variable.
	(clean): Clean up xml-builtin.c and stamp-xml.
	(arm-linux-nat.o): Update.
	* config/arm/linux.mh (TDEP_XML): Define.
	* arm-linux-nat.c (PTRACE_GETWMMXREGS, PTRACE_SETWMMXREGS): Define.
	(arm_linux_has_wmmx_registers): New.
	(GET_THREAD_ID): Fix typo.
	(IWMMXT_REGS_SIZE): Define.
	(fetch_wmmx_regs, store_wmmx_regs): New.
	(arm_linux_fetch_inferior_registers): Use fetch_wmmx_regs.
	(arm_linux_store_inferior_registers): Use store_wmmx_regs.
	(super_xfer_partial, arm_linux_xfer_partial): New.
	(_initialize_arm_linux_nat): Use them.
	* xml-support.c (fetch_xml_builtin): Move outside HAVE_LIBEXPAT.
	(xml_builtin_xfer_partial): New function.
	* xml-support.h (xml_builtin_xfer_partial): New prototype.
	* NEWS: Update mention of iWMMXt support.
This commit is contained in:
Daniel Jacobowitz 2007-02-26 19:20:21 +00:00
parent ff6f572f8b
commit 05a4558a93
7 changed files with 218 additions and 17 deletions

View File

@ -1,3 +1,24 @@
2007-02-26 Daniel Jacobowitz <dan@codesourcery.com>
* Makefile.in (XMLFILES): Include $(TDEP_XML).
(filenames_h): New variable.
(clean): Clean up xml-builtin.c and stamp-xml.
(arm-linux-nat.o): Update.
* config/arm/linux.mh (TDEP_XML): Define.
* arm-linux-nat.c (PTRACE_GETWMMXREGS, PTRACE_SETWMMXREGS): Define.
(arm_linux_has_wmmx_registers): New.
(GET_THREAD_ID): Fix typo.
(IWMMXT_REGS_SIZE): Define.
(fetch_wmmx_regs, store_wmmx_regs): New.
(arm_linux_fetch_inferior_registers): Use fetch_wmmx_regs.
(arm_linux_store_inferior_registers): Use store_wmmx_regs.
(super_xfer_partial, arm_linux_xfer_partial): New.
(_initialize_arm_linux_nat): Use them.
* xml-support.c (fetch_xml_builtin): Move outside HAVE_LIBEXPAT.
(xml_builtin_xfer_partial): New function.
* xml-support.h (xml_builtin_xfer_partial): New prototype.
* NEWS: Update mention of iWMMXt support.
2007-02-26 Daniel Jacobowitz <dan@codesourcery.com>
* arm-tdep.c (arm_scan_prologue): Do not record FPA register saves

View File

@ -401,7 +401,8 @@ RUNTEST = runtest
RUNTESTFLAGS=
# XML files to build in to GDB.
XMLFILES = $(srcdir)/features/gdb-target.dtd $(srcdir)/features/xinclude.dtd
XMLFILES = $(srcdir)/features/gdb-target.dtd $(srcdir)/features/xinclude.dtd \
$(TDEP_XML)
# This is ser-unix.o for any system which supports a v7/BSD/SYSV/POSIX
# interface to the serial port. Hopefully if get ported to OS/2, VMS,
@ -617,6 +618,7 @@ gdb_sim_sh_h = $(INCLUDE_DIR)/gdb/sim-sh.h
splay_tree_h = $(INCLUDE_DIR)/splay-tree.h
safe_ctype_h = $(INCLUDE_DIR)/safe-ctype.h
hashtab_h = $(INCLUDE_DIR)/hashtab.h
filenames_h = $(INCLUDE_DIR)/filenames.h
#
# $BUILD/ headers
@ -1288,6 +1290,7 @@ clean mostlyclean: $(CONFIG_CLEAN)
rm -f gdb$(EXEEXT) core make.log
rm -f gdb[0-9]$(EXEEXT)
rm -f test-cp-name-parser$(EXEEXT)
rm -f xml-builtin.c stamp-xml
.PHONY: clean-tui
clean-tui:
@ -1805,7 +1808,8 @@ arch-utils.o: arch-utils.c $(defs_h) $(arch_utils_h) $(buildsym_h) \
$(floatformat_h) $(target_descriptions_h)
arm-linux-nat.o: arm-linux-nat.c $(defs_h) $(inferior_h) $(gdbcore_h) \
$(gdb_string_h) $(regcache_h) $(arm_tdep_h) $(gregset_h) \
$(target_h) $(linux_nat_h) $(gdb_proc_service_h) $(arm_linux_tdep_h)
$(target_h) $(linux_nat_h) $(gdb_proc_service_h) $(arm_linux_tdep_h) \
$(target_descriptions_h) $(xml_support_h)
arm-linux-tdep.o: arm-linux-tdep.c $(defs_h) $(target_h) $(value_h) \
$(gdbtypes_h) $(floatformat_h) $(gdbcore_h) $(frame_h) $(regcache_h) \
$(doublest_h) $(solib_svr4_h) $(osabi_h) $(arm_tdep_h) \

View File

@ -22,8 +22,8 @@ a local file or over the remote serial protocol.
for architectures which have implemented the support (currently
only ARM).
* The GDB remote stub, gdbserver, now supports the XScale iWMMXt
coprocessor.
* GDB and the GDB remote stub, gdbserver, now support the XScale
iWMMXt coprocessor.
* New commands

View File

@ -26,6 +26,8 @@
#include "regcache.h"
#include "target.h"
#include "linux-nat.h"
#include "target-descriptions.h"
#include "xml-support.h"
#include "arm-tdep.h"
#include "arm-linux-tdep.h"
@ -45,6 +47,14 @@
#define PTRACE_GET_THREAD_AREA 22
#endif
#ifndef PTRACE_GETWMMXREGS
#define PTRACE_GETWMMXREGS 18
#define PTRACE_SETWMMXREGS 19
#endif
/* A flag for whether the WMMX registers are available. */
static int arm_linux_has_wmmx_registers;
extern int arm_apcs_32;
/* The following variables are used to determine the version of the
@ -77,7 +87,7 @@ get_thread_id (ptid_t ptid)
tid = PIDGET (ptid);
return tid;
}
#define GET_THREAD_ID(PTID) get_thread_id ((PTID));
#define GET_THREAD_ID(PTID) get_thread_id (PTID)
/* Get the value of a particular register from the floating point
state of the process and store it into regcache. */
@ -363,6 +373,80 @@ store_regs (void)
}
}
/* Fetch all WMMX registers of the process and store into
regcache. */
#define IWMMXT_REGS_SIZE (16 * 8 + 6 * 4)
static void
fetch_wmmx_regs (void)
{
char regbuf[IWMMXT_REGS_SIZE];
int ret, regno, tid;
/* Get the thread id for the ptrace call. */
tid = GET_THREAD_ID (inferior_ptid);
ret = ptrace (PTRACE_GETWMMXREGS, tid, 0, regbuf);
if (ret < 0)
{
warning (_("Unable to fetch WMMX registers."));
return;
}
for (regno = 0; regno < 16; regno++)
regcache_raw_supply (current_regcache, regno + ARM_WR0_REGNUM,
&regbuf[regno * 8]);
for (regno = 0; regno < 2; regno++)
regcache_raw_supply (current_regcache, regno + ARM_WCSSF_REGNUM,
&regbuf[16 * 8 + regno * 4]);
for (regno = 0; regno < 4; regno++)
regcache_raw_supply (current_regcache, regno + ARM_WCGR0_REGNUM,
&regbuf[16 * 8 + 2 * 4 + regno * 4]);
}
static void
store_wmmx_regs (void)
{
char regbuf[IWMMXT_REGS_SIZE];
int ret, regno, tid;
/* Get the thread id for the ptrace call. */
tid = GET_THREAD_ID (inferior_ptid);
ret = ptrace (PTRACE_GETWMMXREGS, tid, 0, regbuf);
if (ret < 0)
{
warning (_("Unable to fetch WMMX registers."));
return;
}
for (regno = 0; regno < 16; regno++)
if (register_cached (regno + ARM_WR0_REGNUM))
regcache_raw_collect (current_regcache, regno + ARM_WR0_REGNUM,
&regbuf[regno * 8]);
for (regno = 0; regno < 2; regno++)
if (register_cached (regno + ARM_WCSSF_REGNUM))
regcache_raw_collect (current_regcache, regno + ARM_WCSSF_REGNUM,
&regbuf[16 * 8 + regno * 4]);
for (regno = 0; regno < 4; regno++)
if (register_cached (regno + ARM_WCGR0_REGNUM))
regcache_raw_collect (current_regcache, regno + ARM_WCGR0_REGNUM,
&regbuf[16 * 8 + 2 * 4 + regno * 4]);
ret = ptrace (PTRACE_SETWMMXREGS, tid, 0, regbuf);
if (ret < 0)
{
warning (_("Unable to store WMMX registers."));
return;
}
}
/* Fetch registers from the child process. Fetch all registers if
regno == -1, otherwise fetch all general registers or all floating
point registers depending upon the value of regno. */
@ -374,14 +458,18 @@ arm_linux_fetch_inferior_registers (int regno)
{
fetch_regs ();
fetch_fpregs ();
if (arm_linux_has_wmmx_registers)
fetch_wmmx_regs ();
}
else
{
if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM)
fetch_register (regno);
if (regno >= ARM_F0_REGNUM && regno <= ARM_FPS_REGNUM)
else if (regno >= ARM_F0_REGNUM && regno <= ARM_FPS_REGNUM)
fetch_fpregister (regno);
else if (arm_linux_has_wmmx_registers
&& regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM)
fetch_wmmx_regs ();
}
}
@ -396,14 +484,18 @@ arm_linux_store_inferior_registers (int regno)
{
store_regs ();
store_fpregs ();
if (arm_linux_has_wmmx_registers)
store_wmmx_regs ();
}
else
{
if ((regno < ARM_F0_REGNUM) || (regno > ARM_FPS_REGNUM))
if (regno < ARM_F0_REGNUM || regno == ARM_PS_REGNUM)
store_register (regno);
if ((regno >= ARM_F0_REGNUM) && (regno <= ARM_FPS_REGNUM))
else if ((regno >= ARM_F0_REGNUM) && (regno <= ARM_FPS_REGNUM))
store_fpregister (regno);
else if (arm_linux_has_wmmx_registers
&& regno >= ARM_WR0_REGNUM && regno <= ARM_WCGR7_REGNUM)
store_wmmx_regs ();
}
}
@ -485,6 +577,44 @@ get_linux_version (unsigned int *vmajor,
return ((*vmajor << 16) | (*vminor << 8) | *vrelease);
}
static LONGEST (*super_xfer_partial) (struct target_ops *, enum target_object,
const char *, gdb_byte *, const gdb_byte *,
ULONGEST, LONGEST);
static LONGEST
arm_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)
{
int ret;
char regbuf[IWMMXT_REGS_SIZE];
ret = ptrace (PTRACE_GETWMMXREGS, GET_THREAD_ID (inferior_ptid),
0, regbuf);
if (ret < 0)
arm_linux_has_wmmx_registers = 0;
else
arm_linux_has_wmmx_registers = 1;
if (arm_linux_has_wmmx_registers)
annex = "arm-with-iwmmxt.xml";
else
return -1;
}
return xml_builtin_xfer_partial (annex, readbuf, writebuf, offset, len);
}
return super_xfer_partial (ops, object, annex, readbuf, writebuf,
offset, len);
}
void _initialize_arm_linux_nat (void);
void
@ -501,6 +631,10 @@ _initialize_arm_linux_nat (void)
t->to_fetch_registers = arm_linux_fetch_inferior_registers;
t->to_store_registers = arm_linux_store_inferior_registers;
/* Override the default to_xfer_partial. */
super_xfer_partial = t->to_xfer_partial;
t->to_xfer_partial = arm_linux_xfer_partial;
/* Register the target. */
linux_nat_add_target (t);
}

View File

@ -6,3 +6,6 @@ NATDEPFILES= inf-ptrace.o fork-child.o arm-linux-nat.o gcore.o \
LOADLIBES= -ldl -rdynamic
TDEP_XML = $(srcdir)/features/arm-with-iwmmxt.xml \
$(srcdir)/features/xscale-iwmmxt.xml \
$(srcdir)/features/arm-core.xml

View File

@ -21,6 +21,11 @@
#include "defs.h"
#include "gdbcmd.h"
#include "exceptions.h"
#include "xml-support.h"
#include "gdb_string.h"
#include "safe-ctype.h"
/* Debugging flag. */
static int debug_xml;
@ -29,12 +34,7 @@ static int debug_xml;
available. */
#ifdef HAVE_LIBEXPAT
#include "exceptions.h"
#include "xml-support.h"
#include "gdb_expat.h"
#include "gdb_string.h"
#include "safe-ctype.h"
/* The maximum depth of <xi:include> nesting. No need to be miserly,
we just want to avoid running out of stack on loops. */
@ -880,6 +880,7 @@ xml_process_xincludes (const char *name, const char *text,
do_cleanups (back_to);
return result;
}
#endif /* HAVE_LIBEXPAT */
/* Return an XML document which was compiled into GDB, from
@ -897,7 +898,36 @@ fetch_xml_builtin (const char *filename)
return NULL;
}
#endif /* HAVE_LIBEXPAT */
/* A to_xfer_partial helper function which reads XML files which were
compiled into GDB. The target may call this function from its own
to_xfer_partial handler, after converting object and annex to the
appropriate filename. */
LONGEST
xml_builtin_xfer_partial (const char *filename,
gdb_byte *readbuf, const gdb_byte *writebuf,
ULONGEST offset, LONGEST len)
{
const char *buf;
LONGEST len_avail;
gdb_assert (readbuf != NULL && writebuf == NULL);
gdb_assert (filename != NULL);
buf = fetch_xml_builtin (filename);
if (buf == NULL)
return -1;
len_avail = strlen (buf);
if (offset >= len_avail)
return 0;
if (len > len_avail - offset)
len = len_avail - offset;
memcpy (readbuf, buf + offset, len);
return len;
}
static void
show_debug_xml (struct ui_file *file, int from_tty,

View File

@ -53,6 +53,15 @@ char *xml_process_xincludes (const char *name, const char *text,
const char *fetch_xml_builtin (const char *filename);
/* A to_xfer_partial helper function which reads XML files which were
compiled into GDB. The target may call this function from its own
to_xfer_partial handler, after converting object and annex to the
appropriate filename. */
LONGEST xml_builtin_xfer_partial (const char *filename,
gdb_byte *readbuf, const gdb_byte *writebuf,
ULONGEST offset, LONGEST len);
/* The text of compiled-in XML documents, from xml-builtin.c
(generated). */
extern const char *xml_builtin[][2];