* Makefile.in: Add mswin to SUBDIRS. Add rules for
authorStu Grossman <grossman@cygnus>
Thu, 5 Sep 1996 01:01:05 +0000 (01:01 +0000)
committerStu Grossman <grossman@cygnus>
Thu, 5 Sep 1996 01:01:05 +0000 (01:01 +0000)
mswin/libwingdb.a and remote-wiggler.o.
* breakpoint.c (breakpoint_here_p):  Clean up bp enabled test.
* (breakpoint_inserted_here_p):  New func, just like
breakpoint_here_p, except it's honest.  Honestly.
* breakpoint.h:  Proto for above.
start-sanitize-gdbtk
* configure configure.in:  Add host *windows* to list of hosts
that don't support GDBtk.
end-sanitize-gdbtk
* configure configure.in:  Add mswin to configdirs if host is
i[3456]86-*-windows.
* core-aout.c (fetch_core_registers register_addr) gdbcore.h:
Change all vars that can contain addresses to type CORE_ADDR.
* findvar.c (supply_register):  Allow val to be NULL.  This means
that regno is unsupported.
* (read_pc read_pc_pid write_pc write_pc_pid):  Make non-pid forms
just call pid forms with inferior_pid so that there's only once
place to hack PC's and such.
* infrun.c (proceed):  Don't skip breakpoints if user changed PC.
* remote-wiggler.c:  New file.  Support for BDM interface from
Macraigor Systems.
* serial.c:  Enhance serial logging capability.  Add hex and octal
output modes (set remotelogbase {hex|octal|ascii}.  Also log
breaks, timeouts, errors, and eofs.
* serial.h:  Redefine SERIAL_SEND_BREAK to go through a wrapper
function so that we can log breaks.  Don't export serial_logfile
or serial_logfp.
* top.c (execute_command):  Don't test for serial_logfp here.
Just call serial_log_comand, and let serial.c sort it out.
* valops.c (value_of_variable):  Don't attempt to establish frames
for static and global variables.  This makes things work a bit
better if the stack or frame pointer is trashed.
* config/m68k/monitor.mt (TDEPFILES):  Add remote-wiggler.o.
* config/m68k/tm-m68k.h:  Define STACK_ALIGN.  CPU32 can't hack
misaligned stacks during function calls.

gdb/Makefile.in
gdb/config/m68k/tm-m68k.h
gdb/configure
gdb/configure.in
gdb/core-aout.c
gdb/remote-wiggler.c [new file with mode: 0644]
gdb/serial.c
gdb/serial.h
gdb/top.c

index a8d21017e6fa2c62c9f16a94824e303e635af441..344558c380246b9c87f6c061a22f3c446eb07988 100644 (file)
@@ -487,7 +487,7 @@ NTSOBS = standalone.o
 
 NTSSTART = kdb-start.o
 
-SUBDIRS = doc testsuite nlm
+SUBDIRS = doc testsuite nlm mswin
 
 # For now, shortcut the "configure GDB for fewer languages" stuff.
 YYFILES = c-exp.tab.c f-exp.tab.c m2-exp.tab.c
@@ -582,7 +582,9 @@ init.c: $(OBS) $(TSOBS)
        @rm -f init.c-tmp
        @echo '/* Do not modify this file.  */' >init.c-tmp
        @echo '/* It is created automatically by the Makefile.  */'>>init.c-tmp
-       @echo 'void initialize_all_files () {' >>init.c-tmp
+       @echo '#include "ansidecl.h"' >>init.c-tmp
+       @echo 'extern void initialize_all_files PARAMS ((void));' >>init.c-tmp
+       @echo 'void initialize_all_files PARAMS ((void)) {' >>init.c-tmp
        @for i in $(OBS) $(TSOBS); do \
          filename=`echo $$i | sed \
            -e '/^Onindy.o/d' \
@@ -601,7 +603,7 @@ init.c: $(OBS) $(TSOBS)
          case $$filename in \
            "") ;; \
            *) sed <$(srcdir)/$$filename >>init.c-tmp -n \
-           -e '/^_initialize_[a-z_0-9A-Z]* *(/s/^\([a-z_0-9A-Z]*\).*/  {extern void \1 (); \1 ();}/p' ; ;; \
+           -e '/^_initialize_[a-z_0-9A-Z]* *(/s/^\([a-z_0-9A-Z]*\).*/  {extern void \1 PARAMS ((void)); \1 ();}/p' ; ;; \
          esac ; \
        done
        @echo '}' >>init.c-tmp
@@ -620,6 +622,9 @@ nlm:        force
 
 libgdb:        libgdb-files $(LIBGDB_OBS)
 
+mswin/libwingdb.a: force
+       rootme=`pwd`; export rootme; $(MAKE) $(FLAGS_TO_PASS) DO=all DODIRS=mswin subdir_do
+
 # libproc is not listed here because all-libproc is a dependency of all-gui,
 # not all-gdb, and thus might be built after us.
 LIBGDBDEPS=$(COMMON_OBS) $(LIBGDB_OBS) $(TSOBS) $(ADD_DEPS) $(CDEPS) init.o
@@ -1406,6 +1411,9 @@ remote-vx29k.o: remote-vx29k.c $(wait_h) complaints.h $(defs_h) $(gdbcmd_h) \
         vx-share/ptrace.h vx-share/xdr_ld.h vx-share/xdr_ptrace.h \
         vx-share/xdr_rdb.h gdb_string.h
 
+remote-wiggler.o: remote-wiggler.c $(wait_h) complaints.h $(defs_h) \
+       $(gdbcmd_h) $(gdbcore_h) $(inferior_h) target.h
+
 remote-utils.o: remote-utils.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) \
        $(inferior_h) $(remote_utils_h) gdb_string.h
 
index 0c98e1db17329ec7c3c463c035b5a963c338a772..6305f592b37596013a58ea8f66f4d85ea4815224 100644 (file)
@@ -57,6 +57,10 @@ extern void m68k_find_saved_regs PARAMS ((struct frame_info *, struct frame_save
 
 #define INNER_THAN <
 
+/* Stack must be kept short aligned when doing function calls.  */
+
+#define STACK_ALIGN(ADDR) (((ADDR) + 1) & ~1)
+
 /* Sequence of bytes for breakpoint instruction.
    This is a TRAP instruction.  The last 4 bits (0xf below) is the
    vector.  Systems which don't use 0xf should define BPT_VECTOR
index 70ec00d2b07d91aa3e8b05e1e67688bc9d1b104b..8bcdc99091df07ff6a7b83aa77f034dacf4edca1 100755 (executable)
@@ -1869,147 +1869,9 @@ EOF
 fi
 
 
-echo $ac_n "checking whether malloc must be declared""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'bfd_cv_decl_needed_malloc'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1878 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-int main() { return 0; }
-int t() {
-char *(*pfn) = (char *(*)) malloc
-; return 0; }
-EOF
-if { (eval echo configure:1900: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
-  rm -rf conftest*
-  bfd_cv_decl_needed_malloc=no
-else
-  rm -rf conftest*
-  bfd_cv_decl_needed_malloc=yes
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$bfd_cv_decl_needed_malloc" 1>&6
-if test $bfd_cv_decl_needed_malloc = yes; then
-  bfd_tr_decl=NEED_DECLARATION_`echo malloc | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-  cat >> confdefs.h <<EOF
-#define $bfd_tr_decl 1
-EOF
-
-fi
-
-echo $ac_n "checking whether realloc must be declared""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'bfd_cv_decl_needed_realloc'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1925 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-int main() { return 0; }
-int t() {
-char *(*pfn) = (char *(*)) realloc
-; return 0; }
-EOF
-if { (eval echo configure:1947: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
-  rm -rf conftest*
-  bfd_cv_decl_needed_realloc=no
-else
-  rm -rf conftest*
-  bfd_cv_decl_needed_realloc=yes
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$bfd_cv_decl_needed_realloc" 1>&6
-if test $bfd_cv_decl_needed_realloc = yes; then
-  bfd_tr_decl=NEED_DECLARATION_`echo realloc | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-  cat >> confdefs.h <<EOF
-#define $bfd_tr_decl 1
-EOF
-
-fi
-
-echo $ac_n "checking whether free must be declared""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'bfd_cv_decl_needed_free'+set}'`\" = set"; then
-  echo $ac_n "(cached) $ac_c" 1>&6
-else
-  cat > conftest.$ac_ext <<EOF
-#line 1972 "configure"
-#include "confdefs.h"
-
-#include <stdio.h>
-#ifdef HAVE_STRING_H
-#include <string.h>
-#else
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-int main() { return 0; }
-int t() {
-char *(*pfn) = (char *(*)) free
-; return 0; }
-EOF
-if { (eval echo configure:1994: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
-  rm -rf conftest*
-  bfd_cv_decl_needed_free=no
-else
-  rm -rf conftest*
-  bfd_cv_decl_needed_free=yes
-fi
-rm -f conftest*
-
-fi
-
-echo "$ac_t""$bfd_cv_decl_needed_free" 1>&6
-if test $bfd_cv_decl_needed_free = yes; then
-  bfd_tr_decl=NEED_DECLARATION_`echo free | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
-  cat >> confdefs.h <<EOF
-#define $bfd_tr_decl 1
-EOF
-
-fi
-
+BFD_NEED_DECLARATION(malloc)
+BFD_NEED_DECLARATION(realloc)
+BFD_NEED_DECLARATION(free)
 
 
 
@@ -2092,7 +1954,7 @@ if test "${enable_gdbtk+set}" = set; then
        *go32*)
            echo "configure: warning: GDB does not support GDBtk on host ${host}.  GDBtk will be disabled." 1>&2
            enable_gdbtk=no ;;
-       *cygwin32*)
+       *cygwin32* | *windows*)
            echo "configure: warning: GDB does not support GDBtk on host ${host}.  GDBtk will be disabled." 1>&2
            enable_gdbtk=no ;;
        *)
@@ -2107,9 +1969,7 @@ else
   
 # Default is on for everything but go32 and cygwin32
 case "$host" in
-    *go32*)
-       ;;
-    *cygwin32*)
+    *go32* | *cygwin32* | *windows*)
        ;;
     *)
        enable_gdbtk=yes ;;
@@ -2406,12 +2266,12 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2410 "configure"
+#line 2270 "configure"
 #include "confdefs.h"
 #include <tclInt.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2415: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2275: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2538,12 +2398,12 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2542 "configure"
+#line 2402 "configure"
 #include "confdefs.h"
 #include <tk.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2547: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2407: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2685,6 +2545,8 @@ i[3456]86-*-sysv*)        gdb_host=i386v ;;
 i[3456]86-*-isc*)      gdb_host=i386v32 ;;
 i[3456]86-*-os9k)      gdb_host=i386os9k ;;
 i[3456]86-*-cygwin32)  gdb_host=cygwin32 ;;
+i[3456]86-*-windows)   gdb_host=windows
+                       configdirs="${configdirs} mswin" ;;
 m680[01]0-sun-sunos3*) gdb_host=sun2os3 ;;
 m680[01]0-sun-sunos4*) gdb_host=sun2os4 ;;
 m68030-sony-*)         gdb_host=news1000 ;;
index 7c241a12b756b7e226d7892dfdd064d12942dfa2..df786c2757048675bb716a1ddc0eaf577bb1ee52 100644 (file)
@@ -208,7 +208,7 @@ AC_ARG_ENABLE(gdbtk,
        *go32*)
            AC_MSG_WARN([GDB does not support GDBtk on host ${host}.  GDBtk will be disabled.])
            enable_gdbtk=no ;;
-       *cygwin32*)
+       *cygwin32* | *windows*)
            AC_MSG_WARN([GDB does not support GDBtk on host ${host}.  GDBtk will be disabled.])
            enable_gdbtk=no ;;
        *)
@@ -222,9 +222,7 @@ esac],
 [
 # Default is on for everything but go32 and cygwin32
 case "$host" in
-    *go32*)
-       ;;
-    *cygwin32*)
+    *go32* | *cygwin32* | *windows*)
        ;;
     *)
        enable_gdbtk=yes ;;
@@ -346,6 +344,8 @@ i[3456]86-*-sysv*)  gdb_host=i386v ;;
 i[3456]86-*-isc*)      gdb_host=i386v32 ;;
 i[3456]86-*-os9k)      gdb_host=i386os9k ;;
 i[3456]86-*-cygwin32)  gdb_host=cygwin32 ;;
+i[3456]86-*-windows)   gdb_host=windows
+                       configdirs="${configdirs} mswin" ;;
 m680[01]0-sun-sunos3*) gdb_host=sun2os3 ;;
 m680[01]0-sun-sunos4*) gdb_host=sun2os4 ;;
 m68030-sony-*)         gdb_host=news1000 ;;
index ec755c558f1108ecb0408e32ae020145dab10847..a529cf9fb4793f26c26670d9b12fe4c69c9856f2 100644 (file)
@@ -52,8 +52,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include <sys/core.h>
 #endif
 
-static void
-fetch_core_registers PARAMS ((char *, unsigned, int, unsigned));
+static void fetch_core_registers PARAMS ((char *core_reg_sect,
+                                         unsigned core_reg_size, int which,
+                                         CORE_ADDR reg_addr));
 
 /* Extract the register values out of the core file and store
    them where `read_register' will find them.
@@ -73,12 +74,12 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
      char *core_reg_sect;
      unsigned core_reg_size;
      int which;
-     unsigned reg_addr;
+     CORE_ADDR reg_addr;
 {
-  register int regno;
-  register unsigned int addr;
+  int regno;
+  CORE_ADDR addr;
   int bad_reg = -1;
-  register reg_ptr = -reg_addr;                /* Original u.u_ar0 is -reg_addr. */
+  CORE_ADDR reg_ptr = -reg_addr; /* Original u.u_ar0 is -reg_addr. */
   int numregs = ARCH_NUM_REGS;
 
   /* If u.u_ar0 was an absolute address in the core file, relativize it now,
@@ -87,23 +88,21 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
      CORE_REGISTER_ADDR to offset to the other registers.  If this is a modern
      core file without a upage, reg_ptr will be zero and this is all a big
      NOP.  */
-  if (reg_ptr > (int) core_reg_size)
+  if (reg_ptr > core_reg_size)
     reg_ptr -= KERNEL_U_ADDR;
 
   for (regno = 0; regno < numregs; regno++)
     {
       addr = CORE_REGISTER_ADDR (regno, reg_ptr);
-      if (addr >= core_reg_size) {
-       if (bad_reg < 0)
-         bad_reg = regno;
-      } else {
-       supply_register (regno, core_reg_sect + addr);
-      }
+      if (addr >= core_reg_size
+         && bad_reg < 0)
+       bad_reg = regno;
+    else
+      supply_register (regno, core_reg_sect + addr);
     }
+
   if (bad_reg >= 0)
-    {
-      error ("Register %s not found in core file.", reg_names[bad_reg]);
-    }
+    error ("Register %s not found in core file.", reg_names[bad_reg]);
 }
 
 
@@ -112,12 +111,12 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
 /* Return the address in the core dump or inferior of register REGNO.
    BLOCKEND is the address of the end of the user structure.  */
 
-unsigned int
+CORE_ADDR
 register_addr (regno, blockend)
      int regno;
-     int blockend;
+     CORE_ADDR blockend;
 {
-  int addr;
+  CORE_ADDR addr;
 
   if (regno < 0 || regno >= ARCH_NUM_REGS)
     error ("Invalid register number %d.", regno);
diff --git a/gdb/remote-wiggler.c b/gdb/remote-wiggler.c
new file mode 100644 (file)
index 0000000..f70ca70
--- /dev/null
@@ -0,0 +1,1570 @@
+/* Remote target communications for the Macraigor Systems BDM Wiggler
+   Copyright 1996 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "gdb_string.h"
+#include <fcntl.h>
+#include "frame.h"
+#include "inferior.h"
+#include "bfd.h"
+#include "symfile.h"
+#include "target.h"
+#include "wait.h"
+#include "gdbcmd.h"
+#include "objfiles.h"
+#include "gdb-stabs.h"
+
+#include "dcache.h"
+
+#ifdef USG
+#include <sys/types.h>
+#endif
+
+#include <signal.h>
+#include "serial.h"
+
+/* Wiggler serial protocol definitions */
+
+#define DLE 020                        /* Quote char */
+#define SYN 026                        /* Start of packet */
+#define RAW_SYN ((026 << 8) | 026) /* get_quoted_char found a naked SYN */
+
+/* Status flags */
+
+#define WIGGLER_FLAG_RESET 0x01 /* Target is being reset */
+#define WIGGLER_FLAG_STOPPED 0x02 /* Target is halted */
+#define WIGGLER_FLAG_BDM 0x04  /* Target is in BDM */
+#define WIGGLER_FLAG_PWF 0x08  /* Power failed */
+#define WIGGLER_FLAG_CABLE_DISC 0x10 /* BDM cable disconnected */
+
+#define WIGGLER_AYT 0x0                /* Are you there? */
+#define WIGGLER_GET_VERSION 0x1        /* Get Version */
+#define WIGGLER_SET_BAUD_RATE 0x2 /* Set Baud Rate */
+#define WIGGLER_INIT 0x10      /* Initialize Wiggler */
+#define WIGGLER_SET_SPEED 0x11 /* Set Speed */
+#define WIGGLER_GET_STATUS_MASK 0x12 /* Get Status Mask */
+#define WIGGLER_GET_CTRS 0x13  /* Get Error Counters */
+#define WIGGLER_SET_FUNC_CODE 0x14 /* Set Function Code */
+#define WIGGLER_SET_CTL_FLAGS 0x15 /* Set Control Flags */
+#define WIGGLER_SET_BUF_ADDR 0x16 /* Set Register Buffer Address */
+#define WIGGLER_RUN 0x20       /* Run Target from PC */
+#define WIGGLER_RUN_ADDR 0x21  /* Run Target from Specified Address */
+#define WIGGLER_STOP 0x22      /* Stop Target */
+#define WIGGLER_RESET_RUN 0x23 /* Reset Target and Run */
+#define WIGGLER_RESET 0x24     /* Reset Target and Halt */
+#define WIGGLER_STEP 0x25      /* Single step */
+#define WIGGLER_READ_REGS 0x30 /* Read Registers */
+#define WIGGLER_WRITE_REGS 0x31        /* Write Registers */
+#define WIGGLER_READ_MEM 0x32  /* Read Memory */
+#define WIGGLER_WRITE_MEM 0x33 /* Write Memory */
+#define WIGGLER_FILL_MEM 0x34  /* Fill Memory */
+#define WIGGLER_MOVE_MEM 0x35  /* Move Memory */
+
+#define WIGGLER_READ_INT_MEM 0x80 /* Read Internal Memory */
+#define WIGGLER_WRITE_INT_MEM 0x81 /* Write Internal Memory */
+#define WIGGLER_JUMP 0x82      /* Jump to Subroutine */
+
+#define WIGGLER_SET_STATUS 0x0a        /* Set status */
+#define   WIGGLER_FLAG_STOP 0x0 /* Stop the target, enter BDM */
+#define   WIGGLER_FLAG_START 0x01 /* Start the target at PC */
+#define   WIGGLER_FLAG_RETURN_STATUS 0x04 /* Return async status */
+
+/* Stuff that should be in tm-xxx files. */
+#if 1
+#define BDM_NUM_REGS 24
+#define BDM_REGMAP   0,  1,  2,  3,  4,  5,  6,  7, /* d0 -> d7 */ \
+                    8,  9, 10, 11, 12, 13, 14, 15, /* a0 -> a7 */ \
+                   18, 16,                         /* ps, pc */ \
+                   -1, -1, -1, -1, -1, -1, -1, -1, /* fp0 -> fp7 */ \
+                   -1, -1, -1, -1, -1 /* fpcontrol, fpstatus, fpiaddr, fpcode, fpflags */
+#define BDM_BREAKPOINT 0x4a, 0xfa /* BGND insn */
+#else
+#define BDM_NUM_REGS 24
+#define BDM_REGMAP   8,  9, 10, 11, 12, 13, 14, 15, /* d0 -> d7 */ \
+                   16, 17, 18, 19, 20, 21, 22, 23, /* a0 -> a7 */ \
+                    4,  0,                         /* ps, pc */ \
+                   -1, -1, -1, -1, -1, -1, -1, -1, /* fp0 -> fp7 */ \
+                   -1, -1, -1, -1, -1 /* fpcontrol, fpstatus, fpiaddr, fpcode, fpflags */
+#define WIGGLER_POLL
+#endif
+
+/* Prototypes for local functions */
+
+static void wiggler_stop PARAMS ((void));
+
+static void put_packet PARAMS ((unsigned char *packet, int pktlen));
+static unsigned char * get_packet PARAMS ((int cmd, int *pktlen, int timeout));
+
+static int wiggler_write_bytes PARAMS ((CORE_ADDR memaddr,
+                                      char *myaddr, int len));
+
+static int wiggler_read_bytes PARAMS ((CORE_ADDR memaddr,
+                                     char *myaddr, int len));
+
+static void wiggler_files_info PARAMS ((struct target_ops *ignore));
+
+static int wiggler_xfer_memory PARAMS ((CORE_ADDR memaddr, char *myaddr,
+                                      int len, int should_write,
+                                      struct target_ops *target));
+
+static void wiggler_prepare_to_store PARAMS ((void));
+
+static void wiggler_fetch_registers PARAMS ((int regno));
+
+static void wiggler_resume PARAMS ((int pid, int step,
+                                  enum target_signal siggnal));
+
+static int wiggler_start_remote PARAMS ((char *dummy));
+
+static void wiggler_open PARAMS ((char *name, int from_tty));
+
+static void wiggler_close PARAMS ((int quitting));
+
+static void wiggler_store_registers PARAMS ((int regno));
+
+static void wiggler_mourn PARAMS ((void));
+
+static int readchar PARAMS ((int timeout));
+
+static void reset_packet PARAMS ((void));
+
+static void output_packet PARAMS ((void));
+
+static int get_quoted_char PARAMS ((int timeout));
+
+static void put_quoted_char PARAMS ((int c));
+
+static int wiggler_wait PARAMS ((int pid, struct target_waitstatus *status));
+
+static void wiggler_kill PARAMS ((void));
+
+static void wiggler_detach PARAMS ((char *args, int from_tty));
+
+static void wiggler_interrupt PARAMS ((int signo));
+
+static void wiggler_interrupt_twice PARAMS ((int signo));
+
+static void interrupt_query PARAMS ((void));
+
+static unsigned char * do_command PARAMS ((int cmd, int *statusp, int *lenp));
+
+static unsigned char * read_bdm_registers PARAMS ((int first_bdm_regno,
+                                                  int last_bdm_regno,
+                                                  int *numregs));
+
+extern struct target_ops wiggler_ops;  /* Forward decl */
+
+static int last_run_status;
+
+/* This was 5 seconds, which is a long time to sit and wait.
+   Unless this is going though some terminal server or multiplexer or
+   other form of hairy serial connection, I would think 2 seconds would
+   be plenty.  */
+
+/* Changed to allow option to set timeout value.
+   was static int remote_timeout = 2; */
+extern int remote_timeout;
+
+/* Descriptor for I/O to remote machine.  Initialize it to NULL so that
+   wiggler_open knows that we don't have a file open when the program
+   starts.  */
+serial_t wiggler_desc = NULL;
+\f
+static void
+wiggler_error (s, error_code)
+     char *s;
+     int error_code;
+{
+  char buf[100];
+
+  fputs_filtered (s, gdb_stderr);
+
+  switch (error_code)
+    {
+    case 1: s = "Unknown fault"; break;
+    case 2: s = "Power failed"; break;
+    case 3: s = "Cable disconnected"; break;
+    case 4: s = "Couldn't enter BDM"; break;
+    case 5: s = "Target stuck in reset"; break;
+    case 6: s = "Port not configured"; break;
+    case 7: s = "Write verify failed"; break;
+    case 11: s = "Bus error"; break;
+    case 12: s = "Checksum error"; break;
+    case 13: s = "Illegal command"; break;
+    case 14: s = "Parameter error"; break;
+    default:
+      sprintf (buf, "Unknown error code %d", error_code);
+    }
+
+  error (s);
+}
+
+/*  Return nonzero if the thread TH is still alive on the remote system.  */
+
+static int
+wiggler_thread_alive (th)
+     int th;
+{
+  return 1;
+}
+\f
+/* Clean up connection to a remote debugger.  */
+
+/* ARGSUSED */
+static void
+wiggler_close (quitting)
+     int quitting;
+{
+  if (wiggler_desc)
+    SERIAL_CLOSE (wiggler_desc);
+  wiggler_desc = NULL;
+}
+
+/* Stub for catch_errors.  */
+
+static int
+wiggler_start_remote (dummy)
+     char *dummy;
+{
+  unsigned char buf[10], *p;
+  int pktlen;
+  int status;
+  int error_code;
+  int speed;
+
+  immediate_quit = 1;          /* Allow user to interrupt it */
+
+  SERIAL_SEND_BREAK (wiggler_desc); /* Wake up the wiggler */
+
+  do_command (WIGGLER_AYT, &status, &pktlen);
+
+  p = do_command (WIGGLER_GET_VERSION, &status, &pktlen);
+
+  printf_unfiltered ("[Wiggler version %x.%x, capability 0x%x]\n",
+                    p[0], p[1], (p[2] << 16) | p[3]);
+
+#if 1
+  speed = 80;                  /* Divide clock by 4000 */
+
+  buf[0] = WIGGLER_INIT;
+  buf[1] = speed >> 8;
+  buf[2] = speed & 0xff;
+  buf[3] = 0;                  /* CPU32 for now */
+  put_packet (buf, 4);         /* Init Wiggler params */
+  p = get_packet (buf[0], &pktlen, remote_timeout);
+
+  if (pktlen < 2)
+    error ("Truncated response packet from Wiggler");
+
+  status = p[1];
+  error_code = p[2];
+
+  if (error_code != 0)
+    wiggler_error ("WIGGLER_INIT:", error_code);
+#endif
+
+#if 0
+  /* Reset the target */
+
+  do_command (WIGGLER_RESET_RUN, &status, &pktlen);
+/*  do_command (WIGGLER_RESET, &status, &pktlen);*/
+#endif
+
+  /* If processor is still running, stop it.  */
+
+  if (!(status & WIGGLER_FLAG_BDM))
+    wiggler_stop ();
+
+#if 1
+  buf[0] = WIGGLER_SET_CTL_FLAGS;
+  buf[1] = 0;
+  buf[2] = 1;          /* Asynchronously return status when target stops */
+  put_packet (buf, 3);
+
+  p = get_packet (buf[0], &pktlen, remote_timeout);
+
+  if (pktlen < 2)
+    error ("Truncated response packet from Wiggler");
+
+  status = p[1];
+  error_code = p[2];
+
+  if (error_code != 0)
+    wiggler_error ("WIGGLER_SET_CTL_FLAGS:", error_code);
+#endif
+
+  immediate_quit = 0;
+
+/* This is really the job of start_remote however, that makes an assumption
+   that the target is about to print out a status message of some sort.  That
+   doesn't happen here (in fact, it may not be possible to get the monitor to
+   send the appropriate packet).  */
+
+  flush_cached_frames ();
+  registers_changed ();
+  stop_pc = read_pc ();
+  set_current_frame (create_new_frame (read_fp (), stop_pc));
+  select_frame (get_current_frame (), 0);
+  print_stack_frame (selected_frame, -1, 1);
+
+  return 1;
+}
+
+/* Open a connection to a remote debugger.
+   NAME is the filename used for communication.  */
+
+static DCACHE *wiggler_dcache;
+
+static void
+wiggler_open (name, from_tty)
+     char *name;
+     int from_tty;
+{
+  if (name == 0)
+    error ("To open a Wiggler connection, you need to specify what serial\n\
+device the Wiggler is attached to (e.g. /dev/ttya).");
+
+  target_preopen (from_tty);
+
+  unpush_target (&wiggler_ops);
+
+  wiggler_dcache = dcache_init (wiggler_read_bytes, wiggler_write_bytes);
+
+  wiggler_desc = SERIAL_OPEN (name);
+  if (!wiggler_desc)
+    perror_with_name (name);
+
+  if (baud_rate != -1)
+    {
+      if (SERIAL_SETBAUDRATE (wiggler_desc, baud_rate))
+       {
+         SERIAL_CLOSE (wiggler_desc);
+         perror_with_name (name);
+       }
+    }
+
+  SERIAL_RAW (wiggler_desc);
+
+  /* If there is something sitting in the buffer we might take it as a
+     response to a command, which would be bad.  */
+  SERIAL_FLUSH_INPUT (wiggler_desc);
+
+  if (from_tty)
+    {
+      puts_filtered ("Remote target wiggler connected to ");
+      puts_filtered (name);
+      puts_filtered ("\n");
+    }
+  push_target (&wiggler_ops);  /* Switch to using remote target now */
+
+  /* Without this, some commands which require an active target (such as kill)
+     won't work.  This variable serves (at least) double duty as both the pid
+     of the target process (if it has such), and as a flag indicating that a
+     target is active.  These functions should be split out into seperate
+     variables, especially since GDB will someday have a notion of debugging
+     several processes.  */
+
+  inferior_pid = 42000;
+  /* Start the remote connection; if error (0), discard this target.
+     In particular, if the user quits, be sure to discard it
+     (we'd be in an inconsistent state otherwise).  */
+  if (!catch_errors (wiggler_start_remote, (char *)0, 
+                    "Couldn't establish connection to remote target\n", RETURN_MASK_ALL))
+    pop_target();
+}
+
+/* This takes a program previously attached to and detaches it.  After
+   this is done, GDB can be used to debug some other program.  We
+   better not have left any breakpoints in the target program or it'll
+   die when it hits one.  */
+
+static void
+wiggler_detach (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  if (args)
+    error ("Argument given to \"detach\" when remotely debugging.");
+
+  pop_target ();
+  if (from_tty)
+    puts_filtered ("Ending remote debugging.\n");
+}
+\f
+/* Tell the remote machine to resume.  */
+
+static void
+wiggler_resume (pid, step, siggnal)
+     int pid, step;
+     enum target_signal siggnal;
+{
+  int pktlen;
+
+  dcache_flush (wiggler_dcache);
+
+  if (step)
+    do_command (WIGGLER_STEP, &last_run_status, &pktlen);
+  else
+    do_command (WIGGLER_RUN, &last_run_status, &pktlen);
+}
+\f
+static void
+wiggler_stop ()
+{
+  int status;
+  int pktlen;
+
+  do_command (WIGGLER_STOP, &status, &pktlen);
+
+  if (!(status & WIGGLER_FLAG_BDM))
+    error ("Can't stop target via BDM");
+}
+
+static volatile int wiggler_interrupt_flag;
+
+/* Send ^C to target to halt it.  Target will respond, and send us a
+   packet.  */
+
+static void
+wiggler_interrupt (signo)
+     int signo;
+{
+  /* If this doesn't work, try more severe steps.  */
+  signal (signo, wiggler_interrupt_twice);
+  
+  if (remote_debug)
+    printf_unfiltered ("wiggler_interrupt called\n");
+
+  {
+    char buf[1];
+
+    wiggler_stop ();
+    buf[0] = WIGGLER_AYT;
+    put_packet (buf, 1);
+    wiggler_interrupt_flag = 1;
+  }
+}
+
+static void (*ofunc)();
+
+/* The user typed ^C twice.  */
+static void
+wiggler_interrupt_twice (signo)
+     int signo;
+{
+  signal (signo, ofunc);
+  
+  interrupt_query ();
+
+  signal (signo, wiggler_interrupt);
+}
+
+/* Ask the user what to do when an interrupt is received.  */
+
+static void
+interrupt_query ()
+{
+  target_terminal_ours ();
+
+  if (query ("Interrupted while waiting for the program.\n\
+Give up (and stop debugging it)? "))
+    {
+      target_mourn_inferior ();
+      return_to_top_level (RETURN_QUIT);
+    }
+
+  target_terminal_inferior ();
+}
+
+/* If nonzero, ignore the next kill.  */
+static int kill_kludge;
+
+/* Wait until the remote machine stops, then return,
+   storing status in STATUS just as `wait' would.
+   Returns "pid" (though it's not clear what, if anything, that
+   means in the case of this target).  */
+
+static int
+wiggler_wait (pid, target_status)
+     int pid;
+     struct target_waitstatus *target_status;
+{
+  unsigned char *p;
+  int error_code, status;
+  int pktlen;
+
+  wiggler_interrupt_flag = 0;
+
+  target_status->kind = TARGET_WAITKIND_STOPPED;
+  target_status->value.sig = TARGET_SIGNAL_TRAP;
+
+  /* Target may already be stopped by the time we get here. */
+
+  if (!(last_run_status & WIGGLER_FLAG_BDM))
+    {
+      ofunc = (void (*)()) signal (SIGINT, wiggler_interrupt);
+
+      p = get_packet (WIGGLER_AYT, &pktlen, -1);
+
+      signal (SIGINT, ofunc);
+
+      if (pktlen < 2)
+       error ("Truncated response packet from Wiggler");
+
+      status = p[1];
+      error_code = p[2];
+
+      if (error_code != 0)
+       wiggler_error ("target_wait:", error_code);
+
+      if (status & WIGGLER_FLAG_PWF)
+       error ("Wiggler lost VCC at BDM interface.");
+      else if (status & WIGGLER_FLAG_CABLE_DISC)
+       error ("BDM cable appears to have been disconnected.");
+
+      if (!(status & WIGGLER_FLAG_BDM))
+       error ("Wiggler woke up, but wasn't stopped: 0x%x", status);
+
+      if (wiggler_interrupt_flag)
+       target_status->value.sig = TARGET_SIGNAL_INT;
+    }
+
+  /* This test figures out if we just executed a BGND insn, and if it's one of
+     our breakpoints.  If so, then we back up PC.  N.B. When a BGND insn is
+     executed, the PC points at the loc just after the insn (ie: it's always
+     two bytes *after* the BGND).  So, it's not sufficient to just see if PC-2
+     is a BGND insn because we could have gotten there via a jump.  We dis-
+     ambiguate this case by examining the ATEMP register (which is only
+     accessible from BDM).  This will tell us if we entered BDM because we
+     executed a BGND insn.  */
+
+  if (breakpoint_inserted_here_p (read_pc () - 2)) /* One of our breakpoints? */
+    {                          /* Yes, see if we actually executed it */
+#if 0  /* Temporarily disabled until atemp reading is fixed. */
+      int atemp;
+      int numregs;
+
+      p = read_bdm_registers (23, 23, &numregs);
+      atemp = extract_unsigned_integer (p, 4);
+
+      if (atemp == 1)          /* And, did we hit a breakpoint insn? */
+#endif
+       write_pc (read_pc () - 2); /* Yes, then back up PC */
+    }
+
+  return inferior_pid;
+}
+
+/* Read the remote registers into the block REGS.  */
+/* Currently we just read all the registers, so we don't use regno.  */
+/* ARGSUSED */
+
+static unsigned char *
+read_bdm_registers (first_bdm_regno, last_bdm_regno, numregs)
+     int first_bdm_regno;
+     int last_bdm_regno;
+     int *numregs;
+{
+  unsigned char buf[10];
+  int i;
+  unsigned char *p;
+  unsigned char *regs;
+  int error_code, status;
+  int pktlen;
+
+  buf[0] = WIGGLER_READ_REGS;
+  buf[1] = first_bdm_regno >> 8;
+  buf[2] = first_bdm_regno & 0xff;
+  buf[3] = last_bdm_regno >> 8;
+  buf[4] = last_bdm_regno & 0xff;
+
+  put_packet (buf, 5);
+  p = get_packet (WIGGLER_READ_REGS, &pktlen, remote_timeout);
+
+  if (pktlen < 5)
+    error ("Truncated response packet from Wiggler");
+
+  status = p[1];
+  error_code = p[2];
+
+  if (error_code != 0)
+    wiggler_error ("read_bdm_registers:", error_code);
+
+  i = p[3];
+  if (i == 0)
+    i = 256;
+
+  if (i > pktlen - 4
+      || ((i & 3) != 0))
+    error ("Register block size bad:  %d", i);
+
+  *numregs = i / 4;
+
+  regs = p + 4;
+
+  return regs;
+}
+
+static void
+dump_all_bdm_regs ()
+{
+  unsigned char *regs;
+  int numregs;
+  int i;
+
+  regs = read_bdm_registers (0, BDM_NUM_REGS - 1, &numregs);
+
+  printf_unfiltered ("rpc = 0x%x ",
+                    (int)extract_unsigned_integer (regs, 4));
+  regs += 4;
+  printf_unfiltered ("usp = 0x%x ",
+                    (int)extract_unsigned_integer (regs, 4));
+  regs += 4;
+  printf_unfiltered ("ssp = 0x%x ",
+                    (int)extract_unsigned_integer (regs, 4));
+  regs += 4;
+  printf_unfiltered ("vbr = 0x%x ",
+                    (int)extract_unsigned_integer (regs, 4));
+  regs += 4;
+  printf_unfiltered ("sr = 0x%x ",
+                    (int)extract_unsigned_integer (regs, 4));
+  regs += 4;
+  printf_unfiltered ("sfc = 0x%x ",
+                    (int)extract_unsigned_integer (regs, 4));
+  regs += 4;
+  printf_unfiltered ("dfc = 0x%x ",
+                    (int)extract_unsigned_integer (regs, 4));
+  regs += 4;
+  printf_unfiltered ("atemp = 0x%x ",
+                    (int)extract_unsigned_integer (regs, 4));
+  regs += 4;
+  printf_unfiltered ("\n");
+
+  for (i = 0; i <= 7; i++)
+    printf_unfiltered ("d%i = 0x%x ", i,
+                      (int)extract_unsigned_integer (regs + i * 4, 4));
+  regs += 8 * 4;
+  printf_unfiltered ("\n");
+
+  for (i = 0; i <= 7; i++)
+    printf_unfiltered ("a%i = 0x%x ", i,
+                      (int)extract_unsigned_integer (regs + i * 4, 4));
+  printf_unfiltered ("\n");
+}
+
+static int bdm_regmap[] = {BDM_REGMAP};
+
+/* Read the remote registers into the block REGS.  */
+/* Currently we just read all the registers, so we don't use regno.  */
+/* ARGSUSED */
+static void
+wiggler_fetch_registers (regno)
+     int regno;
+{
+  int i;
+  unsigned char *regs;
+  int first_regno, last_regno;
+  int first_bdm_regno, last_bdm_regno;
+  int numregs;
+
+  if (regno == -1)
+    {
+      first_regno = 0;
+      last_regno = NUM_REGS - 1;
+
+      first_bdm_regno = 0;
+      last_bdm_regno = BDM_NUM_REGS - 1;
+    }
+  else
+    {
+      first_regno = regno;
+      last_regno = regno;
+
+      first_bdm_regno = bdm_regmap [regno];
+      last_bdm_regno = bdm_regmap [regno];
+    }
+
+  if (first_bdm_regno == -1)
+    {
+      supply_register (first_regno, NULL);
+      return;                  /* Unsupported register */
+    }
+
+  regs = read_bdm_registers (first_bdm_regno, last_bdm_regno, &numregs);
+
+  for (i = first_regno; i <= last_regno; i++)
+    {
+      int bdm_regno, regoffset;
+
+      bdm_regno = bdm_regmap [i];
+      if (bdm_regno != -1)
+       {
+         regoffset = bdm_regno - first_bdm_regno;
+
+         if (regoffset >= numregs)
+           continue;
+
+         supply_register (i, regs + 4 * regoffset);
+       }
+      else
+       supply_register (i, NULL); /* Unsupported register */
+    }
+}
+
+static void 
+wiggler_prepare_to_store ()
+{
+}
+
+/* Store register REGNO, or all registers if REGNO == -1, from the contents
+   of REGISTERS.  FIXME: ignores errors.  */
+
+static void
+wiggler_store_registers (regno)
+     int regno;
+{
+  unsigned char buf[10 + 256];
+  int i;
+  unsigned char *p;
+  int error_code, status;
+  int pktlen;
+  int first_regno, last_regno;
+  int first_bdm_regno, last_bdm_regno;
+
+  if (regno == -1)
+    {
+      first_regno = 0;
+      last_regno = NUM_REGS - 1;
+
+      first_bdm_regno = 0;
+      last_bdm_regno = BDM_NUM_REGS - 1;
+    }
+  else
+    {
+      first_regno = regno;
+      last_regno = regno;
+
+      first_bdm_regno = bdm_regmap [regno];
+      last_bdm_regno = bdm_regmap [regno];
+    }
+
+  if (first_bdm_regno == -1)
+    return;                    /* Unsupported register */
+
+  buf[0] = WIGGLER_WRITE_REGS;
+  buf[3] = 4;
+
+  for (i = first_regno; i <= last_regno; i++)
+    {
+      int bdm_regno;
+
+      bdm_regno = bdm_regmap [i];
+
+      buf[1] = bdm_regno >> 8;
+      buf[2] = bdm_regno & 0xff;
+
+      memcpy (&buf[4], &registers[REGISTER_BYTE (i)], 4);
+      put_packet (buf, 4 + 4);
+      p = get_packet (WIGGLER_WRITE_REGS, &pktlen, remote_timeout);
+
+      if (pktlen < 3)
+       error ("Truncated response packet from Wiggler");
+
+      status = p[1];
+      error_code = p[2];
+
+      if (error_code != 0)
+       wiggler_error ("wiggler_store_registers:", error_code);
+    }
+}
+\f
+/* Write memory data directly to the remote machine.
+   This does not inform the data cache; the data cache uses this.
+   MEMADDR is the address in the remote memory space.
+   MYADDR is the address of the buffer in our space.
+   LEN is the number of bytes.
+
+   Returns number of bytes transferred, or 0 for error.  */
+
+static int
+wiggler_write_bytes (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  char buf[256 + 10];
+  unsigned char *p;
+  int origlen;
+
+  origlen = len;
+
+  buf[0] = WIGGLER_WRITE_MEM;
+  buf[5] = 1;                  /* Write as bytes */
+  buf[6] = 0;                  /* Don't verify */
+
+  while (len > 0)
+    {
+      int numbytes;
+      int pktlen;
+      int status, error_code;
+
+      numbytes = min (len, 256 - 8);
+/*      numbytes = min (len, 40);*/
+
+      buf[1] = memaddr >> 24;
+      buf[2] = memaddr >> 16;
+      buf[3] = memaddr >> 8;
+      buf[4] = memaddr;
+
+      buf[7] = numbytes;
+
+      memcpy (&buf[8], myaddr, numbytes);
+      put_packet (buf, 8 + numbytes);
+      p = get_packet (WIGGLER_WRITE_MEM, &pktlen, remote_timeout);
+      if (pktlen < 3)
+       error ("Truncated response packet from Wiggler");
+
+      status = p[1];
+      error_code = p[2];
+
+      if (error_code == 11)    /* Got a bus error? */
+       {
+         CORE_ADDR error_address;
+
+         error_address = p[3] << 24;
+         error_address |= p[4] << 16;
+         error_address |= p[5] << 8;
+         error_address |= p[6];
+         numbytes = error_address - memaddr;
+
+         len -= numbytes;
+
+         errno = EIO;
+
+         break;
+       }
+      else if (error_code != 0)
+       wiggler_error ("wiggler_store_registers:", error_code);
+
+      len -= numbytes;
+      memaddr += numbytes;
+      myaddr += numbytes;
+    }
+
+  return origlen - len;
+}
+
+/* Read memory data directly from the remote machine.
+   This does not use the data cache; the data cache uses this.
+   MEMADDR is the address in the remote memory space.
+   MYADDR is the address of the buffer in our space.
+   LEN is the number of bytes.
+
+   Returns number of bytes transferred, or 0 for error.  */
+
+static int
+wiggler_read_bytes (memaddr, myaddr, len)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+{
+  char buf[256 + 10];
+  unsigned char *p;
+  int origlen;
+
+  origlen = len;
+
+  buf[0] = WIGGLER_READ_MEM;
+  buf[5] = 1;                  /* Read as bytes */
+
+  while (len > 0)
+    {
+      int numbytes;
+      int pktlen;
+      int status, error_code;
+
+      numbytes = min (len, 256 - 7);
+
+      buf[1] = memaddr >> 24;
+      buf[2] = memaddr >> 16;
+      buf[3] = memaddr >> 8;
+      buf[4] = memaddr;
+
+      buf[6] = numbytes;
+
+      put_packet (buf, 7);
+      p = get_packet (WIGGLER_READ_MEM, &pktlen, remote_timeout);
+      if (pktlen < 4)
+       error ("Truncated response packet from Wiggler");
+
+      status = p[1];
+      error_code = p[2];
+
+      if (error_code == 0x11)  /* Got a bus error? */
+       {
+         CORE_ADDR error_address;
+
+         error_address = p[3] << 24;
+         error_address |= p[4] << 16;
+         error_address |= p[5] << 8;
+         error_address |= p[6];
+         numbytes = error_address - memaddr;
+
+         len -= numbytes;
+
+         errno = EIO;
+
+         break;
+       }
+      else if (error_code != 0)
+       wiggler_error ("wiggler_store_registers:", error_code);
+
+      memcpy (myaddr, &p[4], numbytes);
+
+      len -= numbytes;
+      memaddr += numbytes;
+      myaddr += numbytes;
+    }
+
+  return origlen - len;
+}
+\f
+/* Read or write LEN bytes from inferior memory at MEMADDR, transferring
+   to or from debugger address MYADDR.  Write to inferior if SHOULD_WRITE is
+   nonzero.  Returns length of data written or read; 0 for error.  */
+
+/* ARGSUSED */
+static int
+wiggler_xfer_memory(memaddr, myaddr, len, should_write, target)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+     int should_write;
+     struct target_ops *target;                        /* ignored */
+{
+  return dcache_xfer_memory (wiggler_dcache, memaddr, myaddr, len, should_write);
+}
+\f
+static void
+wiggler_files_info (ignore)
+     struct target_ops *ignore;
+{
+  puts_filtered ("Debugging a target over a serial line.\n");
+}
+\f
+/* Stuff for dealing with the packets which are part of this protocol.
+   See comment at top of file for details.  */
+
+/* Read a single character from the remote side, handling wierd errors. */
+
+static int
+readchar (timeout)
+     int timeout;
+{
+  int ch;
+
+  ch = SERIAL_READCHAR (wiggler_desc, timeout);
+
+  switch (ch)
+    {
+    case SERIAL_EOF:
+      error ("Remote connection closed");
+    case SERIAL_ERROR:
+      perror_with_name ("Remote communication error");
+    case SERIAL_TIMEOUT:
+    default:
+      return ch;
+    }
+}
+
+#if 0
+/* Read a character from the data stream, dequoting as necessary.  SYN is
+   treated special.  Any SYNs appearing in the data stream are returned as the
+   distinct value RAW_SYN (which has a value > 8 bits and therefore cannot be
+   mistaken for real data).  */
+
+static int
+get_quoted_char (timeout)
+     int timeout;
+{
+  int ch;
+
+  ch = readchar (timeout);
+
+  switch (ch)
+    {
+    case SERIAL_TIMEOUT:
+      error ("Timeout in mid-packet, aborting");
+    case SYN:
+      return RAW_SYN;
+    case DLE:
+      ch = readchar (timeout);
+      if (ch == SYN)
+       return RAW_SYN;
+      return ch & ~0100;
+    default:
+      return ch;
+    }
+}
+
+static unsigned char pkt[256 * 2 + 10], *pktp; /* Worst case */
+
+static void
+reset_packet ()
+{
+  pktp = pkt;
+}
+
+static void
+output_packet ()
+{
+  if (SERIAL_WRITE (wiggler_desc, pkt, pktp - pkt))
+    perror_with_name ("output_packet: write failed");
+
+  reset_packet ();
+}
+
+/* Output a quoted character.  SYNs and DLEs are quoted.  Everything else goes
+   through untouched.  */
+
+static void
+put_quoted_char (c)
+     int c;
+{
+  switch (c)
+    {
+    case SYN:
+    case DLE:
+      *pktp++ = DLE;
+      c |= 0100;
+    }
+
+  *pktp++ = c;
+}
+
+/* Send a packet to the Wiggler.  The packet framed by a SYN character, a byte
+   count and a checksum.  The byte count only counts the number of bytes
+   between the count and the checksum.  A count of zero actually means 256.
+   Any SYNs within the packet (including the checksum and count) must be
+   quoted.  The quote character must be quoted as well.  Quoting is done by
+   replacing the character with the two-character sequence DLE, {char} | 0100.
+   Note that the quoting mechanism has no effect on the byte count.
+ */
+
+static void
+stu_put_packet (buf, len)
+     unsigned char *buf;
+     int len;
+{
+  unsigned char checksum;
+  unsigned char c;
+
+  if (len == 0 || len > 256)
+    abort ();                  /* Can't represent 0 length packet */
+
+  reset_packet ();
+
+  checksum = 0;
+
+  put_quoted_char (RAW_SYN);
+
+  c = len;
+
+  do
+    {
+      checksum += c;
+
+      put_quoted_char (c);
+
+      c = *buf++;
+    }
+  while (len-- > 0);
+
+  put_quoted_char (-checksum & 0xff);
+
+  output_packet ();
+}
+
+#else
+
+/* Send a packet to the Wiggler.  The packet framed by a SYN character, a byte
+   count and a checksum.  The byte count only counts the number of bytes
+   between the count and the checksum.  A count of zero actually means 256.
+   Any SYNs within the packet (including the checksum and count) must be
+   quoted.  The quote character must be quoted as well.  Quoting is done by
+   replacing the character with the two-character sequence DLE, {char} | 0100.
+   Note that the quoting mechanism has no effect on the byte count.
+ */
+
+static void
+put_packet (buf, len)
+     unsigned char *buf;
+     int len;
+{
+  unsigned char checksum;
+  unsigned char c;
+  unsigned char *packet, *packet_ptr;
+
+  packet = alloca (len + 1 + 1); /* packet + SYN + checksum */
+  packet_ptr = packet;
+
+  checksum = 0;
+
+  *packet_ptr++ = 0x55;
+
+  while (len-- > 0)
+    {
+      c = *buf++;
+
+      checksum += c;
+      *packet_ptr++ = c;
+    }
+
+  *packet_ptr++ = -checksum;
+  if (SERIAL_WRITE (wiggler_desc, packet, packet_ptr - packet))
+    perror_with_name ("output_packet: write failed");
+}
+#endif
+
+#if 0
+/* Get a packet from the Wiggler.  Timeout is only enforced for the first byte
+   of the packet.  Subsequent bytes are expected to arrive in time <= 
+   remote_timeout.  Returns a pointer to a static buffer containing the payload
+   of the packet.  *LENP contains the length of the packet.
+*/
+
+static unsigned char *
+stu_get_packet (cmd, lenp, timeout)
+     unsigned char cmd;
+     int *lenp;
+{
+  int ch;
+  int len;
+  static unsigned char buf[256 + 10], *p;
+  unsigned char checksum;
+
+ find_packet:
+
+  ch = get_quoted_char (timeout);
+
+  if (ch < 0)
+    error ("get_packet (readchar): %d", ch);
+
+  if (ch != RAW_SYN)
+    goto find_packet;
+
+ found_syn:                    /* Found the start of a packet */
+
+  p = buf;
+  checksum = 0;
+
+  len = get_quoted_char (remote_timeout);
+
+  if (len == RAW_SYN)
+    goto found_syn;
+
+  checksum += len;
+
+  if (len == 0)
+    len = 256;
+
+  len++;                       /* Include checksum */
+
+  while (len-- > 0)
+    {
+      ch = get_quoted_char (remote_timeout);
+      if (ch == RAW_SYN)
+       goto found_syn;
+
+      *p++ = ch;
+      checksum += ch;
+    }
+
+  if (checksum != 0)
+    goto find_packet;
+
+  if (cmd != buf[0])
+    error ("Response phase error.  Got 0x%x, expected 0x%x", buf[0], cmd);
+
+  *lenp = p - buf - 1;
+  return buf;
+}
+
+#else
+
+/* Get a packet from the Wiggler.  Timeout is only enforced for the first byte
+   of the packet.  Subsequent bytes are expected to arrive in time <= 
+   remote_timeout.  Returns a pointer to a static buffer containing the payload
+   of the packet.  *LENP contains the length of the packet.
+*/
+
+static unsigned char *
+get_packet (cmd, lenp, timeout)
+     int cmd;
+     int *lenp;
+{
+  int ch;
+  int len;
+  int i;
+  static unsigned char packet[512];
+  unsigned char *packet_ptr;
+  unsigned char checksum;
+
+ find_packet:
+
+  ch = readchar (timeout);
+
+  if (ch < 0)
+    error ("get_packet (readchar): %d", ch);
+
+  if (ch != 0x55)
+    goto find_packet;
+
+/* Found the start of a packet */
+
+  packet_ptr = packet;
+  checksum = 0;
+
+/* Read command char.  That sort of tells us how long the packet is. */
+
+  ch = readchar (timeout);
+
+  if (ch < 0)
+    error ("get_packet (readchar): %d", ch);
+
+  *packet_ptr++ = ch;
+  checksum += ch;
+
+/* Get status. */
+
+  ch = readchar (timeout);
+
+  if (ch < 0)
+    error ("get_packet (readchar): %d", ch);
+  *packet_ptr++ = ch;
+  checksum += ch;
+
+/* Get error code. */
+
+  ch = readchar (timeout);
+
+  if (ch < 0)
+    error ("get_packet (readchar): %d", ch);
+  *packet_ptr++ = ch;
+  checksum += ch;
+
+  switch (ch)                  /* Figure out length of packet */
+    {
+    case 0x7:                  /* Write verify error? */
+      len = 8;                 /* write address, value read back */
+      break;
+    case 0x11:                 /* Bus error? */
+                               /* write address, read flag */
+    case 0x15:                 /* Internal error */
+      len = 5;                 /* error code, vector */
+      break;
+    default:                   /* Error w/no params */
+      len = 0;
+    case 0x0:                  /* Normal result */
+      switch (packet[0])
+       {
+       case WIGGLER_AYT:       /* Are You There? */
+       case WIGGLER_SET_BAUD_RATE: /* Set Baud Rate */
+       case WIGGLER_INIT:      /* Initialize wiggler */
+       case WIGGLER_SET_SPEED: /* Set Speed */
+       case WIGGLER_SET_FUNC_CODE: /* Set Function Code */
+       case WIGGLER_SET_CTL_FLAGS: /* Set Control Flags */
+       case WIGGLER_SET_BUF_ADDR: /* Set Register Buffer Address */
+       case WIGGLER_RUN:       /* Run Target from PC  */
+       case WIGGLER_RUN_ADDR:  /* Run Target from Specified Address  */
+       case WIGGLER_STOP:      /* Stop Target */
+       case WIGGLER_RESET_RUN: /* Reset Target and Run */
+       case WIGGLER_RESET:     /* Reset Target and Halt */
+       case WIGGLER_STEP:      /* Single Step */
+       case WIGGLER_WRITE_REGS: /* Write Register */
+       case WIGGLER_WRITE_MEM: /* Write Memory */
+       case WIGGLER_FILL_MEM:  /* Fill Memory */
+       case WIGGLER_MOVE_MEM:  /* Move Memory */
+       case WIGGLER_WRITE_INT_MEM: /* Write Internal Memory */
+       case WIGGLER_JUMP:      /* Jump to Subroutine */
+         len = 0;
+         break;
+       case WIGGLER_GET_VERSION: /* Get Version */
+         len = 4;
+         break;
+       case WIGGLER_GET_STATUS_MASK: /* Get Status Mask */
+         len = 1;
+         break;
+       case WIGGLER_GET_CTRS:  /* Get Error Counters */
+       case WIGGLER_READ_REGS: /* Read Register */
+       case WIGGLER_READ_MEM:  /* Read Memory */
+       case WIGGLER_READ_INT_MEM: /* Read Internal Memory */
+         len = 257;
+         break;
+       default:
+         fprintf_filtered (gdb_stderr, "Unknown packet type 0x%x\n", ch);
+         goto find_packet;
+       }
+    }
+
+  if (len == 257)              /* Byte stream? */
+    {                          /* Yes, byte streams contain the length */
+      ch = readchar (timeout);
+
+      if (ch < 0)
+       error ("get_packet (readchar): %d", ch);
+      *packet_ptr++ = ch;
+      checksum += ch;
+      len = ch;
+      if (len == 0)
+       len = 256;
+    }
+
+  while (len-- >= 0)           /* Do rest of packet and checksum */
+    {
+      ch = readchar (timeout);
+
+      if (ch < 0)
+       error ("get_packet (readchar): %d", ch);
+      *packet_ptr++ = ch;
+      checksum += ch;
+    }
+
+  if (checksum != 0)
+    goto find_packet;
+
+  if (cmd != -1 && cmd != packet[0])
+    error ("Response phase error.  Got 0x%x, expected 0x%x", packet[0], cmd);
+
+  *lenp = packet_ptr - packet - 1; /* Subtract checksum byte */
+  return packet;
+}
+#endif
+
+/* Execute a simple (one-byte) command.  Returns a pointer to the data
+   following the error code.  */
+
+static unsigned char *
+do_command (cmd, statusp, lenp)
+     int cmd;
+     int *statusp;
+     int *lenp;
+{
+  unsigned char buf[100], *p;
+  int status, error_code;
+  char errbuf[100];
+
+  buf[0] = cmd;
+  put_packet (buf, 1);         /* Send command */
+  p = get_packet (*buf, lenp, remote_timeout);
+
+  if (*lenp < 3)
+    error ("Truncated response packet from Wiggler");
+
+  status = p[1];
+  error_code = p[2];
+
+  if (error_code != 0)
+    {
+      sprintf (errbuf, "do_command (0x%x):", cmd);
+      wiggler_error (errbuf, error_code);
+    }
+
+  if (status & WIGGLER_FLAG_PWF)
+    error ("Wiggler can't detect VCC at BDM interface.");
+  else if (status & WIGGLER_FLAG_CABLE_DISC)
+    error ("BDM cable appears to be disconnected.");
+
+  *statusp = status;
+
+  return p + 3;
+}
+\f
+static void
+wiggler_kill ()
+{
+  /* For some mysterious reason, wait_for_inferior calls kill instead of
+     mourn after it gets TARGET_WAITKIND_SIGNALLED.  Work around it.  */
+  if (kill_kludge)
+    {
+      kill_kludge = 0;
+      target_mourn_inferior ();
+      return;
+    }
+
+  /* Don't wait for it to die.  I'm not really sure it matters whether
+     we do or not.  */
+  target_mourn_inferior ();
+}
+
+static void
+wiggler_mourn ()
+{
+  unpush_target (&wiggler_ops);
+  generic_mourn_inferior ();
+}
+
+/* All we actually do is set the PC to the start address of exec_bfd, and start
+   the program at that point.  */
+
+static void
+wiggler_create_inferior (exec_file, args, env)
+     char *exec_file;
+     char *args;
+     char **env;
+{
+  if (args && (*args != '\000'))
+    error ("Args are not supported by BDM.");
+
+  clear_proceed_status ();
+  proceed (bfd_get_start_address (exec_bfd), TARGET_SIGNAL_0, 0);
+}
+
+static void
+wiggler_load (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  generic_load (args, from_tty);
+  inferior_pid = 0;
+}
+
+/* BDM (at least on CPU32) uses a different breakpoint */
+
+static int
+wiggler_insert_breakpoint (addr, contents_cache)
+     CORE_ADDR addr;
+     char *contents_cache;
+{
+  static char break_insn[] = {BDM_BREAKPOINT};
+  int val;
+
+  val = target_read_memory (addr, contents_cache, sizeof break_insn);
+
+  if (val == 0)
+    val = target_write_memory (addr, break_insn, sizeof break_insn);
+
+  return val;
+}
+
+static void
+bdm_command (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  error ("bdm command must be followed by `reset'");
+}
+
+static void
+bdm_reset_command (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  int status, pktlen;
+
+  if (!wiggler_desc)
+    error ("Not connected to wiggler.");
+
+  do_command (WIGGLER_RESET, &status, &pktlen);
+  dcache_flush (wiggler_dcache);
+  registers_changed ();
+}
+
+static void
+bdm_restart_command (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  int status, pktlen;
+
+  if (!wiggler_desc)
+    error ("Not connected to wiggler.");
+
+  do_command (WIGGLER_RESET_RUN, &status, &pktlen);
+  last_run_status = status;
+  clear_proceed_status ();
+  wait_for_inferior ();
+  normal_stop ();
+}
+\f
+/* Define the target subroutine names */
+
+struct target_ops wiggler_ops = {
+  "wiggler",                   /* to_shortname */
+  "",                          /* to_longname */
+  "",                          /* to_doc */
+  wiggler_open,                        /* to_open */
+  wiggler_close,               /* to_close */
+  NULL,                                /* to_attach */
+  wiggler_detach,              /* to_detach */
+  wiggler_resume,              /* to_resume */
+  wiggler_wait,                        /* to_wait */
+  wiggler_fetch_registers,     /* to_fetch_registers */
+  wiggler_store_registers,     /* to_store_registers */
+  wiggler_prepare_to_store,    /* to_prepare_to_store */
+  wiggler_xfer_memory,         /* to_xfer_memory */
+  wiggler_files_info,          /* to_files_info */
+  wiggler_insert_breakpoint,   /* to_insert_breakpoint */
+  memory_remove_breakpoint,    /* to_remove_breakpoint */
+  NULL,                                /* to_terminal_init */
+  NULL,                                /* to_terminal_inferior */
+  NULL,                                /* to_terminal_ours_for_output */
+  NULL,                                /* to_terminal_ours */
+  NULL,                                /* to_terminal_info */
+  wiggler_kill,                        /* to_kill */
+  wiggler_load,                        /* to_load */
+  NULL,                                /* to_lookup_symbol */
+  wiggler_create_inferior,     /* to_create_inferior */
+  wiggler_mourn,               /* to_mourn_inferior */
+  0,                           /* to_can_run */
+  0,                           /* to_notice_signals */
+  wiggler_thread_alive,                /* to_thread_alive */
+  0,                           /* to_stop */
+  process_stratum,             /* to_stratum */
+  NULL,                                /* to_next */
+  1,                           /* to_has_all_memory */
+  1,                           /* to_has_memory */
+  1,                           /* to_has_stack */
+  1,                           /* to_has_registers */
+  1,                           /* to_has_execution */
+  NULL,                                /* sections */
+  NULL,                                /* sections_end */
+  OPS_MAGIC                    /* to_magic */
+};
+
+void
+_initialize_remote_wiggler ()
+{
+  extern struct cmd_list_element *cmdlist;
+  static struct cmd_list_element *bdm_cmd_list = NULL;
+
+  add_target (&wiggler_ops);
+
+  add_show_from_set (add_set_cmd ("remotetimeout", no_class,
+                                 var_integer, (char *)&remote_timeout,
+                                 "Set timeout value for remote read.\n", &setlist),
+                    &showlist);
+
+  add_prefix_cmd ("bdm", class_obscure, bdm_command, "", &bdm_cmd_list, "bdm ",
+                 0, &cmdlist);
+
+  add_cmd ("reset", class_obscure, bdm_reset_command, "", &bdm_cmd_list);
+  add_cmd ("restart", class_obscure, bdm_restart_command, "", &bdm_cmd_list);
+}
index 151881ae88562dc33690dc0a70415b506f9ddd89..c30fda69836965945f1e2af9d0075dffd29e682b 100644 (file)
@@ -38,11 +38,16 @@ static serial_t scb_base;
 /* Non-NULL gives filename which contains a recording of the remote session,
    suitable for playback by gdbserver. */
 
-char *serial_logfile = NULL;
-FILE *serial_logfp = NULL;
+static char *serial_logfile = NULL;
+static FILE *serial_logfp = NULL;
 
 static struct serial_ops *serial_interface_lookup PARAMS ((char *));
-static void serial_logchar PARAMS ((int));
+static void serial_logchar PARAMS ((int ch, int timeout));
+static char logbase_hex[] = "hex";
+static char logbase_octal[] = "octal";
+static char logbase_ascii[] = "ascii";
+static char *logbase_enums[] = {logbase_hex, logbase_octal, logbase_ascii, NULL};
+static char *serial_logbase = logbase_ascii;
 
 \f
 static int serial_reading = 0;
@@ -52,6 +57,9 @@ void
 serial_log_command (cmd)
      const char *cmd;
 {
+  if (!serial_logfp)
+    return;
+
   if (serial_reading || serial_writing)
     {
       fputc_unfiltered ('\n', serial_logfp);
@@ -64,21 +72,50 @@ serial_log_command (cmd)
   fflush (serial_logfp);
 }
 
+/* Define bogus char to represent a BREAK.  Should be careful to choose a value
+   that can't be confused with a normal char, or an error code.  */
+#define SERIAL_BREAK 1235
+
 static void
-serial_logchar (ch)
+serial_logchar (ch, timeout)
      int ch;
+     int timeout;
 {
+  if (serial_logbase != logbase_ascii)
+    fputc_unfiltered (' ', serial_logfp);
+
   switch (ch)
     {
-    case '\\': fputs_unfiltered ("\\\\", serial_logfp); break; 
-    case '\b': fputs_unfiltered ("\\b", serial_logfp); break;  
-    case '\f': fputs_unfiltered ("\\f", serial_logfp); break;  
-    case '\n': fputs_unfiltered ("\\n", serial_logfp); break;  
-    case '\r': fputs_unfiltered ("\\r", serial_logfp); break;  
-    case '\t': fputs_unfiltered ("\\t", serial_logfp); break;  
-    case '\v': fputs_unfiltered ("\\v", serial_logfp); break;  
-    default:   fprintf_unfiltered (serial_logfp, isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF); break;
-    }
+    case SERIAL_TIMEOUT:
+      fprintf_unfiltered (serial_logfp, "<Timeout: %d seconds>", timeout);
+      return;
+    case SERIAL_ERROR:
+      fprintf_unfiltered (serial_logfp, "<Error: %s>", safe_strerror (errno));
+      return;
+    case SERIAL_EOF:
+      fputs_unfiltered ("<Eof>", serial_logfp);
+      return;
+    case SERIAL_BREAK:
+      fputs_unfiltered ("<Break>", serial_logfp);
+      return;
+    default:
+      if (serial_logbase == logbase_hex)
+       fprintf_unfiltered (serial_logfp, "%02x", ch & 0xff);
+      else if (serial_logbase == logbase_octal)
+       fprintf_unfiltered (serial_logfp, "%03o", ch & 0xff);
+      else
+       switch (ch)
+         {
+         case '\\':    fputs_unfiltered ("\\\\", serial_logfp); break; 
+         case '\b':    fputs_unfiltered ("\\b", serial_logfp); break;  
+         case '\f':    fputs_unfiltered ("\\f", serial_logfp); break;  
+         case '\n':    fputs_unfiltered ("\\n", serial_logfp); break;  
+         case '\r':    fputs_unfiltered ("\\r", serial_logfp); break;  
+         case '\t':    fputs_unfiltered ("\\t", serial_logfp); break;  
+         case '\v':    fputs_unfiltered ("\\v", serial_logfp); break;  
+         default:      fprintf_unfiltered (serial_logfp, isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF); break;
+         }
+       }
 }
 
 int
@@ -98,13 +135,12 @@ serial_write (scb, str, len)
        }
       if (!serial_writing)
        {
-         serial_logchar ('w');
-         serial_logchar (' ');
+         fputs_unfiltered ("w ", serial_logfp);
          serial_writing = 1;
        }
       for (count = 0; count < len; count++)
        {
-         serial_logchar (str[count]);
+         serial_logchar (str[count] & 0xff, 0);
        }
       /* Make sure that the log file is as up-to-date as possible,
         in case we are getting ready to dump core or something. */
@@ -130,11 +166,10 @@ serial_readchar (scb, timeout)
        }
       if (!serial_reading)
        {
-         serial_logchar ('r');
-         serial_logchar (' ');
+         fputs_unfiltered ("r ", serial_logfp);
          serial_reading = 1;
        }
-      serial_logchar (ch);
+      serial_logchar (ch, timeout);
       /* Make sure that the log file is as up-to-date as possible,
         in case we are getting ready to dump core or something. */
       fflush (serial_logfp);
@@ -142,6 +177,30 @@ serial_readchar (scb, timeout)
   return (ch);
 }
 
+int
+serial_send_break (scb)
+     serial_t scb;
+{
+  if (serial_logfp != NULL)
+    {
+      if (serial_reading)
+       {
+         fputc_unfiltered ('\n', serial_logfp);
+         serial_reading = 0;
+       }
+      if (!serial_writing)
+       {
+         fputs_unfiltered ("w ", serial_logfp);
+         serial_writing = 1;
+       }
+      serial_logchar (SERIAL_BREAK, 0);
+      /* Make sure that the log file is as up-to-date as possible,
+        in case we are getting ready to dump core or something. */
+      fflush (serial_logfp);
+    }
+  return (scb -> ops -> send_break (scb));
+}
+
 static struct serial_ops *
 serial_interface_lookup (name)
      char *name;
@@ -471,6 +530,8 @@ serial_printf (va_alist)
 void
 _initialize_serial ()
 {
+  struct cmd_list_element *cmd;
+
 #if 0
   add_com ("connect", class_obscure, connect_command,
           "Connect the terminal directly up to the command monitor.\n\
@@ -484,4 +545,10 @@ This file is used to record the remote session for future playback\n\
 by gdbserver.", &setlist),
                     &showlist);
 
+  add_show_from_set (add_set_enum_cmd ("remotelogbase", no_class,
+                                      logbase_enums,
+                                      (char *)&serial_logbase,
+                                      "Set ...",
+                                      &setlist),
+                          &showlist);
 }
index ca4639c510abe74c13b0cccdb344d251118f7b3d..f1963d0961858c74bffd61c00aa9332499aa910e 100644 (file)
@@ -97,8 +97,9 @@ serial_t serial_fdopen PARAMS ((const int fd));
 
 /* Send a break between 0.25 and 0.5 seconds long.  */
 
-#define SERIAL_SEND_BREAK(SERIAL_T) \
-  ((*(SERIAL_T)->ops->send_break) (SERIAL_T))
+extern int serial_send_break PARAMS ((serial_t scb));
+
+#define SERIAL_SEND_BREAK(SERIAL_T) serial_send_break (SERIAL_T)
 
 /* Turn the port into raw mode. */
 
@@ -176,9 +177,6 @@ extern void serial_printf PARAMS ((serial_t desc, const char *, ...))
 
 /* File in which to record the remote debugging session */
 
-extern char *serial_logfile;
-extern FILE *serial_logfp;
-
 extern void serial_log_command PARAMS ((const char *));
 
 #endif /* SERIAL_H */
index ae072248146b3d09e880456984776f30632a9caa..a5a90f429fc1c77feb17fa7eb4d5df7727c09a52 100644 (file)
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -1171,7 +1171,6 @@ execute_command (p, from_tty)
   register enum language flang;
   static int warned = 0;
   /* FIXME: These should really be in an appropriate header file */
-  extern FILE *serial_logfp;
   extern void serial_log_command PARAMS ((const char *));
 
   free_all_values ();
@@ -1180,8 +1179,7 @@ execute_command (p, from_tty)
   if (p == NULL)
       return;
 
-  if (serial_logfp != NULL)
-    serial_log_command (p);
+  serial_log_command (p);
 
   while (*p == ' ' || *p == '\t') p++;
   if (*p)