* Rename files for 14-character limits:
authorJim Kingdon <jkingdon@engr.sgi.com>
Fri, 27 Aug 1993 16:59:46 +0000 (16:59 +0000)
committerJim Kingdon <jkingdon@engr.sgi.com>
Fri, 27 Aug 1993 16:59:46 +0000 (16:59 +0000)
gdbserver/remote-gutils.c -> gdbserver/utils.c
gdbserver/remote-inflow.c -> gdbserver/low-lynx.c
gdbserver/remote-inflow-sparc.c -> gdbserver/low-sparc.c
gdbserver/remote-server.c -> gdbserver/server.c
remote-monitor.c -> remote-mon.c
* Makefile.in, gdbserver/Makefile.in, config/m68k/monitor.mt:
Change accordingly.
* gdbserver/Makefile.in: Remove more junk inherited from gdb Makefile.

14 files changed:
gdb/.Sanitize
gdb/ChangeLog
gdb/Makefile.in
gdb/gdbserver/.Sanitize
gdb/gdbserver/Makefile.in [new file with mode: 0644]
gdb/gdbserver/low-lynx.c [new file with mode: 0644]
gdb/gdbserver/low-sparc.c [new file with mode: 0644]
gdb/gdbserver/remote-gutils.c [deleted file]
gdb/gdbserver/remote-inflow-sparc.c [deleted file]
gdb/gdbserver/remote-inflow.c [deleted file]
gdb/gdbserver/remote-server.c [deleted file]
gdb/gdbserver/utils.c [new file with mode: 0644]
gdb/remote-mon.c [new file with mode: 0644]
gdb/remote-monitor.c

index 95fa78645a4b4c011a73e75e6d74bfc192c7f3f4..6e6697ffd9c65717815dbfe0d17b814ff96b812e 100644 (file)
@@ -188,7 +188,7 @@ remote-es.c
 remote-hms.c
 remote-mips.c
 remote-mm.c
-remote-monitor.c
+remote-mon.c
 remote-nindy.c
 remote-sim.c
 remote-st.c
index 8b54909879d0eec1bf0347380249add8921326af..0e25efe259e5ef180a8a34396de7f1d1bdddbe21 100644 (file)
@@ -1,3 +1,15 @@
+Fri Aug 27 09:30:40 1993  Jim Kingdon  (kingdon@deneb.cygnus.com)
+
+       * Rename files for 14-character limits:
+       gdbserver/remote-gutils.c -> gdbserver/utils.c
+       gdbserver/remote-inflow.c -> gdbserver/low-lynx.c
+       gdbserver/remote-inflow-sparc.c -> gdbserver/low-sparc.c
+       gdbserver/remote-server.c -> gdbserver/server.c
+       remote-monitor.c -> remote-mon.c
+       * Makefile.in, gdbserver/Makefile.in, config/m68k/monitor.mt:
+       Change accordingly.
+       * gdbserver/Makefile.in: Remove more junk inherited from gdb Makefile.
+
 Thu Aug 26 14:32:51 1993  Jim Kingdon  (kingdon@lioth.cygnus.com)
 
        * infcmd.c, inferior.h (run_stack_dummy): If we stop somewhere
index 407abd47d338dbad50df8826e830d39ee3d39ac1..ee3e02a0a1bdeacb394130f52c2747acea66b609 100644 (file)
@@ -812,7 +812,7 @@ ALLDEPFILES = 29k-share/udi/udip2soc.c 29k-share/udi/udr.c \
        nindy-share/ttyflush.c nindy-tdep.c \
        ns32k-pinsn.c paread.c procfs.c pyr-pinsn.c pyr-tdep.c pyr-xdep.c \
        remote-adapt.c remote-bug.c remote-eb.c remote-es.c remote-hms.c remote-mips.c \
-       remote-mm.c remote-monitor.c remote-nindy.c remote-sim.c remote-st.c \
+       remote-mm.c remote-mon.c remote-nindy.c remote-sim.c remote-st.c \
        remote-udi.c remote-vx.c remote-z8k.c rs6000-nat.c rs6000-pinsn.c \
        rs6000-tdep.c ser-go32.c ser-tcp.c sh-tdep.c solib.c sparc-nat.c \
        sparc-pinsn.c sparc-tdep.c sun3-nat.c sun386-nat.c symm-tdep.c \
@@ -1212,7 +1212,7 @@ remote-mips.o: remote-mips.c $(wait_h) $(defs_h) $(gdbcmd_h) \
 remote-mm.o: remote-mm.c $(bfd_h) $(wait_h) $(defs_h) $(inferior_h) \
        minimon.h target.h terminal.h
 
-remote-monitor.o: remote-monitor.c $(wait_h) $(command_h) $(defs_h) \
+remote-mon.o: remote-mon.c $(wait_h) $(command_h) $(defs_h) \
        $(gdbcore_h) monitor.h serial.h target.h
 
 remote-nindy.o: remote-nindy.c $(ieee-float_h) $(wait_h) $(command_h) \
index ab914bfe6b50c1276ee517b4e7deb92597976163..db910a5f389345044f1f16b8da0e67ee39454971 100644 (file)
@@ -26,17 +26,15 @@ Things-to-keep:
 Makefile.in
 README
 configure.in
-remote-gutils.c
-remote-inflow.c
-remote-server.c
+low-lynx.c
+low-sparc.c
 remote-utils.c
+server.c
 server.h
+utils.c
 
 Things-to-lose:
 
-
-remote-inflow-sparc.c
-
 Do-last:
 
 # End of file.
