aboutsummaryrefslogtreecommitdiff
path: root/gdb/gdbserver
diff options
context:
space:
mode:
authornobody <>2002-05-06 21:00:22 +0000
committernobody <>2002-05-06 21:00:22 +0000
commit275602c398b33b8475860af024b006bbbbd495ac (patch)
tree22412a7722268bd297101bcf3e788a3d585c020c /gdb/gdbserver
parent694b26b8e881dd7336e3c0634731f2eee1c1cda6 (diff)
downloadgdb-275602c398b33b8475860af024b006bbbbd495ac.zip
gdb-275602c398b33b8475860af024b006bbbbd495ac.tar.gz
gdb-275602c398b33b8475860af024b006bbbbd495ac.tar.bz2
This commit was manufactured by cvs2svn to create branch 'jimb-jimb-macro-020506-branchpoint
macro-020506-branch'. Sprout from gdb_5_2-branch 2002-03-27 05:12:36 UTC nobody 'This commit was manufactured by cvs2svn to create branch 'gdb_5_2-branch'.' Cherrypick from gdb_5_2-branch 2002-03-02 23:00:05 UTC nobody 'This commit was manufactured by cvs2svn to create branch 'gdb_5_2-branch'.': intl/ChangeLog intl/Makefile.in Cherrypick from master 2002-05-06 21:00:21 UTC Jim Blandy <jimb@codesourcery.com> 'Separate the job of reading the line number info statement program': ChangeLog MAINTAINERS Makefile.in bfd/ChangeLog bfd/ChangeLog-9495 bfd/Makefile.am bfd/Makefile.in bfd/aix5ppc-core.c bfd/aout-adobe.c bfd/aout-target.h bfd/aout-tic30.c bfd/aoutx.h bfd/archive.c bfd/archures.c bfd/bfd-in.h bfd/bfd-in2.h bfd/bfd.c bfd/binary.c bfd/bout.c bfd/coff-arm.c bfd/coff-h8300.c bfd/coff-mcore.c bfd/coff-ppc.c bfd/coff-rs6000.c bfd/coff-sh.c bfd/coff-z8k.c bfd/coff64-rs6000.c bfd/coffcode.h bfd/cofflink.c bfd/coffswap.h bfd/config.bfd bfd/configure bfd/configure.in bfd/cpu-h8300.c bfd/cpu-i370.c bfd/cpu-i386.c bfd/cpu-mips.c bfd/cpu-powerpc.c bfd/cpu-s390.c bfd/cpu-sh.c bfd/cpu-sparc.c bfd/dep-in.sed bfd/doc/ChangeLog bfd/doc/Makefile.in bfd/dwarf2.c bfd/ecoff.c bfd/elf-bfd.h bfd/elf-eh-frame.c bfd/elf-hppa.h bfd/elf-m10300.c bfd/elf.c bfd/elf32-arm.h bfd/elf32-cris.c bfd/elf32-hppa.c bfd/elf32-hppa.h bfd/elf32-i370.c bfd/elf32-i386.c bfd/elf32-m32r.c bfd/elf32-m68k.c bfd/elf32-mips.c bfd/elf32-ppc.c bfd/elf32-s390.c bfd/elf32-sh.c bfd/elf32-sh64.c bfd/elf32-sparc.c bfd/elf32-xstormy16.c bfd/elf64-alpha.c bfd/elf64-hppa.c bfd/elf64-mips.c bfd/elf64-mmix.c bfd/elf64-ppc.c bfd/elf64-ppc.h bfd/elf64-s390.c bfd/elf64-sh64.c bfd/elf64-sparc.c bfd/elf64-x86-64.c bfd/elfarm-nabi.c bfd/elflink.c bfd/elflink.h bfd/elfxx-ia64.c bfd/elfxx-mips.c bfd/elfxx-mips.h bfd/elfxx-target.h bfd/i386linux.c bfd/i386msdos.c bfd/i386os9k.c bfd/ieee.c bfd/ihex.c bfd/libbfd-in.h bfd/libbfd.c bfd/libbfd.h bfd/libcoff-in.h bfd/libcoff.h bfd/libecoff.h bfd/libxcoff.h bfd/linker.c bfd/m68klinux.c bfd/merge.c bfd/mmo.c bfd/nlm-target.h bfd/oasys.c bfd/opncls.c bfd/pdp11.c bfd/po/SRC-POTFILES.in bfd/po/fr.po bfd/ppcboot.c bfd/reloc.c bfd/rs6000-core.c bfd/som.c bfd/sparclinux.c bfd/srec.c bfd/sunos.c bfd/syms.c bfd/targets.c bfd/tekhex.c bfd/versados.c bfd/version.h bfd/vms.c bfd/xcofflink.c config.guess config.sub config/ChangeLog config/acinclude.m4 config/mh-a68bsd config/mh-apollo68 config/mh-cxux config/mh-decstation config/mh-dgux config/mh-dgux386 config/mh-djgpp config/mh-hp300 config/mh-hpux config/mh-hpux8 config/mh-interix config/mh-irix5 config/mh-irix6 config/mh-lynxrs6k config/mh-mingw32 config/mh-ncr3000 config/mh-ncrsvr43 config/mh-necv4 config/mh-openedition config/mh-riscos config/mh-sco config/mh-solaris config/mh-sysv config/mh-sysv4 config/mh-sysv5 config/mt-aix43 config/mt-alphaieee config/mt-linux configure configure.in gdb/ChangeLog gdb/MAINTAINERS gdb/Makefile.in gdb/NEWS gdb/PROBLEMS gdb/README gdb/acconfig.h gdb/acinclude.m4 gdb/aclocal.m4 gdb/alpha-linux-tdep.c gdb/alpha-nat.c gdb/alpha-osf1-tdep.c gdb/alpha-tdep.c gdb/alpha-tdep.h gdb/alphabsd-nat.c gdb/alphafbsd-tdep.c gdb/alphanbsd-nat.c gdb/alphanbsd-tdep.c gdb/arc-tdep.c gdb/arch-utils.c gdb/arch-utils.h gdb/arm-tdep.c gdb/arm-tdep.h gdb/avr-tdep.c gdb/bcache.c gdb/blockframe.c gdb/breakpoint.c gdb/builtin-regs.c gdb/builtin-regs.h gdb/c-exp.y gdb/c-lang.c gdb/cli-out.c gdb/cli/cli-cmds.c gdb/cli/cli-decode.c gdb/cli/cli-decode.h gdb/cli/cli-dump.c gdb/cli/cli-dump.h gdb/cli/cli-script.c gdb/coffread.c gdb/command.h gdb/completer.c gdb/config.in gdb/config/alpha/alpha-linux.mt gdb/config/alpha/alpha-osf1.mt gdb/config/alpha/nbsd.mh gdb/config/alpha/nbsd.mt gdb/config/alpha/nm-linux.h gdb/config/alpha/nm-nbsd.h gdb/config/alpha/nm-osf.h gdb/config/alpha/tm-alpha.h gdb/config/alpha/tm-alphalinux.h gdb/config/alpha/tm-fbsd.h gdb/config/alpha/tm-nbsd.h gdb/config/arc/tm-arc.h gdb/config/avr/avr.mt gdb/config/djgpp/README gdb/config/h8500/tm-h8500.h gdb/config/i386/fbsd.mh gdb/config/i386/i386gnu.mh gdb/config/i386/i386lynx.mh gdb/config/i386/i386v42mp.mh gdb/config/i386/nbsd.mt gdb/config/i386/nbsdelf.mt gdb/config/i386/nm-fbsd.h gdb/config/i386/nm-x86-64.h gdb/config/i386/tm-linux.h gdb/config/i386/x86-64linux.mt gdb/config/i960/tm-i960.h gdb/config/m32r/m32r.mt gdb/config/m68k/m68klynx.mh gdb/config/m68k/nbsd.mt gdb/config/m68k/sun3os4.mh gdb/config/m68k/tm-nbsd.h gdb/config/mcore/tm-mcore.h gdb/config/mips/vr5000.mt gdb/config/mn10200/tm-mn10200.h gdb/config/ns32k/nbsd.mt gdb/config/pa/hppabsd.mh gdb/config/pa/hppaosf.mh gdb/config/pa/hpux1020.mh gdb/config/pa/hpux11.mh gdb/config/pa/hpux11w.mh gdb/config/pa/tm-hppa.h gdb/config/powerpc/nbsd.mt gdb/config/powerpc/tm-ppc-eabi.h gdb/config/rs6000/rs6000lynx.mh gdb/config/rs6000/tm-rs6000.h gdb/config/s390/s390.mh gdb/config/s390/s390.mt gdb/config/s390/s390x.mt gdb/config/sparc/fbsd.mh gdb/config/sparc/fbsd.mt gdb/config/sparc/linux.mh gdb/config/sparc/sparclynx.mh gdb/config/sparc/sun4os4.mh gdb/config/sparc/tm-linux.h gdb/config/sparc/tm-sp64.h gdb/config/sparc/tm-sp64linux.h gdb/config/sparc/tm-sparc.h gdb/config/v850/tm-v850.h gdb/config/vax/tm-vax.h gdb/configure gdb/configure.host gdb/configure.in gdb/configure.tgt gdb/core-sol2.c gdb/corefile.c gdb/corelow.c gdb/cp-valprint.c gdb/cris-tdep.c gdb/d10v-tdep.c gdb/d30v-tdep.c gdb/dbxread.c gdb/defs.h gdb/doc/ChangeLog gdb/doc/gdb.texinfo gdb/doc/gdbint.texinfo gdb/dwarf2cfi.c gdb/dwarf2read.c gdb/elfread.c gdb/eval.c gdb/event-top.c gdb/exec.c gdb/f-exp.y gdb/f-lang.c gdb/fbsd-proc.c gdb/findvar.c gdb/frame.c gdb/frame.h gdb/gcore.c gdb/gdb-events.c gdb/gdb-events.h gdb/gdb-events.sh gdb/gdbarch.c gdb/gdbarch.h gdb/gdbarch.sh gdb/gdbserver/Makefile.in gdb/gdbserver/config.in gdb/gdbserver/configure gdb/gdbserver/configure.in gdb/gdbserver/gdbreplay.c gdb/gdbserver/inferiors.c gdb/gdbserver/linux-arm-low.c gdb/gdbserver/linux-i386-low.c gdb/gdbserver/linux-ia64-low.c gdb/gdbserver/linux-low.c gdb/gdbserver/linux-low.h gdb/gdbserver/linux-m68k-low.c gdb/gdbserver/linux-mips-low.c gdb/gdbserver/linux-ppc-low.c gdb/gdbserver/linux-s390-low.c gdb/gdbserver/linux-sh-low.c gdb/gdbserver/linux-x86-64-low.c gdb/gdbserver/mem-break.c gdb/gdbserver/mem-break.h gdb/gdbserver/regcache.c gdb/gdbserver/regcache.h gdb/gdbserver/remote-utils.c gdb/gdbserver/server.c gdb/gdbserver/server.h gdb/gdbserver/target.c gdb/gdbserver/target.h gdb/gdbserver/utils.c gdb/gdbtypes.c gdb/gdbtypes.h gdb/gnu-nat.c gdb/gnu-v3-abi.c gdb/go32-nat.c gdb/gregset.h gdb/h8300-tdep.c gdb/h8500-tdep.c gdb/hppa-tdep.c gdb/hpread.c gdb/i386-linux-tdep.c gdb/i386-tdep.c gdb/i386gnu-nat.c gdb/i387-nat.c gdb/i960-tdep.c gdb/ia64-tdep.c gdb/infcmd.c gdb/inferior.h gdb/inflow.c gdb/infrun.c gdb/jv-exp.y gdb/kod.c gdb/language.c gdb/lin-lwp.c gdb/linespec.c gdb/linux-proc.c gdb/m2-exp.y gdb/m3-nat.c gdb/m68hc11-tdep.c gdb/m68klinux-nat.c gdb/maint.c gdb/mcore-tdep.c gdb/mdebugread.c gdb/mem-break.c gdb/mi/ChangeLog gdb/mi/mi-cmd-break.c gdb/mi/mi-cmd-disas.c gdb/mi/mi-cmd-stack.c gdb/mi/mi-cmd-var.c gdb/mi/mi-console.c gdb/mi/mi-main.c gdb/mi/mi-out.c gdb/mi/mi-parse.c gdb/minsyms.c gdb/mips-tdep.c gdb/mipsread.c gdb/mn10300-tdep.c gdb/monitor.c gdb/ocd.c gdb/p-exp.y gdb/p-lang.c gdb/p-lang.h gdb/p-typeprint.c gdb/p-valprint.c gdb/parse.c gdb/parser-defs.h gdb/ppc-bdm.c gdb/ppc-linux-nat.c gdb/ppc-linux-tdep.c gdb/ppc-tdep.h gdb/printcmd.c gdb/proc-api.c gdb/regcache.c gdb/regformats/reg-ppc.dat gdb/regformats/reg-x86-64.dat gdb/remote-array.c gdb/remote-e7000.c gdb/remote-es.c gdb/remote-mips.c gdb/remote-os9k.c gdb/remote-rdi.c gdb/remote-rdp.c gdb/remote-st.c gdb/remote-utils.c gdb/remote-vxsparc.c gdb/remote.c gdb/rs6000-nat.c gdb/rs6000-tdep.c gdb/s390-tdep.c gdb/scm-lang.c gdb/ser-unix.h gdb/serial.c gdb/sh-tdep.c gdb/solib-legacy.c gdb/solib-svr4.c gdb/solib.c gdb/somread.c gdb/source.c gdb/sparc-nat.c gdb/sparc-tdep.c gdb/stabsread.c gdb/stack.c gdb/std-regs.c gdb/symfile.c gdb/symfile.h gdb/symmisc.c gdb/symtab.c gdb/symtab.h gdb/target.c gdb/target.h gdb/testsuite/ChangeLog gdb/testsuite/config/sid.exp gdb/testsuite/gdb.asm/Makefile.in gdb/testsuite/gdb.asm/asm-source.exp gdb/testsuite/gdb.asm/configure gdb/testsuite/gdb.asm/configure.in gdb/testsuite/gdb.asm/powerpc.inc gdb/testsuite/gdb.asm/sparc64.inc gdb/testsuite/gdb.base/annota1.exp gdb/testsuite/gdb.base/attach.exp gdb/testsuite/gdb.base/bar.c gdb/testsuite/gdb.base/baz.c gdb/testsuite/gdb.base/completion.exp gdb/testsuite/gdb.base/cvexpr.c gdb/testsuite/gdb.base/dbx.exp gdb/testsuite/gdb.base/default.exp gdb/testsuite/gdb.base/dump.c gdb/testsuite/gdb.base/dump.exp gdb/testsuite/gdb.base/ending-run.exp gdb/testsuite/gdb.base/foo.c gdb/testsuite/gdb.base/funcargs.c gdb/testsuite/gdb.base/funcargs.exp gdb/testsuite/gdb.base/gcore.exp gdb/testsuite/gdb.base/grbx.c gdb/testsuite/gdb.base/help.exp gdb/testsuite/gdb.base/list.exp gdb/testsuite/gdb.base/long_long.exp gdb/testsuite/gdb.base/maint.exp gdb/testsuite/gdb.base/opaque.exp gdb/testsuite/gdb.base/overlays.exp gdb/testsuite/gdb.base/ovlymgr.c gdb/testsuite/gdb.base/printcmds.exp gdb/testsuite/gdb.base/ptype.exp gdb/testsuite/gdb.base/relocate.c gdb/testsuite/gdb.base/relocate.exp gdb/testsuite/gdb.base/scope.exp gdb/testsuite/gdb.base/shlib-call.exp gdb/testsuite/gdb.base/step-test.exp gdb/testsuite/gdb.base/watchpoint.exp gdb/testsuite/gdb.base/whatis.exp gdb/testsuite/gdb.c++/classes.exp gdb/testsuite/gdb.c++/cplusfuncs.exp gdb/testsuite/gdb.c++/hang.H gdb/testsuite/gdb.c++/hang.exp gdb/testsuite/gdb.c++/hang1.C gdb/testsuite/gdb.c++/hang2.C gdb/testsuite/gdb.c++/hang3.C gdb/testsuite/gdb.c++/local.cc gdb/testsuite/gdb.c++/local.exp gdb/testsuite/gdb.c++/method.exp gdb/testsuite/gdb.c++/misc.exp gdb/testsuite/gdb.c++/ovldbreak.exp gdb/testsuite/gdb.gdb/xfullpath.exp gdb/testsuite/gdb.java/jmisc1.exp gdb/testsuite/gdb.java/jmisc2.exp gdb/testsuite/gdb.mi/ChangeLog gdb/testsuite/gdb.mi/mi-var-cmd.exp gdb/testsuite/gdb.mi/mi0-var-cmd.exp gdb/testsuite/gdb.threads/linux-dp.exp gdb/testsuite/gdb.trace/gdb_c_test.c gdb/testsuite/lib/gdb.exp gdb/thread-db.c gdb/thread.c gdb/top.c gdb/top.h gdb/tracepoint.c gdb/tui/ChangeLog gdb/tui/tui-out.c gdb/ui-file.c gdb/ui-out.c gdb/utils.c gdb/valarith.c gdb/valops.c gdb/valprint.c gdb/value.h gdb/varobj.c gdb/vax-tdep.c gdb/vax-tdep.h gdb/version.in gdb/win32-nat.c gdb/x86-64-linux-nat.c gdb/x86-64-tdep.c gdb/x86-64-tdep.h gdb/xcoffread.c gdb/xstormy16-tdep.c gdb/z8k-tdep.c include/ChangeLog include/coff/ChangeLog include/coff/rs6k64.h include/dyn-string.h include/elf/ChangeLog include/elf/dwarf2.h include/floatformat.h include/opcode/ChangeLog include/opcode/i386.h include/opcode/mips.h include/opcode/pdp11.h include/xregex2.h libiberty/ChangeLog libiberty/Makefile.in libiberty/config.table libiberty/configure libiberty/configure.in libiberty/cp-demangle.c libiberty/dyn-string.c libiberty/floatformat.c libiberty/functions.texi libiberty/hashtab.c libiberty/hex.c libiberty/splay-tree.c libiberty/strtod.c libiberty/xatexit.c libiberty/xmalloc.c ltmain.sh mmalloc/ChangeLog mmalloc/mmap-sup.c opcodes/ChangeLog opcodes/Makefile.am opcodes/Makefile.in opcodes/configure opcodes/configure.in opcodes/dep-in.sed opcodes/i386-dis.c opcodes/mips-dis.c opcodes/mips-opc.c opcodes/pdp11-dis.c opcodes/pdp11-opc.c opcodes/po/fr.po opcodes/po/id.po opcodes/ppc-opc.c opcodes/s390-dis.c opcodes/z8k-dis.c opcodes/z8k-opc.h opcodes/z8kgen.c sim/ChangeLog sim/MAINTAINERS sim/arm/ChangeLog sim/arm/wrapper.c sim/common/ChangeLog sim/common/callback.c sim/igen/ChangeLog sim/igen/gen.c sim/igen/igen.c sim/m68hc11/ChangeLog sim/m68hc11/dv-m68hc11.c sim/m68hc11/dv-m68hc11spi.c sim/m68hc11/dv-m68hc11tim.c sim/m68hc11/interp.c sim/m68hc11/interrupts.c sim/m68hc11/interrupts.h sim/m68hc11/m68hc11_sim.c sim/m68hc11/sim-main.h sim/mips/ChangeLog sim/mips/Makefile.in sim/mips/configure sim/mips/configure.in sim/mips/cp1.c sim/mips/interp.c sim/mips/mips.igen sim/mips/sim-main.h sim/ppc/ChangeLog sim/ppc/hw_disk.c sim/ppc/ppc-instructions sim/ppc/sim_calls.c sim/z8k/ChangeLog sim/z8k/writecode.c Delete: config/mh-irix4 config/mh-lynxos config/mh-sun3 config/mh-vaxult2 config/mt-armpic config/mt-elfalphapic config/mt-i370pic config/mt-ia64pic config/mt-m68kpic config/mt-papic config/mt-ppcpic config/mt-s390pic config/mt-sparcpic config/mt-x86pic gdb/a29k-tdep.c gdb/config/a29k/a29k-udi.mt gdb/config/a29k/a29k.mt gdb/config/a29k/tm-a29k.h gdb/config/a29k/tm-vx29k.h gdb/config/a29k/vx29k.mt gdb/remote-adapt.c gdb/remote-eb.c gdb/remote-mm.c gdb/remote-udi.c gdb/signals.c gdb/testsuite/gdb.hp/gdb.threads-hp/usrthbasic.c gdb/testsuite/gdb.hp/gdb.threads-hp/usrthbasic.exp gdb/testsuite/gdb.hp/gdb.threads-hp/usrthcore.c gdb/testsuite/gdb.hp/gdb.threads-hp/usrthcore.exp gdb/testsuite/gdb.hp/gdb.threads-hp/usrthfork.c gdb/testsuite/gdb.hp/gdb.threads-hp/usrthfork.exp
Diffstat (limited to 'gdb/gdbserver')
-rw-r--r--gdb/gdbserver/Makefile.in40
-rw-r--r--gdb/gdbserver/config.in3
-rwxr-xr-xgdb/gdbserver/configure6
-rw-r--r--gdb/gdbserver/configure.in9
-rw-r--r--gdb/gdbserver/gdbreplay.c15
-rw-r--r--gdb/gdbserver/inferiors.c105
-rw-r--r--gdb/gdbserver/linux-arm-low.c22
-rw-r--r--gdb/gdbserver/linux-i386-low.c58
-rw-r--r--gdb/gdbserver/linux-ia64-low.c18
-rw-r--r--gdb/gdbserver/linux-low.c198
-rw-r--r--gdb/gdbserver/linux-low.h26
-rw-r--r--gdb/gdbserver/linux-m68k-low.c23
-rw-r--r--gdb/gdbserver/linux-mips-low.c23
-rw-r--r--gdb/gdbserver/linux-ppc-low.c24
-rw-r--r--gdb/gdbserver/linux-s390-low.c23
-rw-r--r--gdb/gdbserver/linux-sh-low.c18
-rw-r--r--gdb/gdbserver/linux-x86-64-low.c25
-rw-r--r--gdb/gdbserver/mem-break.c280
-rw-r--r--gdb/gdbserver/mem-break.h71
-rw-r--r--gdb/gdbserver/regcache.c57
-rw-r--r--gdb/gdbserver/regcache.h18
-rw-r--r--gdb/gdbserver/remote-utils.c124
-rw-r--r--gdb/gdbserver/server.c52
-rw-r--r--gdb/gdbserver/server.h71
-rw-r--r--gdb/gdbserver/target.c47
-rw-r--r--gdb/gdbserver/target.h141
-rw-r--r--gdb/gdbserver/utils.c4
27 files changed, 1296 insertions, 205 deletions
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
index 9ed226eb..2c8cd33 100644
--- a/gdb/gdbserver/Makefile.in
+++ b/gdb/gdbserver/Makefile.in
@@ -83,20 +83,22 @@ READLINE_DEP = $$(READLINE_DIR)
# -I. for config files.
# -I${srcdir} for our headers.
# -I$(srcdir)/../regformats for regdef.h.
-INCLUDE_CFLAGS = -I. -I${srcdir} -I$(srcdir)/../regformats
+INCLUDE_CFLAGS = -I. -I${srcdir} -I$(srcdir)/../regformats -I$(INCLUDE_DIR)
# M{H,T}_CFLAGS, if defined, has host- and target-dependent CFLAGS
# from the config/ directory.
GLOBAL_CFLAGS = ${MT_CFLAGS} ${MH_CFLAGS}
#PROFILE_CFLAGS = -pg
+WARN_CFLAGS = -Wall
+
# CFLAGS is specifically reserved for setting from the command line
# when running make. I.E. "make CFLAGS=-Wmissing-prototypes".
CFLAGS = @CFLAGS@
# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
-INTERNAL_CFLAGS = ${CFLAGS} ${GLOBAL_CFLAGS} ${PROFILE_CFLAGS} \
- ${INCLUDE_CFLAGS} ${BFD_CFLAGS}
+INTERNAL_CFLAGS = $(WARN_CFLAGS) ${CFLAGS} ${GLOBAL_CFLAGS} \
+ ${PROFILE_CFLAGS} ${INCLUDE_CFLAGS} ${BFD_CFLAGS}
# LDFLAGS is specifically reserved for setting from the command line
# when running make.
@@ -120,7 +122,10 @@ DEPFILES = @GDBSERVER_DEPFILES@
SOURCES = $(SFILES)
TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS}
-OBS = utils.o $(DEPFILES) server.o remote-utils.o regcache.o
+OBS = inferiors.o regcache.o remote-utils.o server.o signals.o target.o \
+ utils.o \
+ mem-break.o \
+ $(DEPFILES)
# 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.
@@ -195,8 +200,12 @@ maintainer-clean realclean: clean
STAGESTUFF=${OBS} ${TSOBS} ${NTSOBS} ${ADD_FILES} init.c init.o version.c gdb
+config.h: stamp-h ; @true
+stamp-h: config.in config.status
+ CONFIG_FILES="" $(SHELL) ./config.status
+
Makefile: Makefile.in config.status
- $(SHELL) ./config.status
+ CONFIG_HEADERS="" $(SHELL) ./config.status
config.status: configure configure.srv
$(SHELL) ./config.status --recheck
@@ -225,12 +234,19 @@ unexport CHILLFLAGS CHILL_LIB CHILL_FOR_TARGET :
regdat_sh = $(srcdir)/../regformats/regdat.sh
regdef_h = $(srcdir)/../regformats/regdef.h
regcache_h = $(srcdir)/regcache.h
-server_h = $(srcdir)/server.h $(regcache_h) config.h
+server_h = $(srcdir)/server.h $(regcache_h) config.h $(srcdir)/target.h \
+ $(srcdir)/mem-break.h
-server.o: server.c $(server_h)
+inferiors.o: inferiors.c $(server_h)
+mem-break.o: mem-break.c $(server_h)
+regcache.o: regcache.c $(server_h) $(regdef_h)
remote-utils.o: remote-utils.c terminal.h $(server_h)
+server.o: server.c $(server_h)
+target.o: target.c $(server_h)
utils.o: utils.c $(server_h)
-regcache.o: regcache.c $(server_h) $(regdef_h)
+
+signals.o: ../signals/signals.c $(server_h)
+ $(CC) -c $(CPPFLAGS) $(INTERNAL_CFLAGS) $< -DGDBSERVER
i387-fp.o: i387-fp.c $(server_h)
@@ -246,14 +262,6 @@ linux-s390-low.o: linux-s390-low.c $(linux_low_h) $(server_h)
linux-sh-low.o: linux-sh-low.c $(linux_low_h) $(server_h)
linux-x86-64-low.o: linux-x86-64-low.c $(linux_low_h) $(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)
sh $(regdat_sh) $(srcdir)/../regformats/reg-arm.dat reg-arm.c
diff --git a/gdb/gdbserver/config.in b/gdb/gdbserver/config.in
index e77d5a7..9d553f2 100644
--- a/gdb/gdbserver/config.in
+++ b/gdb/gdbserver/config.in
@@ -16,6 +16,9 @@
/* Define if you have the <sgtty.h> header file. */
#undef HAVE_SGTTY_H
+/* Define if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
/* Define if you have the <sys/reg.h> header file. */
#undef HAVE_SYS_REG_H
diff --git a/gdb/gdbserver/configure b/gdb/gdbserver/configure
index c08d5c2..758d483 100755
--- a/gdb/gdbserver/configure
+++ b/gdb/gdbserver/configure
@@ -1105,7 +1105,7 @@ EOF
fi
-for ac_hdr in sgtty.h termio.h termios.h sys/reg.h
+for ac_hdr in sgtty.h termio.h termios.h sys/reg.h string.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
@@ -1593,6 +1593,10 @@ cat >> $CONFIG_STATUS <<EOF
EOF
cat >> $CONFIG_STATUS <<\EOF
+case x$CONFIG_HEADERS in
+xconfig.h:config.in)
+echo > stamp-h ;;
+esac
exit 0
EOF
diff --git a/gdb/gdbserver/configure.in b/gdb/gdbserver/configure.in
index 744aac2..db7e301 100644
--- a/gdb/gdbserver/configure.in
+++ b/gdb/gdbserver/configure.in
@@ -30,7 +30,7 @@ AC_PROG_INSTALL
AC_HEADER_STDC
-AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h)
+AC_CHECK_HEADERS(sgtty.h termio.h termios.h sys/reg.h string.h)
. ${srcdir}/configure.srv
@@ -66,4 +66,9 @@ GDBSERVER_DEPFILES="$srv_regobj $srv_tgtobj"
AC_SUBST(GDBSERVER_DEPFILES)
-AC_OUTPUT(Makefile)
+AC_OUTPUT(Makefile,
+[case x$CONFIG_HEADERS in
+xconfig.h:config.in)
+echo > stamp-h ;;
+esac
+])
diff --git a/gdb/gdbserver/gdbreplay.c b/gdb/gdbserver/gdbreplay.c
index ca10a06..65831b1 100644
--- a/gdb/gdbserver/gdbreplay.c
+++ b/gdb/gdbserver/gdbreplay.c
@@ -30,6 +30,12 @@
#include <ctype.h>
#include <fcntl.h>
#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
/* Sort of a hack... */
#define EOL (EOF - 1)
@@ -83,8 +89,6 @@ remote_close (void)
void
remote_open (char *name)
{
- extern char *strchr ();
-
if (!strchr (name, ':'))
{
fprintf (stderr, "%s: Must specify tcp connection as host:addr\n", name);
@@ -97,7 +101,6 @@ remote_open (char *name)
int port;
struct sockaddr_in sockaddr;
int tmp;
- struct protoent *protoent;
int tmp_desc;
port_str = strchr (name, ':');
@@ -126,10 +129,6 @@ remote_open (char *name)
if (remote_desc == -1)
perror_with_name ("Accept failed");
- protoent = getprotobyname ("tcp");
- if (!protoent)
- perror_with_name ("getprotobyname");
-
/* Enable TCP keep alive process. */
tmp = 1;
setsockopt (tmp_desc, SOL_SOCKET, SO_KEEPALIVE, (char *) &tmp, sizeof (tmp));
@@ -137,7 +136,7 @@ remote_open (char *name)
/* Tell TCP not to delay small packets. This greatly speeds up
interactive response. */
tmp = 1;
- setsockopt (remote_desc, protoent->p_proto, TCP_NODELAY,
+ setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
(char *) &tmp, sizeof (tmp));
close (tmp_desc); /* No longer need this */
diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
new file mode 100644
index 0000000..774798d
--- /dev/null
+++ b/gdb/gdbserver/inferiors.c
@@ -0,0 +1,105 @@
+/* Inferior process information for the remote server for GDB.
+ Copyright 2002
+ Free Software Foundation, Inc.
+
+ Contributed by MontaVista Software.
+
+ 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 <stdlib.h>
+
+#include "server.h"
+
+struct inferior_info
+{
+ int pid;
+ void *target_data;
+ void *regcache_data;
+ struct inferior_info *next;
+};
+
+static struct inferior_info *inferiors;
+struct inferior_info *current_inferior;
+int signal_pid;
+
+void
+add_inferior (int pid)
+{
+ struct inferior_info *new_inferior
+ = (struct inferior_info *) malloc (sizeof (*new_inferior));
+
+ memset (new_inferior, 0, sizeof (*new_inferior));
+
+ new_inferior->pid = pid;
+
+ new_inferior->next = inferiors;
+ inferiors = new_inferior;
+
+ if (current_inferior == NULL)
+ current_inferior = inferiors;
+
+ create_register_cache (new_inferior);
+
+ if (signal_pid == 0)
+ signal_pid = pid;
+}
+
+void
+clear_inferiors (void)
+{
+ struct inferior_info *inf = inferiors, *next_inf;
+
+ while (inf)
+ {
+ next_inf = inf->next;
+
+ if (inf->target_data)
+ free (inf->target_data);
+ if (inf->regcache_data)
+ free_register_cache (inf);
+
+ free (inf);
+ inf = next_inf;
+ }
+
+ inferiors = NULL;
+}
+
+void *
+inferior_target_data (struct inferior_info *inferior)
+{
+ return inferior->target_data;
+}
+
+void
+set_inferior_target_data (struct inferior_info *inferior, void *data)
+{
+ inferior->target_data = data;
+}
+
+void *
+inferior_regcache_data (struct inferior_info *inferior)
+{
+ return inferior->regcache_data;
+}
+
+void
+set_inferior_regcache_data (struct inferior_info *inferior, void *data)
+{
+ inferior->regcache_data = data;
+}
diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c
index f873b07..2958fdf 100644
--- a/gdb/gdbserver/linux-arm-low.c
+++ b/gdb/gdbserver/linux-arm-low.c
@@ -26,22 +26,28 @@
#include <sys/reg.h>
#endif
-int num_regs = 16;
+#define arm_num_regs 16
-int regmap[] = {
+static int arm_regmap[] = {
0, 4, 8, 12, 16, 20, 24, 28,
32, 36, 40, 44, 48, 52, 56, 60,
};
-int
-cannot_store_register (int regno)
+static int
+arm_cannot_store_register (int regno)
{
- return (regno >= num_regs);
+ return (regno >= arm_num_regs);
}
-int
-cannot_fetch_register (int regno)
+static int
+arm_cannot_fetch_register (int regno)
{
- return (regno >= num_regs);
+ return (regno >= arm_num_regs);
}
+struct linux_target_ops the_low_target = {
+ arm_num_regs,
+ arm_regmap,
+ arm_cannot_fetch_register,
+ arm_cannot_store_register,
+};
diff --git a/gdb/gdbserver/linux-i386-low.c b/gdb/gdbserver/linux-i386-low.c
index 2a66efa..7126432 100644
--- a/gdb/gdbserver/linux-i386-low.c
+++ b/gdb/gdbserver/linux-i386-low.c
@@ -29,13 +29,13 @@
/* This module only supports access to the general purpose registers. */
-int num_regs = 16;
+#define i386_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[] =
+static int i386_regmap[] =
{
EAX * 4, ECX * 4, EDX * 4, EBX * 4,
UESP * 4, EBP * 4, ESI * 4, EDI * 4,
@@ -43,16 +43,16 @@ int regmap[] =
DS * 4, ES * 4, FS * 4, GS * 4
};
-int
-cannot_store_register (int regno)
+static int
+i386_cannot_store_register (int regno)
{
- return (regno >= num_regs);
+ return (regno >= i386_num_regs);
}
-int
-cannot_fetch_register (int regno)
+static int
+i386_cannot_fetch_register (int regno)
{
- return (regno >= num_regs);
+ return (regno >= i386_num_regs);
}
@@ -65,8 +65,8 @@ i386_fill_gregset (void *buf)
{
int i;
- for (i = 0; i < num_regs; i++)
- collect_register (i, ((char *) buf) + regmap[i]);
+ for (i = 0; i < i386_num_regs; i++)
+ collect_register (i, ((char *) buf) + i386_regmap[i]);
collect_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4);
}
@@ -76,8 +76,8 @@ i386_store_gregset (void *buf)
{
int i;
- for (i = 0; i < num_regs; i++)
- supply_register (i, ((char *) buf) + regmap[i]);
+ for (i = 0; i < i386_num_regs; i++)
+ supply_register (i, ((char *) buf) + i386_regmap[i]);
supply_register_by_name ("orig_eax", ((char *) buf) + ORIG_EAX * 4);
}
@@ -121,3 +121,37 @@ struct regset_info target_regsets[] = {
#endif /* HAVE_LINUX_REGSETS */
+static const char i386_breakpoint[] = { 0xCC };
+#define i386_breakpoint_len 1
+
+static CORE_ADDR
+i386_stop_pc ()
+{
+ unsigned long pc;
+
+ /* Overkill */
+ fetch_inferior_registers (0);
+
+ collect_register_by_name ("eip", &pc);
+ return pc - 1;
+}
+
+static void
+i386_set_pc (CORE_ADDR newpc)
+{
+ supply_register_by_name ("eip", &newpc);
+
+ /* Overkill */
+ store_inferior_registers (0);
+}
+
+struct linux_target_ops the_low_target = {
+ i386_num_regs,
+ i386_regmap,
+ i386_cannot_fetch_register,
+ i386_cannot_store_register,
+ i386_stop_pc,
+ i386_set_pc,
+ i386_breakpoint,
+ i386_breakpoint_len,
+};
diff --git a/gdb/gdbserver/linux-ia64-low.c b/gdb/gdbserver/linux-ia64-low.c
index f0f238f9..9407e6c 100644
--- a/gdb/gdbserver/linux-ia64-low.c
+++ b/gdb/gdbserver/linux-ia64-low.c
@@ -26,11 +26,11 @@
#include <sys/reg.h>
#endif
-int num_regs = 590;
+#define ia64_num_regs 590
#include <asm/ptrace_offsets.h>
-int regmap[] =
+static int ia64_regmap[] =
{
/* general registers */
-1, /* gr0 not available; i.e, it's always zero */
@@ -283,15 +283,21 @@ int regmap[] =
-1, -1, -1, -1, -1, -1, -1, -1,
};
-int
-cannot_store_register (int regno)
+static int
+ia64_cannot_store_register (int regno)
{
return 0;
}
-int
-cannot_fetch_register (int regno)
+static int
+ia64_cannot_fetch_register (int regno)
{
return 0;
}
+struct linux_target_ops the_low_target = {
+ ia64_num_regs,
+ ia64_regmap,
+ ia64_cannot_fetch_register,
+ ia64_cannot_store_register,
+};
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index 4e40d07..6cfe0d5 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -35,6 +35,10 @@
#include <stdlib.h>
#include <unistd.h>
+static CORE_ADDR linux_bp_reinsert;
+
+static void linux_resume (int step, int signal);
+
#define PTRACE_ARG3_TYPE long
#define PTRACE_XFER_TYPE long
@@ -44,17 +48,20 @@ static int use_regsets_p = 1;
extern int errno;
-#ifdef HAVE_LINUX_USRREGS
-extern int num_regs;
-extern int regmap[];
-#endif
+static int inferior_pid;
+
+struct inferior_linux_data
+{
+ int pid;
+};
/* Start an inferior process and returns its pid.
ALLARGS is a vector of program-name and args. */
-int
-create_inferior (char *program, char **allargs)
+static int
+linux_create_inferior (char *program, char **allargs)
{
+ struct inferior_linux_data *tdata;
int pid;
pid = fork ();
@@ -73,14 +80,23 @@ create_inferior (char *program, char **allargs)
_exit (0177);
}
- return pid;
+ add_inferior (pid);
+ tdata = (struct inferior_linux_data *) malloc (sizeof (*tdata));
+ tdata->pid = pid;
+ set_inferior_target_data (current_inferior, tdata);
+
+ /* FIXME remove */
+ inferior_pid = pid;
+ return 0;
}
/* Attach to an inferior process. */
-int
-myattach (int pid)
+static int
+linux_attach (int pid)
{
+ struct inferior_linux_data *tdata;
+
if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0)
{
fprintf (stderr, "Cannot attach to process %d: %s (%d)\n", pid,
@@ -90,50 +106,113 @@ myattach (int pid)
_exit (0177);
}
+ add_inferior (pid);
+ tdata = (struct inferior_linux_data *) malloc (sizeof (*tdata));
+ tdata->pid = pid;
+ set_inferior_target_data (current_inferior, tdata);
return 0;
}
/* Kill the inferior process. Make us have no inferior. */
-void
-kill_inferior (void)
+static void
+linux_kill (void)
{
if (inferior_pid == 0)
return;
ptrace (PTRACE_KILL, inferior_pid, 0, 0);
wait (0);
+ clear_inferiors ();
}
/* Return nonzero if the given thread is still alive. */
-int
-mythread_alive (int pid)
+static int
+linux_thread_alive (int pid)
{
return 1;
}
+static int
+linux_wait_for_one_inferior (struct inferior_info *child)
+{
+ struct inferior_linux_data *child_data = inferior_target_data (child);
+ int pid, wstat;
+
+ while (1)
+ {
+ pid = waitpid (child_data->pid, &wstat, 0);
+
+ if (pid != child_data->pid)
+ perror_with_name ("wait");
+
+ /* If this target supports breakpoints, see if we hit one. */
+ if (the_low_target.stop_pc != NULL
+ && WIFSTOPPED (wstat)
+ && WSTOPSIG (wstat) == SIGTRAP)
+ {
+ CORE_ADDR stop_pc;
+
+ if (linux_bp_reinsert != 0)
+ {
+ reinsert_breakpoint (linux_bp_reinsert);
+ linux_bp_reinsert = 0;
+ linux_resume (0, 0);
+ continue;
+ }
+
+ fetch_inferior_registers (0);
+ stop_pc = (*the_low_target.stop_pc) ();
+
+ if (check_breakpoints (stop_pc) != 0)
+ {
+ if (the_low_target.set_pc != NULL)
+ (*the_low_target.set_pc) (stop_pc);
+
+ if (the_low_target.breakpoint_reinsert_addr == NULL)
+ {
+ linux_bp_reinsert = stop_pc;
+ uninsert_breakpoint (stop_pc);
+ linux_resume (1, 0);
+ }
+ else
+ {
+ reinsert_breakpoint_by_bp
+ (stop_pc, (*the_low_target.breakpoint_reinsert_addr) ());
+ linux_resume (0, 0);
+ }
+
+ continue;
+ }
+ }
+
+ return wstat;
+ }
+ /* NOTREACHED */
+ return 0;
+}
+
/* Wait for process, returns status */
-unsigned char
-mywait (char *status)
+static unsigned char
+linux_wait (char *status)
{
- int pid;
int w;
enable_async_io ();
- pid = waitpid (inferior_pid, &w, 0);
+ w = linux_wait_for_one_inferior (current_inferior);
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';
+ clear_inferiors ();
return ((unsigned char) WEXITSTATUS (w));
}
else if (!WIFSTOPPED (w))
{
fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
+ clear_inferiors ();
*status = 'X';
return ((unsigned char) WTERMSIG (w));
}
@@ -148,8 +227,8 @@ mywait (char *status)
If STEP is nonzero, single-step it.
If SIGNAL is nonzero, give it that signal. */
-void
-myresume (int step, int signal)
+static void
+linux_resume (int step, int signal)
{
errno = 0;
ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
@@ -167,10 +246,10 @@ register_addr (int regnum)
{
int addr;
- if (regnum < 0 || regnum >= num_regs)
+ if (regnum < 0 || regnum >= the_low_target.num_regs)
error ("Invalid register number %d.", regnum);
- addr = regmap[regnum];
+ addr = the_low_target.regmap[regnum];
if (addr == -1)
addr = 0;
@@ -184,9 +263,9 @@ fetch_register (int regno)
CORE_ADDR regaddr;
register int i;
- if (regno >= num_regs)
+ if (regno >= the_low_target.num_regs)
return;
- if (cannot_fetch_register (regno))
+ if ((*the_low_target.cannot_fetch_register) (regno))
return;
regaddr = register_addr (regno);
@@ -217,7 +296,7 @@ static void
usr_fetch_inferior_registers (int regno)
{
if (regno == -1 || regno == 0)
- for (regno = 0; regno < num_regs; regno++)
+ for (regno = 0; regno < the_low_target.num_regs; regno++)
fetch_register (regno);
else
fetch_register (regno);
@@ -234,10 +313,10 @@ usr_store_inferior_registers (int regno)
if (regno >= 0)
{
- if (regno >= num_regs)
+ if (regno >= the_low_target.num_regs)
return;
- if (cannot_store_register (regno))
+ if ((*the_low_target.cannot_store_register) (regno) == 1)
return;
regaddr = register_addr (regno);
@@ -251,20 +330,21 @@ usr_store_inferior_registers (int regno)
*(int *) (register_data (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;
+ if ((*the_low_target.cannot_store_register) (regno) == 0)
+ {
+ 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; regno++)
+ for (regno = 0; regno < the_low_target.num_regs; regno++)
store_inferior_registers (regno);
}
#endif /* HAVE_LINUX_USRREGS */
@@ -292,7 +372,7 @@ regsets_fetch_inferior_registers (void)
}
buf = malloc (regset->size);
- res = ptrace (regset->get_request, inferior_pid, 0, (int) buf);
+ res = ptrace (regset->get_request, inferior_pid, 0, buf);
if (res < 0)
{
if (errno == EIO)
@@ -318,6 +398,7 @@ regsets_fetch_inferior_registers (void)
regset->store_function (buf);
regset ++;
}
+ return 0;
}
static int
@@ -340,7 +421,7 @@ regsets_store_inferior_registers (void)
buf = malloc (regset->size);
regset->fill_function (buf);
- res = ptrace (regset->set_request, inferior_pid, 0, (int) buf);
+ res = ptrace (regset->set_request, inferior_pid, 0, buf);
if (res < 0)
{
if (errno == EIO)
@@ -360,18 +441,19 @@ regsets_store_inferior_registers (void)
}
else
{
- perror ("Warning: ptrace(regsets_fetch_inferior_registers)");
+ perror ("Warning: ptrace(regsets_store_inferior_registers)");
}
}
regset ++;
}
+ return 0;
}
#endif /* HAVE_LINUX_REGSETS */
void
-fetch_inferior_registers (int regno)
+linux_fetch_registers (int regno)
{
#ifdef HAVE_LINUX_REGSETS
if (use_regsets_p)
@@ -386,7 +468,7 @@ fetch_inferior_registers (int regno)
}
void
-store_inferior_registers (int regno)
+linux_store_registers (int regno)
{
#ifdef HAVE_LINUX_REGSETS
if (use_regsets_p)
@@ -404,8 +486,8 @@ store_inferior_registers (int regno)
/* 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)
+static void
+linux_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
{
register int i;
/* Round starting address down to longword boundary. */
@@ -433,8 +515,8 @@ read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
On failure (cannot write the inferior)
returns the value of errno. */
-int
-write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+static int
+linux_write_memory (CORE_ADDR memaddr, const char *myaddr, int len)
{
register int i;
/* Round starting address down to longword boundary. */
@@ -476,9 +558,33 @@ write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
return 0;
}
+
+static void
+linux_look_up_symbols (void)
+{
+ /* Don't need to look up any symbols yet. */
+}
+
+static struct target_ops linux_target_ops = {
+ linux_create_inferior,
+ linux_attach,
+ linux_kill,
+ linux_thread_alive,
+ linux_resume,
+ linux_wait,
+ linux_fetch_registers,
+ linux_store_registers,
+ linux_read_memory,
+ linux_write_memory,
+ linux_look_up_symbols,
+};
+
void
initialize_low (void)
{
+ set_target_ops (&linux_target_ops);
+ set_breakpoint_data (the_low_target.breakpoint,
+ the_low_target.breakpoint_len);
init_registers ();
}
diff --git a/gdb/gdbserver/linux-low.h b/gdb/gdbserver/linux-low.h
index 421fa22..b484982 100644
--- a/gdb/gdbserver/linux-low.h
+++ b/gdb/gdbserver/linux-low.h
@@ -18,13 +18,6 @@
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
-#ifdef HAVE_LINUX_USR_REGISTERS
-extern int regmap[];
-extern int num_regs;
-int cannot_fetch_register (int regno);
-int cannot_store_register (int regno);
-#endif
-
#ifdef HAVE_LINUX_REGSETS
typedef void (*regset_func) (void *);
struct regset_info
@@ -35,3 +28,22 @@ struct regset_info
};
extern struct regset_info target_regsets[];
#endif
+
+struct linux_target_ops
+{
+ int num_regs;
+ int *regmap;
+ int (*cannot_fetch_register) (int);
+
+ /* Returns 0 if we can store the register, 1 if we can not
+ store the register, and 2 if failure to store the register
+ is acceptable. */
+ int (*cannot_store_register) (int);
+ CORE_ADDR (*stop_pc) (void);
+ void (*set_pc) (CORE_ADDR newpc);
+ const char *breakpoint;
+ int breakpoint_len;
+ CORE_ADDR (*breakpoint_reinsert_addr) (void);
+};
+
+extern struct linux_target_ops the_low_target;
diff --git a/gdb/gdbserver/linux-m68k-low.c b/gdb/gdbserver/linux-m68k-low.c
index 9e59fbd..760de6e 100644
--- a/gdb/gdbserver/linux-m68k-low.c
+++ b/gdb/gdbserver/linux-m68k-low.c
@@ -26,10 +26,10 @@
#include <sys/reg.h>
#endif
-int num_regs = 31;
+#define m68k_num_regs 31
/* This table must line up with REGISTER_NAMES in tm-m68k.h */
-int regmap[] =
+static int m68k_regmap[] =
{
#ifdef PT_D0
PT_D0 * 4, PT_D1 * 4, PT_D2 * 4, PT_D3 * 4,
@@ -52,14 +52,21 @@ int regmap[] =
#endif
};
-int
-cannot_store_register (int regno)
+static int
+m68k_cannot_store_register (int regno)
{
- return (regno >= num_regs);
+ return (regno >= m68k_num_regs);
}
-int
-cannot_fetch_register (int regno)
+static int
+m68k_cannot_fetch_register (int regno)
{
- return (regno >= num_regs);
+ return (regno >= m68k_num_regs);
}
+
+struct linux_target_ops the_low_target = {
+ m68k_num_regs,
+ m68k_regmap,
+ m68k_cannot_fetch_register,
+ m68k_cannot_store_register,
+};
diff --git a/gdb/gdbserver/linux-mips-low.c b/gdb/gdbserver/linux-mips-low.c
index a9114d3..f721ec9 100644
--- a/gdb/gdbserver/linux-mips-low.c
+++ b/gdb/gdbserver/linux-mips-low.c
@@ -26,14 +26,14 @@
#include <sys/reg.h>
#endif
-int num_regs = 90;
+#define mips_num_regs 90
#include <asm/ptrace.h>
/* Return the ptrace ``address'' of register REGNO. */
/* Matches mips_generic32_regs */
-int regmap[] = {
+static int mips_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,
@@ -63,10 +63,10 @@ int regmap[] = {
ZERO_REGNUM. We also can not set BADVADDR, CAUSE, or FCRIR via
ptrace(). */
-int
-cannot_fetch_register (int regno)
+static int
+mips_cannot_fetch_register (int regno)
{
- if (regmap[regno] == -1)
+ if (mips_regmap[regno] == -1)
return 1;
if (find_regno ("zero") == regno)
@@ -75,10 +75,10 @@ cannot_fetch_register (int regno)
return 0;
}
-int
-cannot_store_register (int regno)
+static int
+mips_cannot_store_register (int regno)
{
- if (regmap[regno] == -1)
+ if (mips_regmap[regno] == -1)
return 1;
if (find_regno ("zero") == regno)
@@ -95,3 +95,10 @@ cannot_store_register (int regno)
return 0;
}
+
+struct linux_target_ops the_low_target = {
+ mips_num_regs,
+ mips_regmap,
+ mips_cannot_fetch_register,
+ mips_cannot_store_register,
+};
diff --git a/gdb/gdbserver/linux-ppc-low.c b/gdb/gdbserver/linux-ppc-low.c
index dcefa59..7cb315a 100644
--- a/gdb/gdbserver/linux-ppc-low.c
+++ b/gdb/gdbserver/linux-ppc-low.c
@@ -25,10 +25,10 @@
#include <asm/ptrace.h>
-int num_regs = 71;
+#define ppc_num_regs 71
/* Currently, don't check/send MQ. */
-int regmap[] =
+static int ppc_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,
@@ -46,17 +46,27 @@ int regmap[] =
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, };
+ PT_CTR * 4, PT_XER * 4, PT_FPSCR * 4, };
-int
-cannot_store_register (int regno)
+static int
+ppc_cannot_store_register (int regno)
{
+ /* Some kernels do not allow us to store fpscr. */
+ if (regno == find_regno ("fpscr"))
+ return 2;
+
return 0;
}
-int
-cannot_fetch_register (int regno)
+static int
+ppc_cannot_fetch_register (int regno)
{
return 0;
}
+struct linux_target_ops the_low_target = {
+ ppc_num_regs,
+ ppc_regmap,
+ ppc_cannot_fetch_register,
+ ppc_cannot_store_register,
+};
diff --git a/gdb/gdbserver/linux-s390-low.c b/gdb/gdbserver/linux-s390-low.c
index 1920b9c..8d800ae 100644
--- a/gdb/gdbserver/linux-s390-low.c
+++ b/gdb/gdbserver/linux-s390-low.c
@@ -27,9 +27,9 @@
#include <asm/ptrace.h>
-int num_regs = 67;
+#define s390_num_regs 67
-int regmap[] = {
+static int s390_regmap[] = {
PT_PSWMASK, PT_PSWADDR,
PT_GPR0, PT_GPR1, PT_GPR2, PT_GPR3,
@@ -62,20 +62,27 @@ int regmap[] = {
#endif
};
-int
-cannot_fetch_register (int regno)
+static int
+s390_cannot_fetch_register (int regno)
{
- if (regmap[regno] == -1)
+ if (s390_regmap[regno] == -1)
return 1;
return 0;
}
-int
-cannot_store_register (int regno)
+static int
+s390_cannot_store_register (int regno)
{
- if (regmap[regno] == -1)
+ if (s390_regmap[regno] == -1)
return 1;
return 0;
}
+
+struct linux_target_ops the_low_target = {
+ s390_num_regs,
+ s390_regmap,
+ s390_cannot_fetch_register,
+ s390_cannot_store_register,
+};
diff --git a/gdb/gdbserver/linux-sh-low.c b/gdb/gdbserver/linux-sh-low.c
index f763339..cdc390d 100644
--- a/gdb/gdbserver/linux-sh-low.c
+++ b/gdb/gdbserver/linux-sh-low.c
@@ -28,10 +28,10 @@
#include <asm/ptrace.h>
-int num_regs = 41;
+#define sh_num_regs 41
/* Currently, don't check/send MQ. */
-int regmap[] = {
+static int sh_regmap[] = {
0, 4, 8, 12, 16, 20, 24, 28,
32, 36, 40, 44, 48, 52, 56, 60,
@@ -45,15 +45,21 @@ int regmap[] = {
REG_FPREG0+48, REG_FPREG0+52, REG_FPREG0+56, REG_FPREG0+60,
};
-int
-cannot_store_register (int regno)
+static int
+sh_cannot_store_register (int regno)
{
return 0;
}
-int
-cannot_fetch_register (int regno)
+static int
+sh_cannot_fetch_register (int regno)
{
return 0;
}
+struct linux_target_ops the_low_target = {
+ sh_num_regs,
+ sh_regmap,
+ sh_cannot_fetch_register,
+ sh_cannot_store_register,
+};
diff --git a/gdb/gdbserver/linux-x86-64-low.c b/gdb/gdbserver/linux-x86-64-low.c
index ffb0ce7..e124890 100644
--- a/gdb/gdbserver/linux-x86-64-low.c
+++ b/gdb/gdbserver/linux-x86-64-low.c
@@ -28,12 +28,15 @@
#include <sys/procfs.h>
#include <sys/ptrace.h>
-static int regmap[] = {
- RAX, RDX, RCX, RBX,
+#define X86_64_NUM_GREGS 22
+
+static int x86_64_regmap[X86_64_NUM_GREGS] = {
+ RAX, RBX, RCX, RDX,
RSI, RDI, RBP, RSP,
R8, R9, R10, R11,
R12, R13, R14, R15,
- RIP, EFLAGS
+ RIP, EFLAGS,
+ DS, ES, FS, GS
};
static void
@@ -41,8 +44,8 @@ x86_64_fill_gregset (void *buf)
{
int i;
- for (i = 0; i < 18; i++)
- collect_register (i, ((char *) buf) + regmap[i]);
+ for (i = 0; i < X86_64_NUM_GREGS; i++)
+ collect_register (i, ((char *) buf) + x86_64_regmap[i]);
}
static void
@@ -50,8 +53,8 @@ x86_64_store_gregset (void *buf)
{
int i;
- for (i = 0; i < 18; i++)
- supply_register (i, ((char *) buf) + regmap[i]);
+ for (i = 0; i < X86_64_NUM_GREGS; i++)
+ supply_register (i, ((char *) buf) + x86_64_regmap[i]);
}
static void
@@ -66,7 +69,6 @@ x86_64_store_fpregset (void *buf)
i387_fxsave_to_cache (buf);
}
-
struct regset_info target_regsets[] = {
{ PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
x86_64_fill_gregset, x86_64_store_gregset },
@@ -74,3 +76,10 @@ struct regset_info target_regsets[] = {
x86_64_fill_fpregset, x86_64_store_fpregset },
{ 0, 0, -1, NULL, NULL }
};
+
+struct linux_target_ops the_low_target = {
+ -1,
+ NULL,
+ NULL,
+ NULL,
+};
diff --git a/gdb/gdbserver/mem-break.c b/gdb/gdbserver/mem-break.c
new file mode 100644
index 0000000..91addf6
--- /dev/null
+++ b/gdb/gdbserver/mem-break.c
@@ -0,0 +1,280 @@
+/* Memory breakpoint operations for the remote server for GDB.
+ Copyright 2002
+ Free Software Foundation, Inc.
+
+ Contributed by MontaVista Software.
+
+ 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"
+
+const char *breakpoint_data;
+int breakpoint_len;
+
+#define MAX_BREAKPOINT_LEN 8
+
+struct breakpoint
+{
+ struct breakpoint *next;
+ CORE_ADDR pc;
+ unsigned char old_data[MAX_BREAKPOINT_LEN];
+
+ /* Non-zero iff we are stepping over this breakpoint. */
+ int reinserting;
+
+ /* Non-NULL iff this breakpoint was inserted to step over
+ another one. Points to the other breakpoint (which is also
+ in the *next chain somewhere). */
+ struct breakpoint *breakpoint_to_reinsert;
+
+ /* Function to call when we hit this breakpoint. */
+ void (*handler) (CORE_ADDR);
+};
+
+struct breakpoint *breakpoints;
+
+void
+set_breakpoint_at (CORE_ADDR where, void (*handler) (CORE_ADDR))
+{
+ struct breakpoint *bp;
+
+ if (breakpoint_data == NULL)
+ error ("Target does not support breakpoints.");
+
+ bp = malloc (sizeof (struct breakpoint));
+ memset (bp, 0, sizeof (struct breakpoint));
+
+ (*the_target->read_memory) (where, bp->old_data,
+ breakpoint_len);
+ (*the_target->write_memory) (where, breakpoint_data,
+ breakpoint_len);
+
+ bp->pc = where;
+ bp->handler = handler;
+
+ bp->next = breakpoints;
+ breakpoints = bp;
+}
+
+static void
+delete_breakpoint (struct breakpoint *bp)
+{
+ struct breakpoint *cur;
+
+ if (breakpoints == bp)
+ {
+ breakpoints = bp->next;
+ (*the_target->write_memory) (bp->pc, bp->old_data,
+ breakpoint_len);
+ free (bp);
+ return;
+ }
+ cur = breakpoints;
+ while (cur->next)
+ {
+ if (cur->next == bp)
+ {
+ cur->next = bp->next;
+ (*the_target->write_memory) (bp->pc, bp->old_data,
+ breakpoint_len);
+ free (bp);
+ return;
+ }
+ }
+ warning ("Could not find breakpoint in list.");
+}
+
+static struct breakpoint *
+find_breakpoint_at (CORE_ADDR where)
+{
+ struct breakpoint *bp = breakpoints;
+
+ while (bp != NULL)
+ {
+ if (bp->pc == where)
+ return bp;
+ bp = bp->next;
+ }
+
+ return NULL;
+}
+
+static void
+reinsert_breakpoint_handler (CORE_ADDR stop_pc)
+{
+ struct breakpoint *stop_bp, *orig_bp;
+
+ stop_bp = find_breakpoint_at (stop_pc);
+ if (stop_bp == NULL)
+ error ("lost the stopping breakpoint.");
+
+ orig_bp = stop_bp->breakpoint_to_reinsert;
+ if (orig_bp == NULL)
+ error ("no breakpoint to reinsert");
+
+ (*the_target->write_memory) (orig_bp->pc, breakpoint_data,
+ breakpoint_len);
+ orig_bp->reinserting = 0;
+ delete_breakpoint (stop_bp);
+}
+
+void
+reinsert_breakpoint_by_bp (CORE_ADDR stop_pc, CORE_ADDR stop_at)
+{
+ struct breakpoint *bp, *orig_bp;
+
+ set_breakpoint_at (stop_at, reinsert_breakpoint_handler);
+
+ orig_bp = find_breakpoint_at (stop_at);
+ if (orig_bp == NULL)
+ error ("Could not find original breakpoint in list.");
+
+ bp = find_breakpoint_at (stop_at);
+ if (bp == NULL)
+ error ("Could not find breakpoint in list (reinserting by breakpoint).");
+ bp->breakpoint_to_reinsert = orig_bp;
+
+ (*the_target->write_memory) (orig_bp->pc, orig_bp->old_data,
+ breakpoint_len);
+ orig_bp->reinserting = 1;
+}
+
+void
+uninsert_breakpoint (CORE_ADDR stopped_at)
+{
+ struct breakpoint *bp;
+
+ bp = find_breakpoint_at (stopped_at);
+ if (bp == NULL)
+ error ("Could not find breakpoint in list (uninserting).");
+
+ (*the_target->write_memory) (bp->pc, bp->old_data,
+ breakpoint_len);
+ bp->reinserting = 1;
+}
+
+void
+reinsert_breakpoint (CORE_ADDR stopped_at)
+{
+ struct breakpoint *bp;
+
+ bp = find_breakpoint_at (stopped_at);
+ if (bp == NULL)
+ error ("Could not find breakpoint in list (uninserting).");
+ if (! bp->reinserting)
+ error ("Breakpoint already inserted at reinsert time.");
+
+ (*the_target->write_memory) (bp->pc, breakpoint_data,
+ breakpoint_len);
+ bp->reinserting = 0;
+}
+
+int
+check_breakpoints (CORE_ADDR stop_pc)
+{
+ struct breakpoint *bp;
+
+ bp = find_breakpoint_at (stop_pc);
+ if (bp == NULL)
+ return 0;
+ if (bp->reinserting)
+ {
+ warning ("Hit a removed breakpoint?");
+ return 0;
+ }
+
+ (*bp->handler) (bp->pc);
+ return 1;
+}
+
+void
+set_breakpoint_data (const char *bp_data, int bp_len)
+{
+ breakpoint_data = bp_data;
+ breakpoint_len = bp_len;
+}
+
+void
+check_mem_read (CORE_ADDR mem_addr, char *buf, int mem_len)
+{
+ struct breakpoint *bp = breakpoints;
+ CORE_ADDR mem_end = mem_addr + mem_len;
+
+ for (; bp != NULL; bp = bp->next)
+ {
+ CORE_ADDR bp_end = bp->pc + breakpoint_len;
+ CORE_ADDR start, end;
+ int copy_offset, copy_len, buf_offset;
+
+ if (mem_addr >= bp_end)
+ continue;
+ if (bp->pc >= mem_end)
+ continue;
+
+ start = bp->pc;
+ if (mem_addr > start)
+ start = mem_addr;
+
+ end = bp_end;
+ if (end > mem_end)
+ end = mem_end;
+
+ copy_len = end - start;
+ copy_offset = start - bp->pc;
+ buf_offset = start - mem_addr;
+
+ memcpy (buf + buf_offset, bp->old_data + copy_offset, copy_len);
+ }
+}
+
+void
+check_mem_write (CORE_ADDR mem_addr, char *buf, int mem_len)
+{
+ struct breakpoint *bp = breakpoints;
+ CORE_ADDR mem_end = mem_addr + mem_len;
+
+ for (; bp != NULL; bp = bp->next)
+ {
+ CORE_ADDR bp_end = bp->pc + breakpoint_len;
+ CORE_ADDR start, end;
+ int copy_offset, copy_len, buf_offset;
+
+ if (mem_addr >= bp_end)
+ continue;
+ if (bp->pc >= mem_end)
+ continue;
+
+ start = bp->pc;
+ if (mem_addr > start)
+ start = mem_addr;
+
+ end = bp_end;
+ if (end > mem_end)
+ end = mem_end;
+
+ copy_len = end - start;
+ copy_offset = start - bp->pc;
+ buf_offset = start - mem_addr;
+
+ memcpy (bp->old_data + copy_offset, buf + buf_offset, copy_len);
+ if (bp->reinserting == 0)
+ memcpy (buf + buf_offset, breakpoint_data + copy_offset, copy_len);
+ }
+}
+
+
diff --git a/gdb/gdbserver/mem-break.h b/gdb/gdbserver/mem-break.h
new file mode 100644
index 0000000..356e763
--- /dev/null
+++ b/gdb/gdbserver/mem-break.h
@@ -0,0 +1,71 @@
+/* Memory breakpoint interfaces for the remote server for GDB.
+ Copyright 2002
+ Free Software Foundation, Inc.
+
+ Contributed by MontaVista Software.
+
+ 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 MEM_BREAK_H
+#define MEM_BREAK_H
+
+/* Breakpoints are opaque. */
+
+/* Create a new breakpoint at WHERE, and call HANDLER when
+ it is hit. */
+
+void set_breakpoint_at (CORE_ADDR where,
+ void (*handler) (CORE_ADDR));
+
+/* Create a reinsertion breakpoint at STOP_AT for the breakpoint
+ currently at STOP_PC (and temporarily remove the breakpoint at
+ STOP_PC). */
+
+void reinsert_breakpoint_by_bp (CORE_ADDR stop_pc, CORE_ADDR stop_at);
+
+/* Change the status of the breakpoint at WHERE to inserted. */
+
+void reinsert_breakpoint (CORE_ADDR where);
+
+/* Change the status of the breakpoint at WHERE to uninserted. */
+
+void uninsert_breakpoint (CORE_ADDR where);
+
+/* See if any breakpoint claims ownership of STOP_PC. Call the handler for
+ the breakpoint, if found. */
+
+int check_breakpoints (CORE_ADDR stop_pc);
+
+/* See if any breakpoints shadow the target memory area from MEM_ADDR
+ to MEM_ADDR + MEM_LEN. Update the data already read from the target
+ (in BUF) if necessary. */
+
+void check_mem_read (CORE_ADDR mem_addr, char *buf, int mem_len);
+
+/* See if any breakpoints shadow the target memory area from MEM_ADDR
+ to MEM_ADDR + MEM_LEN. Update the data to be written to the target
+ (in BUF) if necessary, as well as the original data for any breakpoints. */
+
+void check_mem_write (CORE_ADDR mem_addr, char *buf, int mem_len);
+
+/* Set the byte pattern to insert for memory breakpoints. This function
+ must be called before any breakpoints are set. */
+
+void set_breakpoint_data (const char *bp_data, int bp_len);
+
+#endif /* MEM_BREAK_H */
diff --git a/gdb/gdbserver/regcache.c b/gdb/gdbserver/regcache.c
index bec20bb..701d092 100644
--- a/gdb/gdbserver/regcache.c
+++ b/gdb/gdbserver/regcache.c
@@ -25,7 +25,11 @@
#include <stdlib.h>
#include <string.h>
-static char *registers;
+struct inferior_regcache_data
+{
+ char *registers;
+};
+
static int register_bytes;
static struct reg *reg_defs;
@@ -33,6 +37,19 @@ static int num_registers;
const char **gdbserver_expedite_regs;
+static struct inferior_regcache_data *
+get_regcache (struct inferior_info *inf)
+{
+ struct inferior_regcache_data *regcache;
+
+ regcache = (struct inferior_regcache_data *) inferior_regcache_data (inf);
+
+ if (regcache == NULL)
+ fatal ("no register cache");
+
+ return regcache;
+}
+
int
registers_length (void)
{
@@ -40,6 +57,28 @@ registers_length (void)
}
void
+create_register_cache (struct inferior_info *inferior)
+{
+ struct inferior_regcache_data *regcache;
+
+ regcache = malloc (sizeof (*regcache));
+
+ regcache->registers = malloc (register_bytes);
+ if (regcache->registers == NULL)
+ fatal ("Could not allocate register cache.");
+
+ set_inferior_regcache_data (inferior, regcache);
+}
+
+void
+free_register_cache (struct inferior_info *inferior)
+{
+ free (get_regcache (current_inferior)->registers);
+ free (get_regcache (current_inferior));
+ set_inferior_regcache_data (inferior, NULL);
+}
+
+void
set_register_cache (struct reg *regs, int n)
{
int offset, i;
@@ -55,14 +94,13 @@ set_register_cache (struct reg *regs, int n)
}
register_bytes = offset / 8;
- registers = malloc (offset / 8);
- if (!registers)
- fatal ("Could not allocate register cache.");
}
void
registers_to_string (char *buf)
{
+ char *registers = get_regcache (current_inferior)->registers;
+
convert_int_to_ascii (registers, buf, register_bytes);
}
@@ -70,6 +108,7 @@ void
registers_from_string (char *buf)
{
int len = strlen (buf);
+ char *registers = get_regcache (current_inferior)->registers;
if (len != register_bytes * 2)
{
@@ -119,29 +158,31 @@ register_size (int n)
char *
register_data (int n)
{
+ char *registers = get_regcache (current_inferior)->registers;
+
return registers + (reg_defs[n].offset / 8);
}
void
-supply_register (int n, const char *buf)
+supply_register (int n, const void *buf)
{
memcpy (register_data (n), buf, register_size (n));
}
void
-supply_register_by_name (const char *name, const char *buf)
+supply_register_by_name (const char *name, const void *buf)
{
supply_register (find_regno (name), buf);
}
void
-collect_register (int n, char *buf)
+collect_register (int n, void *buf)
{
memcpy (buf, register_data (n), register_size (n));
}
void
-collect_register_by_name (const char *name, char *buf)
+collect_register_by_name (const char *name, void *buf)
{
collect_register (find_regno (name), buf);
}
diff --git a/gdb/gdbserver/regcache.h b/gdb/gdbserver/regcache.h
index 07195b3..362288e 100644
--- a/gdb/gdbserver/regcache.h
+++ b/gdb/gdbserver/regcache.h
@@ -21,6 +21,16 @@
#ifndef REGCACHE_H
#define REGCACHE_H
+struct inferior_info;
+
+/* Create a new register cache for INFERIOR. */
+
+void create_register_cache (struct inferior_info *inferior);
+
+/* Release all memory associated with the register cache for INFERIOR. */
+
+void free_register_cache (struct inferior_info *inferior);
+
/* Convert all registers to a string in the currently specified remote
format. */
@@ -46,4 +56,12 @@ int find_regno (const char *name);
extern const char **gdbserver_expedite_regs;
+void supply_register (int n, const void *buf);
+
+void supply_register_by_name (const char *name, const void *buf);
+
+void collect_register (int n, void *buf);
+
+void collect_register_by_name (const char *name, void *buf);
+
#endif /* REGCACHE_H */
diff --git a/gdb/gdbserver/remote-utils.c b/gdb/gdbserver/remote-utils.c
index ff1718f..14734f1 100644
--- a/gdb/gdbserver/remote-utils.c
+++ b/gdb/gdbserver/remote-utils.c
@@ -35,6 +35,7 @@
#include <fcntl.h>
#include <sys/time.h>
#include <unistd.h>
+#include <arpa/inet.h>
int remote_debug = 0;
struct ui_file *gdb_stdlog;
@@ -48,7 +49,7 @@ void
remote_open (char *name)
{
int save_fcntl_flags;
-
+
if (!strchr (name, ':'))
{
remote_desc = open (name, O_RDWR);
@@ -99,7 +100,7 @@ remote_open (char *name)
}
#endif
-
+ fprintf (stderr, "Remote debugging using %s\n", name);
}
else
{
@@ -107,7 +108,6 @@ remote_open (char *name)
int port;
struct sockaddr_in sockaddr;
int tmp;
- struct protoent *protoent;
int tmp_desc;
port_str = strchr (name, ':');
@@ -136,10 +136,6 @@ remote_open (char *name)
if (remote_desc == -1)
perror_with_name ("Accept failed");
- protoent = getprotobyname ("tcp");
- if (!protoent)
- perror_with_name ("getprotobyname");
-
/* Enable TCP keep alive process. */
tmp = 1;
setsockopt (tmp_desc, SOL_SOCKET, SO_KEEPALIVE, (char *) &tmp, sizeof (tmp));
@@ -147,13 +143,17 @@ remote_open (char *name)
/* Tell TCP not to delay small packets. This greatly speeds up
interactive response. */
tmp = 1;
- setsockopt (remote_desc, protoent->p_proto, TCP_NODELAY,
+ setsockopt (remote_desc, IPPROTO_TCP, TCP_NODELAY,
(char *) &tmp, sizeof (tmp));
close (tmp_desc); /* No longer need this */
signal (SIGPIPE, SIG_IGN); /* If we don't do this, then gdbserver simply
exits when the remote side dies. */
+
+ /* Convert IP address to string. */
+ fprintf (stderr, "Remote debugging from host %s\n",
+ inet_ntoa (sockaddr.sin_addr));
}
#if defined(F_SETFL) && defined (FASYNC)
@@ -164,7 +164,6 @@ remote_open (char *name)
#endif
#endif
disable_async_io ();
- fprintf (stderr, "Remote debugging using %s\n", name);
}
void
@@ -187,6 +186,42 @@ fromhex (int a)
return 0;
}
+int
+unhexify (char *bin, const char *hex, int count)
+{
+ int i;
+
+ for (i = 0; i < count; i++)
+ {
+ if (hex[0] == 0 || hex[1] == 0)
+ {
+ /* Hex string is short, or of uneven length.
+ Return the count that has been converted so far. */
+ return i;
+ }
+ *bin++ = fromhex (hex[0]) * 16 + fromhex (hex[1]);
+ hex += 2;
+ }
+ return i;
+}
+
+static void
+decode_address (CORE_ADDR *addrp, const char *start, int len)
+{
+ CORE_ADDR addr;
+ char ch;
+ int i;
+
+ addr = 0;
+ for (i = 0; i < len; i++)
+ {
+ ch = start[i];
+ addr = addr << 4;
+ addr = addr | (fromhex (ch) & 0x0f);
+ }
+ *addrp = addr;
+}
+
/* Convert number NIB to a hex digit. */
static int
@@ -198,6 +233,24 @@ tohex (int nib)
return 'a' + nib - 10;
}
+int
+hexify (char *hex, const char *bin, int count)
+{
+ int i;
+
+ /* May use a length, or a nul-terminated string as input. */
+ if (count == 0)
+ count = strlen (bin);
+
+ for (i = 0; i < count; i++)
+ {
+ *hex++ = tohex ((*bin >> 4) & 0xf);
+ *hex++ = tohex (*bin++ & 0xf);
+ }
+ *hex = 0;
+ return i;
+}
+
/* Send a packet to the remote machine, with error checking.
The data of the packet is in BUF. Returns >= 0 on success, -1 otherwise. */
@@ -293,7 +346,7 @@ input_interrupt (int unused)
return;
}
- kill (inferior_pid, SIGINT);
+ kill (signal_pid, SIGINT);
}
}
@@ -465,17 +518,15 @@ outreg (int regno, char *buf)
void
prepare_resume_reply (char *buf, char status, unsigned char signo)
{
- int nib;
+ int nib, sig;
*buf++ = status;
- /* FIXME! Should be converting this signal number (numbered
- according to the signal numbering of the system we are running on)
- to the signal numbers used by the gdb protocol (see enum target_signal
- in gdb/target.h). */
- nib = ((signo & 0xf0) >> 4);
+ sig = (int)target_signal_from_host (signo);
+
+ nib = ((sig & 0xf0) >> 4);
*buf++ = tohex (nib);
- nib = signo & 0x0f;
+ nib = sig & 0x0f;
*buf++ = tohex (nib);
if (status == 'T')
@@ -547,3 +598,42 @@ decode_M_packet (char *from, CORE_ADDR *mem_addr_ptr, unsigned int *len_ptr,
convert_ascii_to_int (&from[i++], to, *len_ptr);
}
+
+int
+look_up_one_symbol (const char *name, CORE_ADDR *addrp)
+{
+ char own_buf[266], *p, *q;
+ int len;
+
+ /* Send the request. */
+ strcpy (own_buf, "qSymbol:");
+ hexify (own_buf + strlen ("qSymbol:"), name, strlen (name));
+ if (putpkt (own_buf) < 0)
+ return -1;
+
+ /* FIXME: Eventually add buffer overflow checking (to getpkt?) */
+ len = getpkt (own_buf);
+ if (len < 0)
+ return -1;
+
+ if (strncmp (own_buf, "qSymbol:", strlen ("qSymbol:")) != 0)
+ {
+ /* Malformed response. */
+ if (remote_debug)
+ fprintf (stderr, "Malformed response to qSymbol, ignoring.\n");
+ return -1;
+ }
+
+ p = own_buf + strlen ("qSymbol:");
+ q = p;
+ while (*q && *q != ':')
+ q++;
+
+ /* Make sure we found a value for the symbol. */
+ if (p == q || *q == '\0')
+ return 0;
+
+ decode_address (addrp, p, q - p);
+ return 1;
+}
+
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index d845422..ba85b59 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -27,13 +27,14 @@ int thread_from_wait;
int old_thread_from_wait;
int extended_protocol;
jmp_buf toplevel;
-int inferior_pid;
static unsigned char
start_inferior (char *argv[], char *statusptr)
{
- inferior_pid = create_inferior (argv[0], argv);
- fprintf (stderr, "Process %s created; pid = %d\n", argv[0], inferior_pid);
+ /* FIXME Check error? Or turn to void. */
+ create_inferior (argv[0], argv);
+ /* FIXME Print pid properly. */
+ fprintf (stderr, "Process %s created; pid = %d\n", argv[0], signal_pid);
/* Wait till we are at 1st instruction in program, return signal number. */
return mywait (statusptr);
@@ -47,8 +48,6 @@ attach_inferior (int pid, char *statusptr, unsigned char *sigptr)
if (myattach (pid) != 0)
return -1;
- inferior_pid = pid;
-
*sigptr = mywait (statusptr);
return 0;
@@ -56,6 +55,26 @@ attach_inferior (int pid, char *statusptr, unsigned char *sigptr)
extern int remote_debug;
+/* Handle all of the extended 'q' packets. */
+void
+handle_query (char *own_buf)
+{
+ if (strcmp ("qSymbol::", own_buf) == 0)
+ {
+ if (the_target->look_up_symbols != NULL)
+ (*the_target->look_up_symbols) ();
+
+ strcpy (own_buf, "OK");
+ return;
+ }
+
+ /* Otherwise we didn't know what packet it was. Say we didn't
+ understand it. */
+ own_buf[0] = 0;
+}
+
+static int attached;
+
int
main (int argc, char *argv[])
{
@@ -64,9 +83,8 @@ main (int argc, char *argv[])
unsigned char signal;
unsigned int len;
CORE_ADDR mem_addr;
- int bad_attach = 0;
- int pid = 0;
- int attached = 0;
+ int bad_attach;
+ int pid;
char *arg_end;
if (setjmp (toplevel))
@@ -75,6 +93,9 @@ main (int argc, char *argv[])
exit (1);
}
+ bad_attach = 0;
+ pid = 0;
+ attached = 0;
if (argc >= 3 && strcmp (argv[2], "--attach") == 0)
{
if (argc == 4
@@ -129,6 +150,9 @@ main (int argc, char *argv[])
ch = own_buf[i++];
switch (ch)
{
+ case 'q':
+ handle_query (own_buf);
+ break;
case 'd':
remote_debug = !remote_debug;
break;
@@ -190,13 +214,21 @@ main (int argc, char *argv[])
break;
case 'C':
convert_ascii_to_int (own_buf + 1, &sig, 1);
- myresume (0, sig);
+ if (target_signal_to_host_p (sig))
+ signal = target_signal_to_host (sig);
+ else
+ signal = 0;
+ myresume (0, signal);
signal = mywait (&status);
prepare_resume_reply (own_buf, status, signal);
break;
case 'S':
convert_ascii_to_int (own_buf + 1, &sig, 1);
- myresume (1, sig);
+ if (target_signal_to_host_p (sig))
+ signal = target_signal_to_host (sig);
+ else
+ signal = 0;
+ myresume (1, signal);
signal = mywait (&status);
prepare_resume_reply (own_buf, status, signal);
break;
diff --git a/gdb/gdbserver/server.h b/gdb/gdbserver/server.h
index 6202b0f..32b90b5 100644
--- a/gdb/gdbserver/server.h
+++ b/gdb/gdbserver/server.h
@@ -23,38 +23,65 @@
#define SERVER_H
#include "config.h"
+
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
+#include <setjmp.h>
-
-/* FIXME: Both of these should be autoconf'd for. */
-#define NORETURN
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#ifndef ATTR_NORETURN
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7))
+#define ATTR_NORETURN __attribute__ ((noreturn))
+#else
+#define ATTR_NORETURN /* nothing */
+#endif
+#endif
+
+#ifndef ATTR_FORMAT
+#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 4))
+#define ATTR_FORMAT(type, x, y) __attribute__ ((format(type, x, y)))
+#else
+#define ATTR_FORMAT(type, x, y) /* nothing */
+#endif
+#endif
+
+/* FIXME: This should probably be autoconf'd for. It's an integer type at
+ least the size of a (void *). */
typedef long long CORE_ADDR;
+/* Opaque inferior process information. */
+struct inferior_info;
+
#include "regcache.h"
+#include "gdb/signals.h"
-#include <setjmp.h>
+#include "target.h"
+#include "mem-break.h"
/* Target-specific functions */
-int create_inferior (char *program, char **allargs);
-void kill_inferior (void);
-void fetch_inferior_registers (int regno);
-void store_inferior_registers (int regno);
-int mythread_alive (int pid);
-void myresume (int step, int signo);
-unsigned char mywait (char *status);
-void read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len);
-int write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len);
-int create_inferior ();
void initialize_low ();
/* Target-specific variables */
extern char *registers;
+/* From inferiors.c. */
+
+extern struct inferior_info *current_inferior;
+extern int signal_pid;
+void add_inferior (int pid);
+void clear_inferiors (void);
+void *inferior_target_data (struct inferior_info *);
+void set_inferior_target_data (struct inferior_info *, void *);
+void *inferior_regcache_data (struct inferior_info *);
+void set_inferior_regcache_data (struct inferior_info *, void *);
+
/* Public variables in server.c */
extern int cont_thread;
@@ -63,7 +90,6 @@ extern int thread_from_wait;
extern int old_thread_from_wait;
extern jmp_buf toplevel;
-extern int inferior_pid;
/* Functions from remote-utils.c */
@@ -84,15 +110,26 @@ void decode_m_packet (char *from, CORE_ADDR * mem_addr_ptr,
void decode_M_packet (char *from, CORE_ADDR * mem_addr_ptr,
unsigned int *len_ptr, char *to);
+int unhexify (char *bin, const char *hex, int count);
+int hexify (char *hex, const char *bin, int count);
+
+int look_up_one_symbol (const char *name, CORE_ADDR *addrp);
+
+/* Functions from ``signals.c''. */
+enum target_signal target_signal_from_host (int hostsig);
+int target_signal_to_host_p (enum target_signal oursig);
+int target_signal_to_host (enum target_signal oursig);
/* Functions from utils.c */
void perror_with_name (char *string);
-void error (const char *string,...);
-void fatal (const char *string,...);
+void error (const char *string,...) ATTR_NORETURN;
+void fatal (const char *string,...) ATTR_NORETURN;
void warning (const char *string,...);
+/* Functions from the register cache definition. */
+void init_registers (void);
/* Maximum number of bytes to read/write at once. The value here
is chosen to fill up a packet (the headers account for the 32). */
diff --git a/gdb/gdbserver/target.c b/gdb/gdbserver/target.c
new file mode 100644
index 0000000..53a4c1e
--- /dev/null
+++ b/gdb/gdbserver/target.c
@@ -0,0 +1,47 @@
+/* Target operations for the remote server for GDB.
+ Copyright 2002
+ Free Software Foundation, Inc.
+
+ Contributed by MontaVista Software.
+
+ 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"
+
+struct target_ops *the_target;
+
+void
+read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ (*the_target->read_memory) (memaddr, myaddr, len);
+ check_mem_read (memaddr, myaddr, len);
+}
+
+int
+write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len)
+{
+ check_mem_write (memaddr, myaddr, len);
+ return (*the_target->write_memory) (memaddr, myaddr, len);
+}
+
+void
+set_target_ops (struct target_ops *target)
+{
+ the_target = (struct target_ops *) malloc (sizeof (*the_target));
+ memcpy (the_target, target, sizeof (*the_target));
+}
diff --git a/gdb/gdbserver/target.h b/gdb/gdbserver/target.h
new file mode 100644
index 0000000..6d06b9f
--- /dev/null
+++ b/gdb/gdbserver/target.h
@@ -0,0 +1,141 @@
+/* Target operations for the remote server for GDB.
+ Copyright 2002
+ Free Software Foundation, Inc.
+
+ Contributed by MontaVista Software.
+
+ 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 TARGET_H
+#define TARGET_H
+
+struct target_ops
+{
+ /* Start a new process.
+
+ PROGRAM is a path to the program to execute.
+ ARGS is a standard NULL-terminated array of arguments,
+ to be passed to the inferior as ``argv''.
+
+ Returns 0 on success, -1 on failure. Registers the new
+ process with the process list. */
+
+ int (*create_inferior) (char *program, char **args);
+
+ /* Attach to a running process.
+
+ PID is the process ID to attach to, specified by the user
+ or a higher layer. */
+
+ int (*attach) (int pid);
+
+ /* Kill all inferiors. */
+
+ void (*kill) (void);
+
+ /* Return 1 iff the thread with process ID PID is alive. */
+
+ int (*thread_alive) (int pid);
+
+ /* Resume the inferior process.
+
+ If STEP is non-zero, we want to single-step.
+
+ If SIGNAL is nonzero, send the process that signal as we resume it.
+ */
+
+ void (*resume) (int step, int signo);
+
+ /* Wait for the inferior process to change state.
+
+ STATUSP will be filled in with a response code to send to GDB.
+
+ Returns the signal which caused the process to stop. */
+
+ unsigned char (*wait) (char *status);
+
+ /* Fetch registers from the inferior process.
+
+ If REGNO is -1, fetch all registers; otherwise, fetch at least REGNO. */
+
+ void (*fetch_registers) (int regno);
+
+ /* Store registers to the inferior process.
+
+ If REGNO is -1, store all registers; otherwise, store at least REGNO. */
+
+ void (*store_registers) (int regno);
+
+ /* Read memory from the inferior process. This should generally be
+ called through read_inferior_memory, which handles breakpoint shadowing.
+
+ Read LEN bytes at MEMADDR into a buffer at MYADDR. */
+
+ void (*read_memory) (CORE_ADDR memaddr, char *myaddr, int len);
+
+ /* Write memory to the inferior process. This should generally be
+ called through write_inferior_memory, which handles breakpoint shadowing.
+
+ Write LEN bytes from the buffer at MYADDR to MEMADDR.
+
+ Returns 0 on success and errno on failure. */
+
+ int (*write_memory) (CORE_ADDR memaddr, const char *myaddr, int len);
+
+ /* Query GDB for the values of any symbols we're interested in.
+ This function is called whenever we receive a "qSymbols::"
+ query, which corresponds to every time more symbols (might)
+ become available. NULL if we aren't interested in any
+ symbols. */
+
+ void (*look_up_symbols) (void);
+};
+
+extern struct target_ops *the_target;
+
+void set_target_ops (struct target_ops *);
+
+#define create_inferior(program, args) \
+ (*the_target->create_inferior) (program, args)
+
+#define myattach(pid) \
+ (*the_target->attach) (pid)
+
+#define kill_inferior() \
+ (*the_target->kill) ()
+
+#define mythread_alive(pid) \
+ (*the_target->thread_alive) (pid)
+
+#define myresume(step,signo) \
+ (*the_target->resume) (step, signo)
+
+#define mywait(statusp) \
+ (*the_target->wait) (statusp)
+
+#define fetch_inferior_registers(regno) \
+ (*the_target->fetch_registers) (regno)
+
+#define store_inferior_registers(regno) \
+ (*the_target->store_registers) (regno)
+
+void read_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len);
+
+int write_inferior_memory (CORE_ADDR memaddr, char *myaddr, int len);
+
+#endif /* TARGET_H */
diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
index a8ea9a1..e13eda8 100644
--- a/gdb/gdbserver/utils.c
+++ b/gdb/gdbserver/utils.c
@@ -57,7 +57,7 @@ perror_with_name (char *string)
STRING is the error message, used as a fprintf string,
and ARG is passed as an argument to it. */
-NORETURN void
+void
error (const char *string,...)
{
extern jmp_buf toplevel;
@@ -74,7 +74,7 @@ error (const char *string,...)
STRING and ARG are passed to fprintf. */
/* VARARGS */
-NORETURN void
+void
fatal (const char *string,...)
{
va_list args;