From 05a4558a934667e0e219e95d2c898f5c069b860c Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Mon, 26 Feb 2007 19:20:21 +0000 Subject: [PATCH] * 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. --- gdb/ChangeLog | 21 ++++++ gdb/Makefile.in | 8 ++- gdb/NEWS | 4 +- gdb/arm-linux-nat.c | 148 ++++++++++++++++++++++++++++++++++++++-- gdb/config/arm/linux.mh | 3 + gdb/xml-support.c | 42 ++++++++++-- gdb/xml-support.h | 9 +++ 7 files changed, 218 insertions(+), 17 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index d9302aa4a7..bd19559820 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,24 @@ +2007-02-26 Daniel Jacobowitz + + * 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 * arm-tdep.c (arm_scan_prologue): Do not record FPA register saves diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 4b9f988869..be270da3b2 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -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) \ diff --git a/gdb/NEWS b/gdb/NEWS index 90af6ce44f..be9c3e3755 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -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 diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c index ce3f881c89..05b48a7289 100644 --- a/gdb/arm-linux-nat.c +++ b/gdb/arm-linux-nat.c @@ -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, + ®buf[regno * 8]); + + for (regno = 0; regno < 2; regno++) + regcache_raw_supply (current_regcache, regno + ARM_WCSSF_REGNUM, + ®buf[16 * 8 + regno * 4]); + + for (regno = 0; regno < 4; regno++) + regcache_raw_supply (current_regcache, regno + ARM_WCGR0_REGNUM, + ®buf[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, + ®buf[regno * 8]); + + for (regno = 0; regno < 2; regno++) + if (register_cached (regno + ARM_WCSSF_REGNUM)) + regcache_raw_collect (current_regcache, regno + ARM_WCSSF_REGNUM, + ®buf[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, + ®buf[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); } diff --git a/gdb/config/arm/linux.mh b/gdb/config/arm/linux.mh index 7de23271df..00858268ce 100644 --- a/gdb/config/arm/linux.mh +++ b/gdb/config/arm/linux.mh @@ -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 diff --git a/gdb/xml-support.c b/gdb/xml-support.c index c9196ecfe1..49a10d72d5 100644 --- a/gdb/xml-support.c +++ b/gdb/xml-support.c @@ -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 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, diff --git a/gdb/xml-support.h b/gdb/xml-support.h index b01ea1903d..19fd44d54c 100644 --- a/gdb/xml-support.h +++ b/gdb/xml-support.h @@ -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]; -- 2.34.1