From: Daniel Jacobowitz Date: Thu, 14 Feb 2002 06:21:24 +0000 (+0000) Subject: 2002-02-14 Daniel Jacobowitz X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0a30fbc4cfd38f7966ea783b292031986645c6ce;p=binutils-gdb.git 2002-02-14 Daniel Jacobowitz * gdbserver/Makefile.in: Add regformats directory to INCLUDE_CFLAGS, and remove unused $(INCLUDE_DIR). Add regcache.c to OBS. Add generated register protocol files to clean target. Update dependencies for new objects, obsolete old target code. * gdbserver/linux-low.c: Remove all platform-specific code to new files. Remove various dead code. Update to use regcache functionality. * gdbserver/remote-utils.c (fromhex): Add return statement to quiet warning. (putpkt): Dynamically allocate buf2 because PBUFSIZ is no longer constant. (input_interrupt): Add integer parameter to match prototype of a signal handler. (outreg): Use register_data (). (prepare_resume_reply): Use gdbserver_expedite_regs. * gdbserver/server.c (main): Dynamically allocate own_buf because PBUFSIZ is no longer constant. Use registers_to_string () and registers_from_string (). * gdbserver/server.h: No longer include "defs.h". Add prototypes for error (), fatal (), and warning (). Update definition of PBUFSIZ to use regcache functionality. Add include guard. * gdbserver/utils.c (fatal): Add missing ``const''. (warning): New function. * regformats/regdat.sh: Include "regcache.h" in generated files. Provide init_registers () function. * regformats/regdef.h: Add prototype for set_register_cache (). Add include guard. * gdbserver/linux-arm-low.c: New file. * gdbserver/linux-i386-low.c: New file. * gdbserver/linux-ia64-low.c: New file. * gdbserver/linux-m68k-low.c: New file. * gdbserver/linux-mips-low.c: New file. * gdbserver/linux-ppc-low.c: New file. * gdbserver/linux-sh-low.c: New file. * gdbserver/regcache.c: New file. * gdbserver/regcache.h: New file. * gdbserver/low-linux.c: Removed obsolete file. --- diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 97af1bc6dba..50a3dfcf62a 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,49 @@ +2002-02-14 Daniel Jacobowitz + + * gdbserver/Makefile.in: Add regformats directory to INCLUDE_CFLAGS, + and remove unused $(INCLUDE_DIR). + Add regcache.c to OBS. + Add generated register protocol files to clean target. + Update dependencies for new objects, obsolete old target code. + + * gdbserver/linux-low.c: Remove all platform-specific code to + new files. Remove various dead code. Update to use regcache + functionality. + * gdbserver/remote-utils.c (fromhex): Add return statement + to quiet warning. + (putpkt): Dynamically allocate buf2 because PBUFSIZ is no longer + constant. + (input_interrupt): Add integer parameter to match prototype + of a signal handler. + (outreg): Use register_data (). + (prepare_resume_reply): Use gdbserver_expedite_regs. + * gdbserver/server.c (main): Dynamically allocate own_buf because + PBUFSIZ is no longer constant. Use registers_to_string () and + registers_from_string (). + * gdbserver/server.h: No longer include "defs.h". Add prototypes + for error (), fatal (), and warning (). Update definition of + PBUFSIZ to use regcache functionality. Add include guard. + * gdbserver/utils.c (fatal): Add missing ``const''. + (warning): New function. + + * regformats/regdat.sh: Include "regcache.h" in generated files. + Provide init_registers () function. + * regformats/regdef.h: Add prototype for set_register_cache (). + Add include guard. + + * gdbserver/linux-arm-low.c: New file. + * gdbserver/linux-i386-low.c: New file. + * gdbserver/linux-ia64-low.c: New file. + * gdbserver/linux-m68k-low.c: New file. + * gdbserver/linux-mips-low.c: New file. + * gdbserver/linux-ppc-low.c: New file. + * gdbserver/linux-sh-low.c: New file. + + * gdbserver/regcache.c: New file. + * gdbserver/regcache.h: New file. + + * gdbserver/low-linux.c: Removed obsolete file. + 2002-02-14 Daniel Jacobowitz * config/arm/linux.mt: Update GDBSERVER_DEPFILES. diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in index c3e1dae8457..f6505f07881 100644 --- a/gdb/gdbserver/Makefile.in +++ b/gdb/gdbserver/Makefile.in @@ -1,6 +1,5 @@ -#Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, -#1999, 2000 -#Free Software Foundation, Inc. +# Copyright 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, +# 1999, 2000, 2001, 2002 Free Software Foundation, Inc. # This file is part of GDB. @@ -97,8 +96,8 @@ READLINE_DEP = $$(READLINE_DIR) # -I${srcdir} possibly for regex.h also. # -I${srcdir}/config for more generic config files. # -I$(srcdir)/../regformats for regdef.h -INCLUDE_CFLAGS = -I. -I.. -I${srcdir} -I${srcdir}/.. -I${srcdir}/../config \ - -I$(INCLUDE_DIR) -I$(srcdir)/../regformats +INCLUDE_CFLAGS = -I. -I.. -I${srcdir} -I${srcdir}/.. \ + -I$(srcdir)/../regformats # M{H,T}_CFLAGS, if defined, has host- and target-dependent CFLAGS # from the config/ directory. @@ -139,7 +138,7 @@ DEPFILES = $(GDBSERVER_DEPFILES) SOURCES = $(SFILES) $(ALLDEPFILES) TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS} -OBS = utils.o $(GDBSERVER_DEPFILES) server.o remote-utils.o +OBS = utils.o $(GDBSERVER_DEPFILES) server.o remote-utils.o regcache.o # Prevent Sun make from putting in the machine type. Setting # TARGET_ARCH to nothing works for SunOS 3, 4.0, but not for 4.1. @@ -201,6 +200,8 @@ tags: TAGS clean: rm -f *.o ${ADD_FILES} *~ rm -f gdbserver gdbreplay core make.log + rm -f reg-arm.c reg-i386.c reg-ia64.c reg-m68k.c reg-mips.c + rm -f reg-ppc.c reg-sh.c distclean: clean rm -f nm.h tm.h xm.h config.status @@ -239,19 +240,31 @@ MAKEOVERRIDES= ## with no dependencies and no actions. unexport CHILLFLAGS CHILL_LIB CHILL_FOR_TARGET : -server.o : ${srcdir}/server.c ${srcdir}/server.h -remote-utils.o : ${srcdir}/remote-utils.c ${srcdir}/server.h -low-linux.o : ${srcdir}/low-linux.c ${srcdir}/server.h -low-lynx.o : ${srcdir}/low-lynx.c ${srcdir}/server.h -low-nbsd.o : ${srcdir}/low-nbsd.c ${srcdir}/server.h -low-sim.o : ${srcdir}/low-sim.c ${srcdir}/server.h -low-sparc.o : $(srcdir)/low-sparc.c $(srcdir)/server.h -low-sun3.o : $(srcdir)/low-sun3.c $(srcdir)/server.h -low-hppabsd.o : $(srcdir)/low-hppabsd.c $(srcdir)/server.h -utils.o : ${srcdir}/utils.c ${srcdir}/server.h - -regdef_h = $(srcdir)/../regformats/regdef.h regdat_sh = $(srcdir)/../regformats/regdat.sh +regdef_h = $(srcdir)/../regformats/regdef.h +regcache_h = $(srcdir)/regcache.h +server_h = $(srcdir)/server.h $(regcache_h) + +server.o: server.c $(server_h) +remote-utils.o: remote-utils.c $(server_h) +utils.o: utils.c $(server_h) +regcache.o: regcache.c $(server_h) $(regdef_h) + +linux-low.o: linux-low.c $(server_h) +linux-low-arm.o: linux-low-arm.c $(server_h) +linux-low-i386.o: linux-low-i386.c $(server_h) +linux-low-ia64.o: linux-low-ia64.c $(server_h) +linux-low-mips.o: linux-low-mips.c $(server_h) +linux-low-ppc.o: linux-low-ppc.c $(server_h) +linux-low-sh.o: linux-low-sh.c $(server_h) + +# OBSOLETE TARGETS +# OBSOLETE # low-lynx.o : ${srcdir}/low-lynx.c ${srcdir}/server.h +# OBSOLETE # low-nbsd.o : ${srcdir}/low-nbsd.c ${srcdir}/server.h +# OBSOLETE # low-sim.o : ${srcdir}/low-sim.c ${srcdir}/server.h +# OBSOLETE # low-sparc.o : $(srcdir)/low-sparc.c $(srcdir)/server.h +# OBSOLETE # low-sun3.o : $(srcdir)/low-sun3.c $(srcdir)/server.h +# OBSOLETE # low-hppabsd.o : $(srcdir)/low-hppabsd.c $(srcdir)/server.h reg-arm.o : reg-arm.c $(regdef_h) reg-arm.c : $(srcdir)/../regformats/reg-arm.dat $(regdat_sh) diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c new file mode 100644 index 00000000000..761653af423 --- /dev/null +++ b/gdb/gdbserver/linux-arm-low.c @@ -0,0 +1,46 @@ +/* GNU/Linux/ARM specific low level interface, for the remote server for GDB. + Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "server.h" + +#ifdef HAVE_SYS_REG_H +#include +#endif + +int num_regs = 16; + +int regmap[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, +}; + +int +cannot_store_register (int regno) +{ + return (regno >= num_regs); +} + +int +cannot_fetch_register (int regno) +{ + return (regno >= num_regs); +} + diff --git a/gdb/gdbserver/linux-i386-low.c b/gdb/gdbserver/linux-i386-low.c new file mode 100644 index 00000000000..cb7b55f0f6c --- /dev/null +++ b/gdb/gdbserver/linux-i386-low.c @@ -0,0 +1,59 @@ +/* GNU/Linux/i386 specific low level interface, for the remote server for GDB. + Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "server.h" + +#ifdef HAVE_SYS_REG_H +#include +#endif + +/* This module only supports access to the general purpose registers. + Adjust the relevant constants accordingly. + + FIXME: kettenis/2001-03-28: We should really use PTRACE_GETREGS to + get at the registers. Better yet, we should try to share code with + i386-linux-nat.c. */ + +int num_regs = 16; + +/* This stuff comes from i386-linux-nat.c. */ + +/* Mapping between the general-purpose registers in `struct user' + format and GDB's register array layout. */ +int regmap[] = +{ + EAX * 4, ECX * 4, EDX * 4, EBX * 4, + UESP * 4, EBP * 4, ESI * 4, EDI * 4, + EIP * 4, EFL * 4, CS * 4, SS * 4, + DS * 4, ES * 4, FS * 4, GS * 4 +}; + +int +cannot_store_register (int regno) +{ + return (regno >= num_regs); +} + +int +cannot_fetch_register (int regno) +{ + return (regno >= num_regs); +} diff --git a/gdb/gdbserver/linux-ia64-low.c b/gdb/gdbserver/linux-ia64-low.c new file mode 100644 index 00000000000..d7ab99bf9ef --- /dev/null +++ b/gdb/gdbserver/linux-ia64-low.c @@ -0,0 +1,296 @@ +/* GNU/Linux/IA64 specific low level interface, for the remote server for GDB. + Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "server.h" + +#ifdef HAVE_SYS_REG_H +#include +#endif + +int num_regs = 590; + +#include + +int regmap[] = + { + /* general registers */ + -1, /* gr0 not available; i.e, it's always zero */ + PT_R1, + PT_R2, + PT_R3, + PT_R4, + PT_R5, + PT_R6, + PT_R7, + PT_R8, + PT_R9, + PT_R10, + PT_R11, + PT_R12, + PT_R13, + PT_R14, + PT_R15, + PT_R16, + PT_R17, + PT_R18, + PT_R19, + PT_R20, + PT_R21, + PT_R22, + PT_R23, + PT_R24, + PT_R25, + PT_R26, + PT_R27, + PT_R28, + PT_R29, + PT_R30, + PT_R31, + /* gr32 through gr127 not directly available via the ptrace interface */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + /* Floating point registers */ + -1, -1, /* f0 and f1 not available (f0 is +0.0 and f1 is +1.0) */ + PT_F2, + PT_F3, + PT_F4, + PT_F5, + PT_F6, + PT_F7, + PT_F8, + PT_F9, + PT_F10, + PT_F11, + PT_F12, + PT_F13, + PT_F14, + PT_F15, + PT_F16, + PT_F17, + PT_F18, + PT_F19, + PT_F20, + PT_F21, + PT_F22, + PT_F23, + PT_F24, + PT_F25, + PT_F26, + PT_F27, + PT_F28, + PT_F29, + PT_F30, + PT_F31, + PT_F32, + PT_F33, + PT_F34, + PT_F35, + PT_F36, + PT_F37, + PT_F38, + PT_F39, + PT_F40, + PT_F41, + PT_F42, + PT_F43, + PT_F44, + PT_F45, + PT_F46, + PT_F47, + PT_F48, + PT_F49, + PT_F50, + PT_F51, + PT_F52, + PT_F53, + PT_F54, + PT_F55, + PT_F56, + PT_F57, + PT_F58, + PT_F59, + PT_F60, + PT_F61, + PT_F62, + PT_F63, + PT_F64, + PT_F65, + PT_F66, + PT_F67, + PT_F68, + PT_F69, + PT_F70, + PT_F71, + PT_F72, + PT_F73, + PT_F74, + PT_F75, + PT_F76, + PT_F77, + PT_F78, + PT_F79, + PT_F80, + PT_F81, + PT_F82, + PT_F83, + PT_F84, + PT_F85, + PT_F86, + PT_F87, + PT_F88, + PT_F89, + PT_F90, + PT_F91, + PT_F92, + PT_F93, + PT_F94, + PT_F95, + PT_F96, + PT_F97, + PT_F98, + PT_F99, + PT_F100, + PT_F101, + PT_F102, + PT_F103, + PT_F104, + PT_F105, + PT_F106, + PT_F107, + PT_F108, + PT_F109, + PT_F110, + PT_F111, + PT_F112, + PT_F113, + PT_F114, + PT_F115, + PT_F116, + PT_F117, + PT_F118, + PT_F119, + PT_F120, + PT_F121, + PT_F122, + PT_F123, + PT_F124, + PT_F125, + PT_F126, + PT_F127, + /* predicate registers - we don't fetch these individually */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + /* branch registers */ + PT_B0, + PT_B1, + PT_B2, + PT_B3, + PT_B4, + PT_B5, + PT_B6, + PT_B7, + /* virtual frame pointer and virtual return address pointer */ + -1, -1, + /* other registers */ + PT_PR, + PT_CR_IIP, /* ip */ + PT_CR_IPSR, /* psr */ + PT_CFM, /* cfm */ + /* kernel registers not visible via ptrace interface (?) */ + -1, -1, -1, -1, -1, -1, -1, -1, + /* hole */ + -1, -1, -1, -1, -1, -1, -1, -1, + PT_AR_RSC, + PT_AR_BSP, + PT_AR_BSPSTORE, + PT_AR_RNAT, + -1, + -1, /* Not available: FCR, IA32 floating control register */ + -1, -1, + -1, /* Not available: EFLAG */ + -1, /* Not available: CSD */ + -1, /* Not available: SSD */ + -1, /* Not available: CFLG */ + -1, /* Not available: FSR */ + -1, /* Not available: FIR */ + -1, /* Not available: FDR */ + -1, + PT_AR_CCV, + -1, -1, -1, + PT_AR_UNAT, + -1, -1, -1, + PT_AR_FPSR, + -1, -1, -1, + -1, /* Not available: ITC */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, + PT_AR_PFS, + PT_AR_LC, + -1, /* Not available: EC, the Epilog Count register */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, + /* nat bits - not fetched directly; instead we obtain these bits from + either rnat or unat or from memory. */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + }; + +int +cannot_store_register (int regno) +{ + return 0; +} + +int +cannot_fetch_register (int regno) +{ + return 0; +} + diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c index 368c3f226c0..4c293165730 100644 --- a/gdb/gdbserver/linux-low.c +++ b/gdb/gdbserver/linux-low.c @@ -31,22 +31,15 @@ #include #include #include - -/***************Begin MY defs*********************/ -static char my_registers[REGISTER_BYTES]; -char *registers = my_registers; -/***************End MY defs*********************/ - -#ifdef HAVE_SYS_REG_H -#include -#endif +#include +#include #define PTRACE_ARG3_TYPE long #define PTRACE_XFER_TYPE int extern int errno; - -static void initialize_arch (void); +extern int num_regs; +extern int regmap[]; /* Start an inferior process and returns its pid. ALLARGS is a vector of program-name and args. */ @@ -156,432 +149,23 @@ myresume (int step, int signal) perror_with_name ("ptrace"); } - -#if !defined (offsetof) -#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) -#endif - -/* U_REGS_OFFSET is the offset of the registers within the u area. */ -#if !defined (U_REGS_OFFSET) -#define U_REGS_OFFSET \ - ptrace (PT_READ_U, inferior_pid, \ - (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \ - - KERNEL_U_ADDR -#endif - -#ifdef I386_GNULINUX_TARGET -/* This module only supports access to the general purpose registers. - Adjust the relevant constants accordingly. - - FIXME: kettenis/2001-03-28: We should really use PTRACE_GETREGS to - get at the registers. Better yet, we should try to share code with - i386-linux-nat.c. */ -#undef NUM_FREGS -#define NUM_FREGS 0 -#undef NUM_REGS -#define NUM_REGS NUM_GREGS - -/* This stuff comes from i386-tdep.c. */ - -/* i386_register_byte[i] is the offset into the register file of the - start of register number i. We initialize this from - i386_register_raw_size. */ -int i386_register_byte[MAX_NUM_REGS]; - -/* i386_register_raw_size[i] is the number of bytes of storage in - GDB's register array occupied by register i. */ -int i386_register_raw_size[MAX_NUM_REGS] = { - 4, 4, 4, 4, - 4, 4, 4, 4, - 4, 4, 4, 4, - 4, 4, 4, 4, - 10, 10, 10, 10, - 10, 10, 10, 10, - 4, 4, 4, 4, - 4, 4, 4, 4, - 16, 16, 16, 16, - 16, 16, 16, 16, - 4 -}; - -static void -initialize_arch (void) -{ - /* Initialize the table saying where each register starts in the - register file. */ - { - int i, offset; - - offset = 0; - for (i = 0; i < MAX_NUM_REGS; i++) - { - i386_register_byte[i] = offset; - offset += i386_register_raw_size[i]; - } - } -} - -/* This stuff comes from i386-linux-nat.c. */ - -/* Mapping between the general-purpose registers in `struct user' - format and GDB's register array layout. */ -static int regmap[] = -{ - EAX, ECX, EDX, EBX, - UESP, EBP, ESI, EDI, - EIP, EFL, CS, SS, - DS, ES, FS, GS -}; - -/* Return the address of register REGNUM. BLOCKEND is the value of - u.u_ar0, which should point to the registers. */ - -CORE_ADDR -register_u_addr (CORE_ADDR blockend, int regnum) -{ - return (blockend + 4 * regmap[regnum]); -} -#elif defined(TARGET_M68K) -static void -initialize_arch (void) -{ - return; -} - -/* This table must line up with REGISTER_NAMES in tm-m68k.h */ -static int regmap[] = -{ -#ifdef PT_D0 - PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7, - PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP, - PT_SR, PT_PC, -#else - 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, - 17, 18, -#endif -#ifdef PT_FP0 - PT_FP0, PT_FP1, PT_FP2, PT_FP3, PT_FP4, PT_FP5, PT_FP6, PT_FP7, - PT_FPCR, PT_FPSR, PT_FPIAR -#else - 21, 24, 27, 30, 33, 36, 39, 42, 45, 46, 47 -#endif -}; - -/* BLOCKEND is the value of u.u_ar0, and points to the place where GS - is stored. */ +#define REGISTER_RAW_SIZE(regno) register_size((regno)) int -m68k_linux_register_u_addr (int blockend, int regnum) -{ - return (blockend + 4 * regmap[regnum]); -} -#elif defined(IA64_GNULINUX_TARGET) -#undef NUM_FREGS -#define NUM_FREGS 0 - -#include - -static int u_offsets[] = - { - /* general registers */ - -1, /* gr0 not available; i.e, it's always zero */ - PT_R1, - PT_R2, - PT_R3, - PT_R4, - PT_R5, - PT_R6, - PT_R7, - PT_R8, - PT_R9, - PT_R10, - PT_R11, - PT_R12, - PT_R13, - PT_R14, - PT_R15, - PT_R16, - PT_R17, - PT_R18, - PT_R19, - PT_R20, - PT_R21, - PT_R22, - PT_R23, - PT_R24, - PT_R25, - PT_R26, - PT_R27, - PT_R28, - PT_R29, - PT_R30, - PT_R31, - /* gr32 through gr127 not directly available via the ptrace interface */ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* Floating point registers */ - -1, -1, /* f0 and f1 not available (f0 is +0.0 and f1 is +1.0) */ - PT_F2, - PT_F3, - PT_F4, - PT_F5, - PT_F6, - PT_F7, - PT_F8, - PT_F9, - PT_F10, - PT_F11, - PT_F12, - PT_F13, - PT_F14, - PT_F15, - PT_F16, - PT_F17, - PT_F18, - PT_F19, - PT_F20, - PT_F21, - PT_F22, - PT_F23, - PT_F24, - PT_F25, - PT_F26, - PT_F27, - PT_F28, - PT_F29, - PT_F30, - PT_F31, - PT_F32, - PT_F33, - PT_F34, - PT_F35, - PT_F36, - PT_F37, - PT_F38, - PT_F39, - PT_F40, - PT_F41, - PT_F42, - PT_F43, - PT_F44, - PT_F45, - PT_F46, - PT_F47, - PT_F48, - PT_F49, - PT_F50, - PT_F51, - PT_F52, - PT_F53, - PT_F54, - PT_F55, - PT_F56, - PT_F57, - PT_F58, - PT_F59, - PT_F60, - PT_F61, - PT_F62, - PT_F63, - PT_F64, - PT_F65, - PT_F66, - PT_F67, - PT_F68, - PT_F69, - PT_F70, - PT_F71, - PT_F72, - PT_F73, - PT_F74, - PT_F75, - PT_F76, - PT_F77, - PT_F78, - PT_F79, - PT_F80, - PT_F81, - PT_F82, - PT_F83, - PT_F84, - PT_F85, - PT_F86, - PT_F87, - PT_F88, - PT_F89, - PT_F90, - PT_F91, - PT_F92, - PT_F93, - PT_F94, - PT_F95, - PT_F96, - PT_F97, - PT_F98, - PT_F99, - PT_F100, - PT_F101, - PT_F102, - PT_F103, - PT_F104, - PT_F105, - PT_F106, - PT_F107, - PT_F108, - PT_F109, - PT_F110, - PT_F111, - PT_F112, - PT_F113, - PT_F114, - PT_F115, - PT_F116, - PT_F117, - PT_F118, - PT_F119, - PT_F120, - PT_F121, - PT_F122, - PT_F123, - PT_F124, - PT_F125, - PT_F126, - PT_F127, - /* predicate registers - we don't fetch these individually */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - /* branch registers */ - PT_B0, - PT_B1, - PT_B2, - PT_B3, - PT_B4, - PT_B5, - PT_B6, - PT_B7, - /* virtual frame pointer and virtual return address pointer */ - -1, -1, - /* other registers */ - PT_PR, - PT_CR_IIP, /* ip */ - PT_CR_IPSR, /* psr */ - PT_CFM, /* cfm */ - /* kernel registers not visible via ptrace interface (?) */ - -1, -1, -1, -1, -1, -1, -1, -1, - /* hole */ - -1, -1, -1, -1, -1, -1, -1, -1, - PT_AR_RSC, - PT_AR_BSP, - PT_AR_BSPSTORE, - PT_AR_RNAT, - -1, - -1, /* Not available: FCR, IA32 floating control register */ - -1, -1, - -1, /* Not available: EFLAG */ - -1, /* Not available: CSD */ - -1, /* Not available: SSD */ - -1, /* Not available: CFLG */ - -1, /* Not available: FSR */ - -1, /* Not available: FIR */ - -1, /* Not available: FDR */ - -1, - PT_AR_CCV, - -1, -1, -1, - PT_AR_UNAT, - -1, -1, -1, - PT_AR_FPSR, - -1, -1, -1, - -1, /* Not available: ITC */ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, - PT_AR_PFS, - PT_AR_LC, - -1, /* Not available: EC, the Epilog Count register */ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, - /* nat bits - not fetched directly; instead we obtain these bits from - either rnat or unat or from memory. */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - }; - -int -ia64_register_u_addr (int blockend, int regnum) +register_addr (int regnum) { int addr; - if (regnum < 0 || regnum >= NUM_REGS) + if (regnum < 0 || regnum >= num_regs) error ("Invalid register number %d.", regnum); - addr = u_offsets[regnum]; + addr = regmap[regnum]; if (addr == -1) addr = 0; return addr; } -static void -initialize_arch (void) -{ - return; -} - -#elif defined(ARM_GNULINUX_TARGET) -int arm_register_u_addr(blockend, regnum) - int blockend; - int regnum; -{ - return blockend + REGISTER_BYTE(regnum); -} - -static void -initialize_arch () -{ -} -#endif - -CORE_ADDR -register_addr (int regno, CORE_ADDR blockend) -{ - CORE_ADDR addr; - - if (regno < 0 || regno >= NUM_REGS) - error ("Invalid register number %d.", regno); - - REGISTER_U_ADDR (addr, blockend, regno); - - return addr; -} - /* Fetch one register. */ static void @@ -590,16 +174,18 @@ fetch_register (int regno) CORE_ADDR regaddr; register int i; - /* Offset of registers within the u area. */ - unsigned int offset; - - offset = U_REGS_OFFSET; + if (regno >= num_regs) + return; + if (cannot_fetch_register (regno)) + return; - regaddr = register_addr (regno, offset); + regaddr = register_addr (regno); + if (regaddr == -1) + return; for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) { errno = 0; - *(PTRACE_XFER_TYPE *) ®isters[REGISTER_BYTE (regno) + i] = + *(PTRACE_XFER_TYPE *) (register_data (regno) + i) = ptrace (PTRACE_PEEKUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, 0); regaddr += sizeof (PTRACE_XFER_TYPE); if (errno != 0) @@ -622,7 +208,7 @@ void fetch_inferior_registers (int regno) { if (regno == -1 || regno == 0) - for (regno = 0; regno < NUM_REGS - NUM_FREGS; regno++) + for (regno = 0; regno < num_regs; regno++) fetch_register (regno); else fetch_register (regno); @@ -637,62 +223,43 @@ store_inferior_registers (int regno) { CORE_ADDR regaddr; int i; - unsigned int offset = U_REGS_OFFSET; if (regno >= 0) { -#if 0 - if (CANNOT_STORE_REGISTER (regno)) + if (regno >= num_regs) + return; + + if (cannot_store_register (regno)) + return; + + regaddr = register_addr (regno); + if (regaddr == -1) return; -#endif - regaddr = register_addr (regno, offset); errno = 0; -#if 0 - if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM) + for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) { - scratch = *(int *) ®isters[REGISTER_BYTE (regno)] | 0x3; - ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, - scratch, 0); + errno = 0; + ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, + *(int *) (register_data (regno) + i)); if (errno != 0) { - /* Error, even if attached. Failing to write these two - registers is pretty serious. */ - sprintf (buf, "writing register number %d", regno); - perror_with_name (buf); + /* Warning, not error, in case we are attached; sometimes the + kernel doesn't let us at the registers. */ + char *err = strerror (errno); + char *msg = alloca (strlen (err) + 128); + sprintf (msg, "writing register %d: %s", + regno, err); + error (msg); + return; } + regaddr += sizeof (int); } - else -#endif - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) - { - errno = 0; - ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, - *(int *) ®isters[REGISTER_BYTE (regno) + i]); - if (errno != 0) - { - /* Warning, not error, in case we are attached; sometimes the - kernel doesn't let us at the registers. */ - char *err = strerror (errno); - char *msg = alloca (strlen (err) + 128); - sprintf (msg, "writing register %d: %s", - regno, err); - error (msg); - return; - } - regaddr += sizeof (int); - } } else - for (regno = 0; regno < NUM_REGS - NUM_FREGS; regno++) + for (regno = 0; regno < num_regs; regno++) store_inferior_registers (regno); } -/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory - in the NEW_SUN_PTRACE case. - It ought to be straightforward. But it appears that writing did - not write the data that I specified. I cannot understand where - it got the data that it actually did write. */ - /* Copy LEN bytes from inferior's memory starting at MEMADDR to debugger memory starting at MYADDR. */ @@ -772,5 +339,5 @@ write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) void initialize_low (void) { - initialize_arch (); + init_registers (); } diff --git a/gdb/gdbserver/linux-m68k-low.c b/gdb/gdbserver/linux-m68k-low.c new file mode 100644 index 00000000000..334084ad61c --- /dev/null +++ b/gdb/gdbserver/linux-m68k-low.c @@ -0,0 +1,64 @@ +/* GNU/Linux/m68k specific low level interface, for the remote server for GDB. + Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "server.h" + +#ifdef HAVE_SYS_REG_H +#include +#endif + +int num_regs = 31; + +/* This table must line up with REGISTER_NAMES in tm-m68k.h */ +int regmap[] = +{ +#ifdef PT_D0 + PT_D0 * 4, PT_D1 * 4, PT_D2 * 4, PT_D3 * 4, + PT_D4 * 4, PT_D5 * 4, PT_D6 * 4, PT_D7 * 4, + PT_A0 * 4, PT_A1 * 4, PT_A2 * 4, PT_A3 * 4, + PT_A4 * 4, PT_A5 * 4, PT_A6 * 4, PT_USP * 4, + PT_SR * 4, PT_PC * 4, +#else + 14 * 4, 0 * 4, 1 * 4, 2 * 4, 3 * 4, 4 * 4, 5 * 4, 6 * 4, + 7 * 4, 8 * 4, 9 * 4, 10 * 4, 11 * 4, 12 * 4, 13 * 4, 15 * 4, + 17 * 4, 18 * 4, +#endif +#ifdef PT_FP0 + PT_FP0 * 4, PT_FP1 * 4, PT_FP2 * 4, PT_FP3 * 4, + PT_FP4 * 4, PT_FP5 * 4, PT_FP6 * 4, PT_FP7 * 4, + PT_FPCR * 4, PT_FPSR * 4, PT_FPIAR * 4 +#else + 21 * 4, 24 * 4, 27 * 4, 30 * 4, 33 * 4, 36 * 4, + 39 * 4, 42 * 4, 45 * 4, 46 * 4, 47 * 4 +#endif +}; + +int +cannot_store_register (int regno) +{ + return (regno >= num_regs); +} + +int +cannot_fetch_register (int regno) +{ + return (regno >= num_regs); +} diff --git a/gdb/gdbserver/linux-mips-low.c b/gdb/gdbserver/linux-mips-low.c new file mode 100644 index 00000000000..ef14c6a9d6e --- /dev/null +++ b/gdb/gdbserver/linux-mips-low.c @@ -0,0 +1,104 @@ +/* GNU/Linux/MIPS specific low level interface, for the remote server for GDB. + Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "server.h" + +#ifdef HAVE_SYS_REG_H +#include +#endif + +int num_regs = 90; + +#include + +/* Return the ptrace ``address'' of register REGNO. */ + +/* Matches mips_generic32_regs */ +int regmap[] = { + 0, 1, 2, 3, 4, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, + + -1, MMLO, MMHI, BADVADDR, CAUSE, PC, + + FPR_BASE, FPR_BASE + 1, FPR_BASE + 2, FPR_BASE + 3, + FPR_BASE + 4, FPR_BASE + 5, FPR_BASE + 6, FPR_BASE + 7, + FPR_BASE + 8, FPR_BASE + 8, FPR_BASE + 10, FPR_BASE + 11, + FPR_BASE + 12, FPR_BASE + 13, FPR_BASE + 14, FPR_BASE + 15, + FPR_BASE + 16, FPR_BASE + 17, FPR_BASE + 18, FPR_BASE + 19, + FPR_BASE + 20, FPR_BASE + 21, FPR_BASE + 22, FPR_BASE + 23, + FPR_BASE + 24, FPR_BASE + 25, FPR_BASE + 26, FPR_BASE + 27, + FPR_BASE + 28, FPR_BASE + 29, FPR_BASE + 30, FPR_BASE + 31, + FPC_CSR, FPC_EIR, + + -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, +}; + +/* From mips-linux-nat.c. */ + +/* Pseudo registers can not be read. ptrace does not provide a way to + read (or set) PS_REGNUM, and there's no point in reading or setting + ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or FCRIR via + ptrace(). */ + +int +cannot_fetch_register (int regno) +{ + struct reg *reg; + + if (regmap[regno] == -1) + return 1; + + reg = find_register_by_number (regno); + + if (strcmp (reg->name, "zero") == 0) + return 1; + + return 0; +} + +int +cannot_store_register (int regno) +{ + struct reg *reg; + + if (regmap[regno] == -1) + return 1; + + reg = find_register_by_number (regno); + + if (strcmp (reg->name, "zero") == 0) + return 1; + + if (strcmp (reg->name, "cause") == 0) + return 1; + + if (strcmp (reg->name, "bad") == 0) + return 1; + + if (strcmp (reg->name, "fir") == 0) + return 1; + + return 0; +} diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c new file mode 100644 index 00000000000..38f7b70a80a --- /dev/null +++ b/gdb/gdbserver/linux-ppc-low.c @@ -0,0 +1,61 @@ +/* GNU/Linux/PowerPC specific low level interface, for the remote server for + GDB. + Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "server.h" + +#include + +int num_regs = 71; + +/* Currently, don't check/send MQ. */ +int regmap[] = + {PT_R0 * 4, PT_R1 * 4, PT_R2 * 4, PT_R3 * 4, + PT_R4 * 4, PT_R5 * 4, PT_R6 * 4, PT_R7 * 4, + PT_R8 * 4, PT_R9 * 4, PT_R10 * 4, PT_R11 * 4, + PT_R12 * 4, PT_R13 * 4, PT_R14 * 4, PT_R15 * 4, + PT_R16 * 4, PT_R17 * 4, PT_R18 * 4, PT_R19 * 4, + PT_R20 * 4, PT_R21 * 4, PT_R22 * 4, PT_R23 * 4, + PT_R24 * 4, PT_R25 * 4, PT_R26 * 4, PT_R27 * 4, + PT_R28 * 4, PT_R29 * 4, PT_R30 * 4, PT_R31 * 4, + PT_FPR0*4, PT_FPR0*4 + 8, PT_FPR0*4+16, PT_FPR0*4+24, + PT_FPR0*4+32, PT_FPR0*4+40, PT_FPR0*4+48, PT_FPR0*4+56, + PT_FPR0*4+64, PT_FPR0*4+72, PT_FPR0*4+80, PT_FPR0*4+88, + PT_FPR0*4+96, PT_FPR0*4+104, PT_FPR0*4+112, PT_FPR0*4+120, + PT_FPR0*4+128, PT_FPR0*4+136, PT_FPR0*4+144, PT_FPR0*4+152, + PT_FPR0*4+160, PT_FPR0*4+168, PT_FPR0*4+176, PT_FPR0*4+184, + PT_FPR0*4+192, PT_FPR0*4+200, PT_FPR0*4+208, PT_FPR0*4+216, + PT_FPR0*4+224, PT_FPR0*4+232, PT_FPR0*4+240, PT_FPR0*4+248, + PT_NIP * 4, PT_MSR * 4, PT_CCR * 4, PT_LNK * 4, + PT_CTR * 4, PT_XER * 4, -1, }; + +int +cannot_store_register (int regno) +{ + return 0; +} + +int +cannot_fetch_register (int regno) +{ + return 0; +} + diff --git a/gdb/gdbserver/linux-sh-low.c b/gdb/gdbserver/linux-sh-low.c new file mode 100644 index 00000000000..9fdb75700a9 --- /dev/null +++ b/gdb/gdbserver/linux-sh-low.c @@ -0,0 +1,58 @@ +/* GNU/Linux/SH specific low level interface, for the remote server for GDB. + Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "server.h" + +#ifdef HAVE_SYS_REG_H +#include +#endif + +#include + +int num_regs = 41; + +/* Currently, don't check/send MQ. */ +int regmap[] = { + 0, 4, 8, 12, 16, 20, 24, 28, + 32, 36, 40, 44, 48, 52, 56, 60, + + REG_PC*4, REG_PR*4, REG_GBR*4, -1, + REG_MACH*4, REG_MACL*4, REG_SR*4, + REG_FPUL*4, REG_FPSCR*4, + + REG_FPREG0+0, REG_FPREG0+4, REG_FPREG0+8, REG_FPREG0+12, + REG_FPREG0+16, REG_FPREG0+20, REG_FPREG0+24, REG_FPREG0+28, + REG_FPREG0+32, REG_FPREG0+36, REG_FPREG0+40, REG_FPREG0+44, + REG_FPREG0+48, REG_FPREG0+52, REG_FPREG0+56, REG_FPREG0+60, +}; + +int +cannot_store_register (int regno) +{ + return 0; +} + +int +cannot_fetch_register (int regno) +{ + return 0; +} + diff --git a/gdb/gdbserver/low-linux.c b/gdb/gdbserver/low-linux.c deleted file mode 100644 index 726e276540d..00000000000 --- a/gdb/gdbserver/low-linux.c +++ /dev/null @@ -1,777 +0,0 @@ -/* Low level interface to ptrace, for the remote server for GDB. - Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "server.h" -#include -#include "frame.h" -#include "inferior.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -/***************Begin MY defs*********************/ -static char my_registers[REGISTER_BYTES]; -char *registers = my_registers; -/***************End MY defs*********************/ - -#ifdef HAVE_SYS_REG_H -#include -#endif - -/* Default the type of the ptrace transfer to int. */ -#ifndef PTRACE_XFER_TYPE -#define PTRACE_XFER_TYPE int -#endif - -extern int errno; - -static void initialize_arch (void); - -/* Start an inferior process and returns its pid. - ALLARGS is a vector of program-name and args. */ - -int -create_inferior (char *program, char **allargs) -{ - int pid; - - pid = fork (); - if (pid < 0) - perror_with_name ("fork"); - - if (pid == 0) - { - ptrace (PTRACE_TRACEME, 0, 0, 0); - - execv (program, allargs); - - fprintf (stderr, "Cannot exec %s: %s.\n", program, - errno < sys_nerr ? sys_errlist[errno] : "unknown error"); - fflush (stderr); - _exit (0177); - } - - return pid; -} - -/* Attach to an inferior process. */ - -int -myattach (int pid) -{ - if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0) - { - fprintf (stderr, "Cannot attach to process %d: %s (%d)\n", pid, - errno < sys_nerr ? sys_errlist[errno] : "unknown error", - errno); - fflush (stderr); - _exit (0177); - } - - return 0; -} - -/* Kill the inferior process. Make us have no inferior. */ - -void -kill_inferior (void) -{ - if (inferior_pid == 0) - return; - ptrace (PTRACE_KILL, inferior_pid, 0, 0); - wait (0); -/*************inferior_died ();****VK**************/ -} - -/* Return nonzero if the given thread is still alive. */ -int -mythread_alive (int pid) -{ - return 1; -} - -/* Wait for process, returns status */ - -unsigned char -mywait (char *status) -{ - int pid; - union wait w; - - enable_async_io (); - pid = waitpid (inferior_pid, &w, 0); - disable_async_io (); - if (pid != inferior_pid) - perror_with_name ("wait"); - - if (WIFEXITED (w)) - { - fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w)); - *status = 'W'; - return ((unsigned char) WEXITSTATUS (w)); - } - else if (!WIFSTOPPED (w)) - { - fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w)); - *status = 'X'; - return ((unsigned char) WTERMSIG (w)); - } - - fetch_inferior_registers (0); - - *status = 'T'; - return ((unsigned char) WSTOPSIG (w)); -} - -/* Resume execution of the inferior process. - If STEP is nonzero, single-step it. - If SIGNAL is nonzero, give it that signal. */ - -void -myresume (int step, int signal) -{ - errno = 0; - ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal); - if (errno) - perror_with_name ("ptrace"); -} - - -#if !defined (offsetof) -#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) -#endif - -/* U_REGS_OFFSET is the offset of the registers within the u area. */ -#if !defined (U_REGS_OFFSET) -#define U_REGS_OFFSET \ - ptrace (PT_READ_U, inferior_pid, \ - (PTRACE_ARG3_TYPE) (offsetof (struct user, u_ar0)), 0) \ - - KERNEL_U_ADDR -#endif - -#ifdef I386_GNULINUX_TARGET -/* This module only supports access to the general purpose registers. - Adjust the relevant constants accordingly. - - FIXME: kettenis/2001-03-28: We should really use PTRACE_GETREGS to - get at the registers. Better yet, we should try to share code with - i386-linux-nat.c. */ -#undef NUM_FREGS -#define NUM_FREGS 0 -#undef NUM_REGS -#define NUM_REGS NUM_GREGS - -/* This stuff comes from i386-tdep.c. */ - -/* i386_register_byte[i] is the offset into the register file of the - start of register number i. We initialize this from - i386_register_raw_size. */ -int i386_register_byte[MAX_NUM_REGS]; - -/* i386_register_raw_size[i] is the number of bytes of storage in - GDB's register array occupied by register i. */ -int i386_register_raw_size[MAX_NUM_REGS] = { - 4, 4, 4, 4, - 4, 4, 4, 4, - 4, 4, 4, 4, - 4, 4, 4, 4, - 10, 10, 10, 10, - 10, 10, 10, 10, - 4, 4, 4, 4, - 4, 4, 4, 4, - 16, 16, 16, 16, - 16, 16, 16, 16, - 4 -}; - -static void -initialize_arch (void) -{ - /* Initialize the table saying where each register starts in the - register file. */ - { - int i, offset; - - offset = 0; - for (i = 0; i < MAX_NUM_REGS; i++) - { - i386_register_byte[i] = offset; - offset += i386_register_raw_size[i]; - } - } -} - -/* This stuff comes from i386-linux-nat.c. */ - -/* Mapping between the general-purpose registers in `struct user' - format and GDB's register array layout. */ -static int regmap[] = -{ - EAX, ECX, EDX, EBX, - UESP, EBP, ESI, EDI, - EIP, EFL, CS, SS, - DS, ES, FS, GS -}; - -/* Return the address of register REGNUM. BLOCKEND is the value of - u.u_ar0, which should point to the registers. */ - -CORE_ADDR -register_u_addr (CORE_ADDR blockend, int regnum) -{ - return (blockend + 4 * regmap[regnum]); -} -#elif defined(TARGET_M68K) -static void -initialize_arch (void) -{ - return; -} - -/* This table must line up with REGISTER_NAMES in tm-m68k.h */ -static int regmap[] = -{ -#ifdef PT_D0 - PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7, - PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP, - PT_SR, PT_PC, -#else - 14, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 15, - 17, 18, -#endif -#ifdef PT_FP0 - PT_FP0, PT_FP1, PT_FP2, PT_FP3, PT_FP4, PT_FP5, PT_FP6, PT_FP7, - PT_FPCR, PT_FPSR, PT_FPIAR -#else - 21, 24, 27, 30, 33, 36, 39, 42, 45, 46, 47 -#endif -}; - -/* BLOCKEND is the value of u.u_ar0, and points to the place where GS - is stored. */ - -int -m68k_linux_register_u_addr (int blockend, int regnum) -{ - return (blockend + 4 * regmap[regnum]); -} -#elif defined(IA64_GNULINUX_TARGET) -#undef NUM_FREGS -#define NUM_FREGS 0 - -#include - -static int u_offsets[] = - { - /* general registers */ - -1, /* gr0 not available; i.e, it's always zero */ - PT_R1, - PT_R2, - PT_R3, - PT_R4, - PT_R5, - PT_R6, - PT_R7, - PT_R8, - PT_R9, - PT_R10, - PT_R11, - PT_R12, - PT_R13, - PT_R14, - PT_R15, - PT_R16, - PT_R17, - PT_R18, - PT_R19, - PT_R20, - PT_R21, - PT_R22, - PT_R23, - PT_R24, - PT_R25, - PT_R26, - PT_R27, - PT_R28, - PT_R29, - PT_R30, - PT_R31, - /* gr32 through gr127 not directly available via the ptrace interface */ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - /* Floating point registers */ - -1, -1, /* f0 and f1 not available (f0 is +0.0 and f1 is +1.0) */ - PT_F2, - PT_F3, - PT_F4, - PT_F5, - PT_F6, - PT_F7, - PT_F8, - PT_F9, - PT_F10, - PT_F11, - PT_F12, - PT_F13, - PT_F14, - PT_F15, - PT_F16, - PT_F17, - PT_F18, - PT_F19, - PT_F20, - PT_F21, - PT_F22, - PT_F23, - PT_F24, - PT_F25, - PT_F26, - PT_F27, - PT_F28, - PT_F29, - PT_F30, - PT_F31, - PT_F32, - PT_F33, - PT_F34, - PT_F35, - PT_F36, - PT_F37, - PT_F38, - PT_F39, - PT_F40, - PT_F41, - PT_F42, - PT_F43, - PT_F44, - PT_F45, - PT_F46, - PT_F47, - PT_F48, - PT_F49, - PT_F50, - PT_F51, - PT_F52, - PT_F53, - PT_F54, - PT_F55, - PT_F56, - PT_F57, - PT_F58, - PT_F59, - PT_F60, - PT_F61, - PT_F62, - PT_F63, - PT_F64, - PT_F65, - PT_F66, - PT_F67, - PT_F68, - PT_F69, - PT_F70, - PT_F71, - PT_F72, - PT_F73, - PT_F74, - PT_F75, - PT_F76, - PT_F77, - PT_F78, - PT_F79, - PT_F80, - PT_F81, - PT_F82, - PT_F83, - PT_F84, - PT_F85, - PT_F86, - PT_F87, - PT_F88, - PT_F89, - PT_F90, - PT_F91, - PT_F92, - PT_F93, - PT_F94, - PT_F95, - PT_F96, - PT_F97, - PT_F98, - PT_F99, - PT_F100, - PT_F101, - PT_F102, - PT_F103, - PT_F104, - PT_F105, - PT_F106, - PT_F107, - PT_F108, - PT_F109, - PT_F110, - PT_F111, - PT_F112, - PT_F113, - PT_F114, - PT_F115, - PT_F116, - PT_F117, - PT_F118, - PT_F119, - PT_F120, - PT_F121, - PT_F122, - PT_F123, - PT_F124, - PT_F125, - PT_F126, - PT_F127, - /* predicate registers - we don't fetch these individually */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - /* branch registers */ - PT_B0, - PT_B1, - PT_B2, - PT_B3, - PT_B4, - PT_B5, - PT_B6, - PT_B7, - /* virtual frame pointer and virtual return address pointer */ - -1, -1, - /* other registers */ - PT_PR, - PT_CR_IIP, /* ip */ - PT_CR_IPSR, /* psr */ - PT_CFM, /* cfm */ - /* kernel registers not visible via ptrace interface (?) */ - -1, -1, -1, -1, -1, -1, -1, -1, - /* hole */ - -1, -1, -1, -1, -1, -1, -1, -1, - PT_AR_RSC, - PT_AR_BSP, - PT_AR_BSPSTORE, - PT_AR_RNAT, - -1, - -1, /* Not available: FCR, IA32 floating control register */ - -1, -1, - -1, /* Not available: EFLAG */ - -1, /* Not available: CSD */ - -1, /* Not available: SSD */ - -1, /* Not available: CFLG */ - -1, /* Not available: FSR */ - -1, /* Not available: FIR */ - -1, /* Not available: FDR */ - -1, - PT_AR_CCV, - -1, -1, -1, - PT_AR_UNAT, - -1, -1, -1, - PT_AR_FPSR, - -1, -1, -1, - -1, /* Not available: ITC */ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, - PT_AR_PFS, - PT_AR_LC, - -1, /* Not available: EC, the Epilog Count register */ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, - /* nat bits - not fetched directly; instead we obtain these bits from - either rnat or unat or from memory. */ - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - }; - -int -ia64_register_u_addr (int blockend, int regnum) -{ - int addr; - - if (regnum < 0 || regnum >= NUM_REGS) - error ("Invalid register number %d.", regnum); - - addr = u_offsets[regnum]; - if (addr == -1) - addr = 0; - - return addr; -} - -static void -initialize_arch (void) -{ - return; -} - -#elif defined(ARM_GNULINUX_TARGET) -int arm_register_u_addr(blockend, regnum) - int blockend; - int regnum; -{ - return blockend + REGISTER_BYTE(regnum); -} - -static void -initialize_arch () -{ -} -#endif - -CORE_ADDR -register_addr (int regno, CORE_ADDR blockend) -{ - CORE_ADDR addr; - - if (regno < 0 || regno >= NUM_REGS) - error ("Invalid register number %d.", regno); - - REGISTER_U_ADDR (addr, blockend, regno); - - return addr; -} - -/* Fetch one register. */ - -static void -fetch_register (int regno) -{ - CORE_ADDR regaddr; - register int i; - - /* Offset of registers within the u area. */ - unsigned int offset; - - offset = U_REGS_OFFSET; - - regaddr = register_addr (regno, offset); - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (PTRACE_XFER_TYPE)) - { - errno = 0; - *(PTRACE_XFER_TYPE *) ®isters[REGISTER_BYTE (regno) + i] = - ptrace (PTRACE_PEEKUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, 0); - regaddr += sizeof (PTRACE_XFER_TYPE); - if (errno != 0) - { - /* Warning, not error, in case we are attached; sometimes the - kernel doesn't let us at the registers. */ - char *err = strerror (errno); - char *msg = alloca (strlen (err) + 128); - sprintf (msg, "reading register %d: %s", regno, err); - error (msg); - goto error_exit; - } - } -error_exit:; -} - -/* Fetch all registers, or just one, from the child process. */ - -void -fetch_inferior_registers (int regno) -{ - if (regno == -1 || regno == 0) - for (regno = 0; regno < NUM_REGS - NUM_FREGS; regno++) - fetch_register (regno); - else - fetch_register (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) -{ - CORE_ADDR regaddr; - int i; - unsigned int offset = U_REGS_OFFSET; - - if (regno >= 0) - { -#if 0 - if (CANNOT_STORE_REGISTER (regno)) - return; -#endif - regaddr = register_addr (regno, offset); - errno = 0; -#if 0 - if (regno == PCOQ_HEAD_REGNUM || regno == PCOQ_TAIL_REGNUM) - { - scratch = *(int *) ®isters[REGISTER_BYTE (regno)] | 0x3; - ptrace (PT_WUREGS, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, - scratch, 0); - if (errno != 0) - { - /* Error, even if attached. Failing to write these two - registers is pretty serious. */ - sprintf (buf, "writing register number %d", regno); - perror_with_name (buf); - } - } - else -#endif - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) - { - errno = 0; - ptrace (PTRACE_POKEUSER, inferior_pid, (PTRACE_ARG3_TYPE) regaddr, - *(int *) ®isters[REGISTER_BYTE (regno) + i]); - if (errno != 0) - { - /* Warning, not error, in case we are attached; sometimes the - kernel doesn't let us at the registers. */ - char *err = strerror (errno); - char *msg = alloca (strlen (err) + 128); - sprintf (msg, "writing register %d: %s", - regno, err); - error (msg); - return; - } - regaddr += sizeof (int); - } - } - else - for (regno = 0; regno < NUM_REGS - NUM_FREGS; regno++) - store_inferior_registers (regno); -} - -/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory - in the NEW_SUN_PTRACE case. - It ought to be straightforward. But it appears that writing did - not write the data that I specified. I cannot understand where - it got the data that it actually did write. */ - -/* Copy LEN bytes from inferior's memory starting at MEMADDR - to debugger memory starting at MYADDR. */ - -void -read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) -{ - register int i; - /* Round starting address down to longword boundary. */ - register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE); - /* Round ending address up; get number of longwords that makes. */ - register int count - = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) - / sizeof (PTRACE_XFER_TYPE); - /* Allocate buffer of that many longwords. */ - register PTRACE_XFER_TYPE *buffer - = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); - - /* Read all the longwords */ - for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) - { - buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0); - } - - /* Copy appropriate bytes out of the buffer. */ - memcpy (myaddr, (char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), len); -} - -/* Copy LEN bytes of data from debugger memory at MYADDR - to inferior's memory at MEMADDR. - On failure (cannot write the inferior) - returns the value of errno. */ - -int -write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len) -{ - register int i; - /* Round starting address down to longword boundary. */ - register CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_XFER_TYPE); - /* Round ending address up; get number of longwords that makes. */ - register int count - = (((memaddr + len) - addr) + sizeof (PTRACE_XFER_TYPE) - 1) / sizeof (PTRACE_XFER_TYPE); - /* Allocate buffer of that many longwords. */ - register PTRACE_XFER_TYPE *buffer = (PTRACE_XFER_TYPE *) alloca (count * sizeof (PTRACE_XFER_TYPE)); - extern int errno; - - /* Fill start and end extra bytes of buffer with existing memory data. */ - - buffer[0] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0); - - if (count > 1) - { - buffer[count - 1] - = ptrace (PTRACE_PEEKTEXT, inferior_pid, - addr + (count - 1) * sizeof (PTRACE_XFER_TYPE), 0); - } - - /* Copy data to be written over corresponding part of buffer */ - - memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_XFER_TYPE) - 1)), myaddr, len); - - /* Write the entire buffer. */ - - for (i = 0; i < count; i++, addr += sizeof (PTRACE_XFER_TYPE)) - { - errno = 0; - ptrace (PTRACE_POKETEXT, inferior_pid, addr, buffer[i]); - if (errno) - return errno; - } - - return 0; -} - -void -initialize_low (void) -{ - initialize_arch (); -} diff --git a/gdb/gdbserver/regcache.c b/gdb/gdbserver/regcache.c new file mode 100644 index 00000000000..551a71a349a --- /dev/null +++ b/gdb/gdbserver/regcache.c @@ -0,0 +1,124 @@ +/* Register support routines for the remote server for GDB. + Copyright 2001, 2002 + Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include "server.h" +#include "regdef.h" + +#include +#include + +static char *registers; +static int register_bytes; + +static struct reg *reg_defs; +static int num_registers; + +const char **gdbserver_expedite_regs; + +int +registers_length (void) +{ + return 2 * register_bytes; +} + +void +set_register_cache (struct reg *regs, int n) +{ + int offset, i; + + reg_defs = regs; + num_registers = n; + + offset = 0; + for (i = 0; i < n; i++) + { + regs[i].offset = offset; + offset += regs[i].size; + } + + register_bytes = offset / 8; + registers = malloc (offset / 8); + if (!registers) + fatal ("Could not allocate register cache."); +} + +void +registers_to_string (char *buf) +{ + convert_int_to_ascii (registers, buf, register_bytes); +} + +void +registers_from_string (char *buf) +{ + int len = strlen (buf); + + if (len != register_bytes * 2) + { + warning ("Wrong sized register packet (expected %d bytes, got %d)", 2*register_bytes, len); + if (len > register_bytes * 2) + len = register_bytes * 2; + } + convert_ascii_to_int (buf, registers, len / 2); +} + +struct reg * +find_register_by_name (const char *name) +{ + int i; + + for (i = 0; i < num_registers; i++) + if (!strcmp (name, reg_defs[i].name)) + return ®_defs[i]; + fatal ("Unknown register %s requested", name); + return 0; +} + +int +find_regno (const char *name) +{ + int i; + + for (i = 0; i < num_registers; i++) + if (!strcmp (name, reg_defs[i].name)) + return i; + fatal ("Unknown register %s requested", name); + return -1; +} + +struct reg * +find_register_by_number (int n) +{ + return ®_defs[n]; +} + +int +register_size (int n) +{ + return reg_defs[n].size / 8; +} + +char * +register_data (int n) +{ + return registers + (reg_defs[n].offset / 8); +} + diff --git a/gdb/gdbserver/regcache.h b/gdb/gdbserver/regcache.h new file mode 100644 index 00000000000..07195b3f44e --- /dev/null +++ b/gdb/gdbserver/regcache.h @@ -0,0 +1,49 @@ +/* Register support routines for the remote server for GDB. + Copyright 2001, 2002 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef REGCACHE_H +#define REGCACHE_H + +/* Convert all registers to a string in the currently specified remote + format. */ + +void registers_to_string (char *buf); + +/* Convert a string to register values and fill our register cache. */ + +void registers_from_string (char *buf); + +/* Return the size in bytes of a string-encoded register packet. */ + +int registers_length (void); + +/* Return a pointer to the description of register ``n''. */ + +struct reg *find_register_by_number (int n); + +char *register_data (int n); + +int register_size (int n); + +int find_regno (const char *name); + +extern const char **gdbserver_expedite_regs; + +#endif /* REGCACHE_H */ diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c index cfde0a7dae4..ff1718fc089 100644 --- a/gdb/gdbserver/remote-utils.c +++ b/gdb/gdbserver/remote-utils.c @@ -1,5 +1,6 @@ /* Remote utility routines for the remote server for GDB. - Copyright 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Copyright 1986, 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, + 2002 Free Software Foundation, Inc. This file is part of GDB. @@ -183,6 +184,7 @@ fromhex (int a) return a - 'a' + 10; else error ("Reply contains invalid hex digit"); + return 0; } /* Convert number NIB to a hex digit. */ @@ -204,11 +206,13 @@ putpkt (char *buf) { int i; unsigned char csum = 0; - char buf2[PBUFSIZ]; + char *buf2; char buf3[1]; int cnt = strlen (buf); char *p; + buf2 = malloc (PBUFSIZ); + /* Copy the packet into buffer BUF2, encapsulating it and giving it a checksum. */ @@ -250,11 +254,13 @@ putpkt (char *buf) else perror ("putpkt(read)"); + free (buf2); return -1; } } while (buf3[0] != '+'); + free (buf2); return 1; /* Success! */ } @@ -264,7 +270,7 @@ putpkt (char *buf) will cause us to send a SIGINT to the child. */ static void -input_interrupt (void) +input_interrupt (int unused) { fd_set readset; struct timeval immediate = { 0, 0 }; @@ -440,7 +446,7 @@ convert_ascii_to_int (char *from, char *to, int n) static char * outreg (int regno, char *buf) { - int regsize = REGISTER_RAW_SIZE (regno); + int regsize = register_size (regno); if ((regno >> 12) != 0) *buf++ = tohex ((regno >> 12) & 0xf); @@ -449,7 +455,7 @@ outreg (int regno, char *buf) *buf++ = tohex ((regno >> 4) & 0xf); *buf++ = tohex (regno & 0xf); *buf++ = ':'; - convert_int_to_ascii (®isters[REGISTER_BYTE (regno)], buf, regsize); + convert_int_to_ascii (register_data (regno), buf, regsize); buf += 2 * regsize; *buf++ = ';'; @@ -474,30 +480,15 @@ prepare_resume_reply (char *buf, char status, unsigned char signo) if (status == 'T') { -#ifdef GDBSERVER_RESUME_REGS - static int gdbserver_resume_regs[] = GDBSERVER_RESUME_REGS ; - int i; - for (i = 0; - i < sizeof (gdbserver_resume_regs) - / sizeof (gdbserver_resume_regs[0]); - i++) + const char **regp = gdbserver_expedite_regs; + while (*regp) { - int regnum = gdbserver_resume_regs[i]; - buf = outreg (regnum, buf); + buf = outreg (find_regno (*regp), buf); + regp ++; } -#else /* !defined(GDBSERVER_RESUME_REGS) */ - buf = outreg (PC_REGNUM, buf); - buf = outreg (FP_REGNUM, buf); - buf = outreg (SP_REGNUM, buf); - if (NPC_REGNUM >= 0) - buf = outreg (NPC_REGNUM, buf); -#ifdef O7_REGNUM - buf = outreg (O7_REGNUM, buf); -#endif -#endif /* GDBSERVER_RESUME_REGS */ /* If the debugger hasn't used any thread features, don't burden it with - threads. If we didn't check this, GDB 4.13 and older would choke. */ + threads. If we didn't check this, GDB 4.13 and older would choke. */ if (cont_thread != 0) { if (old_thread_from_wait != thread_from_wait) diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c index d995127a223..d845422a698 100644 --- a/gdb/gdbserver/server.c +++ b/gdb/gdbserver/server.c @@ -59,7 +59,7 @@ extern int remote_debug; int main (int argc, char *argv[]) { - char ch, status, own_buf[PBUFSIZ], mem_buf[2000]; + char ch, status, *own_buf, mem_buf[2000]; int i = 0; unsigned char signal; unsigned int len; @@ -94,6 +94,8 @@ main (int argc, char *argv[]) initialize_low (); + own_buf = malloc (PBUFSIZ); + if (pid == 0) { /* Wait till we are at first instruction in program. */ @@ -167,10 +169,10 @@ main (int argc, char *argv[]) } break; case 'g': - convert_int_to_ascii (registers, own_buf, REGISTER_BYTES); + registers_to_string (own_buf); break; case 'G': - convert_ascii_to_int (&own_buf[1], registers, REGISTER_BYTES); + registers_from_string (&own_buf[1]); store_inferior_registers (-1); write_ok (own_buf); break; diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h index 2e0b7ba15f2..6202b0fc1ae 100644 --- a/gdb/gdbserver/server.h +++ b/gdb/gdbserver/server.h @@ -1,5 +1,5 @@ /* Common definitions for remote server for GDB. - Copyright 1993, 1995, 1997, 1998, 1999, 2000 + Copyright 1993, 1995, 1997, 1998, 1999, 2000, 2002 Free Software Foundation, Inc. This file is part of GDB. @@ -19,7 +19,22 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "defs.h" +#ifndef SERVER_H +#define SERVER_H + +#include "config.h" +#include +#include +#include +#include + + +/* FIXME: Both of these should be autoconf'd for. */ +#define NORETURN +typedef long long CORE_ADDR; + +#include "regcache.h" + #include /* Target-specific functions */ @@ -73,6 +88,10 @@ void decode_M_packet (char *from, CORE_ADDR * mem_addr_ptr, /* Functions from utils.c */ void perror_with_name (char *string); +void error (const char *string,...); +void fatal (const char *string,...); +void warning (const char *string,...); + /* Maximum number of bytes to read/write at once. The value here @@ -81,6 +100,8 @@ void perror_with_name (char *string); /* Buffer sizes for transferring memory, registers, etc. Round up PBUFSIZ to hold all the registers, at least. */ -#define PBUFSIZ ((REGISTER_BYTES > MAXBUFBYTES (2000)) \ - ? (REGISTER_BYTES * 2 + 32) \ +#define PBUFSIZ ((registers_length () + 32 > 2000) \ + ? (registers_length () + 32) \ : 2000) + +#endif /* SERVER_H */ diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c index cd9f8c39208..a8ea9a15f8b 100644 --- a/gdb/gdbserver/utils.c +++ b/gdb/gdbserver/utils.c @@ -1,5 +1,5 @@ /* General utility routines for the remote server for GDB. - Copyright 1986, 1989, 1993, 1995, 1996, 1997, 1999, 2000 + Copyright 1986, 1989, 1993, 1995, 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc. This file is part of GDB. @@ -75,7 +75,7 @@ error (const char *string,...) /* VARARGS */ NORETURN void -fatal (char *string,...) +fatal (const char *string,...) { va_list args; va_start (args, string); @@ -85,3 +85,15 @@ fatal (char *string,...) va_end (args); exit (1); } + +/* VARARGS */ +void +warning (const char *string,...) +{ + va_list args; + va_start (args, string); + fprintf (stderr, "gdb: "); + vfprintf (stderr, string, args); + fprintf (stderr, "\n"); + va_end (args); +} diff --git a/gdb/regformats/regdat.sh b/gdb/regformats/regdat.sh index eb0475e4ddb..9035b3dc90d 100755 --- a/gdb/regformats/regdat.sh +++ b/gdb/regformats/regdat.sh @@ -123,6 +123,7 @@ EOF exec > new-$2 copyright $1 echo '#include "regdef.h"' +echo '#include "regcache.h"' echo offset=0 i=0 @@ -151,6 +152,17 @@ done echo "};" echo echo "const char *expedite_regs_${name}[] = { \"`echo ${expedite} | sed 's/,/", "/g'`\", 0 };" +echo + +cat <&2 diff --git a/gdb/regformats/regdef.h b/gdb/regformats/regdef.h index 17174ee3c67..c1f862cc356 100644 --- a/gdb/regformats/regdef.h +++ b/gdb/regformats/regdef.h @@ -18,6 +18,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#ifndef REGDEF_H +#define REGDEF_H + struct reg { /* The name of this register - NULL for pad entries. */ @@ -34,3 +37,10 @@ struct reg /* The size (in bits) of the value of this register, as transmitted. */ int size; }; + +/* Set the current remote protocol and register cache according to the array + ``regs'', with ``n'' elements. */ + +void set_register_cache (struct reg *regs, int n); + +#endif /* REGDEF_H */