diff --git a/gdb/gdbserver/Makefile.in b/gdb/gdbserver/Makefile.in
new file mode 100644 (file)
index 0000000..9cd7990
--- /dev/null
@@ -0,0 +1,284 @@
+#Copyright 1989, 1990, 1991, 1992, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+prefix = /usr/local
+
+program_transform_name =
+exec_prefix = $(prefix)
+bindir = $(exec_prefix)/bin
+libdir = $(exec_prefix)/lib
+tooldir = $(libdir)/$(target_alias)
+
+datadir = $(prefix)/lib
+mandir = $(prefix)/man
+man1dir = $(mandir)/man1
+man2dir = $(mandir)/man2
+man3dir = $(mandir)/man3
+man4dir = $(mandir)/man4
+man5dir = $(mandir)/man5
+man6dir = $(mandir)/man6
+man7dir = $(mandir)/man7
+man8dir = $(mandir)/man8
+man9dir = $(mandir)/man9
+infodir = $(prefix)/info
+includedir = $(prefix)/include
+docdir = $(datadir)/doc
+
+SHELL = /bin/sh
+
+INSTALL = install -c
+INSTALL_PROGRAM = $(INSTALL)
+INSTALL_DATA = $(INSTALL)
+
+AR = ar
+AR_FLAGS = qv
+RANLIB = ranlib
+
+# Flags that describe where you can find the termcap library.
+# This can be overridden in the host Makefile fragment file.
+TERMCAP = -ltermcap
+
+# System V: If you compile gdb with a compiler which uses the coff
+# encapsulation feature (this is a function of the compiler used, NOT
+# of the m-?.h file selected by config.gdb), you must make sure that
+# the GNU nm is the one that is used by munch.
+
+# If you are compiling with GCC, make sure that either 1) You use the
+# -traditional flag, or 2) You have the fixed include files where GCC
+# can reach them.  Otherwise the ioctl calls in inflow.c
+# will be incorrectly compiled.  The "fixincludes" script in the gcc
+# distribution will fix your include files up.
+#CC=cc
+#CC=gcc -traditional
+GCC=gcc
+
+# Directory containing source files.  Don't clean up the spacing,
+# this exact string is matched for by the "configure" script.
+srcdir = .
+
+# It is also possible that you will need to add -I/usr/include/sys to the
+# CFLAGS section if your system doesn't have fcntl.h in /usr/include (which 
+# is where it should be according to Posix).
+
+# If you use bison instead of yacc, it needs to include the "-y" argument.
+#BISON=bison -y
+BISON=yacc
+YACC=$(BISON)
+
+# where to find texinfo; GDB dist should include a recent one
+TEXIDIR=${srcdir}/../texinfo
+
+# where to find makeinfo, preferably one designed for texinfo-2
+MAKEINFO=makeinfo
+
+# Set this up with gcc if you have gnu ld and the loader will print out
+# line numbers for undefinded refs.
+#CC-LD=gcc -static
+CC-LD=${CC}
+
+# Where is the "include" directory?  Traditionally ../include or ./include
+INCLUDE_DIR =  ${srcdir}/../../include
+INCLUDE_DEP = $$(INCLUDE_DIR)
+
+# Where is the source dir for the MMALLOC library? Traditionally ../mmalloc
+# or ./mmalloc  (When we want the binary library built from it, we use
+# ${MMALLOC_DIR}${subdir}.)
+# Note that mmalloc can still be used on systems without mmap().
+# To use your system malloc, comment out the following defines.
+MMALLOC_DIR = ${srcdir}/../mmalloc
+MMALLOC_DEP = $$(MMALLOC_DIR)
+# To use your system malloc, uncomment MMALLOC_DISABLE.
+#MMALLOC_DISABLE = -DNO_MMALLOC
+# To use mmalloc but disable corruption checking, uncomment MMALLOC_CHECK
+#MMALLOC_CHECK = -DNO_MMALLOC_CHECK
+MMALLOC_CFLAGS = ${MMALLOC_CHECK} ${MMALLOC_DISABLE}
+
+# Where is the source dir for the READLINE library?  Traditionally in .. or .
+# (For the binary library built from it, we use ${READLINE_DIR}${subdir}.)
+READLINE_DIR = ${srcdir}/../readline
+READLINE_DEP = $$(READLINE_DIR)
+
+# All the includes used for CFLAGS and for lint.
+# -I. for config files.
+# -I${srcdir} possibly for regex.h also.
+# -I${srcdir}/config for more generic config files.
+INCLUDE_CFLAGS = -I. -I${srcdir} -I${srcdir}/.. -I${srcdir}/../config -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
+
+# CFLAGS is specifically reserved for setting from the command line
+# when running make.  I.E.  "make CFLAGS=-Wmissing-prototypes".
+CFLAGS = -g
+# INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
+INTERNAL_CFLAGS = ${CFLAGS} ${GLOBAL_CFLAGS} ${PROFILE_CFLAGS} ${MMALLOC_CFLAGS} ${INCLUDE_CFLAGS} ${USER_CFLAGS}
+LDFLAGS = $(CFLAGS)
+
+# Perhaps should come from parent Makefile
+VERSION = gdbserver-4.9.1
+DIST=gdb
+
+LINT=/usr/5bin/lint
+LINTFLAGS= -I${BFD_DIR}
+
+# Host and target-dependent makefile fragments come in here.
+####
+# End of host and target-dependent makefile fragments
+
+# All source files that go into linking GDB remote server.
+
+SFILES = $(srcdir)/utils.c $(srcdir)/low-lynx.c $(srcdir)/low-sparc.c \
+        $(srcdir)/server.c $(srcdir)/remote-utils.c
+
+DEPFILES = $(GDBSERVER_DEPFILES)
+
+SOURCES = $(SFILES) $(ALLDEPFILES) $(YYFILES)
+TAGFILES = $(SOURCES) ${HFILES} ${ALLPARAM} ${POSSLIBS} 
+
+OBS = utils.o $(GDBSERVER_DEPFILES) server.o remote-utils.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.
+.c.o:
+       ${CC} -c ${INTERNAL_CFLAGS} $<
+
+all: gdbserver
+
+installcheck:
+check:
+info dvi:
+install-info:
+clean-info:
+
+gdbserver: $(OBS) ${ADD_DEPS} ${CDEPS}
+       ${CC-LD} $(GLOBAL_CFLAGS) $(LDFLAGS) -o gdbserver $(OBS) \
+         $(GDBSERVER_LIBS)
+
+config.status:
+       @echo "You must configure gdbserver.  Look at the README file for details."
+       @false
+
+# Put the proper machine-specific files first, so M-. on a machine
+# specific routine gets the one for the correct machine.
+# The xyzzy stuff below deals with empty DEPFILES
+TAGS:  ${TAGFILES}
+       etags `find ${srcdir}/config -name $(TM_FILE) -print` \
+         `find ${srcdir}/config -name ${XM_FILE} -print` \
+         `find ${srcdir}/config -name ${NAT_FILE} -print` \
+         `for i in yzzy ${DEPFILES}; do \
+            if [ x$$i != xyzzy ]; then \
+              echo ${srcdir}/$$i | sed -e 's/\.o$$/\.c/' ; \
+            fi; \
+          done` \
+         ${TAGFILES}
+tags: TAGS
+
+# Making distributions of GDB and friends.
+
+# Make a tar file containing the GDB directory of the distribution.
+gdb.tar.Z: force_update
+       $(MAKE) $(MFLAGS) -f Makefile.in setup-to-dist
+       $(MAKE) $(MFLAGS) -f Makefile.in gdb-$(VERSION).tar.Z
+
+# Make a directory `proto-gdb.dir' that contains an image of the GDB
+# directory of the distribution, built up with symlinks.  Note that this
+# make target is not directly referenced by any other rules in this makefile,
+# it is referenced by the makefile in the parent directory.
+make-proto-gdb.dir: force_update 
+       $(MAKE) $(MFLAGS) -f Makefile.in setup-to-dist
+       $(MAKE) $(MFLAGS) -f Makefile make-proto-gdb-1
+
+# Set up the GDB source directory for distribution, by building all files that
+# are products of other files.
+setup-to-dist: update-depend force_update
+       ../configure none
+       (cd doc; $(MAKE) $(MFLAGS) GDBvn.texi)
+       $(MAKE) $(MFLAGS) gdb.info
+       $(MAKE) $(MFLAGS) refcard.ps
+
+# Update the "depend" and "alldeps.mak" files in a source directory.
+# We update alldeps.mak first, since it is used to generate the list
+# of files to be checked for dependencies.
+update-depend: update-alldeps force_update
+       ../configure none -norecursion
+       rm -f depend
+       $(MAKE) $(MFLAGS) depend
+
+# Update the "alldeps.mak" file in a source directory.
+update-alldeps: force_update
+       ../configure none -norecursion
+       rm -f alldeps.mak
+       $(MAKE) $(MFLAGS) alldeps.mak
+
+# Build a tar file from a proto-gdb.dir.
+gdb-$(VERSION).tar.Z: force_update
+       rm -f gdb.tar gdb-$(VERSION).tar.Z
+       $(MAKE) $(MFLAGS) -f Makefile make-proto-gdb-1
+       ln -s proto-gdb.dir $(DIST)
+       tar chf - $(DIST) | compress >gdb-$(VERSION).tar.Z
+       rm -rf $(DIST) proto-gdb.dir
+
+clean:
+       rm -f *.o ${ADD_FILES} *~
+       rm -f init.c version.c
+       rm -f gdbserver core make.log
+
+distclean: clean c-exp.tab.c m2-exp.tab.c ch-exp.tab.c TAGS
+       rm -f tm.h xm.h config.status
+       rm -f Makefile
+
+realclean: clean
+       rm -f c-exp.tab.c m2-exp.tab.c ch-exp.tab.c TAGS
+       rm -f tm.h xm.h config.status
+       rm -f Makefile
+
+STAGESTUFF=${OBS} ${TSOBS} ${NTSOBS} ${ADD_FILES} init.c init.o version.c gdb
+
+Makefile: $(srcdir)/Makefile.in $(host_makefile_frag) $(target_makefile_frag)
+       $(SHELL) ./config.status
+
+force:
+
+version.c: Makefile
+       echo 'char *version = "$(VERSION)";' >version.c
+
+# GNU Make has an annoying habit of putting *all* the Makefile variables
+# into the environment, unless you include this target as a circumvention.
+# Rumor is that this will be fixed (and this target can be removed)
+# in GNU Make 4.0.
+.NOEXPORT:
+
+# GNU Make 3.63 has a different problem: it keeps tacking command line
+# overrides onto the definition of $(MAKE).  This variable setting
+# will remove them.
+MAKEOVERRIDES=
+
+## This is ugly, but I don't want GNU make to put these variables in
+## the environment.  Older makes will see this as a set of targets
+## 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-lynx.o : ${srcdir}/low-lynx.c ${srcdir}/server.h
+low-sparc.o : $(srcdir)/low-sparc.c $(srcdir)/server.h
+utils.o : ${srcdir}/utils.c ${srcdir}/server.h
+
+# This is the end of "Makefile.in".
diff --git a/gdb/gdbserver/low-lynx.c b/gdb/gdbserver/low-lynx.c
new file mode 100644 (file)
index 0000000..44070c5
--- /dev/null
@@ -0,0 +1,345 @@
+/* Low level interface to ptrace, for the remote server for GDB.
+   Copyright (C) 1986, 1987, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "server.h"
+#include "frame.h"
+#include "inferior.h"
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#define LYNXOS
+#include <sys/mem.h>
+#include <sys/signal.h>
+#include <sys/file.h>
+#include <sys/kernel.h>
+#include <sys/itimer.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/proc.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sgtty.h>
+#include <fcntl.h>
+#include "/usr/include/wait.h"
+
+char registers[REGISTER_BYTES];
+
+#include <sys/ptrace.h>
+
+/* Start an inferior process and returns its pid.
+   ALLARGS is a vector of program-name and args. */
+
+int
+create_inferior (program, allargs)
+     char *program;
+     char **allargs;
+{
+  int pid;
+
+  pid = fork ();
+  if (pid < 0)
+    perror_with_name ("fork");
+
+  if (pid == 0)
+    {
+      int pgrp;
+
+      /* Switch child to it's own process group so that signals won't
+        directly affect gdbserver. */
+
+      pgrp = getpid();
+      setpgrp(0, pgrp);
+      ioctl (0, TIOCSPGRP, &pgrp);
+
+      ptrace (PTRACE_TRACEME);
+
+      execv (program, allargs);
+
+      fprintf (stderr, "GDBserver (process %d):  Cannot exec %s: %s.\n",
+              getpid(), program,
+              errno < sys_nerr ? sys_errlist[errno] : "unknown error");
+      fflush (stderr);
+      _exit (0177);
+    }
+
+  return pid;
+}
+
+/* Kill the inferior process.  Make us have no inferior.  */
+
+void
+kill_inferior ()
+{
+  if (inferior_pid == 0)
+    return;
+  ptrace (PTRACE_KILL, inferior_pid, 0, 0);
+  wait (0);
+
+  inferior_pid = 0;
+}
+
+/* Wait for process, returns status */
+
+unsigned char
+mywait (status)
+     char *status;
+{
+  int pid;
+  union wait w;
+
+  enable_async_io();
+
+  pid = wait (&w);
+
+  disable_async_io();
+
+  if (pid != PIDGET(inferior_pid))
+    perror_with_name ("wait");
+
+  inferior_pid = BUILDPID (inferior_pid, w.w_tid);
+
+  if (WIFEXITED (w))
+    {
+      fprintf (stderr, "\nChild exited with status %d\n", WEXITSTATUS (w));
+      fprintf (stderr, "GDBserver exiting\n");
+      exit (0);
+    }
+  else if (!WIFSTOPPED (w))
+    {
+      fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
+      *status = 'T';
+      return ((unsigned char) WTERMSIG (w));
+    }
+
+  fetch_inferior_registers (0);
+
+  *status = 'S';
+  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 (step, signal)
+     int step;
+     int signal;
+{
+  errno = 0;
+  ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
+  if (errno)
+    perror_with_name ("ptrace");
+}
+
+#undef offsetof
+#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
+
+static struct econtext *
+lynx_registers_addr()
+{
+  st_t *stblock;
+  int ecpoff = offsetof(st_t, ecp);
+  CORE_ADDR ecp;
+
+  errno = 0;
+  stblock = (st_t *) ptrace (PTRACE_THREADUSER, inferior_pid,
+                            (PTRACE_ARG3_TYPE)0, 0);
+  if (errno)
+    perror_with_name ("PTRACE_THREADUSER");
+
+  ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, inferior_pid,
+                           (PTRACE_ARG3_TYPE)ecpoff, 0);
+  ecp -= (CORE_ADDR)stblock;
+  if (errno)
+    perror_with_name ("lynx_registers_addr(PTRACE_PEEKTHREAD)");
+
+  return (struct econtext *)ecp;
+}
+
+static struct econtext *ecp;
+
+/* Mapping between GDB register #s and offsets into econtext.  Must be
+   consistent with REGISTER_NAMES macro in tm-i386v.h. */
+
+#define X(ENTRY)(offsetof(struct econtext, ENTRY) / 4)
+static int regmap[] = {
+  X(eax),
+  X(ecx),
+  X(edx),
+  X(ebx),
+  X(esp),
+  X(ebp),
+  X(esi),
+  X(edi),
+  X(eip),
+  X(flags),                    /* ps */
+  X(cs),
+  X(ss),
+  X(ds),
+  X(es),
+  X(ecode),                    /* Lynx doesn't give us either fs or gs, so */
+  X(fault)                     /* we just substitute these two in the hopes
+                                  that they are useful. */
+  };
+
+/* Fetch one or more registers from the inferior.  REGNO == -1 to get
+   them all.  We actually fetch more than requested, when convenient,
+   marking them as valid so we won't fetch them again.  */
+
+void
+fetch_inferior_registers (ignored)
+     int ignored;
+{
+  int regno;
+  unsigned long reg;
+  struct econtext *ecp;
+
+  ecp = lynx_registers_addr();
+
+  for (regno = 0; regno < NUM_REGS; regno++)
+    {
+      errno = 0;
+      reg = ptrace (PTRACE_PEEKTHREAD, inferior_pid,
+                   (PTRACE_ARG3_TYPE) (&ecp->fault + regmap[regno]), 0);
+      if (errno)
+       perror_with_name ("fetch_inferior_registers(PTRACE_PEEKTHREAD)");
+  
+      *(unsigned long *)&registers[REGISTER_BYTE (regno)] = reg;
+    }
+}
+
+/* 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 (ignored)
+     int ignored;
+{
+  int regno;
+  unsigned long reg;
+  struct econtext *ecp;
+
+  ecp = lynx_registers_addr();
+
+  for (regno = 0; regno < NUM_REGS; regno++)
+    {
+      reg = *(unsigned long *)&registers[REGISTER_BYTE (regno)];
+
+      errno = 0;
+      ptrace (PTRACE_POKEUSER, inferior_pid,
+             (PTRACE_ARG3_TYPE) (&ecp->fault + regmap[regno]), reg);
+      if (errno)
+       perror_with_name ("PTRACE_POKEUSER");
+    }
+}
+
+/* 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 (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  register int i;
+  /* Round starting address down to longword boundary.  */
+  register CORE_ADDR addr = memaddr & -sizeof (int);
+  /* Round ending address up; get number of longwords that makes.  */
+  register int count
+  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+  /* Allocate buffer of that many longwords.  */
+  register int *buffer = (int *) alloca (count * sizeof (int));
+
+  /* Read all the longwords */
+  for (i = 0; i < count; i++, addr += sizeof (int))
+    {
+      buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
+    }
+
+  /* Copy appropriate bytes out of the buffer.  */
+  bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, 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 (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  register int i;
+  /* Round starting address down to longword boundary.  */
+  register CORE_ADDR addr = memaddr & -sizeof (int);
+  /* Round ending address up; get number of longwords that makes.  */
+  register int count
+  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+  /* Allocate buffer of that many longwords.  */
+  register int *buffer = (int *) alloca (count * sizeof (int));
+  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 (int), 0);
+    }
+
+  /* Copy data to be written over corresponding part of buffer */
+
+  bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
+
+  /* Write the entire buffer.  */
+
+  for (i = 0; i < count; i++, addr += sizeof (int))
+    {
+      while (1)
+       {
+         errno = 0;
+         ptrace (PTRACE_POKETEXT, inferior_pid, addr, buffer[i]);
+         if (errno)
+           {
+             fprintf(stderr, "ptrace (PTRACE_POKETEXT): errno=%d, inferior_pid=0x%x, addr=0x%x, buffer[i] = 0x%x\n", errno, inferior_pid, addr, buffer[i]);
+             fprintf(stderr, "Sleeping for 1 second\n");
+             sleep(1);
+           }
+         else
+           break;
+       }
+    }
+
+  return 0;
+}
diff --git a/gdb/gdbserver/low-sparc.c b/gdb/gdbserver/low-sparc.c
new file mode 100644 (file)
index 0000000..eb578ee
--- /dev/null
@@ -0,0 +1,326 @@
+/* Low level interface to ptrace, for the remote server for GDB.
+   Copyright (C) 1986, 1987, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "defs.h"
+#include "/usr/include/sys/wait.h"
+#include "frame.h"
+#include "inferior.h"
+/***************************
+#include "initialize.h"
+****************************/
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/dir.h>
+#include <sys/user.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+#include <sgtty.h>
+#include <fcntl.h>
+
+/***************Begin MY defs*********************/
+int quit_flag = 0;
+char registers[REGISTER_BYTES];
+
+/* Index within `registers' of the first byte of the space for
+   register N.  */
+
+
+char buf2[MAX_REGISTER_RAW_SIZE];
+/***************End MY defs*********************/
+
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+extern int sys_nerr;
+extern char **sys_errlist;
+extern char **environ;
+extern int errno;
+extern int inferior_pid;
+void error (), quit (), perror_with_name ();
+int query ();
+
+/* Start an inferior process and returns its pid.
+   ALLARGS is a vector of program-name and args.
+   ENV is the environment vector to pass.  */
+
+int
+create_inferior (program, allargs)
+     char *program;
+     char **allargs;
+{
+  int pid;
+
+  pid = fork ();
+  if (pid < 0)
+    perror_with_name ("fork");
+
+  if (pid == 0)
+    {
+      ptrace (PTRACE_TRACEME);
+
+      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;
+}
+
+/* Kill the inferior process.  Make us have no inferior.  */
+
+void
+kill_inferior ()
+{
+  if (inferior_pid == 0)
+    return;
+  ptrace (8, inferior_pid, 0, 0);
+  wait (0);
+  /*************inferior_died ();****VK**************/
+}
+
+/* Wait for process, returns status */
+
+unsigned char
+mywait (status)
+     char *status;
+{
+  int pid;
+  union wait w;
+
+  pid = wait (&w);
+  if (pid != inferior_pid)
+    perror_with_name ("wait");
+
+  if (WIFEXITED (w))
+    {
+      fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
+      *status = 'E';
+      return ((unsigned char) WEXITSTATUS (w));
+    }
+  else if (!WIFSTOPPED (w))
+    {
+      fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
+      *status = 'T';
+      return ((unsigned char) WTERMSIG (w));
+    }
+
+  fetch_inferior_registers (0);
+
+  *status = 'S';
+  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 (step, signal)
+     int step;
+     int signal;
+{
+  errno = 0;
+  ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
+  if (errno)
+    perror_with_name ("ptrace");
+}
+
+/* Fetch one or more registers from the inferior.  REGNO == -1 to get
+   them all.  We actually fetch more than requested, when convenient,
+   marking them as valid so we won't fetch them again.  */
+
+void
+fetch_inferior_registers (ignored)
+     int ignored;
+{
+  struct regs inferior_registers;
+  struct fp_status inferior_fp_registers;
+  int i;
+
+  /* Global and Out regs are fetched directly, as well as the control
+     registers.  If we're getting one of the in or local regs,
+     and the stack pointer has not yet been fetched,
+     we have to do that first, since they're found in memory relative
+     to the stack pointer.  */
+
+  if (ptrace (PTRACE_GETREGS, inferior_pid,
+             (PTRACE_ARG3_TYPE) &inferior_registers, 0))
+    perror("ptrace_getregs");
+      
+  registers[REGISTER_BYTE (0)] = 0;
+  memcpy (&registers[REGISTER_BYTE (1)], &inferior_registers.r_g1,
+         15 * REGISTER_RAW_SIZE (G0_REGNUM));
+  *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; 
+  *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
+  *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc;
+  *(int *)&registers[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y;
+
+  /* Floating point registers */
+
+  if (ptrace (PTRACE_GETFPREGS, inferior_pid,
+             (PTRACE_ARG3_TYPE) &inferior_fp_registers,
+             0))
+    perror("ptrace_getfpregs");
+  memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
+         sizeof inferior_fp_registers.fpu_fr);
+
+  /* These regs are saved on the stack by the kernel.  Only read them
+     all (16 ptrace calls!) if we really need them.  */
+
+  read_inferior_memory (*(CORE_ADDR*)&registers[REGISTER_BYTE (SP_REGNUM)],
+                       &registers[REGISTER_BYTE (L0_REGNUM)],
+                       16*REGISTER_RAW_SIZE (L0_REGNUM));
+}
+
+/* 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 (ignored)
+     int ignored;
+{
+  struct regs inferior_registers;
+  struct fp_status inferior_fp_registers;
+  CORE_ADDR sp = *(CORE_ADDR *)&registers[REGISTER_BYTE (SP_REGNUM)];
+
+  write_inferior_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
+                        16*REGISTER_RAW_SIZE (L0_REGNUM));
+
+  memcpy (&inferior_registers.r_g1, &registers[REGISTER_BYTE (G1_REGNUM)],
+         15 * REGISTER_RAW_SIZE (G1_REGNUM));
+
+  inferior_registers.r_ps =
+    *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
+  inferior_registers.r_pc =
+    *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
+  inferior_registers.r_npc =
+    *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)];
+  inferior_registers.r_y =
+    *(int *)&registers[REGISTER_BYTE (Y_REGNUM)];
+
+  if (ptrace (PTRACE_SETREGS, inferior_pid,
+             (PTRACE_ARG3_TYPE) &inferior_registers, 0))
+    perror("ptrace_setregs");
+
+  memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
+         sizeof inferior_fp_registers.fpu_fr);
+
+  if (ptrace (PTRACE_SETFPREGS, inferior_pid,
+             (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0))
+    perror("ptrace_setfpregs");
+}
+
+/* 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.  */
+
+read_inferior_memory (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  register int i;
+  /* Round starting address down to longword boundary.  */
+  register CORE_ADDR addr = memaddr & -sizeof (int);
+  /* Round ending address up; get number of longwords that makes.  */
+  register int count
+  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+  /* Allocate buffer of that many longwords.  */
+  register int *buffer = (int *) alloca (count * sizeof (int));
+
+  /* Read all the longwords */
+  for (i = 0; i < count; i++, addr += sizeof (int))
+    {
+      buffer[i] = ptrace (1, inferior_pid, addr, 0);
+    }
+
+  /* Copy appropriate bytes out of the buffer.  */
+  bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, 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 (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  register int i;
+  /* Round starting address down to longword boundary.  */
+  register CORE_ADDR addr = memaddr & -sizeof (int);
+  /* Round ending address up; get number of longwords that makes.  */
+  register int count
+  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
+  /* Allocate buffer of that many longwords.  */
+  register int *buffer = (int *) alloca (count * sizeof (int));
+  extern int errno;
+
+  /* Fill start and end extra bytes of buffer with existing memory data.  */
+
+  buffer[0] = ptrace (1, inferior_pid, addr, 0);
+
+  if (count > 1)
+    {
+      buffer[count - 1]
+       = ptrace (1, inferior_pid,
+                 addr + (count - 1) * sizeof (int), 0);
+    }
+
+  /* Copy data to be written over corresponding part of buffer */
+
+  bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
+
+  /* Write the entire buffer.  */
+
+  for (i = 0; i < count; i++, addr += sizeof (int))
+    {
+      errno = 0;
+      ptrace (4, inferior_pid, addr, buffer[i]);
+      if (errno)
+       return errno;
+    }
+
+  return 0;
+}
+\f
+void
+initialize ()
+{
+  inferior_pid = 0;
+}
+
+int
+have_inferior_p ()
+{
+  return inferior_pid != 0;
+}
diff --git a/gdb/gdbserver/remote-gutils.c b/gdb/gdbserver/remote-gutils.c
deleted file mode 100644 (file)
index de8226b..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/* General utility routines for the remote server for GDB.
-   Copyright (C) 1986, 1989, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-#include "server.h"
-#include <stdio.h>
-
-/* Generally useful subroutines used throughout the program.  */
-
-/* Print the system error message for errno, and also mention STRING
-   as the file name for which the error was encountered.
-   Then return to command level.  */
-
-void
-perror_with_name (string)
-     char *string;
-{
-  extern int sys_nerr;
-  extern char *sys_errlist[];
-  extern int errno;
-  char *err;
-  char *combined;
-
-  if (errno < sys_nerr)
-    err = sys_errlist[errno];
-  else
-    err = "unknown error";
-
-  combined = (char *) alloca (strlen (err) + strlen (string) + 3);
-  strcpy (combined, string);
-  strcat (combined, ": ");
-  strcat (combined, err);
-
-  error ("%s.", combined);
-}
-
-/* Print an error message and return to command level.
-   STRING is the error message, used as a fprintf string,
-   and ARG is passed as an argument to it.  */
-
-NORETURN void
-error (string, arg1, arg2, arg3)
-     char *string;
-     int arg1, arg2, arg3;
-{
-  extern jmp_buf toplevel;
-
-  fflush (stdout);
-  fprintf (stderr, string, arg1, arg2, arg3);
-  fprintf (stderr, "\n");
-  longjmp(toplevel, 1);
-}
-
-/* Print an error message and exit reporting failure.
-   This is for a error that we cannot continue from.
-   STRING and ARG are passed to fprintf.  */
-
-void
-fatal (string, arg)
-     char *string;
-     int arg;
-{
-  fprintf (stderr, "gdb: ");
-  fprintf (stderr, string, arg);
-  fprintf (stderr, "\n");
-  exit (1);
-}
diff --git a/gdb/gdbserver/remote-inflow-sparc.c b/gdb/gdbserver/remote-inflow-sparc.c
deleted file mode 100644 (file)
index eb578ee..0000000
+++ /dev/null
@@ -1,326 +0,0 @@
-/* Low level interface to ptrace, for the remote server for GDB.
-   Copyright (C) 1986, 1987, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-#include "defs.h"
-#include "/usr/include/sys/wait.h"
-#include "frame.h"
-#include "inferior.h"
-/***************************
-#include "initialize.h"
-****************************/
-
-#include <stdio.h>
-#include <sys/param.h>
-#include <sys/dir.h>
-#include <sys/user.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <sgtty.h>
-#include <fcntl.h>
-
-/***************Begin MY defs*********************/
-int quit_flag = 0;
-char registers[REGISTER_BYTES];
-
-/* Index within `registers' of the first byte of the space for
-   register N.  */
-
-
-char buf2[MAX_REGISTER_RAW_SIZE];
-/***************End MY defs*********************/
-
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-extern int sys_nerr;
-extern char **sys_errlist;
-extern char **environ;
-extern int errno;
-extern int inferior_pid;
-void error (), quit (), perror_with_name ();
-int query ();
-
-/* Start an inferior process and returns its pid.
-   ALLARGS is a vector of program-name and args.
-   ENV is the environment vector to pass.  */
-
-int
-create_inferior (program, allargs)
-     char *program;
-     char **allargs;
-{
-  int pid;
-
-  pid = fork ();
-  if (pid < 0)
-    perror_with_name ("fork");
-
-  if (pid == 0)
-    {
-      ptrace (PTRACE_TRACEME);
-
-      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;
-}
-
-/* Kill the inferior process.  Make us have no inferior.  */
-
-void
-kill_inferior ()
-{
-  if (inferior_pid == 0)
-    return;
-  ptrace (8, inferior_pid, 0, 0);
-  wait (0);
-  /*************inferior_died ();****VK**************/
-}
-
-/* Wait for process, returns status */
-
-unsigned char
-mywait (status)
-     char *status;
-{
-  int pid;
-  union wait w;
-
-  pid = wait (&w);
-  if (pid != inferior_pid)
-    perror_with_name ("wait");
-
-  if (WIFEXITED (w))
-    {
-      fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
-      *status = 'E';
-      return ((unsigned char) WEXITSTATUS (w));
-    }
-  else if (!WIFSTOPPED (w))
-    {
-      fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
-      *status = 'T';
-      return ((unsigned char) WTERMSIG (w));
-    }
-
-  fetch_inferior_registers (0);
-
-  *status = 'S';
-  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 (step, signal)
-     int step;
-     int signal;
-{
-  errno = 0;
-  ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
-  if (errno)
-    perror_with_name ("ptrace");
-}
-
-/* Fetch one or more registers from the inferior.  REGNO == -1 to get
-   them all.  We actually fetch more than requested, when convenient,
-   marking them as valid so we won't fetch them again.  */
-
-void
-fetch_inferior_registers (ignored)
-     int ignored;
-{
-  struct regs inferior_registers;
-  struct fp_status inferior_fp_registers;
-  int i;
-
-  /* Global and Out regs are fetched directly, as well as the control
-     registers.  If we're getting one of the in or local regs,
-     and the stack pointer has not yet been fetched,
-     we have to do that first, since they're found in memory relative
-     to the stack pointer.  */
-
-  if (ptrace (PTRACE_GETREGS, inferior_pid,
-             (PTRACE_ARG3_TYPE) &inferior_registers, 0))
-    perror("ptrace_getregs");
-      
-  registers[REGISTER_BYTE (0)] = 0;
-  memcpy (&registers[REGISTER_BYTE (1)], &inferior_registers.r_g1,
-         15 * REGISTER_RAW_SIZE (G0_REGNUM));
-  *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; 
-  *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
-  *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc;
-  *(int *)&registers[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y;
-
-  /* Floating point registers */
-
-  if (ptrace (PTRACE_GETFPREGS, inferior_pid,
-             (PTRACE_ARG3_TYPE) &inferior_fp_registers,
-             0))
-    perror("ptrace_getfpregs");
-  memcpy (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
-         sizeof inferior_fp_registers.fpu_fr);
-
-  /* These regs are saved on the stack by the kernel.  Only read them
-     all (16 ptrace calls!) if we really need them.  */
-
-  read_inferior_memory (*(CORE_ADDR*)&registers[REGISTER_BYTE (SP_REGNUM)],
-                       &registers[REGISTER_BYTE (L0_REGNUM)],
-                       16*REGISTER_RAW_SIZE (L0_REGNUM));
-}
-
-/* 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 (ignored)
-     int ignored;
-{
-  struct regs inferior_registers;
-  struct fp_status inferior_fp_registers;
-  CORE_ADDR sp = *(CORE_ADDR *)&registers[REGISTER_BYTE (SP_REGNUM)];
-
-  write_inferior_memory (sp, &registers[REGISTER_BYTE (L0_REGNUM)],
-                        16*REGISTER_RAW_SIZE (L0_REGNUM));
-
-  memcpy (&inferior_registers.r_g1, &registers[REGISTER_BYTE (G1_REGNUM)],
-         15 * REGISTER_RAW_SIZE (G1_REGNUM));
-
-  inferior_registers.r_ps =
-    *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
-  inferior_registers.r_pc =
-    *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
-  inferior_registers.r_npc =
-    *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)];
-  inferior_registers.r_y =
-    *(int *)&registers[REGISTER_BYTE (Y_REGNUM)];
-
-  if (ptrace (PTRACE_SETREGS, inferior_pid,
-             (PTRACE_ARG3_TYPE) &inferior_registers, 0))
-    perror("ptrace_setregs");
-
-  memcpy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
-         sizeof inferior_fp_registers.fpu_fr);
-
-  if (ptrace (PTRACE_SETFPREGS, inferior_pid,
-             (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0))
-    perror("ptrace_setfpregs");
-}
-
-/* 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.  */
-
-read_inferior_memory (memaddr, myaddr, len)
-     CORE_ADDR memaddr;
-     char *myaddr;
-     int len;
-{
-  register int i;
-  /* Round starting address down to longword boundary.  */
-  register CORE_ADDR addr = memaddr & -sizeof (int);
-  /* Round ending address up; get number of longwords that makes.  */
-  register int count
-  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
-  /* Allocate buffer of that many longwords.  */
-  register int *buffer = (int *) alloca (count * sizeof (int));
-
-  /* Read all the longwords */
-  for (i = 0; i < count; i++, addr += sizeof (int))
-    {
-      buffer[i] = ptrace (1, inferior_pid, addr, 0);
-    }
-
-  /* Copy appropriate bytes out of the buffer.  */
-  bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, 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 (memaddr, myaddr, len)
-     CORE_ADDR memaddr;
-     char *myaddr;
-     int len;
-{
-  register int i;
-  /* Round starting address down to longword boundary.  */
-  register CORE_ADDR addr = memaddr & -sizeof (int);
-  /* Round ending address up; get number of longwords that makes.  */
-  register int count
-  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
-  /* Allocate buffer of that many longwords.  */
-  register int *buffer = (int *) alloca (count * sizeof (int));
-  extern int errno;
-
-  /* Fill start and end extra bytes of buffer with existing memory data.  */
-
-  buffer[0] = ptrace (1, inferior_pid, addr, 0);
-
-  if (count > 1)
-    {
-      buffer[count - 1]
-       = ptrace (1, inferior_pid,
-                 addr + (count - 1) * sizeof (int), 0);
-    }
-
-  /* Copy data to be written over corresponding part of buffer */
-
-  bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
-
-  /* Write the entire buffer.  */
-
-  for (i = 0; i < count; i++, addr += sizeof (int))
-    {
-      errno = 0;
-      ptrace (4, inferior_pid, addr, buffer[i]);
-      if (errno)
-       return errno;
-    }
-
-  return 0;
-}
-\f
-void
-initialize ()
-{
-  inferior_pid = 0;
-}
-
-int
-have_inferior_p ()
-{
-  return inferior_pid != 0;
-}
diff --git a/gdb/gdbserver/remote-inflow.c b/gdb/gdbserver/remote-inflow.c
deleted file mode 100644 (file)
index 44070c5..0000000
+++ /dev/null
@@ -1,345 +0,0 @@
-/* Low level interface to ptrace, for the remote server for GDB.
-   Copyright (C) 1986, 1987, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-#include "server.h"
-#include "frame.h"
-#include "inferior.h"
-
-#include <stdio.h>
-#include <sys/param.h>
-#include <sys/dir.h>
-#define LYNXOS
-#include <sys/mem.h>
-#include <sys/signal.h>
-#include <sys/file.h>
-#include <sys/kernel.h>
-#include <sys/itimer.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/proc.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <sgtty.h>
-#include <fcntl.h>
-#include "/usr/include/wait.h"
-
-char registers[REGISTER_BYTES];
-
-#include <sys/ptrace.h>
-
-/* Start an inferior process and returns its pid.
-   ALLARGS is a vector of program-name and args. */
-
-int
-create_inferior (program, allargs)
-     char *program;
-     char **allargs;
-{
-  int pid;
-
-  pid = fork ();
-  if (pid < 0)
-    perror_with_name ("fork");
-
-  if (pid == 0)
-    {
-      int pgrp;
-
-      /* Switch child to it's own process group so that signals won't
-        directly affect gdbserver. */
-
-      pgrp = getpid();
-      setpgrp(0, pgrp);
-      ioctl (0, TIOCSPGRP, &pgrp);
-
-      ptrace (PTRACE_TRACEME);
-
-      execv (program, allargs);
-
-      fprintf (stderr, "GDBserver (process %d):  Cannot exec %s: %s.\n",
-              getpid(), program,
-              errno < sys_nerr ? sys_errlist[errno] : "unknown error");
-      fflush (stderr);
-      _exit (0177);
-    }
-
-  return pid;
-}
-
-/* Kill the inferior process.  Make us have no inferior.  */
-
-void
-kill_inferior ()
-{
-  if (inferior_pid == 0)
-    return;
-  ptrace (PTRACE_KILL, inferior_pid, 0, 0);
-  wait (0);
-
-  inferior_pid = 0;
-}
-
-/* Wait for process, returns status */
-
-unsigned char
-mywait (status)
-     char *status;
-{
-  int pid;
-  union wait w;
-
-  enable_async_io();
-
-  pid = wait (&w);
-
-  disable_async_io();
-
-  if (pid != PIDGET(inferior_pid))
-    perror_with_name ("wait");
-
-  inferior_pid = BUILDPID (inferior_pid, w.w_tid);
-
-  if (WIFEXITED (w))
-    {
-      fprintf (stderr, "\nChild exited with status %d\n", WEXITSTATUS (w));
-      fprintf (stderr, "GDBserver exiting\n");
-      exit (0);
-    }
-  else if (!WIFSTOPPED (w))
-    {
-      fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
-      *status = 'T';
-      return ((unsigned char) WTERMSIG (w));
-    }
-
-  fetch_inferior_registers (0);
-
-  *status = 'S';
-  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 (step, signal)
-     int step;
-     int signal;
-{
-  errno = 0;
-  ptrace (step ? PTRACE_SINGLESTEP : PTRACE_CONT, inferior_pid, 1, signal);
-  if (errno)
-    perror_with_name ("ptrace");
-}
-
-#undef offsetof
-#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
-
-static struct econtext *
-lynx_registers_addr()
-{
-  st_t *stblock;
-  int ecpoff = offsetof(st_t, ecp);
-  CORE_ADDR ecp;
-
-  errno = 0;
-  stblock = (st_t *) ptrace (PTRACE_THREADUSER, inferior_pid,
-                            (PTRACE_ARG3_TYPE)0, 0);
-  if (errno)
-    perror_with_name ("PTRACE_THREADUSER");
-
-  ecp = (CORE_ADDR) ptrace (PTRACE_PEEKTHREAD, inferior_pid,
-                           (PTRACE_ARG3_TYPE)ecpoff, 0);
-  ecp -= (CORE_ADDR)stblock;
-  if (errno)
-    perror_with_name ("lynx_registers_addr(PTRACE_PEEKTHREAD)");
-
-  return (struct econtext *)ecp;
-}
-
-static struct econtext *ecp;
-
-/* Mapping between GDB register #s and offsets into econtext.  Must be
-   consistent with REGISTER_NAMES macro in tm-i386v.h. */
-
-#define X(ENTRY)(offsetof(struct econtext, ENTRY) / 4)
-static int regmap[] = {
-  X(eax),
-  X(ecx),
-  X(edx),
-  X(ebx),
-  X(esp),
-  X(ebp),
-  X(esi),
-  X(edi),
-  X(eip),
-  X(flags),                    /* ps */
-  X(cs),
-  X(ss),
-  X(ds),
-  X(es),
-  X(ecode),                    /* Lynx doesn't give us either fs or gs, so */
-  X(fault)                     /* we just substitute these two in the hopes
-                                  that they are useful. */
-  };
-
-/* Fetch one or more registers from the inferior.  REGNO == -1 to get
-   them all.  We actually fetch more than requested, when convenient,
-   marking them as valid so we won't fetch them again.  */
-
-void
-fetch_inferior_registers (ignored)
-     int ignored;
-{
-  int regno;
-  unsigned long reg;
-  struct econtext *ecp;
-
-  ecp = lynx_registers_addr();
-
-  for (regno = 0; regno < NUM_REGS; regno++)
-    {
-      errno = 0;
-      reg = ptrace (PTRACE_PEEKTHREAD, inferior_pid,
-                   (PTRACE_ARG3_TYPE) (&ecp->fault + regmap[regno]), 0);
-      if (errno)
-       perror_with_name ("fetch_inferior_registers(PTRACE_PEEKTHREAD)");
-  
-      *(unsigned long *)&registers[REGISTER_BYTE (regno)] = reg;
-    }
-}
-
-/* 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 (ignored)
-     int ignored;
-{
-  int regno;
-  unsigned long reg;
-  struct econtext *ecp;
-
-  ecp = lynx_registers_addr();
-
-  for (regno = 0; regno < NUM_REGS; regno++)
-    {
-      reg = *(unsigned long *)&registers[REGISTER_BYTE (regno)];
-
-      errno = 0;
-      ptrace (PTRACE_POKEUSER, inferior_pid,
-             (PTRACE_ARG3_TYPE) (&ecp->fault + regmap[regno]), reg);
-      if (errno)
-       perror_with_name ("PTRACE_POKEUSER");
-    }
-}
-
-/* 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 (memaddr, myaddr, len)
-     CORE_ADDR memaddr;
-     char *myaddr;
-     int len;
-{
-  register int i;
-  /* Round starting address down to longword boundary.  */
-  register CORE_ADDR addr = memaddr & -sizeof (int);
-  /* Round ending address up; get number of longwords that makes.  */
-  register int count
-  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
-  /* Allocate buffer of that many longwords.  */
-  register int *buffer = (int *) alloca (count * sizeof (int));
-
-  /* Read all the longwords */
-  for (i = 0; i < count; i++, addr += sizeof (int))
-    {
-      buffer[i] = ptrace (PTRACE_PEEKTEXT, inferior_pid, addr, 0);
-    }
-
-  /* Copy appropriate bytes out of the buffer.  */
-  bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, 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 (memaddr, myaddr, len)
-     CORE_ADDR memaddr;
-     char *myaddr;
-     int len;
-{
-  register int i;
-  /* Round starting address down to longword boundary.  */
-  register CORE_ADDR addr = memaddr & -sizeof (int);
-  /* Round ending address up; get number of longwords that makes.  */
-  register int count
-  = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
-  /* Allocate buffer of that many longwords.  */
-  register int *buffer = (int *) alloca (count * sizeof (int));
-  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 (int), 0);
-    }
-
-  /* Copy data to be written over corresponding part of buffer */
-
-  bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
-
-  /* Write the entire buffer.  */
-
-  for (i = 0; i < count; i++, addr += sizeof (int))
-    {
-      while (1)
-       {
-         errno = 0;
-         ptrace (PTRACE_POKETEXT, inferior_pid, addr, buffer[i]);
-         if (errno)
-           {
-             fprintf(stderr, "ptrace (PTRACE_POKETEXT): errno=%d, inferior_pid=0x%x, addr=0x%x, buffer[i] = 0x%x\n", errno, inferior_pid, addr, buffer[i]);
-             fprintf(stderr, "Sleeping for 1 second\n");
-             sleep(1);
-           }
-         else
-           break;
-       }
-    }
-
-  return 0;
-}
diff --git a/gdb/gdbserver/remote-server.c b/gdb/gdbserver/remote-server.c
deleted file mode 100644 (file)
index ca8412e..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-/* Main code for remote server for GDB.
-   Copyright (C) 1989, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-#include "server.h"
-
-main (argc, argv)
-     int argc;
-     char *argv[];
-{
-  char ch, status, own_buf[2000], mem_buf[2000];
-  int i = 0;
-  unsigned char signal;
-  unsigned int mem_addr, len;
-
-  if (setjmp(toplevel))
-    {
-      fprintf(stderr, "Exiting\n");
-      exit(1);
-    }
-
-  if (argc < 3)
-    error("Usage: gdbserver tty prog [args ...]");
-
-  inferior_pid = create_inferior (argv[2], &argv[2]);
-  fprintf (stderr, "Process %s created; pid = %d\n", argv[2], inferior_pid);
-
-  signal = mywait (&status);   /* Wait till we are at 1st instr in prog */
-
-  /* We are now stopped at the first instruction of the target process */
-
-  while (1)
-    {
-      remote_open (argv[1]);
-
-      setjmp(toplevel);
-      while (getpkt (own_buf) > 0)
-       {
-         i = 0;
-         ch = own_buf[i++];
-         switch (ch)
-           {
-           case '?':
-             prepare_resume_reply (own_buf, status, signal);
-             break;
-           case 'g':
-             convert_int_to_ascii (registers, own_buf, REGISTER_BYTES);
-             break;
-           case 'G':
-             convert_ascii_to_int (&own_buf[1], registers, REGISTER_BYTES);
-             store_inferior_registers (-1);
-             write_ok (own_buf);
-             break;
-           case 'm':
-             decode_m_packet (&own_buf[1], &mem_addr, &len);
-             read_inferior_memory (mem_addr, mem_buf, len);
-             convert_int_to_ascii (mem_buf, own_buf, len);
-             break;
-           case 'M':
-             decode_M_packet (&own_buf[1], &mem_addr, &len, mem_buf);
-             if (write_inferior_memory (mem_addr, mem_buf, len) == 0)
-               write_ok (own_buf);
-             else
-               write_enn (own_buf);
-             break;
-           case 'c':
-             myresume (0, 0);
-             signal = mywait (&status);
-             prepare_resume_reply (own_buf, status, signal);
-             break;
-           case 's':
-             myresume (1, 0);
-             signal = mywait (&status);
-             prepare_resume_reply (own_buf, status, signal);
-             break;
-           case 'k':
-             fprintf (stderr, "Killing inferior\n");
-             kill_inferior ();
-             inferior_pid = create_inferior (argv[2], &argv[2]);
-             fprintf (stderr, "Process %s created; pid = %d\n", argv[2],
-                      inferior_pid);
-             signal = mywait (&status); /* Wait till we are at 1st instr in prog */
-             break;
-           default:
-             printf ("\nUnknown option chosen by master\n");
-             write_enn (own_buf);
-             break;
-           }
-
-         putpkt (own_buf);
-       }
-
-      /* We come here when getpkt fails.  Close the connection, and re-open it
-         at the top of the loop.  */
-
-      fprintf (stderr, "Remote side has terminated connection.  GDBserver will reopen the connection.\n");
-
-      remote_close ();
-    }
-}
diff --git a/gdb/gdbserver/utils.c b/gdb/gdbserver/utils.c
new file mode 100644 (file)
index 0000000..de8226b
--- /dev/null
@@ -0,0 +1,82 @@
+/* General utility routines for the remote server for GDB.
+   Copyright (C) 1986, 1989, 1993 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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+#include "server.h"
+#include <stdio.h>
+
+/* Generally useful subroutines used throughout the program.  */
+
+/* Print the system error message for errno, and also mention STRING
+   as the file name for which the error was encountered.
+   Then return to command level.  */
+
+void
+perror_with_name (string)
+     char *string;
+{
+  extern int sys_nerr;
+  extern char *sys_errlist[];
+  extern int errno;
+  char *err;
+  char *combined;
+
+  if (errno < sys_nerr)
+    err = sys_errlist[errno];
+  else
+    err = "unknown error";
+
+  combined = (char *) alloca (strlen (err) + strlen (string) + 3);
+  strcpy (combined, string);
+  strcat (combined, ": ");
+  strcat (combined, err);
+
+  error ("%s.", combined);
+}
+
+/* Print an error message and return to command level.
+   STRING is the error message, used as a fprintf string,
+   and ARG is passed as an argument to it.  */
+
+NORETURN void
+error (string, arg1, arg2, arg3)
+     char *string;
+     int arg1, arg2, arg3;
+{
+  extern jmp_buf toplevel;
+
+  fflush (stdout);
+  fprintf (stderr, string, arg1, arg2, arg3);
+  fprintf (stderr, "\n");
+  longjmp(toplevel, 1);
+}
+
+/* Print an error message and exit reporting failure.
+   This is for a error that we cannot continue from.
+   STRING and ARG are passed to fprintf.  */
+
+void
+fatal (string, arg)
+     char *string;
+     int arg;
+{
+  fprintf (stderr, "gdb: ");
+  fprintf (stderr, string, arg);
+  fprintf (stderr, "\n");
+  exit (1);
+}
diff --git a/gdb/remote-mon.c b/gdb/remote-mon.c
new file mode 100644 (file)
index 0000000..d9367a8
--- /dev/null
@@ -0,0 +1,1209 @@
+/* Remote debugging interface for MONITOR boot monitor, for GDB.
+   Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
+   Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
+
+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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+
+/* This file was derived from remote-eb.c, which did a similar job, but for
+   an AMD-29K running EBMON.  That file was in turn derived from remote.c
+   as mentioned in the following comment (left in for comic relief):
+
+  "This is like remote.c but is for an esoteric situation--
+   having an a29k board in a PC hooked up to a unix machine with
+   a serial line, and running ctty com1 on the PC, through which
+   the unix machine can run ebmon.  Not to mention that the PC
+   has PC/NFS, so it can access the same executables that gdb can,
+   over the net in real time."
+
+   In reality, this module talks to a debug monitor called 'MONITOR', which
+   We communicate with MONITOR via either a direct serial line, or a TCP
+   (or possibly TELNET) stream to a terminal multiplexor,
+   which in turn talks to the target board.
+
+   This is based on remote-st2000.c. I left in the above note here for histerical
+   reasons.
+*/
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "target.h"
+#include "wait.h"
+#include <varargs.h>
+#include <signal.h>
+#include <string.h>
+#include <sys/types.h>
+#include "command.h"
+#include "serial.h"
+#include "monitor.h"
+
+#ifdef HAVE_TERMIO
+#  define TERMINAL struct termios
+#else
+#  define TERMINAL struct sgttyb
+#endif
+
+struct monitor_ops *current_monitor;
+extern struct target_ops rom68k_ops;           /* Forward declaration */
+extern struct target_ops mon68_ops;            /* Forward declaration */
+extern struct target_ops monitor_bug_ops;      /* Forward declaration */
+extern struct monitor_ops rom68k_cmds;         /* Forward declaration */
+extern struct monitor_ops mon68_cmds;          /* Forward declaration */
+extern struct monitor_ops bug_cmds;            /* Forward declaration */
+extern struct cmd_list_element *setlist;
+extern struct cmd_list_element *unsetlist;
+struct cmd_list_element *showlist;
+
+static void monitor_close();
+static void monitor_fetch_register();
+static void monitor_store_register();
+static int kiodebug;                           /* flag set by "set remotedebug" */
+static int hashmark;                           /* flag set by "set hash" */
+
+#define LOG_FILE "monitor.log"
+#if defined (LOG_FILE)
+FILE *log_file;
+#endif
+
+static int timeout = 24;
+
+/* Descriptor for I/O to remote machine.  Initialize it to NULL so that
+   monitor_open knows that we don't have a file open when the program starts.
+   */
+static serial_t monitor_desc = NULL;
+
+/* Send data to monitor.  Works just like printf. */
+
+static void
+printf_monitor(va_alist)
+     va_dcl
+{
+  va_list args;
+  char *pattern;
+  char buf[200];
+  int i;
+
+  va_start(args);
+
+  pattern = va_arg(args, char *);
+
+  vsprintf(buf, pattern, args);
+
+  if (SERIAL_WRITE(monitor_desc, buf, strlen(buf)))
+    fprintf(stderr, "SERIAL_WRITE failed: %s\n", safe_strerror(errno));
+}
+
+/* Read a character from the remote system, doing all the fancy
+   timeout stuff.  */
+static int
+readchar(timeout)
+     int timeout;
+{
+  int c;
+
+  c = SERIAL_READCHAR(monitor_desc, timeout);
+
+  if (kiodebug)
+    putchar(c & 0x7f);
+
+#ifdef LOG_FILE
+  if (isascii (c))
+    putc(c & 0x7f, log_file);
+#endif
+
+  if (c >= 0)
+    return c & 0x7f;
+
+  if (c == SERIAL_TIMEOUT)
+    {
+      if (timeout == 0)
+       return c;               /* Polls shouldn't generate timeout errors */
+
+      error("Timeout reading from remote system.");
+    }
+
+  perror_with_name("remote-monitor");
+}
+
+/* Scan input from the remote system, until STRING is found.  If DISCARD is
+   non-zero, then discard non-matching input, else print it out.
+   Let the user break out immediately.  */
+static void
+expect(string, discard)
+     char *string;
+     int discard;
+{
+  char *p = string;
+  int c;
+
+  if (kiodebug)
+    printf ("Expecting \"%s\"\n", string);
+
+  immediate_quit = 1;
+  while (1)
+    {
+      c = readchar(timeout);
+      if (!isascii (c))
+       continue;
+      if (c == *p++)
+       {
+         if (*p == '\0')
+           {
+             immediate_quit = 0;
+             if (kiodebug)
+               printf ("\nMatched\n");
+             return;
+           }
+       }
+      else
+       {
+         if (!discard)
+           {
+             fwrite(string, 1, (p - 1) - string, stdout);
+             putchar((char)c);
+             fflush(stdout);
+           }
+         p = string;
+       }
+    }
+}
+
+/* Keep discarding input until we see the MONITOR prompt.
+
+   The convention for dealing with the prompt is that you
+   o give your command
+   o *then* wait for the prompt.
+
+   Thus the last thing that a procedure does with the serial line
+   will be an expect_prompt().  Exception:  monitor_resume does not
+   wait for the prompt, because the terminal is being handed over
+   to the inferior.  However, the next thing which happens after that
+   is a monitor_wait which does wait for the prompt.
+   Note that this includes abnormal exit, e.g. error().  This is
+   necessary to prevent getting into states from which we can't
+   recover.  */
+static void
+expect_prompt(discard)
+     int discard;
+{
+#if defined (LOG_FILE)
+  /* This is a convenient place to do this.  The idea is to do it often
+     enough that we never lose much data if we terminate abnormally.  */
+  fflush(log_file);
+#endif
+  expect (PROMPT, discard);
+}
+
+/* Get a hex digit from the remote system & return its value.
+   If ignore_space is nonzero, ignore spaces (not newline, tab, etc).  */
+static int
+get_hex_digit(ignore_space)
+     int ignore_space;
+{
+  int ch;
+  while (1)
+    {
+      ch = readchar(timeout);
+      if (ch >= '0' && ch <= '9')
+       return ch - '0';
+      else if (ch >= 'A' && ch <= 'F')
+       return ch - 'A' + 10;
+      else if (ch >= 'a' && ch <= 'f')
+       return ch - 'a' + 10;
+      else if (ch == ' ' && ignore_space)
+       ;
+      else
+       {
+         expect_prompt(1);
+         error("Invalid hex digit from remote system.");
+       }
+    }
+}
+
+/* Get a byte from monitor and put it in *BYT.  Accept any number
+   leading spaces.  */
+static void
+get_hex_byte (byt)
+     char *byt;
+{
+  int val;
+
+  val = get_hex_digit (1) << 4;
+  val |= get_hex_digit (0);
+  *byt = val;
+}
+
+/* Get N 32-bit words from remote, each preceded by a space,
+   and put them in registers starting at REGNO.  */
+static void
+get_hex_regs (n, regno)
+     int n;
+     int regno;
+{
+  long val;
+  int i;
+
+  for (i = 0; i < n; i++)
+    {
+      int j;
+      
+      val = 0;
+      for (j = 0; j < 8; j++)
+       val = (val << 4) + get_hex_digit (j == 0);
+      supply_register (regno++, (char *) &val);
+    }
+}
+
+/* This is called not only when we first attach, but also when the
+   user types "run" after having attached.  */
+static void
+monitor_create_inferior (execfile, args, env)
+     char *execfile;
+     char *args;
+     char **env;
+{
+  int entry_pt;
+
+  if (args && *args)
+    error("Can't pass arguments to remote MONITOR process");
+
+  if (execfile == 0 || exec_bfd == 0)
+    error("No exec file specified");
+
+  entry_pt = (int) bfd_get_start_address (exec_bfd);
+
+#ifdef CREATE_INFERIOR_HOOK
+  CREATE_INFERIOR_HOOK (0);            /* No process-ID */
+#endif  
+#ifdef LOG_FILE
+  fputs ("\nIn Create_inferior()", log_file);
+#endif
+
+/* The "process" (board) is already stopped awaiting our commands, and
+   the program is already downloaded.  We just set its PC and go.  */
+
+  clear_proceed_status ();
+
+  /* Tell wait_for_inferior that we've started a new process.  */
+  init_wait_for_inferior ();
+
+  /* Set up the "saved terminal modes" of the inferior
+     based on what modes we are starting it with.  */
+  target_terminal_init ();
+
+  /* Install inferior's terminal modes.  */
+  target_terminal_inferior ();
+
+  /* insert_step_breakpoint ();  FIXME, do we need this?  */
+  proceed ((CORE_ADDR)entry_pt, -1, 0);                /* Let 'er rip... */
+}
+
+/* Open a connection to a remote debugger.
+   NAME is the filename used for communication.  */
+
+static int baudrate = 9600;
+static char dev_name[100];
+
+static void
+general_open(args, name, from_tty)
+     char *args;
+     char *name;
+     int from_tty;
+{
+  if (args == NULL)
+    error ("Use `target %s DEVICE-NAME' to use a serial port, or \n\
+`target %s HOST-NAME:PORT-NUMBER' to use a network connection.", name, name);
+
+  target_preopen(from_tty);
+
+  monitor_close(0);
+
+  monitor_desc = SERIAL_OPEN(dev_name);
+
+  if (monitor_desc == NULL)
+    perror_with_name(dev_name);
+
+  /* The baud rate was specified when GDB was started.  */
+  if (baud_rate)
+    {
+      int rate;
+
+      if (sscanf (baud_rate, "%d", &rate) == 1)
+       if (SERIAL_SETBAUDRATE (monitor_desc, rate))
+         {
+           SERIAL_CLOSE (monitor_desc);
+           perror_with_name (name);
+         }
+    }
+
+  SERIAL_RAW(monitor_desc);
+
+#if defined (LOG_FILE)
+  log_file = fopen (LOG_FILE, "w");
+  if (log_file == NULL)
+    perror_with_name (LOG_FILE);
+#endif
+
+  /* Hello?  Are you there?  */
+  printf_monitor("\r");        /* CR wakes up monitor */
+  
+  expect_prompt(1);
+
+  if (from_tty)
+    printf("Remote %s connected to %s\n", target_shortname,
+          dev_name);
+}
+
+static void
+rom68k_open(args, from_tty)
+     char *args;
+     int from_tty;
+{
+  push_target(&rom68k_ops);
+  push_monitor (&rom68k_cmds);
+
+  general_open (args, "rom68k", from_tty);
+}
+
+static void
+mon68_open(args, from_tty)
+     char *args;
+     int from_tty;
+{
+  push_target(&mon68_ops);
+  push_monitor (&mon68_cmds);
+
+  general_open (args, "mon68", from_tty);
+}
+
+static void
+bug_open(args, from_tty)
+     char *args;
+     int from_tty;
+{
+  push_target(&monitor_bug_ops);
+  push_monitor (&bug_cmds);
+
+  general_open (args, "bug", from_tty);
+}
+
+/*
+ * _close -- Close out all files and local state before this target loses control.
+ */
+
+static void
+monitor_close (quitting)
+     int quitting;
+{
+  SERIAL_CLOSE(monitor_desc);
+  monitor_desc = NULL;
+
+#if defined (LOG_FILE)
+  if (log_file) {
+    if (ferror(log_file))
+      fprintf(stderr, "Error writing log file.\n");
+    if (fclose(log_file) != 0)
+      fprintf(stderr, "Error closing log file.\n");
+  }
+#endif
+}
+
+/* Terminate the open connection to the remote debugger.
+   Use this when you want to detach and do something else
+   with your gdb.  */
+static void
+monitor_detach (from_tty)
+     int from_tty;
+{
+  pop_target();                /* calls monitor_close to do the real work */
+  if (from_tty)
+    printf ("Ending remote %s debugging\n", target_shortname);
+}
+/*
+ * _resume -- Tell the remote machine to resume.
+ */
+static void
+monitor_resume (pid, step, sig)
+     int pid, step, sig;
+{
+#ifdef LOG_FILE
+  fprintf (log_file, "\nIn Resume (step=%d, sig=%d)\n", step, sig);
+#endif
+
+  if (step)
+    {
+      printf_monitor (STEP_CMD);
+      /* wait for the echo.  */
+      expect (STEP_CMD, 1);
+    }
+  else
+    {
+      printf_monitor (GO_CMD);
+      /* swallow the echo.  */
+      expect (GO_CMD, 1);
+    }
+}
+
+/*
+ * _wait -- Wait until the remote machine stops, then return,
+ *          storing status in status just as `wait' would.
+ */
+
+static int
+monitor_wait (status)
+     WAITTYPE *status;
+{
+  int old_timeout = timeout;
+#ifdef LOG_FILE
+  fputs ("\nIn wait ()", log_file);
+#endif
+
+  WSETEXIT ((*status), 0);
+
+  timeout = 0;         /* Don't time out -- user program is running. */
+
+  expect_prompt(0);    /* Wait for prompt, outputting extraneous text */
+
+  WSETSTOP ((*status), SIGTRAP);
+
+  timeout = old_timeout;
+
+  return 0;
+}
+
+/* Return the name of register number regno in the form input and output by
+   monitor.  Currently, register_names just happens to contain exactly what
+   monitor wants.  Lets take advantage of that just as long as possible! */
+
+static char *
+get_reg_name (regno)
+     int regno;
+{
+  static char buf[50];
+  const char *p;
+  char *b;
+
+  b = buf;
+
+  if (regno < 0)
+    return ("");
+  for (p = reg_names[regno]; *p; p++)
+    *b++ = toupper(*p);
+  *b = '\000';
+
+  return buf;
+}
+
+/* read the remote registers into the block regs.  */
+
+static void
+monitor_fetch_registers ()
+{
+  int regno;
+
+  /* yeah yeah, i know this is horribly inefficient.  but it isn't done
+     very often...  i'll clean it up later.  */
+
+  for (regno = 0; regno <= PC_REGNUM; regno++)
+    monitor_fetch_register(regno);
+}
+
+/* Fetch register REGNO, or all registers if REGNO is -1.
+   Returns errno value.  */
+static void
+monitor_fetch_register (regno)
+     int regno;
+{
+  int val, j;
+
+#ifdef LOG_FILE
+  fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno));
+  fflush (log_file);
+#endif
+
+  if (regno < 0)
+    {
+      monitor_fetch_registers ();
+    }
+  else
+    {
+      char *name = get_reg_name (regno);
+      printf_monitor (GET_REG, name);
+      expect (name, 1);
+      expect (REG_DELIM, 1);
+      if (strcasecmp (name, "SR") == 0)
+       {
+         val = 0;
+         for (j = 0; j < 4; j++)
+           val = (val << 4) + get_hex_digit (j == 0);
+         supply_register (regno, (char *) &val);
+       }
+      else
+       {
+         get_hex_regs (1, regno);
+       }
+      if (CMD_END) 
+       {
+         expect (CMD_DELIM);
+         printf_monitor (CMD_END);
+       }
+      expect_prompt (1);
+    }
+  return;
+}
+
+/* Store the remote registers from the contents of the block REGS.  */
+
+static void
+monitor_store_registers ()
+{
+  int regno;
+
+  for (regno = 0; regno <= PC_REGNUM; regno++)
+    monitor_store_register(regno);
+
+  registers_changed ();
+}
+
+/* Store register REGNO, or all if REGNO == 0.
+   return errno value.  */
+static void
+monitor_store_register (regno)
+     int regno;
+{
+#ifdef LOG_FILE
+  fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno);
+#endif
+  if (regno == -1)
+    monitor_store_registers ();
+  else
+    {
+      if (kiodebug)
+       printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno));
+
+      printf_monitor (SET_REG, get_reg_name (regno),
+                     read_register (regno));
+
+      expect_prompt (1);
+    }
+}
+
+/* Get ready to modify the registers array.  On machines which store
+   individual registers, this doesn't need to do anything.  On machines
+   which store all the registers in one fell swoop, this makes sure
+   that registers contains all the registers from the program being
+   debugged.  */
+
+static void
+monitor_prepare_to_store ()
+{
+  /* Do nothing, since we can store individual regs */
+}
+
+static void
+monitor_files_info ()
+{
+  printf ("\tAttached to %s at %d baud.\n",
+         dev_name, baudrate);
+}
+
+/* Copy LEN bytes of data from debugger memory at MYADDR
+   to inferior's memory at MEMADDR.  Returns length moved.  */
+static int
+monitor_write_inferior_memory (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     unsigned char *myaddr;
+     int len;
+{
+  int i;
+  char buf[10];
+
+#ifdef LOG_FILE
+  fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
+#endif
+  for (i = 0; i < len; i++)
+    {
+      printf_monitor (MEM_SET_CMD, memaddr + i);
+      expect (sprintf (buf, MEM_PROMPT, memaddr + i), 1); 
+      expect (CMD_DELIM);
+      printf_monitor ("%x", myaddr[i]);
+      if (kiodebug)
+       printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]);
+      if (CMD_END)
+       {
+/***     expect (sprintf (buf, MEM_PROMPT, memaddr + i +1), 1);          
+         expect (CMD_DELIM); ***/
+         printf_monitor (CMD_END);
+       }
+      expect_prompt (1);
+    }
+  return len;
+}
+
+/* Read LEN bytes from inferior memory at MEMADDR.  Put the result
+   at debugger address MYADDR.  Returns length moved.  */
+static int
+monitor_read_inferior_memory(memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  int i, j;
+  char buf[20];
+
+  /* Number of bytes read so far.  */
+  int count;
+
+  /* Starting address of this pass.  */
+  unsigned long startaddr;
+
+  /* Number of bytes to read in this pass.  */
+  int len_this_pass;
+
+#ifdef LOG_FILE
+  fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
+#endif
+
+  /* Note that this code works correctly if startaddr is just less
+     than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
+     thing).  That is, something like
+     monitor_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
+     works--it never adds len To memaddr and gets 0.  */
+  /* However, something like
+     monitor_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
+     doesn't need to work.  Detect it and give up if there's an attempt
+     to do that.  */
+  if (((memaddr - 1) + len) < memaddr) {
+    errno = EIO;
+    return 0;
+  }
+  
+  startaddr = memaddr;
+  count = 0;
+  while (count < len)
+    {
+      len_this_pass = 16;
+      if ((startaddr % 16) != 0)
+       len_this_pass -= startaddr % 16;
+      if (len_this_pass > (len - count))
+       len_this_pass = (len - count);
+      if (kiodebug)
+       printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr);
+
+      for (i = 0; i < len_this_pass; i++)
+       {
+         printf_monitor (MEM_DIS_CMD, startaddr);
+         expect (sprintf(buf, MEM_PROMPT, startaddr), 1);
+         get_hex_byte (&myaddr[count++]);
+         if (kiodebug)
+           printf ("\nRead a 0x%x from 0x%x\n", myaddr[count-1], startaddr);
+         if (CMD_END) 
+           {
+             expect (CMD_DELIM);
+             printf_monitor (CMD_END);
+           }
+         expect_prompt (1);
+         startaddr += 1;
+       }
+    }
+  return len;
+}
+
+/* FIXME-someday!  merge these two.  */
+static int
+monitor_xfer_inferior_memory (memaddr, myaddr, len, write, target)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+     int write;
+     struct target_ops *target;                /* ignored */
+{
+  if (write)
+    return monitor_write_inferior_memory (memaddr, myaddr, len);
+  else
+    return monitor_read_inferior_memory (memaddr, myaddr, len);
+}
+
+static void
+monitor_kill (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  return;              /* ignore attempts to kill target system */
+}
+
+/* Clean up when a program exits.
+   The program actually lives on in the remote processor's RAM, and may be
+   run again without a download.  Don't leave it full of breakpoint
+   instructions.  */
+
+static void
+monitor_mourn_inferior ()
+{
+  remove_breakpoints ();
+  generic_mourn_inferior ();   /* Do all the proper things now */
+}
+
+#define MAX_MONITOR_BREAKPOINTS 16
+
+extern int memory_breakpoint_size;
+static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] = {0};
+
+static int
+monitor_insert_breakpoint (addr, shadow)
+     CORE_ADDR addr;
+     char *shadow;
+{
+  int i;
+
+#ifdef LOG_FILE
+  fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
+#endif
+  for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
+    if (breakaddr[i] == 0)
+      {
+       breakaddr[i] = addr;
+       if (kiodebug)
+         printf ("Breakpoint at %x\n", addr);
+       monitor_read_inferior_memory(addr, shadow, memory_breakpoint_size);
+       printf_monitor(SET_BREAK_CMD, addr);
+       expect_prompt(1);
+       return 0;
+      }
+
+  fprintf(stderr, "Too many breakpoints (> 16) for monitor\n");
+  return 1;
+}
+
+/*
+ * _remove_breakpoint -- Tell the monitor to remove a breakpoint
+ */
+static int
+monitor_remove_breakpoint (addr, shadow)
+     CORE_ADDR addr;
+     char *shadow;
+{
+  int i;
+
+#ifdef LOG_FILE
+  fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
+#endif
+  for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
+    if (breakaddr[i] == addr)
+      {
+       breakaddr[i] = 0;
+       /* some monitors remove breakpoints based on the address */
+       if (strcasecmp (target_shortname, "bug") == 0)   
+           printf_monitor(CLR_BREAK_CMD, addr);
+         else
+           printf_monitor(CLR_BREAK_CMD, i);
+       expect_prompt(1);
+       return 0;
+      }
+
+  fprintf(stderr, "Can't find breakpoint associated with 0x%x\n", addr);
+  return 1;
+}
+
+/* Load a file. This is usually an srecord, which is ascii. No 
+   protocol, just sent line by line. */
+
+#define DOWNLOAD_LINE_SIZE 100
+static void
+monitor_load (arg)
+    char       *arg;
+{
+  FILE *download;
+  char buf[DOWNLOAD_LINE_SIZE];
+  int i, bytes_read;
+
+  if (kiodebug)
+    printf ("Loading %s to monitor\n", arg);
+
+  download = fopen (arg, "r");
+  if (download == NULL)
+    {
+    error (sprintf (buf, "%s Does not exist", arg));
+    return;
+  }
+
+  printf_monitor (LOAD_CMD);
+/*  expect ("Waiting for S-records from host... ", 1); */
+
+  while (!feof (download))
+    {
+      bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
+      if (hashmark)
+       {
+         putchar ('.');
+         fflush (stdout);
+       }
+
+      if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
+       fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
+       break;
+      }
+      i = 0;
+      while (i++ <=200000) {} ;                        /* Ugly HACK, probably needs flow control */
+      if (bytes_read < DOWNLOAD_LINE_SIZE)
+       {
+         if (!feof (download))
+           error ("Only read %d bytes\n", bytes_read);
+         break;
+       }
+    }
+
+  if (hashmark)
+    {
+      putchar ('\n');
+    }
+  if (!feof (download))
+    error ("Never got EOF while downloading");
+  fclose (download);
+}
+
+/* Put a command string, in args, out to MONITOR.  Output from MONITOR is placed
+   on the users terminal until the prompt is seen. */
+
+static void
+monitor_command (args, fromtty)
+     char      *args;
+     int       fromtty;
+{
+#ifdef LOG_FILE
+  fprintf (log_file, "\nIn command (args=%s)\n", args);
+#endif
+  if (monitor_desc == NULL)
+    error("monitor target not open.");
+  
+  if (!args)
+    error("Missing command.");
+       
+  printf_monitor("%s\r", args);
+  expect_prompt(0);
+}
+
+#if 0
+
+/* Connect the user directly to MONITOR.  This command acts just like the
+   'cu' or 'tip' command.  Use <CR>~. or <CR>~^D to break out.  */
+
+static struct ttystate ttystate;
+
+static void
+cleanup_tty()
+{  printf("\r\n[Exiting connect mode]\r\n");
+  /*SERIAL_RESTORE(0, &ttystate);*/
+}
+
+static void
+connect_command (args, fromtty)
+     char      *args;
+     int       fromtty;
+{
+  fd_set readfds;
+  int numfds;
+  int c;
+  char cur_esc = 0;
+
+  dont_repeat();
+
+  if (monitor_desc == NULL)
+    error("monitor target not open.");
+  
+  if (args)
+    fprintf("This command takes no args.  They have been ignored.\n");
+       
+  printf("[Entering connect mode.  Use ~. or ~^D to escape]\n");
+
+  serial_raw(0, &ttystate);
+
+  make_cleanup(cleanup_tty, 0);
+
+  FD_ZERO(&readfds);
+
+  while (1)
+    {
+      do
+       {
+         FD_SET(0, &readfds);
+         FD_SET(monitor_desc, &readfds);
+         numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
+       }
+      while (numfds == 0);
+
+      if (numfds < 0)
+       perror_with_name("select");
+
+      if (FD_ISSET(0, &readfds))
+       {                       /* tty input, send to monitor */
+         c = getchar();
+         if (c < 0)
+           perror_with_name("connect");
+
+         printf_monitor("%c", c);
+         switch (cur_esc)
+           {
+           case 0:
+             if (c == '\r')
+               cur_esc = c;
+             break;
+           case '\r':
+             if (c == '~')
+               cur_esc = c;
+             else
+               cur_esc = 0;
+             break;
+           case '~':
+             if (c == '.' || c == '\004')
+               return;
+             else
+               cur_esc = 0;
+           }
+       }
+
+      if (FD_ISSET(monitor_desc, &readfds))
+       {
+         while (1)
+           {
+             c = readchar(0);
+             if (c < 0)
+               break;
+             putchar(c);
+           }
+         fflush(stdout);
+       }
+    }
+}
+#endif
+
+/*
+ * Define the monitor command strings. Since these are passed directly
+ * through to a printf style function, we need can include formatting
+ * strings. We also need a CR or LF on the end.
+ */
+struct monitor_ops rom68k_cmds = {
+  "go \r",                             /* execute or usually GO command */
+  "go \r",                             /* continue command */
+  "st \r",                             /* single step */
+  "db %x\r",                           /* set a breakpoint */
+  "cb %x\r",                           /* clear a breakpoint */
+  "pm %x\r",                           /* set memory to a value */
+  "pm %x\r",                           /* display memory */
+  "-%08X  ",                           /* prompt memory commands use */
+  "pr %s %x\r",                                /* set a register */
+  ":  ",                               /* delimiter between registers */
+  "pr %s\r",                           /* read a register */
+  "dc \r",                             /* download command */
+  "ROM68K :->",                                /* monitor command prompt */
+  "=",                                 /* end-of-command delimitor */
+  ".\r"                                        /* optional command terminator */
+};
+
+struct monitor_ops bug_cmds = {
+  "go \r",                             /* execute or usually GO command */
+  "go \r",                             /* continue command */
+  "gn \r",                             /* single step */
+  "br %x\r",                           /* set a breakpoint */
+  "nobr %x\r",                         /* clear a breakpoint */
+  "mm %x\r",                           /* set memory to a value */
+  "mm %x\r",                           /* display memory */
+  "%08X",                              /* prompt memory commands use */
+  "rs %s %x\r",                                /* set a register */
+  "=",                                 /* delimiter between registers */
+  "rm %s\r",                           /* read a register */
+  "lo 0\r",                            /* download command */
+  "Bug>",                              /* monitor command prompt */
+  "? ",                                        /* end-of-command delimitor */
+  ".\r"                                        /* optional command terminator */
+};
+
+/* Define the target subroutine names */
+struct monitor_ops mon68_cmds = {
+  "",                          /* execute or usually GO command */
+  "",                          /* continue command */
+  "",                          /* single step */
+  "",                          /* set a breakpoint */
+  "",                          /* clear a breakpoint */
+  "",                          /* set memory to a value */
+  "",                          /* display memory */
+  "",                          /* set a register */
+  "",                          /* delimiter between registers */       
+  "",                          /* read a register */
+  "",                          /* download command */
+  ">",                         /* monitor command prompt */
+  "",                                  /* end-of-command delimitor */
+  ""                                   /* optional command terminator */
+};
+
+struct target_ops rom68k_ops = {
+  "rom68k",
+  "Integrated System's ROM68K remote debug monitor",
+  "Use a remote computer running the ROM68K debug monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).",
+  rom68k_open,
+  monitor_close, 
+  0,
+  monitor_detach,
+  monitor_resume,
+  monitor_wait,
+  monitor_fetch_register,
+  monitor_store_register,
+  monitor_prepare_to_store,
+  monitor_xfer_inferior_memory,
+  monitor_files_info,
+  monitor_insert_breakpoint,
+  monitor_remove_breakpoint,   /* Breakpoints */
+  0,
+  0,
+  0,
+  0,
+  0,                           /* Terminal handling */
+  monitor_kill,
+  monitor_load,                        /* load */
+  0,                           /* lookup_symbol */
+  monitor_create_inferior,
+  monitor_mourn_inferior,
+  0,                           /* can_run */
+  0,                           /* notice_signals */
+  process_stratum,
+  0,                           /* next */
+  1,
+  1,
+  1,
+  1,
+  1,                           /* all mem, mem, stack, regs, exec */
+  0,
+  0,                           /* Section pointers */
+  OPS_MAGIC,                   /* Always the last thing */
+};
+
+struct target_ops monitor_bug_ops = {
+  "bug",
+  "Motorola's BUG remote serial debug monitor",
+  "Use a remote computer running Motorola's BUG debug monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).",
+  bug_open,
+  monitor_close, 
+  0,
+  monitor_detach,
+  monitor_resume,
+  monitor_wait,
+  monitor_fetch_register,
+  monitor_store_register,
+  monitor_prepare_to_store,
+  monitor_xfer_inferior_memory,
+  monitor_files_info,
+  monitor_insert_breakpoint,
+  monitor_remove_breakpoint,   /* Breakpoints */
+  0,
+  0,
+  0,
+  0,
+  0,                           /* Terminal handling */
+  monitor_kill,
+  monitor_load,                        /* load */
+  0,                           /* lookup_symbol */
+  monitor_create_inferior,
+  monitor_mourn_inferior,
+  0,                           /* can_run */
+  0,                           /* notice_signals */
+  process_stratum,
+  0,                           /* next */
+  1,
+  1,
+  1,
+  1,
+  1,                           /* all mem, mem, stack, regs, exec */
+  0,
+  0,                           /* Section pointers */
+  OPS_MAGIC,                   /* Always the last thing */
+};
+
+struct target_ops mon68_ops = {
+  "mon68",
+  "Intermetric's MON68 remote serial debug monitor",
+  "Use a remote computer running the MON68 debug monitor.\n\
+Specify the serial device it is connected to (e.g. /dev/ttya).",
+  mon68_open,
+  monitor_close, 
+  0,
+  monitor_detach,
+  monitor_resume,
+  monitor_wait,
+  monitor_fetch_register,
+  monitor_store_register,
+  monitor_prepare_to_store,
+  monitor_xfer_inferior_memory,
+  monitor_files_info,
+  monitor_insert_breakpoint,
+  monitor_remove_breakpoint,   /* Breakpoints */
+  0,
+  0,
+  0,
+  0,
+  0,                           /* Terminal handling */
+  monitor_kill,
+  monitor_load,                        /* load */
+  0,                           /* lookup_symbol */
+  monitor_create_inferior,
+  monitor_mourn_inferior,
+  0,                           /* can_run */
+  0,                           /* notice_signals */
+  process_stratum,
+  0,                           /* next */
+  1,
+  1,
+  1,
+  1,
+  1,                           /* all mem, mem, stack, regs, exec */
+  0,
+  0,                           /* Section pointers */
+  OPS_MAGIC,                   /* Always the last thing */
+};
+
+void
+_initialize_remote_monitors ()
+{
+  add_show_from_set (
+                     add_set_cmd ("remotedebug", no_class, var_boolean,
+                                  (char *)&kiodebug,
+                                  "Set debugging of I/O to a serial based Monitor.\n\
+When enabled, debugging info is displayed.",
+                                  &setlist),
+                    &showlist);
+  add_show_from_set (
+                     add_set_cmd ("hash", no_class, var_boolean,
+                                  (char *)&hashmark,
+                                 "Set display of activity while downloading a file.\n\
+When enabled, a period \'.\' is displayed.",
+                                  &setlist),
+                    &showlist);
+
+  /* generic monitor command */
+  add_com ("monitor <command>", class_obscure, monitor_command,
+          "Send a command to the debug monitor."); 
+#if 0
+  add_com ("connect", class_obscure, connect_command,
+          "Connect the terminal directly up to a serial based command monitor.\n\
+Use <CR>~. or <CR>~^D to break out.");
+#endif
+
+  add_target (&rom68k_ops);
+/*  add_target (&mon68_ops); */
+  add_target (&monitor_bug_ops);
+}
index d9367a8517d17f8b57f0f5f03b2be91ee2c7f869..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 (file)
-/* Remote debugging interface for MONITOR boot monitor, for GDB.
-   Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
-   Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
-
-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., 675 Mass Ave, Cambridge, MA 02139, USA.  */
-
-/* This file was derived from remote-eb.c, which did a similar job, but for
-   an AMD-29K running EBMON.  That file was in turn derived from remote.c
-   as mentioned in the following comment (left in for comic relief):
-
-  "This is like remote.c but is for an esoteric situation--
-   having an a29k board in a PC hooked up to a unix machine with
-   a serial line, and running ctty com1 on the PC, through which
-   the unix machine can run ebmon.  Not to mention that the PC
-   has PC/NFS, so it can access the same executables that gdb can,
-   over the net in real time."
-
-   In reality, this module talks to a debug monitor called 'MONITOR', which
-   We communicate with MONITOR via either a direct serial line, or a TCP
-   (or possibly TELNET) stream to a terminal multiplexor,
-   which in turn talks to the target board.
-
-   This is based on remote-st2000.c. I left in the above note here for histerical
-   reasons.
-*/
-
-#include "defs.h"
-#include "gdbcore.h"
-#include "target.h"
-#include "wait.h"
-#include <varargs.h>
-#include <signal.h>
-#include <string.h>
-#include <sys/types.h>
-#include "command.h"
-#include "serial.h"
-#include "monitor.h"
-
-#ifdef HAVE_TERMIO
-#  define TERMINAL struct termios
-#else
-#  define TERMINAL struct sgttyb
-#endif
-
-struct monitor_ops *current_monitor;
-extern struct target_ops rom68k_ops;           /* Forward declaration */
-extern struct target_ops mon68_ops;            /* Forward declaration */
-extern struct target_ops monitor_bug_ops;      /* Forward declaration */
-extern struct monitor_ops rom68k_cmds;         /* Forward declaration */
-extern struct monitor_ops mon68_cmds;          /* Forward declaration */
-extern struct monitor_ops bug_cmds;            /* Forward declaration */
-extern struct cmd_list_element *setlist;
-extern struct cmd_list_element *unsetlist;
-struct cmd_list_element *showlist;
-
-static void monitor_close();
-static void monitor_fetch_register();
-static void monitor_store_register();
-static int kiodebug;                           /* flag set by "set remotedebug" */
-static int hashmark;                           /* flag set by "set hash" */
-
-#define LOG_FILE "monitor.log"
-#if defined (LOG_FILE)
-FILE *log_file;
-#endif
-
-static int timeout = 24;
-
-/* Descriptor for I/O to remote machine.  Initialize it to NULL so that
-   monitor_open knows that we don't have a file open when the program starts.
-   */
-static serial_t monitor_desc = NULL;
-
-/* Send data to monitor.  Works just like printf. */
-
-static void
-printf_monitor(va_alist)
-     va_dcl
-{
-  va_list args;
-  char *pattern;
-  char buf[200];
-  int i;
-
-  va_start(args);
-
-  pattern = va_arg(args, char *);
-
-  vsprintf(buf, pattern, args);
-
-  if (SERIAL_WRITE(monitor_desc, buf, strlen(buf)))
-    fprintf(stderr, "SERIAL_WRITE failed: %s\n", safe_strerror(errno));
-}
-
-/* Read a character from the remote system, doing all the fancy
-   timeout stuff.  */
-static int
-readchar(timeout)
-     int timeout;
-{
-  int c;
-
-  c = SERIAL_READCHAR(monitor_desc, timeout);
-
-  if (kiodebug)
-    putchar(c & 0x7f);
-
-#ifdef LOG_FILE
-  if (isascii (c))
-    putc(c & 0x7f, log_file);
-#endif
-
-  if (c >= 0)
-    return c & 0x7f;
-
-  if (c == SERIAL_TIMEOUT)
-    {
-      if (timeout == 0)
-       return c;               /* Polls shouldn't generate timeout errors */
-
-      error("Timeout reading from remote system.");
-    }
-
-  perror_with_name("remote-monitor");
-}
-
-/* Scan input from the remote system, until STRING is found.  If DISCARD is
-   non-zero, then discard non-matching input, else print it out.
-   Let the user break out immediately.  */
-static void
-expect(string, discard)
-     char *string;
-     int discard;
-{
-  char *p = string;
-  int c;
-
-  if (kiodebug)
-    printf ("Expecting \"%s\"\n", string);
-
-  immediate_quit = 1;
-  while (1)
-    {
-      c = readchar(timeout);
-      if (!isascii (c))
-       continue;
-      if (c == *p++)
-       {
-         if (*p == '\0')
-           {
-             immediate_quit = 0;
-             if (kiodebug)
-               printf ("\nMatched\n");
-             return;
-           }
-       }
-      else
-       {
-         if (!discard)
-           {
-             fwrite(string, 1, (p - 1) - string, stdout);
-             putchar((char)c);
-             fflush(stdout);
-           }
-         p = string;
-       }
-    }
-}
-
-/* Keep discarding input until we see the MONITOR prompt.
-
-   The convention for dealing with the prompt is that you
-   o give your command
-   o *then* wait for the prompt.
-
-   Thus the last thing that a procedure does with the serial line
-   will be an expect_prompt().  Exception:  monitor_resume does not
-   wait for the prompt, because the terminal is being handed over
-   to the inferior.  However, the next thing which happens after that
-   is a monitor_wait which does wait for the prompt.
-   Note that this includes abnormal exit, e.g. error().  This is
-   necessary to prevent getting into states from which we can't
-   recover.  */
-static void
-expect_prompt(discard)
-     int discard;
-{
-#if defined (LOG_FILE)
-  /* This is a convenient place to do this.  The idea is to do it often
-     enough that we never lose much data if we terminate abnormally.  */
-  fflush(log_file);
-#endif
-  expect (PROMPT, discard);
-}
-
-/* Get a hex digit from the remote system & return its value.
-   If ignore_space is nonzero, ignore spaces (not newline, tab, etc).  */
-static int
-get_hex_digit(ignore_space)
-     int ignore_space;
-{
-  int ch;
-  while (1)
-    {
-      ch = readchar(timeout);
-      if (ch >= '0' && ch <= '9')
-       return ch - '0';
-      else if (ch >= 'A' && ch <= 'F')
-       return ch - 'A' + 10;
-      else if (ch >= 'a' && ch <= 'f')
-       return ch - 'a' + 10;
-      else if (ch == ' ' && ignore_space)
-       ;
-      else
-       {
-         expect_prompt(1);
-         error("Invalid hex digit from remote system.");
-       }
-    }
-}
-
-/* Get a byte from monitor and put it in *BYT.  Accept any number
-   leading spaces.  */
-static void
-get_hex_byte (byt)
-     char *byt;
-{
-  int val;
-
-  val = get_hex_digit (1) << 4;
-  val |= get_hex_digit (0);
-  *byt = val;
-}
-
-/* Get N 32-bit words from remote, each preceded by a space,
-   and put them in registers starting at REGNO.  */
-static void
-get_hex_regs (n, regno)
-     int n;
-     int regno;
-{
-  long val;
-  int i;
-
-  for (i = 0; i < n; i++)
-    {
-      int j;
-      
-      val = 0;
-      for (j = 0; j < 8; j++)
-       val = (val << 4) + get_hex_digit (j == 0);
-      supply_register (regno++, (char *) &val);
-    }
-}
-
-/* This is called not only when we first attach, but also when the
-   user types "run" after having attached.  */
-static void
-monitor_create_inferior (execfile, args, env)
-     char *execfile;
-     char *args;
-     char **env;
-{
-  int entry_pt;
-
-  if (args && *args)
-    error("Can't pass arguments to remote MONITOR process");
-
-  if (execfile == 0 || exec_bfd == 0)
-    error("No exec file specified");
-
-  entry_pt = (int) bfd_get_start_address (exec_bfd);
-
-#ifdef CREATE_INFERIOR_HOOK
-  CREATE_INFERIOR_HOOK (0);            /* No process-ID */
-#endif  
-#ifdef LOG_FILE
-  fputs ("\nIn Create_inferior()", log_file);
-#endif
-
-/* The "process" (board) is already stopped awaiting our commands, and
-   the program is already downloaded.  We just set its PC and go.  */
-
-  clear_proceed_status ();
-
-  /* Tell wait_for_inferior that we've started a new process.  */
-  init_wait_for_inferior ();
-
-  /* Set up the "saved terminal modes" of the inferior
-     based on what modes we are starting it with.  */
-  target_terminal_init ();
-
-  /* Install inferior's terminal modes.  */
-  target_terminal_inferior ();
-
-  /* insert_step_breakpoint ();  FIXME, do we need this?  */
-  proceed ((CORE_ADDR)entry_pt, -1, 0);                /* Let 'er rip... */
-}
-
-/* Open a connection to a remote debugger.
-   NAME is the filename used for communication.  */
-
-static int baudrate = 9600;
-static char dev_name[100];
-
-static void
-general_open(args, name, from_tty)
-     char *args;
-     char *name;
-     int from_tty;
-{
-  if (args == NULL)
-    error ("Use `target %s DEVICE-NAME' to use a serial port, or \n\
-`target %s HOST-NAME:PORT-NUMBER' to use a network connection.", name, name);
-
-  target_preopen(from_tty);
-
-  monitor_close(0);
-
-  monitor_desc = SERIAL_OPEN(dev_name);
-
-  if (monitor_desc == NULL)
-    perror_with_name(dev_name);
-
-  /* The baud rate was specified when GDB was started.  */
-  if (baud_rate)
-    {
-      int rate;
-
-      if (sscanf (baud_rate, "%d", &rate) == 1)
-       if (SERIAL_SETBAUDRATE (monitor_desc, rate))
-         {
-           SERIAL_CLOSE (monitor_desc);
-           perror_with_name (name);
-         }
-    }
-
-  SERIAL_RAW(monitor_desc);
-
-#if defined (LOG_FILE)
-  log_file = fopen (LOG_FILE, "w");
-  if (log_file == NULL)
-    perror_with_name (LOG_FILE);
-#endif
-
-  /* Hello?  Are you there?  */
-  printf_monitor("\r");        /* CR wakes up monitor */
-  
-  expect_prompt(1);
-
-  if (from_tty)
-    printf("Remote %s connected to %s\n", target_shortname,
-          dev_name);
-}
-
-static void
-rom68k_open(args, from_tty)
-     char *args;
-     int from_tty;
-{
-  push_target(&rom68k_ops);
-  push_monitor (&rom68k_cmds);
-
-  general_open (args, "rom68k", from_tty);
-}
-
-static void
-mon68_open(args, from_tty)
-     char *args;
-     int from_tty;
-{
-  push_target(&mon68_ops);
-  push_monitor (&mon68_cmds);
-
-  general_open (args, "mon68", from_tty);
-}
-
-static void
-bug_open(args, from_tty)
-     char *args;
-     int from_tty;
-{
-  push_target(&monitor_bug_ops);
-  push_monitor (&bug_cmds);
-
-  general_open (args, "bug", from_tty);
-}
-
-/*
- * _close -- Close out all files and local state before this target loses control.
- */
-
-static void
-monitor_close (quitting)
-     int quitting;
-{
-  SERIAL_CLOSE(monitor_desc);
-  monitor_desc = NULL;
-
-#if defined (LOG_FILE)
-  if (log_file) {
-    if (ferror(log_file))
-      fprintf(stderr, "Error writing log file.\n");
-    if (fclose(log_file) != 0)
-      fprintf(stderr, "Error closing log file.\n");
-  }
-#endif
-}
-
-/* Terminate the open connection to the remote debugger.
-   Use this when you want to detach and do something else
-   with your gdb.  */
-static void
-monitor_detach (from_tty)
-     int from_tty;
-{
-  pop_target();                /* calls monitor_close to do the real work */
-  if (from_tty)
-    printf ("Ending remote %s debugging\n", target_shortname);
-}
-/*
- * _resume -- Tell the remote machine to resume.
- */
-static void
-monitor_resume (pid, step, sig)
-     int pid, step, sig;
-{
-#ifdef LOG_FILE
-  fprintf (log_file, "\nIn Resume (step=%d, sig=%d)\n", step, sig);
-#endif
-
-  if (step)
-    {
-      printf_monitor (STEP_CMD);
-      /* wait for the echo.  */
-      expect (STEP_CMD, 1);
-    }
-  else
-    {
-      printf_monitor (GO_CMD);
-      /* swallow the echo.  */
-      expect (GO_CMD, 1);
-    }
-}
-
-/*
- * _wait -- Wait until the remote machine stops, then return,
- *          storing status in status just as `wait' would.
- */
-
-static int
-monitor_wait (status)
-     WAITTYPE *status;
-{
-  int old_timeout = timeout;
-#ifdef LOG_FILE
-  fputs ("\nIn wait ()", log_file);
-#endif
-
-  WSETEXIT ((*status), 0);
-
-  timeout = 0;         /* Don't time out -- user program is running. */
-
-  expect_prompt(0);    /* Wait for prompt, outputting extraneous text */
-
-  WSETSTOP ((*status), SIGTRAP);
-
-  timeout = old_timeout;
-
-  return 0;
-}
-
-/* Return the name of register number regno in the form input and output by
-   monitor.  Currently, register_names just happens to contain exactly what
-   monitor wants.  Lets take advantage of that just as long as possible! */
-
-static char *
-get_reg_name (regno)
-     int regno;
-{
-  static char buf[50];
-  const char *p;
-  char *b;
-
-  b = buf;
-
-  if (regno < 0)
-    return ("");
-  for (p = reg_names[regno]; *p; p++)
-    *b++ = toupper(*p);
-  *b = '\000';
-
-  return buf;
-}
-
-/* read the remote registers into the block regs.  */
-
-static void
-monitor_fetch_registers ()
-{
-  int regno;
-
-  /* yeah yeah, i know this is horribly inefficient.  but it isn't done
-     very often...  i'll clean it up later.  */
-
-  for (regno = 0; regno <= PC_REGNUM; regno++)
-    monitor_fetch_register(regno);
-}
-
-/* Fetch register REGNO, or all registers if REGNO is -1.
-   Returns errno value.  */
-static void
-monitor_fetch_register (regno)
-     int regno;
-{
-  int val, j;
-
-#ifdef LOG_FILE
-  fprintf (log_file, "\nIn Fetch Register (reg=%s)\n", get_reg_name (regno));
-  fflush (log_file);
-#endif
-
-  if (regno < 0)
-    {
-      monitor_fetch_registers ();
-    }
-  else
-    {
-      char *name = get_reg_name (regno);
-      printf_monitor (GET_REG, name);
-      expect (name, 1);
-      expect (REG_DELIM, 1);
-      if (strcasecmp (name, "SR") == 0)
-       {
-         val = 0;
-         for (j = 0; j < 4; j++)
-           val = (val << 4) + get_hex_digit (j == 0);
-         supply_register (regno, (char *) &val);
-       }
-      else
-       {
-         get_hex_regs (1, regno);
-       }
-      if (CMD_END) 
-       {
-         expect (CMD_DELIM);
-         printf_monitor (CMD_END);
-       }
-      expect_prompt (1);
-    }
-  return;
-}
-
-/* Store the remote registers from the contents of the block REGS.  */
-
-static void
-monitor_store_registers ()
-{
-  int regno;
-
-  for (regno = 0; regno <= PC_REGNUM; regno++)
-    monitor_store_register(regno);
-
-  registers_changed ();
-}
-
-/* Store register REGNO, or all if REGNO == 0.
-   return errno value.  */
-static void
-monitor_store_register (regno)
-     int regno;
-{
-#ifdef LOG_FILE
-  fprintf (log_file, "\nIn Store_register (regno=%d)\n", regno);
-#endif
-  if (regno == -1)
-    monitor_store_registers ();
-  else
-    {
-      if (kiodebug)
-       printf ("Setting register %s to 0x%x\n", get_reg_name (regno), read_register (regno));
-
-      printf_monitor (SET_REG, get_reg_name (regno),
-                     read_register (regno));
-
-      expect_prompt (1);
-    }
-}
-
-/* Get ready to modify the registers array.  On machines which store
-   individual registers, this doesn't need to do anything.  On machines
-   which store all the registers in one fell swoop, this makes sure
-   that registers contains all the registers from the program being
-   debugged.  */
-
-static void
-monitor_prepare_to_store ()
-{
-  /* Do nothing, since we can store individual regs */
-}
-
-static void
-monitor_files_info ()
-{
-  printf ("\tAttached to %s at %d baud.\n",
-         dev_name, baudrate);
-}
-
-/* Copy LEN bytes of data from debugger memory at MYADDR
-   to inferior's memory at MEMADDR.  Returns length moved.  */
-static int
-monitor_write_inferior_memory (memaddr, myaddr, len)
-     CORE_ADDR memaddr;
-     unsigned char *myaddr;
-     int len;
-{
-  int i;
-  char buf[10];
-
-#ifdef LOG_FILE
-  fprintf (log_file, "\nIn Write_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
-#endif
-  for (i = 0; i < len; i++)
-    {
-      printf_monitor (MEM_SET_CMD, memaddr + i);
-      expect (sprintf (buf, MEM_PROMPT, memaddr + i), 1); 
-      expect (CMD_DELIM);
-      printf_monitor ("%x", myaddr[i]);
-      if (kiodebug)
-       printf ("\nSet 0x%x to 0x%x\n", memaddr + i, myaddr[i]);
-      if (CMD_END)
-       {
-/***     expect (sprintf (buf, MEM_PROMPT, memaddr + i +1), 1);          
-         expect (CMD_DELIM); ***/
-         printf_monitor (CMD_END);
-       }
-      expect_prompt (1);
-    }
-  return len;
-}
-
-/* Read LEN bytes from inferior memory at MEMADDR.  Put the result
-   at debugger address MYADDR.  Returns length moved.  */
-static int
-monitor_read_inferior_memory(memaddr, myaddr, len)
-     CORE_ADDR memaddr;
-     char *myaddr;
-     int len;
-{
-  int i, j;
-  char buf[20];
-
-  /* Number of bytes read so far.  */
-  int count;
-
-  /* Starting address of this pass.  */
-  unsigned long startaddr;
-
-  /* Number of bytes to read in this pass.  */
-  int len_this_pass;
-
-#ifdef LOG_FILE
-  fprintf (log_file, "\nIn Read_inferior_memory (memaddr=%x, len=%d)\n", memaddr, len);
-#endif
-
-  /* Note that this code works correctly if startaddr is just less
-     than UINT_MAX (well, really CORE_ADDR_MAX if there was such a
-     thing).  That is, something like
-     monitor_read_bytes (CORE_ADDR_MAX - 4, foo, 4)
-     works--it never adds len To memaddr and gets 0.  */
-  /* However, something like
-     monitor_read_bytes (CORE_ADDR_MAX - 3, foo, 4)
-     doesn't need to work.  Detect it and give up if there's an attempt
-     to do that.  */
-  if (((memaddr - 1) + len) < memaddr) {
-    errno = EIO;
-    return 0;
-  }
-  
-  startaddr = memaddr;
-  count = 0;
-  while (count < len)
-    {
-      len_this_pass = 16;
-      if ((startaddr % 16) != 0)
-       len_this_pass -= startaddr % 16;
-      if (len_this_pass > (len - count))
-       len_this_pass = (len - count);
-      if (kiodebug)
-       printf ("\nDisplay %d bytes at %x\n", len_this_pass, startaddr);
-
-      for (i = 0; i < len_this_pass; i++)
-       {
-         printf_monitor (MEM_DIS_CMD, startaddr);
-         expect (sprintf(buf, MEM_PROMPT, startaddr), 1);
-         get_hex_byte (&myaddr[count++]);
-         if (kiodebug)
-           printf ("\nRead a 0x%x from 0x%x\n", myaddr[count-1], startaddr);
-         if (CMD_END) 
-           {
-             expect (CMD_DELIM);
-             printf_monitor (CMD_END);
-           }
-         expect_prompt (1);
-         startaddr += 1;
-       }
-    }
-  return len;
-}
-
-/* FIXME-someday!  merge these two.  */
-static int
-monitor_xfer_inferior_memory (memaddr, myaddr, len, write, target)
-     CORE_ADDR memaddr;
-     char *myaddr;
-     int len;
-     int write;
-     struct target_ops *target;                /* ignored */
-{
-  if (write)
-    return monitor_write_inferior_memory (memaddr, myaddr, len);
-  else
-    return monitor_read_inferior_memory (memaddr, myaddr, len);
-}
-
-static void
-monitor_kill (args, from_tty)
-     char *args;
-     int from_tty;
-{
-  return;              /* ignore attempts to kill target system */
-}
-
-/* Clean up when a program exits.
-   The program actually lives on in the remote processor's RAM, and may be
-   run again without a download.  Don't leave it full of breakpoint
-   instructions.  */
-
-static void
-monitor_mourn_inferior ()
-{
-  remove_breakpoints ();
-  generic_mourn_inferior ();   /* Do all the proper things now */
-}
-
-#define MAX_MONITOR_BREAKPOINTS 16
-
-extern int memory_breakpoint_size;
-static CORE_ADDR breakaddr[MAX_MONITOR_BREAKPOINTS] = {0};
-
-static int
-monitor_insert_breakpoint (addr, shadow)
-     CORE_ADDR addr;
-     char *shadow;
-{
-  int i;
-
-#ifdef LOG_FILE
-  fprintf (log_file, "\nIn Insert_breakpoint (addr=%x)\n", addr);
-#endif
-  for (i = 0; i <= MAX_MONITOR_BREAKPOINTS; i++)
-    if (breakaddr[i] == 0)
-      {
-       breakaddr[i] = addr;
-       if (kiodebug)
-         printf ("Breakpoint at %x\n", addr);
-       monitor_read_inferior_memory(addr, shadow, memory_breakpoint_size);
-       printf_monitor(SET_BREAK_CMD, addr);
-       expect_prompt(1);
-       return 0;
-      }
-
-  fprintf(stderr, "Too many breakpoints (> 16) for monitor\n");
-  return 1;
-}
-
-/*
- * _remove_breakpoint -- Tell the monitor to remove a breakpoint
- */
-static int
-monitor_remove_breakpoint (addr, shadow)
-     CORE_ADDR addr;
-     char *shadow;
-{
-  int i;
-
-#ifdef LOG_FILE
-  fprintf (log_file, "\nIn Remove_breakpoint (addr=%x)\n", addr);
-#endif
-  for (i = 0; i < MAX_MONITOR_BREAKPOINTS; i++)
-    if (breakaddr[i] == addr)
-      {
-       breakaddr[i] = 0;
-       /* some monitors remove breakpoints based on the address */
-       if (strcasecmp (target_shortname, "bug") == 0)   
-           printf_monitor(CLR_BREAK_CMD, addr);
-         else
-           printf_monitor(CLR_BREAK_CMD, i);
-       expect_prompt(1);
-       return 0;
-      }
-
-  fprintf(stderr, "Can't find breakpoint associated with 0x%x\n", addr);
-  return 1;
-}
-
-/* Load a file. This is usually an srecord, which is ascii. No 
-   protocol, just sent line by line. */
-
-#define DOWNLOAD_LINE_SIZE 100
-static void
-monitor_load (arg)
-    char       *arg;
-{
-  FILE *download;
-  char buf[DOWNLOAD_LINE_SIZE];
-  int i, bytes_read;
-
-  if (kiodebug)
-    printf ("Loading %s to monitor\n", arg);
-
-  download = fopen (arg, "r");
-  if (download == NULL)
-    {
-    error (sprintf (buf, "%s Does not exist", arg));
-    return;
-  }
-
-  printf_monitor (LOAD_CMD);
-/*  expect ("Waiting for S-records from host... ", 1); */
-
-  while (!feof (download))
-    {
-      bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
-      if (hashmark)
-       {
-         putchar ('.');
-         fflush (stdout);
-       }
-
-      if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
-       fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
-       break;
-      }
-      i = 0;
-      while (i++ <=200000) {} ;                        /* Ugly HACK, probably needs flow control */
-      if (bytes_read < DOWNLOAD_LINE_SIZE)
-       {
-         if (!feof (download))
-           error ("Only read %d bytes\n", bytes_read);
-         break;
-       }
-    }
-
-  if (hashmark)
-    {
-      putchar ('\n');
-    }
-  if (!feof (download))
-    error ("Never got EOF while downloading");
-  fclose (download);
-}
-
-/* Put a command string, in args, out to MONITOR.  Output from MONITOR is placed
-   on the users terminal until the prompt is seen. */
-
-static void
-monitor_command (args, fromtty)
-     char      *args;
-     int       fromtty;
-{
-#ifdef LOG_FILE
-  fprintf (log_file, "\nIn command (args=%s)\n", args);
-#endif
-  if (monitor_desc == NULL)
-    error("monitor target not open.");
-  
-  if (!args)
-    error("Missing command.");
-       
-  printf_monitor("%s\r", args);
-  expect_prompt(0);
-}
-
-#if 0
-
-/* Connect the user directly to MONITOR.  This command acts just like the
-   'cu' or 'tip' command.  Use <CR>~. or <CR>~^D to break out.  */
-
-static struct ttystate ttystate;
-
-static void
-cleanup_tty()
-{  printf("\r\n[Exiting connect mode]\r\n");
-  /*SERIAL_RESTORE(0, &ttystate);*/
-}
-
-static void
-connect_command (args, fromtty)
-     char      *args;
-     int       fromtty;
-{
-  fd_set readfds;
-  int numfds;
-  int c;
-  char cur_esc = 0;
-
-  dont_repeat();
-
-  if (monitor_desc == NULL)
-    error("monitor target not open.");
-  
-  if (args)
-    fprintf("This command takes no args.  They have been ignored.\n");
-       
-  printf("[Entering connect mode.  Use ~. or ~^D to escape]\n");
-
-  serial_raw(0, &ttystate);
-
-  make_cleanup(cleanup_tty, 0);
-
-  FD_ZERO(&readfds);
-
-  while (1)
-    {
-      do
-       {
-         FD_SET(0, &readfds);
-         FD_SET(monitor_desc, &readfds);
-         numfds = select(sizeof(readfds)*8, &readfds, 0, 0, 0);
-       }
-      while (numfds == 0);
-
-      if (numfds < 0)
-       perror_with_name("select");
-
-      if (FD_ISSET(0, &readfds))
-       {                       /* tty input, send to monitor */
-         c = getchar();
-         if (c < 0)
-           perror_with_name("connect");
-
-         printf_monitor("%c", c);
-         switch (cur_esc)
-           {
-           case 0:
-             if (c == '\r')
-               cur_esc = c;
-             break;
-           case '\r':
-             if (c == '~')
-               cur_esc = c;
-             else
-               cur_esc = 0;
-             break;
-           case '~':
-             if (c == '.' || c == '\004')
-               return;
-             else
-               cur_esc = 0;
-           }
-       }
-
-      if (FD_ISSET(monitor_desc, &readfds))
-       {
-         while (1)
-           {
-             c = readchar(0);
-             if (c < 0)
-               break;
-             putchar(c);
-           }
-         fflush(stdout);
-       }
-    }
-}
-#endif
-
-/*
- * Define the monitor command strings. Since these are passed directly
- * through to a printf style function, we need can include formatting
- * strings. We also need a CR or LF on the end.
- */
-struct monitor_ops rom68k_cmds = {
-  "go \r",                             /* execute or usually GO command */
-  "go \r",                             /* continue command */
-  "st \r",                             /* single step */
-  "db %x\r",                           /* set a breakpoint */
-  "cb %x\r",                           /* clear a breakpoint */
-  "pm %x\r",                           /* set memory to a value */
-  "pm %x\r",                           /* display memory */
-  "-%08X  ",                           /* prompt memory commands use */
-  "pr %s %x\r",                                /* set a register */
-  ":  ",                               /* delimiter between registers */
-  "pr %s\r",                           /* read a register */
-  "dc \r",                             /* download command */
-  "ROM68K :->",                                /* monitor command prompt */
-  "=",                                 /* end-of-command delimitor */
-  ".\r"                                        /* optional command terminator */
-};
-
-struct monitor_ops bug_cmds = {
-  "go \r",                             /* execute or usually GO command */
-  "go \r",                             /* continue command */
-  "gn \r",                             /* single step */
-  "br %x\r",                           /* set a breakpoint */
-  "nobr %x\r",                         /* clear a breakpoint */
-  "mm %x\r",                           /* set memory to a value */
-  "mm %x\r",                           /* display memory */
-  "%08X",                              /* prompt memory commands use */
-  "rs %s %x\r",                                /* set a register */
-  "=",                                 /* delimiter between registers */
-  "rm %s\r",                           /* read a register */
-  "lo 0\r",                            /* download command */
-  "Bug>",                              /* monitor command prompt */
-  "? ",                                        /* end-of-command delimitor */
-  ".\r"                                        /* optional command terminator */
-};
-
-/* Define the target subroutine names */
-struct monitor_ops mon68_cmds = {
-  "",                          /* execute or usually GO command */
-  "",                          /* continue command */
-  "",                          /* single step */
-  "",                          /* set a breakpoint */
-  "",                          /* clear a breakpoint */
-  "",                          /* set memory to a value */
-  "",                          /* display memory */
-  "",                          /* set a register */
-  "",                          /* delimiter between registers */       
-  "",                          /* read a register */
-  "",                          /* download command */
-  ">",                         /* monitor command prompt */
-  "",                                  /* end-of-command delimitor */
-  ""                                   /* optional command terminator */
-};
-
-struct target_ops rom68k_ops = {
-  "rom68k",
-  "Integrated System's ROM68K remote debug monitor",
-  "Use a remote computer running the ROM68K debug monitor.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya).",
-  rom68k_open,
-  monitor_close, 
-  0,
-  monitor_detach,
-  monitor_resume,
-  monitor_wait,
-  monitor_fetch_register,
-  monitor_store_register,
-  monitor_prepare_to_store,
-  monitor_xfer_inferior_memory,
-  monitor_files_info,
-  monitor_insert_breakpoint,
-  monitor_remove_breakpoint,   /* Breakpoints */
-  0,
-  0,
-  0,
-  0,
-  0,                           /* Terminal handling */
-  monitor_kill,
-  monitor_load,                        /* load */
-  0,                           /* lookup_symbol */
-  monitor_create_inferior,
-  monitor_mourn_inferior,
-  0,                           /* can_run */
-  0,                           /* notice_signals */
-  process_stratum,
-  0,                           /* next */
-  1,
-  1,
-  1,
-  1,
-  1,                           /* all mem, mem, stack, regs, exec */
-  0,
-  0,                           /* Section pointers */
-  OPS_MAGIC,                   /* Always the last thing */
-};
-
-struct target_ops monitor_bug_ops = {
-  "bug",
-  "Motorola's BUG remote serial debug monitor",
-  "Use a remote computer running Motorola's BUG debug monitor.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya).",
-  bug_open,
-  monitor_close, 
-  0,
-  monitor_detach,
-  monitor_resume,
-  monitor_wait,
-  monitor_fetch_register,
-  monitor_store_register,
-  monitor_prepare_to_store,
-  monitor_xfer_inferior_memory,
-  monitor_files_info,
-  monitor_insert_breakpoint,
-  monitor_remove_breakpoint,   /* Breakpoints */
-  0,
-  0,
-  0,
-  0,
-  0,                           /* Terminal handling */
-  monitor_kill,
-  monitor_load,                        /* load */
-  0,                           /* lookup_symbol */
-  monitor_create_inferior,
-  monitor_mourn_inferior,
-  0,                           /* can_run */
-  0,                           /* notice_signals */
-  process_stratum,
-  0,                           /* next */
-  1,
-  1,
-  1,
-  1,
-  1,                           /* all mem, mem, stack, regs, exec */
-  0,
-  0,                           /* Section pointers */
-  OPS_MAGIC,                   /* Always the last thing */
-};
-
-struct target_ops mon68_ops = {
-  "mon68",
-  "Intermetric's MON68 remote serial debug monitor",
-  "Use a remote computer running the MON68 debug monitor.\n\
-Specify the serial device it is connected to (e.g. /dev/ttya).",
-  mon68_open,
-  monitor_close, 
-  0,
-  monitor_detach,
-  monitor_resume,
-  monitor_wait,
-  monitor_fetch_register,
-  monitor_store_register,
-  monitor_prepare_to_store,
-  monitor_xfer_inferior_memory,
-  monitor_files_info,
-  monitor_insert_breakpoint,
-  monitor_remove_breakpoint,   /* Breakpoints */
-  0,
-  0,
-  0,
-  0,
-  0,                           /* Terminal handling */
-  monitor_kill,
-  monitor_load,                        /* load */
-  0,                           /* lookup_symbol */
-  monitor_create_inferior,
-  monitor_mourn_inferior,
-  0,                           /* can_run */
-  0,                           /* notice_signals */
-  process_stratum,
-  0,                           /* next */
-  1,
-  1,
-  1,
-  1,
-  1,                           /* all mem, mem, stack, regs, exec */
-  0,
-  0,                           /* Section pointers */
-  OPS_MAGIC,                   /* Always the last thing */
-};
-
-void
-_initialize_remote_monitors ()
-{
-  add_show_from_set (
-                     add_set_cmd ("remotedebug", no_class, var_boolean,
-                                  (char *)&kiodebug,
-                                  "Set debugging of I/O to a serial based Monitor.\n\
-When enabled, debugging info is displayed.",
-                                  &setlist),
-                    &showlist);
-  add_show_from_set (
-                     add_set_cmd ("hash", no_class, var_boolean,
-                                  (char *)&hashmark,
-                                 "Set display of activity while downloading a file.\n\
-When enabled, a period \'.\' is displayed.",
-                                  &setlist),
-                    &showlist);
-
-  /* generic monitor command */
-  add_com ("monitor <command>", class_obscure, monitor_command,
-          "Send a command to the debug monitor."); 
-#if 0
-  add_com ("connect", class_obscure, connect_command,
-          "Connect the terminal directly up to a serial based command monitor.\n\
-Use <CR>~. or <CR>~^D to break out.");
-#endif
-
-  add_target (&rom68k_ops);
-/*  add_target (&mon68_ops); */
-  add_target (&monitor_bug_ops);
-}