From 58caa3dcdb43a5d66932182338f41df0bfd6cc98 Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Wed, 27 Feb 2002 07:07:49 +0000 Subject: 2002-02-27 Daniel Jacobowitz * gdbserver/acconfig.h: New file. * gdbserver/i387-fp.c: New file. * gdbserver/i387-fp.h: New file. * gdbserver/linux-x86-64.c: New file. * regformats/reg-x86-64.dat: New file. * configure.tgt: Add x86_64-*-linux* gdbserver support. & gdbserver/configure.srv: Add x86_64-*-linux* and regset support. * gdbserver/configure.in: Add support for regsets. * gdbserver/config.in: Regenerate. * gdbserver/configure: Regenerate. * gdbserver/Makefile.in: Likewise. Add $(linux_low_h). * gdbserver/linux-low.h: New file. * gdbserver/linux-low.c: Include "linux-low.h". Add support for regsets. * gdbserver/linux-arm-low.c: Include "linux-low.h". * gdbserver/linux-ia64-low.c: Include "linux-low.h". * gdbserver/linux-m68k-low.c: Include "linux-low.h". * gdbserver/linux-mips-low.c: Include "linux-low.h". * gdbserver/linux-ppc-low.c: Include "linux-low.h". * gdbserver/linux-sh-low.c: Include "linux-low.h". * gdbserver/linux-i386-low.c: Include "linux-low.h". Include "i387-fp.h". Add PTRACE_GETREGS and friends. * gdbserver/regcache.c (supply_register): New function. (supply_register_by_name): New function. (collect_register): New function. (collect_register_by_name): New function. --- gdb/gdbserver/linux-low.c | 155 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 147 insertions(+), 8 deletions(-) (limited to 'gdb/gdbserver/linux-low.c') diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index f9152c7..b1e3d13 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -20,8 +20,9 @@ Boston, MA 02111-1307, USA. */ #include "server.h" -#include +#include "linux-low.h" +#include #include #include #include @@ -37,6 +38,10 @@ #define PTRACE_ARG3_TYPE long #define PTRACE_XFER_TYPE int +#ifdef HAVE_LINUX_REGSETS +static int use_regsets_p = 1; +#endif + extern int errno; extern int num_regs; extern int regmap[]; @@ -166,8 +171,11 @@ register_addr (int regnum) return addr; } -/* Fetch one register. */ + +#ifdef HAVE_LINUX_USRREGS + +/* Fetch one register. */ static void fetch_register (int regno) { @@ -203,9 +211,8 @@ error_exit:; } /* Fetch all registers, or just one, from the child process. */ - -void -fetch_inferior_registers (int regno) +static void +usr_fetch_inferior_registers (int regno) { if (regno == -1 || regno == 0) for (regno = 0; regno < num_regs; regno++) @@ -217,9 +224,8 @@ fetch_inferior_registers (int regno) /* Store our register values back into the inferior. If REGNO is -1, do this for all registers. Otherwise, REGNO specifies which register (so we can save time). */ - -void -store_inferior_registers (int regno) +static void +usr_store_inferior_registers (int regno) { CORE_ADDR regaddr; int i; @@ -259,6 +265,139 @@ store_inferior_registers (int regno) for (regno = 0; regno < num_regs; regno++) store_inferior_registers (regno); } +#endif /* HAVE_LINUX_USRREGS */ + + + +#ifdef HAVE_LINUX_REGSETS + +static int +regsets_fetch_inferior_registers (void) +{ + struct regset_info *regset; + + regset = target_regsets; + + while (regset->size >= 0) + { + void *buf; + int res; + + if (regset->size == 0) + { + regset ++; + continue; + } + + buf = malloc (regset->size); + res = ptrace (regset->get_request, inferior_pid, 0, (int) buf); + if (res < 0) + { + if (errno == EIO) + { + /* If we get EIO on the first regset, do not try regsets again. + If we get EIO on a later regset, disable that regset. */ + if (regset == target_regsets) + { + use_regsets_p = 0; + return -1; + } + else + { + regset->size = 0; + continue; + } + } + else + { + perror ("Warning: ptrace(regsets_fetch_inferior_registers)"); + } + } + regset->store_function (buf); + regset ++; + } +} + +static int +regsets_store_inferior_registers (void) +{ + struct regset_info *regset; + + regset = target_regsets; + + while (regset->size >= 0) + { + void *buf; + int res; + + if (regset->size == 0) + { + regset ++; + continue; + } + + buf = malloc (regset->size); + regset->fill_function (buf); + res = ptrace (regset->set_request, inferior_pid, 0, (int) buf); + if (res < 0) + { + if (errno == EIO) + { + /* If we get EIO on the first regset, do not try regsets again. + If we get EIO on a later regset, disable that regset. */ + if (regset == target_regsets) + { + use_regsets_p = 0; + return -1; + } + else + { + regset->size = 0; + continue; + } + } + else + { + perror ("Warning: ptrace(regsets_fetch_inferior_registers)"); + } + } + regset ++; + } +} + +#endif /* HAVE_LINUX_REGSETS */ + + +void +fetch_inferior_registers (int regno) +{ +#ifdef HAVE_LINUX_REGSETS + if (use_regsets_p) + { + if (regsets_fetch_inferior_registers () == 0) + return; + } +#endif +#ifdef HAVE_LINUX_USRREGS + usr_fetch_inferior_registers (regno); +#endif +} + +void +store_inferior_registers (int regno) +{ +#ifdef HAVE_LINUX_REGSETS + if (use_regsets_p) + { + if (regsets_store_inferior_registers () == 0) + return; + } +#endif +#ifdef HAVE_LINUX_USRREGS + usr_store_inferior_registers (regno); +#endif +} + /* Copy LEN bytes from inferior's memory starting at MEMADDR to debugger memory starting at MYADDR. */ -- cgit v1.1