* Makefile.in (INTERNAL_CFLAGS): Add ENABLE_CFLAGS.
authorStu Grossman <grossman@cygnus>
Sat, 4 Nov 1995 19:02:42 +0000 (19:02 +0000)
committerStu Grossman <grossman@cygnus>
Sat, 4 Nov 1995 19:02:42 +0000 (19:02 +0000)
* fork-child.c (fork_inferior):  Add call to
TARGET_CREATE_INFERIOR_HOOK to allow target specific code to get
control just before the new process executes it's first instruction.
* remote-mips.c (mips_initialize):  Cleanup a bit.  Don't try to
receive a packet at first.  This speeds up initialization a lot.
Use TARGET_MONITOR_PROMPT instead of "<IDT>".
(common_breakpoint):  Use rresponse instead of rerrflg to inspect
error code.
* symfile.c (syms_from_objfile reread_symbols):  Call
TARGET_SYMFILE_POSTREAD to allow target specific code to get
control after reading new symbols.
* target.h:  New macros TARGET_SYMFILE_POSTREAD, and
TARGET_CREATE_INFERIOR_HOOK.  See above for descriptions.
* config/mips/{irix5.mh nm-irix5.h}:  Delete nm-irix5.h.  Make
NAT_FILE point directly at ../nm-sysv4.h.
* config/mips/{mipsm3.mh nm-m3.h}:  Delete nm-m3.h.  Make
NAT_FILE point directly at ../nm-m3.h.
* config/mips/{mipsv4.mh nm-sysv4.h}:  Delete nm-sysv4.h.  Make
NAT_FILE point directly at ../nm-sysv4.h.
* config/mips/nm-mips.h:  Improve comment at top of file.
* config/mips/tm-mips.h (TARGET_MONITOR_PROMPT):  Change
definition into a proper string.
start-sanitize-gm
* configure configure.in:  Add support for --enable-gm.
(mips*-*-magic*):  Change target from magic to idt.
* eval.c expprint.c expression.h parse.c remote-mips.c utils.c:
Change GENERAL_MAGIC_HACKS to GENERAL_MAGIC.
* magic.c magic.h:  Update files from GM.
* config/mips/magic.mt:  Delete.  No longer necessary now that we
use --enable mechanism.
* config/mips/tm-idt.h:  Add GM stuff needed for remote GM box.
* config/mips/tm-irix5.h:  Add GM stuff needed for native Irix box.
* config/mips/tm-magic.h:  Move up to config/tm-magic.h.  Move all
platform specific stuff into tm-irix.h and tm-idt.h.  Add defs for
TARGET_SYMFILE_POSTREAD and TARGET_CREATE_INFERIOR_HOOK.
end-sanitize-gm

22 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/config/.Sanitize
gdb/config/mips/.Sanitize
gdb/config/mips/magic.mt [deleted file]
gdb/config/mips/mipsm3.mh
gdb/config/mips/mipsv4.mh
gdb/config/mips/nm-m3.h [deleted file]
gdb/config/mips/nm-mips.h
gdb/config/mips/nm-sysv4.h [deleted file]
gdb/config/mips/tm-idt.h
gdb/config/mips/tm-irix5.h
gdb/config/mips/tm-magic.h [deleted file]
gdb/config/mips/tm-mips.h
gdb/config/tm-magic.h [new file with mode: 0644]
gdb/configure
gdb/configure.in
gdb/fork-child.c
gdb/magic.c
gdb/magic.h
gdb/parse.c
gdb/remote-mips.c

index 2b526c6..38ddf94 100644 (file)
@@ -1,3 +1,43 @@
+Sat Nov  4 10:21:58 1995  Stu Grossman  (grossman@cygnus.com)
+
+       * Makefile.in (INTERNAL_CFLAGS):  Add ENABLE_CFLAGS.
+       * fork-child.c (fork_inferior):  Add call to
+       TARGET_CREATE_INFERIOR_HOOK to allow target specific code to get
+       control just before the new process executes it's first instruction.
+       * remote-mips.c (mips_initialize):  Cleanup a bit.  Don't try to
+       receive a packet at first.  This speeds up initialization a lot.
+       Use TARGET_MONITOR_PROMPT instead of "<IDT>".
+       (common_breakpoint):  Use rresponse instead of rerrflg to inspect
+       error code.
+       * symfile.c (syms_from_objfile reread_symbols):  Call
+       TARGET_SYMFILE_POSTREAD to allow target specific code to get
+       control after reading new symbols.
+       * target.h:  New macros TARGET_SYMFILE_POSTREAD, and
+       TARGET_CREATE_INFERIOR_HOOK.  See above for descriptions.
+       * config/mips/{irix5.mh nm-irix5.h}:  Delete nm-irix5.h.  Make
+       NAT_FILE point directly at ../nm-sysv4.h.
+       * config/mips/{mipsm3.mh nm-m3.h}:  Delete nm-m3.h.  Make
+       NAT_FILE point directly at ../nm-m3.h.
+       * config/mips/{mipsv4.mh nm-sysv4.h}:  Delete nm-sysv4.h.  Make
+       NAT_FILE point directly at ../nm-sysv4.h.
+       * config/mips/nm-mips.h:  Improve comment at top of file.
+       * config/mips/tm-mips.h (TARGET_MONITOR_PROMPT):  Change
+       definition into a proper string.
+start-sanitize-gm
+       * configure configure.in:  Add support for --enable-gm.
+       (mips*-*-magic*):  Change target from magic to idt.
+       * eval.c expprint.c expression.h parse.c remote-mips.c utils.c:
+       Change GENERAL_MAGIC_HACKS to GENERAL_MAGIC.
+       * magic.c magic.h:  Update files from GM.
+       * config/mips/magic.mt:  Delete.  No longer necessary now that we
+       use --enable mechanism.
+       * config/mips/tm-idt.h:  Add GM stuff needed for remote GM box.
+       * config/mips/tm-irix5.h:  Add GM stuff needed for native Irix box.
+       * config/mips/tm-magic.h:  Move up to config/tm-magic.h.  Move all
+       platform specific stuff into tm-irix.h and tm-idt.h.  Add defs for
+       TARGET_SYMFILE_POSTREAD and TARGET_CREATE_INFERIOR_HOOK.
+end-sanitize-gm
+
 Wed Nov  1 20:18:08 1995  Fred Fish  <fnf@cygnus.com>
 
        * config/i386/tm-i386.h: New file containing generic i*86 target
index ff0ec64..211a407 100644 (file)
@@ -174,7 +174,7 @@ CXXFLAGS = -g -O
 # INTERNAL_CFLAGS is the aggregate of all other *CFLAGS macros.
 INTERNAL_CFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \
        $(GDB_CFLAGS) $(OPCODES_CFLAGS) $(READLINE_CFLAGS) \
-       $(BFD_CFLAGS) $(MMALLOC_CFLAGS) $(INCLUDE_CFLAGS)
+       $(BFD_CFLAGS) $(MMALLOC_CFLAGS) $(INCLUDE_CFLAGS) $(ENABLE_CFLAGS)
 
 # LDFLAGS is specifically reserved for setting from the command line
 # when running make.
index 1825126..f54894d 100644 (file)
@@ -21,6 +21,20 @@ else
        lose_these_too="arc ${lose_these_too}"
 fi
 
+gm_files="tm-magic.h"
+
+if ( echo $* | grep keep\-gm > /dev/null ) ; then
+       keep_these_too="${gm_files} ${keep_these_too}"
+       if [ -n "${verbose}" ] ; then
+               echo Keeping ${gm_files}
+       fi
+else
+       lose_these_too="${gm_files} ${lose_these_too}"
+       if [ -n "${verbose}" ] ; then
+               echo Deleting ${gm_files}
+       fi
+fi
+
 # All files listed between the "Things-to-keep:" line and the
 # "Files-to-sed:" line will be kept.  All other files will be removed.
 # Directories listed in this section will have their own Sanitize
index 67b41b8..c4c5bd2 100644 (file)
 
 Do-first:
 
-gm_files="magic.mt tm-magic.h"
-
-if ( echo $* | grep keep\-gm > /dev/null ) ; then
-       keep_these_too="${gm_files} ${keep_these_too}"
-       if [ -n "${verbose}" ] ; then
-               echo Keeping ${gm_files}
-       fi
-else
-       lose_these_too="${gm_files} ${lose_these_too}"
-       if [ -n "${verbose}" ] ; then
-               echo Deleting ${gm_files}
-       fi
-fi
-
 # All files listed between the "Things-to-keep:" line and the
 # "Files-to-sed:" line will be kept.  All other files will be removed.
 # Directories listed in this section will have their own Sanitize
@@ -97,4 +83,31 @@ Things-to-lose:
 
 Do-last:
 
+if ( echo $* | grep keep\-gm > /dev/null ) ; then
+       for i in * ; do
+               if test ! -d $i && (grep sanitize-gm $i > /dev/null) ; then
+                       if [ -n "${verbose}" ] ; then
+                               echo Keeping gm stuff in $i
+                       fi
+               fi
+       done
+else
+       for i in * ; do
+               if test ! -d $i && (grep sanitize-gm $i > /dev/null) ; then
+                       if [ -n "${verbose}" ] ; then
+                               echo Removing traces of \"gm\" from $i...
+                       fi
+                       cp $i new
+                       sed '/start\-sanitize\-gm/,/end-\sanitize\-gm/d' < $i > new
+                       if [ -n "${safe}" -a ! -f .Recover/$i ] ; then
+                               if [ -n "${verbose}" ] ; then
+                                       echo Caching $i in .Recover...
+                               fi
+                               mv $i .Recover
+                       fi
+                       mv new $i
+               fi
+       done
+fi
+
 # End of file.
diff --git a/gdb/config/mips/magic.mt b/gdb/config/mips/magic.mt
deleted file mode 100644 (file)
index 8327a2b..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-# Target: Big-endian IDT board running MagiCAP
-TDEPFILES= mips-tdep.o remote-mips.o magic.o
-TM_FILE= tm-magic.h
index 08c8392..fe7cbad 100644 (file)
@@ -4,7 +4,7 @@
 XDEPFILES= coredep.o
 NATDEPFILES= mipsm3-nat.o m3-nat.o
 XM_FILE= xm-mipsm3.h
-NAT_FILE= nm-m3.h
+NAT_FILE= ../nm-m3.h
 
 # Don't use the mmalloc library in Mach 3.
 MMALLOC = 
index c01bfcb..d6b328b 100644 (file)
@@ -1,4 +1,4 @@
 # Host: Mips running SVR4
 XM_FILE= xm-mipsv4.h
-NAT_FILE= nm-sysv4.h
+NAT_FILE= ../nm-sysv4.h
 NATDEPFILES= fork-child.o procfs.o mipsv4-nat.o corelow.o core-svr4.o solib.o
diff --git a/gdb/config/mips/nm-m3.h b/gdb/config/mips/nm-m3.h
deleted file mode 100644 (file)
index 0fe7cf2..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Native-dependent definitions for mips running Mach 3.
-   Copyright 1994 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 the generic Mach 3 definitions.  */
-
-#include "nm-m3.h"
index ac77782..0f49e34 100644 (file)
@@ -1,4 +1,4 @@
-/* Definitions for GDB on mips.
+/* Native definitions for GDB on DECstations, Sony News. and MIPS Riscos systems
    Copyright (C) 1986, 1987, 1989, 1992 Free Software Foundation, Inc.
    Contributed by Per Bothner(bothner@cs.wisc.edu) at U.Wisconsin
    and by Alessandro Forin(af@cs.cmu.edu) at CMU
diff --git a/gdb/config/mips/nm-sysv4.h b/gdb/config/mips/nm-sysv4.h
deleted file mode 100644 (file)
index a1c6bc6..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Native-dependent definitions for mips running SVR4.
-   Copyright 1994 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 the generic SVR4 definitions.  */
-
-#include "nm-sysv4.h"
index 47bcfb5..f3d2cc8 100644 (file)
@@ -22,3 +22,39 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #undef DEFAULT_MIPS_TYPE
 #define DEFAULT_MIPS_TYPE "r3051"
+
+/* start-sanitize-gm */
+#ifdef GENERAL_MAGIC
+
+#include "tm-magic.h"          /* Include generic stuff */
+
+/* For some reason GM can't hack this... */
+
+#undef GET_LONGJMP_TARGET
+
+/* Watchpoint support */
+
+#define TARGET_HAS_HARDWARE_WATCHPOINTS
+
+#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \
+       (1 == 1)                /* We allow all types of hardware watchpoints */
+
+/* Use these macros for watchpoint insertion/deletion.  */
+/* type can be 0: write watch, 1: read watch, 2: access watch (read/write) */
+
+#define target_insert_watchpoint(addr, len, type) \
+       remote_mips_set_watchpoint (addr, len, type)
+
+#define target_remove_watchpoint(addr, len, type) \
+       remote_mips_remove_watchpoint (addr, len, type)
+
+/* We need to remove watchpoints when stepping, else we hit them again! */
+
+#define HAVE_NONSTEPPABLE_WATCHPOINT
+
+#define STOPPED_BY_WATCHPOINT(w) remote_mips_stopped_by_watchpoint ()
+
+#define FLUSH_CACHED_MEMORY() flush_cached_memory()
+
+#endif /* GENERAL_MAGIC */
+/* end-sanitize-gm */
index faf6d45..3cda7b7 100644 (file)
@@ -44,3 +44,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #undef SIGFRAME_FPREGSAVE_OFF
 #define SIGFRAME_FPREGSAVE_OFF (SIGFRAME_BASE + 2 * 4 + 8 + 32 * 8 + 4)
 #define SIGFRAME_REG_SIZE      8
+
+/* start-sanitize-gm */
+#ifdef GENERAL_MAGIC
+#include "tm-magic.h"
+#endif /* GENERAL_MAGIC */
+/* end-sanitize-gm */
diff --git a/gdb/config/mips/tm-magic.h b/gdb/config/mips/tm-magic.h
deleted file mode 100644 (file)
index c333f73..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/* Definitions for General Magic MIPS target.
-   Copyright (C) 1995 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 "mips/tm-idt.h"
-
-/* For some reason GM can't hack this... */
-
-#undef GET_LONGJMP_TARGET
-
-#define GENERAL_MAGIC_HACKS
-
-#define SEND_BREAK_ON_QUIT
-
-
-/* Watchpoint support */
-
-#define TARGET_HAS_HARDWARE_WATCHPOINTS
-
-#define TARGET_CAN_USE_HARDWARE_WATCHPOINT(type, cnt, ot) \
-       (1 == 1)                /* We allow all types of hardware watchpoints */
-
-/* Use these macros for watchpoint insertion/deletion.  */
-/* type can be 0: write watch, 1: read watch, 2: access watch (read/write) */
-
-#define target_insert_watchpoint(addr, len, type) \
-       remote_mips_set_watchpoint (addr, len, type)
-
-#define target_remove_watchpoint(addr, len, type) \
-       remote_mips_remove_watchpoint (addr, len, type)
-
-/* We need to remove watchpoints when stepping, else we hit them again! */
-
-#define HAVE_NONSTEPPABLE_WATCHPOINT
-
-#define STOPPED_BY_WATCHPOINT(w) remote_mips_stopped_by_watchpoint ()
-
-#define FLUSH_CACHED_MEMORY() flush_cached_memory()
index afbb2e0..d8b2bd1 100644 (file)
@@ -33,7 +33,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #endif
 
 #if !defined (TARGET_MONITOR_PROMPT)
-#define TARGET_MONITOR_PROMPT { '<', 'I', 'D', 'T', '>' }
+#define TARGET_MONITOR_PROMPT "<IDT>"
 #endif
 
 /* Floating point is IEEE compliant */
diff --git a/gdb/config/tm-magic.h b/gdb/config/tm-magic.h
new file mode 100644 (file)
index 0000000..0436036
--- /dev/null
@@ -0,0 +1,40 @@
+/* Definitions for General Magic target.
+   Copyright (C) 1995 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 "magic.h"
+
+#define TARGET_SYMFILE_POSTREAD(OBJFILE) init_magic ()
+
+#define TARGET_CREATE_INFERIOR_HOOK(PID) magic_create_inferior_hook ()
+
+/* Magic Cap method stepping support.
+   We use the shared library trampoline support to implement stepping over
+   the method dispatcher.  We consider the entire dispatcher to be one big
+   trampoline, and use SKIP_TRAMPOLINE_CODE() to skip from a dispatcher
+   entry point to the dispatcher exit site, or from the exit site to the
+   first instruction of the dispatched-to method.  */
+
+#define SKIP_TRAMPOLINE_CODE(pc) \
+       magic_skip_dispatcher(pc)
+
+#define IN_SOLIB_CALL_TRAMPOLINE(pc, name) \
+       magic_in_dispatcher(pc, name)
+
+#define IN_SOLIB_RETURN_TRAMPOLINE(pc, name) \
+       magic_in_dispatcher(pc, name)
index 13a17f0..3a45c91 100755 (executable)
@@ -1,7 +1,7 @@
 #! /bin/sh
 
 # Guess values for system-dependent variables and create Makefiles.
-# Generated automatically using autoconf version 2.4 
+# Generated automatically using autoconf version 2.4.2 
 # Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
 #
 # This configure script is free software; the Free Software Foundation
@@ -14,6 +14,8 @@ ac_default_prefix=/usr/local
 ac_help="$ac_help
   --enable-netrom "
 ac_help="$ac_help
+  --enable-gm "
+ac_help="$ac_help
   --enable-gdbtk "
 ac_help="$ac_help
   --with-x                use the X Window System"
@@ -39,6 +41,18 @@ target=NONE
 verbose=
 x_includes=NONE
 x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
 
 # Initialize some other variables.
 subdirs=
@@ -63,9 +77,14 @@ do
 
   case "$ac_option" in
 
-  -build | --build | --buil | --bui | --bu | --b)
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
     ac_prev=build ;;
-  -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*)
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
     build="$ac_optarg" ;;
 
   -cache-file | --cache-file | --cache-fil | --cache-fi \
@@ -75,6 +94,12 @@ do
   | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
     cache_file="$ac_optarg" ;;
 
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
   -disable-* | --disable-*)
     ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
     # Reject names that are not valid shell variable names.
@@ -125,12 +150,26 @@ Configuration:
 Directory and file names:
   --prefix=PREFIX         install architecture-independent files in PREFIX
                           [$ac_default_prefix]
-  --exec-prefix=PREFIX    install architecture-dependent files in PREFIX
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
                           [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
   --srcdir=DIR            find the sources in DIR [configure dir or ..]
   --program-prefix=PREFIX prepend PREFIX to installed program names
   --program-suffix=SUFFIX append SUFFIX to installed program names
   --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+EOF
+    cat << EOF
 Host type:
   --build=BUILD           configure for building on BUILD [BUILD=HOST]
   --host=HOST             configure for HOST [guessed]
@@ -151,6 +190,44 @@ EOF
   -host=* | --host=* | --hos=* | --ho=*)
     host="$ac_optarg" ;;
 
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
   -nfp | --nfp | --nf)
     # Obsolete; use --without-fp.
     with_fp=no ;;
@@ -163,6 +240,15 @@ EOF
   | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
     no_recursion=yes ;;
 
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
   -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
     ac_prev=prefix ;;
   -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
@@ -203,6 +289,23 @@ EOF
   | -silent | --silent | --silen | --sile | --sil)
     silent=yes ;;
 
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
   -site | --site | --sit)
     ac_prev=site ;;
   -site=* | --site=* | --sit=*)
@@ -213,6 +316,13 @@ EOF
   -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
     srcdir="$ac_optarg" ;;
 
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
   -target | --target | --targe | --targ | --tar | --ta | --t)
     ac_prev=target ;;
   -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
@@ -222,7 +332,7 @@ EOF
     verbose=yes ;;
 
   -version | --version | --versio | --versi | --vers)
-    echo "configure generated by autoconf version 2.4"
+    echo "configure generated by autoconf version 2.4.2"
     exit 0 ;;
 
   -with-* | --with-*)
@@ -387,9 +497,12 @@ fi
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5'
-ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5'
+ac_cpp='echo $CPP $CPPFLAGS 1>&5;
+$CPP $CPPFLAGS'
+ac_compile='echo ${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5;
+${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5 2>&5'
+ac_link='echo ${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5;
+${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5 2>&5'
 
 if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
   # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
@@ -416,7 +529,7 @@ else
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
   IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
-  for ac_dir in $PATH; do
+  for ac_dir in cc; do
     test -z "$ac_dir" && ac_dir=.
     if test -f $ac_dir/$ac_word; then
       ac_cv_prog_CC="gcc"
@@ -450,6 +563,7 @@ else
   ac_cv_prog_gcc=no
 fi
 fi
+
 echo "$ac_t""$ac_cv_prog_gcc" 1>&6
 if test $ac_cv_prog_gcc = yes; then
   GCC=yes
@@ -467,7 +581,8 @@ fi
 rm -f conftest*
 
 fi
-    echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6
+
+echo "$ac_t""$ac_cv_prog_gcc_g" 1>&6
     if test $ac_cv_prog_gcc_g = yes; then
       CFLAGS="-g -O"
     else
@@ -494,7 +609,7 @@ else
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 498 "configure"
+#line 613 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
@@ -508,7 +623,7 @@ else
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 512 "configure"
+#line 627 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
@@ -535,7 +650,7 @@ echo "$ac_t""$CPP" 1>&6
 
 echo $ac_n "checking for AIX""... $ac_c" 1>&6
 cat > conftest.$ac_ext <<EOF
-#line 539 "configure"
+#line 654 "configure"
 #include "confdefs.h"
 #ifdef _AIX
   yes
@@ -562,7 +677,7 @@ 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 566 "configure"
+#line 681 "configure"
 #include "confdefs.h"
 #include <minix/config.h>
 EOF
@@ -680,10 +795,17 @@ else
     esac
   done
   IFS="$ac_save_ifs"
-  # As a last resort, use the slow shell script.
-  test -z "$ac_cv_path_install" && ac_cv_path_install="$ac_install_sh"
+
 fi
-  INSTALL="$ac_cv_path_install"
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
 fi
 echo "$ac_t""$INSTALL" 1>&6
 
@@ -703,7 +825,7 @@ else
   ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
 else
   IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
-  for ac_dir in $PATH; do
+  for ac_dir in :; do
     test -z "$ac_dir" && ac_dir=.
     if test -f $ac_dir/$ac_word; then
       ac_cv_prog_RANLIB="ranlib"
@@ -887,7 +1009,7 @@ else
   ac_cv_c_cross=yes
 else
 cat > conftest.$ac_ext <<EOF
-#line 891 "configure"
+#line 1013 "configure"
 #include "confdefs.h"
 main(){return(0);}
 EOF
@@ -900,15 +1022,16 @@ fi
 fi
 rm -fr conftest*
 fi
-cross_compiling=$ac_cv_c_cross
+
 echo "$ac_t""$ac_cv_c_cross" 1>&6
+cross_compiling=$ac_cv_c_cross
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 912 "configure"
+#line 1035 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -930,7 +1053,7 @@ rm -f conftest*
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 934 "configure"
+#line 1057 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -948,7 +1071,7 @@ fi
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 952 "configure"
+#line 1075 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -969,7 +1092,7 @@ if test "$cross_compiling" = yes; then
   ac_cv_header_stdc=no
 else
 cat > conftest.$ac_ext <<EOF
-#line 973 "configure"
+#line 1096 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -990,6 +1113,7 @@ fi
 rm -fr conftest*
 fi
 fi
+
 echo "$ac_t""$ac_cv_header_stdc" 1>&6
 if test $ac_cv_header_stdc = yes; then
   cat >> confdefs.h <<\EOF
@@ -1006,7 +1130,7 @@ 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 1010 "configure"
+#line 1134 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
@@ -1024,7 +1148,7 @@ rm -f conftest*
 fi
 if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
   echo "$ac_t""yes" 1>&6
-    ac_tr_hdr=HAVE_`echo $ac_hdr | tr '[a-z]./\055' '[A-Z]___'`
+    ac_tr_hdr=HAVE_`echo $ac_hdr | tr 'abcdedfghijklmnopqrstuvwxyz./\055' 'ABCDEDFGHIJKLMNOPQRSTUVWXYZ___'`
   cat >> confdefs.h <<EOF
 #define $ac_tr_hdr 1
 EOF
@@ -1039,7 +1163,7 @@ if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1043 "configure"
+#line 1167 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -1080,6 +1204,7 @@ fi
 rm -f conftest*
 
 fi
+
 echo "$ac_t""$ac_cv_header_stat_broken" 1>&6
 if test $ac_cv_header_stat_broken = yes; then
   cat >> confdefs.h <<\EOF
@@ -1097,7 +1222,7 @@ else
   ac_cv_func_mmap=no
 else
 cat > conftest.$ac_ext <<EOF
-#line 1101 "configure"
+#line 1226 "configure"
 #include "confdefs.h"
 
 /* Thanks to Mike Haertel and Jim Avera for this test. */
@@ -1181,6 +1306,7 @@ fi
 fi
 rm -fr conftest*
 fi
+
 echo "$ac_t""$ac_cv_func_mmap" 1>&6
 if test $ac_cv_func_mmap = yes; then
   cat >> confdefs.h <<\EOF
@@ -1195,8 +1321,8 @@ ENABLE_CLIBS=
 ENABLE_OBS=
 
 # Check whether --enable-netrom or --disable-netrom was given.
-enableval="$enable_netrom"
-if test -n "$enableval"; then
+if test "${enable_netrom+set}" = set; then
+  enableval="$enable_netrom"
   case "${enableval}" in
 yes)   enable_netrom=yes ;;
 no)    enable_netrom=no ;;
@@ -1209,12 +1335,30 @@ if test "${enable_netrom}" = "yes"; then
        ENABLE_OBS="${ENABLE_OBS} remote-nrom.o" 
 fi
 
+# start-sanitize-gm
+ENABLE_GM=
+
+# Check whether --enable-gm or --disable-gm was given.
+if test "${enable_gm+set}" = set; then
+  enableval="$enable_gm"
+  case "${enableval}" in
+yes)   ENABLE_OBS="${ENABLE_OBS} magic.o"
+       ENABLE_CFLAGS=-DGENERAL_MAGIC
+       ;;
+no)    ;;
+*)     { echo "configure: error: bad value ${enableval} given for gm option" 1>&2; exit 1; } ;;
+esac
+fi
+
+
+# end-sanitize-gm
+
 # start-sanitize-gdbtk
 ENABLE_GDBTK=
 
 # Check whether --enable-gdbtk or --disable-gdbtk was given.
-enableval="$enable_gdbtk"
-if test -n "$enableval"; then
+if test "${enable_gdbtk+set}" = set; then
+  enableval="$enable_gdbtk"
   case "${enableval}" in
 yes)   enable_gdbtk=yes ;;
 no)    enable_gdbtk=no  ;;
@@ -1231,8 +1375,8 @@ if test "${enable_gdbtk}" = "yes"; then
 echo $ac_n "checking for X""... $ac_c" 1>&6
 
 # Check whether --with-x or --without-x was given.
-withval="$with_x"
-if test -n "$withval"; then
+if test "${with_x+set}" = set; then
+  withval="$with_x"
   :
 fi
 
@@ -1285,7 +1429,7 @@ test -z "$x_direct_test_library" && x_direct_test_library=Xt
 test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc
 test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h
 cat > conftest.$ac_ext <<EOF
-#line 1289 "configure"
+#line 1433 "configure"
 #include "confdefs.h"
 #include <$x_direct_test_include>
 EOF
@@ -1348,7 +1492,7 @@ rm -f conftest*
 ac_save_LIBS="$LIBS"
 LIBS="-l$x_direct_test_library $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1352 "configure"
+#line 1496 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1460,13 +1604,14 @@ else
   # libraries we check for below, so use a different variable.
   #  --interran@uluru.Stanford.EDU, kb@cs.umb.edu.
   echo $ac_n "checking for -lICE""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_lib_ICE'+set}'`\" = set"; then
+ac_lib_var=`echo ICE | tr '+./' 'p__'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lICE  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1470 "configure"
+#line 1615 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1476,16 +1621,16 @@ IceConnectionNumber()
 EOF
 if eval $ac_link; then
   rm -rf conftest*
-  eval "ac_cv_lib_ICE=yes"
+  eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
-  eval "ac_cv_lib_ICE=no"
+  eval "ac_cv_lib_$ac_lib_var=no"
 fi
 rm -f conftest*
 LIBS="$ac_save_LIBS"
 
 fi
-if eval "test \"`echo '$ac_cv_lib_'ICE`\" = yes"; then
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   X_PRE_LIBS="$X_PRE_LIBS -lSM -lICE"
 else
@@ -1503,13 +1648,14 @@ fi
     # libraries were built with DECnet support.  And karl@cs.umb.edu says
     # the Alpha needs dnet_stub (dnet does not exist).
     echo $ac_n "checking for -ldnet""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_lib_dnet'+set}'`\" = set"; then
+ac_lib_var=`echo dnet | tr '+./' 'p__'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-ldnet  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1513 "configure"
+#line 1659 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1519,16 +1665,16 @@ dnet_ntoa()
 EOF
 if eval $ac_link; then
   rm -rf conftest*
-  eval "ac_cv_lib_dnet=yes"
+  eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
-  eval "ac_cv_lib_dnet=no"
+  eval "ac_cv_lib_$ac_lib_var=no"
 fi
 rm -f conftest*
 LIBS="$ac_save_LIBS"
 
 fi
-if eval "test \"`echo '$ac_cv_lib_'dnet`\" = yes"; then
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"
 else
@@ -1537,13 +1683,14 @@ fi
 
     if test $ac_cv_lib_dnet = no; then
       echo $ac_n "checking for -ldnet_stub""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_lib_dnet_stub'+set}'`\" = set"; then
+ac_lib_var=`echo dnet_stub | tr '+./' 'p__'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-ldnet_stub  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1547 "configure"
+#line 1694 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1553,16 +1700,16 @@ dnet_ntoa()
 EOF
 if eval $ac_link; then
   rm -rf conftest*
-  eval "ac_cv_lib_dnet_stub=yes"
+  eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
-  eval "ac_cv_lib_dnet_stub=no"
+  eval "ac_cv_lib_$ac_lib_var=no"
 fi
 rm -f conftest*
 LIBS="$ac_save_LIBS"
 
 fi
-if eval "test \"`echo '$ac_cv_lib_'dnet_stub`\" = yes"; then
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"
 else
@@ -1576,13 +1723,14 @@ fi
     # Not sure which flavor of 386 UNIX this is, but it seems harmless to
     # check for it.
     echo $ac_n "checking for -lnsl""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_lib_nsl'+set}'`\" = set"; then
+ac_lib_var=`echo nsl | tr '+./' 'p__'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1586 "configure"
+#line 1734 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1592,16 +1740,16 @@ t_accept()
 EOF
 if eval $ac_link; then
   rm -rf conftest*
-  eval "ac_cv_lib_nsl=yes"
+  eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
-  eval "ac_cv_lib_nsl=no"
+  eval "ac_cv_lib_$ac_lib_var=no"
 fi
 rm -f conftest*
 LIBS="$ac_save_LIBS"
 
 fi
-if eval "test \"`echo '$ac_cv_lib_'nsl`\" = yes"; then
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl"
 else
@@ -1614,13 +1762,14 @@ fi
     # But -lsocket is broken on IRIX, according to simon@lia.di.epfl.ch.
     if test "`(uname) 2>/dev/null`" != IRIX; then
       echo $ac_n "checking for -lsocket""... $ac_c" 1>&6
-if eval "test \"`echo '$''{'ac_cv_lib_socket'+set}'`\" = set"; then
+ac_lib_var=`echo socket | tr '+./' 'p__'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lsocket  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1624 "configure"
+#line 1773 "configure"
 #include "confdefs.h"
 
 int main() { return 0; }
@@ -1630,16 +1779,16 @@ socket()
 EOF
 if eval $ac_link; then
   rm -rf conftest*
-  eval "ac_cv_lib_socket=yes"
+  eval "ac_cv_lib_$ac_lib_var=yes"
 else
   rm -rf conftest*
-  eval "ac_cv_lib_socket=no"
+  eval "ac_cv_lib_$ac_lib_var=no"
 fi
 rm -f conftest*
 LIBS="$ac_save_LIBS"
 
 fi
-if eval "test \"`echo '$ac_cv_lib_'socket`\" = yes"; then
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   X_EXTRA_LIBS="$X_EXTRA_LIBS -lsocket"
 else
@@ -1677,7 +1826,7 @@ 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 1681 "configure"
+#line 1830 "configure"
 #include "confdefs.h"
 #include <tk.h>
 EOF
@@ -1779,7 +1928,7 @@ 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 1783 "configure"
+#line 1932 "configure"
 #include "confdefs.h"
 #include <tclInt.h>
 EOF
@@ -2208,7 +2357,7 @@ mips64*-*-elf*)           gdb_target=idt64 ;;
 mips*el-*-ecoff*)      gdb_target=idtl ;;
 mips*-*-ecoff*)                gdb_target=idt ;;
 # start-sanitize-gm
-mips*-*-magic*)                gdb_target=magic ;;
+mips*-*-magic*)                gdb_target=idt ;;
 # end-sanitize-gm
 mips*el-*-elf*)                gdb_target=idtl ;;
 mips*-*-elf*)          gdb_target=idt ;;
@@ -2438,7 +2587,7 @@ do
     echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
     exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
   -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
-    echo "$CONFIG_STATUS generated by autoconf version 2.4"
+    echo "$CONFIG_STATUS generated by autoconf version 2.4.2"
     exit 0 ;;
   -help | --help | --hel | --he | --h)
     echo "\$ac_cs_usage"; exit 0 ;;
@@ -2465,6 +2614,18 @@ s%@LIBS@%$LIBS%g
 s%@exec_prefix@%$exec_prefix%g
 s%@prefix@%$prefix%g
 s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
 s%@CC@%$CC%g
 s%@CPP@%$CPP%g
 s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
index 38114d1..4c2331a 100644 (file)
@@ -39,6 +39,21 @@ if test "${enable_netrom}" = "yes"; then
        ENABLE_OBS="${ENABLE_OBS} remote-nrom.o" 
 fi
 
+# start-sanitize-gm
+ENABLE_GM=
+
+AC_ARG_ENABLE(gm,
+[  --enable-gm ],
+[case "${enableval}" in
+yes)   ENABLE_OBS="${ENABLE_OBS} magic.o"
+       ENABLE_CFLAGS=-DGENERAL_MAGIC
+       ;;
+no)    ;;
+*)     AC_MSG_ERROR(bad value ${enableval} given for gm option) ;;
+esac])
+
+# end-sanitize-gm
+
 # start-sanitize-gdbtk
 ENABLE_GDBTK=
 
@@ -418,7 +433,7 @@ mips64*-*-elf*)             gdb_target=idt64 ;;
 mips*el-*-ecoff*)      gdb_target=idtl ;;
 mips*-*-ecoff*)                gdb_target=idt ;;
 # start-sanitize-gm
-mips*-*-magic*)                gdb_target=magic ;;
+mips*-*-magic*)                gdb_target=idt ;;
 # end-sanitize-gm
 mips*el-*-elf*)                gdb_target=idtl ;;
 mips*-*-elf*)          gdb_target=idt ;;
index 41e46af..df289d4 100644 (file)
@@ -238,6 +238,12 @@ fork_inferior (exec_file, allargs, env, traceme_fun, init_trace_fun,
   /* We are now in the child process of interest, having exec'd the
      correct program, and are poised at the first instruction of the
      new program.  */
+
+  /* Allow target dependant code to play with the new process.  This might be
+     used to have target-specific code initialize a variable in the new process
+     prior to executing the first instruction.  */
+  TARGET_CREATE_INFERIOR_HOOK (pid);
+
 #ifdef SOLIB_CREATE_INFERIOR_HOOK
   SOLIB_CREATE_INFERIOR_HOOK (pid);
 #endif
index 6576e23..d8812cd 100644 (file)
 #include "gdbcmd.h"
 #include "symtab.h"
 #include "value.h"
+#include "frame.h"
+#include "breakpoint.h"
+#include "inferior.h"
+#include "gdbcore.h"
+#include "magic.h"
 #include <ctype.h>
 #include <string.h>
+
 #ifdef DYNAMIC_COMMAND_SUPPORT
 #include <dlfcn.h>
 #endif
 
-typedef unsigned long ulong;
+#ifdef ANSI_PROTOTYPES
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+
+/* Maximum number of bytes of extra data to print, or UINT_MAX for no limit.
+   Note that "set extra-data-max 0" stores UINT_MAX in extra_data_max, which
+   displays in a show command as "unlimited."  */
+
+static unsigned int extra_data_max;
+#define EXTRA_DATA_MAX_DEFAULT         1024
+
+/* Return the number of elements in ARRAY.  */
+
+#define ARRAY_NELEMENTS(array)         (sizeof (array) / sizeof (array[0]))
+
+/* Basic information about a text label */
+
+struct text_label
+{
+  char *name;          /* label name */
+  CORE_ADDR addr;      /* label value or 0 if label not found */
+};
+
+/* Labels within the Magic Cap dispatcher that we need to know about
+   in order to implement "magic stepping" (that is, stepping over
+   Magic Cap method dispatches).  The label addresses are refreshed
+   whenever a new symbol table is loaded.  */
+
+struct text_label dispatch_labels[] =
+{
+  {"__DispatchMethod",         0},     /* normal dispatch entry point */
+  {"__DispatchInherited",      0},     /* inherited dispatch entry point */
+  {"__DispatchDelegated",      0},     /* delegated dispatch entry point */
+  {"__DispatchIntrinsic",      0},     /* intrinsic dispatch entry point */
+  {"__DoDispatchMethodBpSite", 0},     /* do dispatch site */
+};
+
+/* Accessors for the array above.  */
+
+#define DISPATCH_METHOD_ADDR           dispatch_labels[0].addr
+#define DISPATCH_INHERITED_ADDR                dispatch_labels[1].addr
+#define DISPATCH_DELEGATED_ADDR                dispatch_labels[2].addr
+#define DISPATCH_INTRINSIC_ADDR                dispatch_labels[3].addr
+#define DO_DISPATCH_METHOD_ADDR                dispatch_labels[4].addr
+
+/* Cached value objects describing functions in the target program that
+   we call frequently.  These are refreshed whenever a new symbol table
+   is loaded.  */
+
+static value_ptr remote_get_class_name_val;
+static value_ptr remote_get_base_ptr_val;
+
+/* Nonzero means that "magic step" (stepping through the Magic Cap method
+   dispatcher to the dispatch target) is enabled.  */
+
+static int magic_step_enabled;
+
+/* function prototypes */
 
-#ifdef DYNAMIC_COMMAND_SUPPORT
 static void
-dlopen_command PARAMS ((char *, int));
-#endif
+print_object PARAMS ((char *args, int dump));
+
+static void
+get_class_name PARAMS ((unsigned long objectID, char **name, int *is_scripted));
+
+static CORE_ADDR
+get_base_ptr PARAMS ((unsigned long objectID));
+
+static int
+should_dump_extra_data PARAMS ((char *class_name));
+
+static void
+dump_extra_data PARAMS ((CORE_ADDR addr, unsigned long length));
+
+static value_ptr
+call_function_by_name PARAMS ((char *function_name, int nargs, ...));
+
+static value_ptr
+call_function_by_value PARAMS ((value_ptr function_value, int nargs, ...));
+
+static value_ptr
+vcall_function_by_value PARAMS ((value_ptr function_value, int nargs,
+                                va_list args));
+static void
+local_shell_escape PARAMS ((char *arg));
+
+static CORE_ADDR
+lookup_text_label PARAMS ((char *name, value_ptr *val_ptrptr));
+
+static int
+is_dispatcher_entry PARAMS ((CORE_ADDR pc));
+
+static int
+is_dispatcher_exit PARAMS ((CORE_ADDR pc));
+
+
+/* This is the GDB handler for the "dobj" command, which prints a
+   verbose description of an object.  ARGS is a string containing an
+   expression for the object ID, and FROM_TTY is nonzero if the 
+   command was issued interactively.  */
 
-#ifdef DYNAMIC_COMMAND_SUPPORT
 /* ARGSUSED */
 static void
-dlopen_command (arg, from_tty)
-     char *arg;
+dobj_command (args, from_tty)
+     char *args;
      int from_tty;
 {
-       char *p;
-       void *hdl;
-       void (*sym)();
+  if (remote_get_class_name_val == NULL)
+    error ("This version of Magic Cap lacks the runtime support for \"dobj\".");
 
-       if (arg == 0) {
-               error ("No arguments specified.");
-               return;
-       }
-       p = arg;
-       while(*p != ' ' && *p != '\0')
-               p++;
-       if (*p != ' ') {
-               error ("Not enough arguments.");
-               return;
-       }
-    *p++ = '\0';
+  print_object (args, 1);
+}
 
-       hdl = dlopen(arg, RTLD_NOW);
-       if (hdl == NULL) {
-               fprintf(stderr, "%s: %s\n", arg, dlerror());
-               return;
-       }
-       sym = dlsym(hdl, p);
+/* This is the GDB handler for the "pobj" command, which prints a 
+   brief description of an object.  ARGS is a string containing an
+   expression for the object ID, and FROM_TTY is nonzero if the 
+   command was issued interactively.  */
 
-       if (sym == NULL) {
-               fprintf(stderr, "%s: %s\n", p, dlerror());
-               return;
-       }
+/* ARGSUSED */
+static void
+pobj_command (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  if (remote_get_class_name_val == NULL)
+    error ("This version of Magic Cap lacks the runtime support for \"pobj\".");
 
-       sym();
+  print_object (args, 0);
 }
-#endif
 
+/* This is the GDB handler for the "cdump" command, which prints a
+   description of a cluster.  ARGS is a string containing a cluster
+   selector, and FROM_TTY is nonzero if the command was issued
+   interactively.  
+   
+   cdump <contextSlot> [/l[ocked]] [/s[tartAddr] <expr>]
+                      [/c[lass] <className> | <classNumber>] */
+
+/* ARGSUSED */
 static void
-local_shell_escape (char *arg)
+cdump_command (args, from_tty)
+     char *args;
+     int from_tty;
 {
-#ifdef CANT_FORK
-  /* FIXME: what about errors (I don't know how GO32 system() handles
-     them)?  */
-  system (arg);
-#else /* Can fork.  */
-  int rc, status, pid;
-  char *p, *user_shell;
+  char *token;
+  unsigned long cluster;
+  CORE_ADDR min_object;
+  long display_only_locked;
+  long filter_classes;
+  long display_only_class_number;
+  char *display_only_class_name;
 
-  if ((user_shell = (char *) getenv ("SHELL")) == NULL)
-    user_shell = "/bin/sh";
+  if (args == NULL)
+    error_no_arg ("expression for context slot to dump");
 
-  /* Get the name of the shell for arg0 */
-  if ((p = strrchr (user_shell, '/')) == NULL)
-    p = user_shell;
-  else
-    p++;                       /* Get past '/' */
+  token = strtok (args, " \t");
+  if (token[0] == '/')
+    error ("The first argument to cdump must be an expression for the context slot to dump.");
 
-  if ((pid = fork()) == 0)
+  cluster = parse_and_eval_address (token);
+
+  /* Initialize option values.  Note that we assume that
+     sizeof (long) == sizeof (void *) here, in that we pass
+     min_object as a long, even though it is a pointer.  */
+
+  min_object                   = 0;
+  display_only_locked          = 0;
+  filter_classes               = 0;
+  display_only_class_name      = NULL;
+  display_only_class_number    = 0;
+
+  while ((token = strtok (NULL, " \t")) != NULL)
     {
-      if (!arg)
-       execl (user_shell, p, 0);
-      else
-       execl (user_shell, p, "-c", arg, 0);
+      if (token[0] != '/')
+       goto bad_option;
 
-      fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", user_shell,
-                         safe_strerror (errno));
-      gdb_flush (gdb_stderr);
-      _exit (0177);
+      switch (token[1])
+       {
+       case 'l':
+         if (token[2] && strcmp (token + 1, "locked"))
+           goto bad_option;
+
+         display_only_locked = 1;
+         break;
+
+       case 's':
+         if (token[2] && strcmp (token + 1, "startAddr"))
+           goto bad_option;
+
+         if ((token = strtok (NULL, " \t")) == NULL)
+           error ("Missing start address expression for `/s' option.");
+
+         min_object = parse_and_eval_address (token);
+         break;
+
+       case 'c':
+         if (token[2] && strcmp (token + 1, "class"))
+           goto bad_option;
+
+         if ((token = strtok (NULL, " \t")) == NULL)
+           error ("Missing class name or number for `/c' option.");
+
+         filter_classes = 1;
+         if (isdigit (token[0]))
+           display_only_class_number = parse_and_eval_address (token);
+         else
+           display_only_class_name = token;
+
+         break;
+       
+       default:
+         goto bad_option;
+       }
     }
 
-  if (pid != -1)
-    while ((rc = wait (&status)) != pid && rc != -1)
-      ;
+  if (display_only_class_name != NULL)
+    error ("Sorry, `/c <className>' isn't supported yet.");
+
+  (void)call_function_by_name ("cdump", 6, cluster, min_object,
+                              display_only_locked,
+                              filter_classes, display_only_class_number,
+                              display_only_class_name);
+  return;
+
+bad_option:
+  error ("Invalid option: `%s'.", token);
+}
+
+/* This is the GDB handler for the "esc" command, which lists the
+   exception handlers for a given actor.  ARGS is a string containing
+   an expression for the objectID of the actor in question, and FROM_TTY
+   is nonzero if the command was issued interactively.  */
+
+/* ARGSUSED */
+static void
+esc_command (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  unsigned long object;
+
+  if (args == NULL)
+    error_no_arg ("expression for actor's object ID");
+
+  object = parse_and_eval_address (args);
+  (void)call_function_by_name ("esc", 1, object);
+}
+
+/* This is the GDB handler for the "cnum" command, which converts
+   a class number to a class name.  ARGS is a string containing an
+   expression for the class number, and FROM_TTY is nonzero if the
+   command was issued interactively.  */
+
+/* ARGSUSED */
+static void
+cnum_command (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  unsigned long cnum;
+
+  if (args == NULL)
+    error_no_arg ("expression for class number");
+
+  cnum = parse_and_eval_address (args);
+  (void)call_function_by_name ("cnum", 1, cnum);
+}
+
+/* This is the GDB handler for the "getint" command, which converts an
+   intrinsic operation number to the corresponding intrinsic operation name,
+   or vice-versa.  ARGS is a string containing the intrinsic number or name,
+   and FROM_TTY is nonzero if the command was issued interactively.  */
+
+/* ARGSUSED */
+static void
+getint_command (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  char shell_command[256];
+
+  if (args == NULL)
+    error_no_arg ("intrinsic operation number or name");
+
+  if (isdigit (args[0]))
+    sprintf (shell_command, "getint %ld", parse_and_eval_address (args));
   else
-    error ("Fork failed");
-#endif /* Can fork.  */
+    sprintf (shell_command, "getint %s", args);
+
+  local_shell_escape (shell_command);
 }
 
+/* This is the GDB handler for the "getop" command, which converts an
+   operation number to the corresponding operation name, or vice-versa.
+   ARGS is a string containing the operation number or name, and FROM_TTY
+   is nonzero if the command was issued interactively.  */
+
+/* ARGSUSED */
 static void
-GetClassName(long objectID, char* name)
+getop_command (args, from_tty)
+     char *args;
+     int from_tty;
 {
-  register value_ptr val;
-  register struct symbol *sym;
-  struct minimal_symbol *msymbol;
-  struct type *type;
-  value_ptr blocklen;
-  LONGEST maddr;
+  char shell_command[256];
+  CORE_ADDR op_number;
 
-  /* Find the address of RemoteGetClassName in the inferior.  */
+  if (args == NULL)
+    error_no_arg ("operation number or name");
 
-  sym = lookup_symbol ("RemoteGetClassName", 0, VAR_NAMESPACE, 0, NULL);
-  if (sym != NULL)
+  if (isdigit (args[0]))
+    sprintf (shell_command, "getop %ld", parse_and_eval_address (args));
+  else
+    sprintf (shell_command, "getop %s", args);
+
+  local_shell_escape (shell_command);
+}
+
+/* This is the GDB handler for the "getindexical" command, which converts
+   an indexical number to the corresponding indexical name, or vice-versa.
+   ARGS is a string containing the indexical number or name, and FROM_TTY
+   is nonzero if the command was issued interactively.  */
+
+/* ARGSUSED */
+static void
+getindexical_command (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  char shell_command[256];
+
+  if (args == NULL)
+    error_no_arg ("indexical number or name");
+
+  if (isdigit (args[0]))
+    sprintf (shell_command, "getindexical 0x%lx",
+            parse_and_eval_address (args));
+  else
+    sprintf (shell_command, "getindexical %s", args);
+
+  local_shell_escape (shell_command);
+}
+
+/* This is the GDB handler for the "exc" command, which converts an
+   exception number to the corresponding exception name, or vice-versa.
+   ARGS is a string containing the exception number or name, and FROM_TTY
+   is nonzero if the command was issued interactively.
+
+   FIXME why is this one "exc" instead of "getexc?" (inconsistent naming).  */
+
+/* ARGSUSED */
+static void
+exc_command (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  char shell_command[256];
+
+  if (args == NULL)
+    error_no_arg ("exception number or name");
+       
+  if (isdigit (args[0]))
+    sprintf (shell_command, "getexc %ld", parse_and_eval_address (args));
+  else
+    sprintf (shell_command, "getexc %s", args);
+
+  local_shell_escape (shell_command);
+}
+
+#ifdef DYNAMIC_COMMAND_SUPPORT
+/* Open a dynamic library and invoke an entry point within it.
+   ARGS is a string containing the names of the dynamic library
+   and the symbolic entry point, separated by whitespace.  */
+
+/* ARGSUSED */
+static void
+dlopen_command (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  char *p;
+  void *hdl;
+  void (*sym)();
+
+  if (args == 0)
     {
-      if (SYMBOL_CLASS (sym) != LOC_BLOCK)
-       {
-         error ("\"RemoteGetClassName\" exists in this program but is not a function.");
-       }
-      val = value_of_variable (sym, NULL);
+      error ("No arguments specified.");
+      return;
     }
-  else
+
+  p = args;
+  while (*p != ' ' && *p != '\0')
+    p++;
+
+  if (*p != ' ')
     {
-      msymbol = lookup_minimal_symbol ("RemoteGetClassName", "", (struct objfile *) NULL);
-      if (msymbol != NULL)
-       {
-         type = lookup_pointer_type (builtin_type_char);
-         type = lookup_function_type (type);
-         type = lookup_pointer_type (type);
-         maddr = (LONGEST) SYMBOL_VALUE_ADDRESS (msymbol);
-         val = value_from_longest (type, maddr);
-       }
-      else
-       {
-         error ("evaluation of this expression requires the program to have a function \"RemoteGetClassName\".");
-       }
+      error ("Not enough arguments.");
+      return;
     }
+  *p++ = '\0';
 
-  blocklen = value_from_longest (builtin_type_int, (LONGEST) objectID);
-  val = call_function_by_hand (val, 1, &blocklen);
-  if (value_logical_not (val))
+  hdl = dlopen (args, RTLD_NOW);
+  if (hdl == NULL)
     {
-      error ("Could not get class name.");
+      fprintf (stderr, "%s: %s\n", args, dlerror ());
+      return;
     }
-       read_memory(value_as_pointer(val), name, 32);
-       
+
+  sym = dlsym (hdl, p);
+  if (sym == NULL)
+    {
+      fprintf (stderr, "%s: %s\n", p, dlerror ());
+      return;
+    }
+
+  sym();
 }
+#endif /* DYNAMIC_COMMAND_SUPPORT */
 
-static CORE_ADDR
-GetBasePtr(long objectID)
+/* Given an object ID OBJECT, return a pointer to a type structure
+   representing the GDB type that describes the layout of the object's
+   fields in memory (i.e., the "_AllFields" structure corresponding 
+   to the object's class).  */
+
+struct type *
+type_of_object (object)
+     CORE_ADDR object;
 {
-  register value_ptr val;
-  register struct symbol *sym;
-  struct minimal_symbol *msymbol;
+  char *class_name = NULL;
+  char classAllFieldsName[128];
+  struct type *type = NULL;
+  int is_scripted;
+
+  get_class_name (object, &class_name, &is_scripted);
+  sprintf (classAllFieldsName, "%s_AllFields", class_name);
+  free (class_name);
+
+  type = lookup_typename (classAllFieldsName, (struct block *)NULL, 0);
+  return lookup_pointer_type (type);
+}
+
+/* Given OBJECT, an object ID, return the address of the object's
+   fixed fields.  */
+
+CORE_ADDR
+baseptr_of_object (object)
+     unsigned long object;
+{
+  return get_base_ptr (object) + kSizeOfObjectHeader;
+}
+
+/* Given an expression for an object ID, ARGS, print information about
+   the object--including its class, the values of its fixed fields, and
+   the values in its extra data block.  */
+
+/* ARGSUSED */
+static void
+print_object (args, dump)
+     char *args;
+     int dump;
+{
+  CORE_ADDR addr;
+  unsigned long object, object_length;
+  char *class_name = NULL;
+  char class_all_fields_name[128];
   struct type *type;
-  value_ptr blocklen;
-  LONGEST maddr;
+  int is_scripted;
+  struct cleanup *old_chain;
 
-  /* Find the address of RemoteGetBasePtr in the inferior.  */
+  if (args == NULL)
+    error_no_arg ("expression for object ID");
 
-  sym = lookup_symbol ("RemoteGetBasePtr", 0, VAR_NAMESPACE, 0, NULL);
-  if (sym != NULL)
+  object = parse_and_eval_address (args);
+
+  /* check for nilObject */
+
+  if (!object)
     {
-      if (SYMBOL_CLASS (sym) != LOC_BLOCK)
-       {
-         error ("\"RemoteGetBasePtr\" exists in this program but is not a function.");
-       }
-      val = value_of_variable (sym, NULL);
+      printf_filtered ("\"%s\" evaluates to nilObject.\n", args);
+      return;
     }
-  else
+
+  /* allow shortcut for system object ids */
+
+  if (IsObjectID (object))
+    object |= 1 << kIDBitUsable;
+  else if (object < 0x5000)
+    object |= (1 << kIDBitObject) | (1 << kIDBitUsable); /* 0x84000000 */
+
+  /* Get the name of the object's class, as well as the GDB type that
+     describes the layout of the object's fixed fields.  */
+   
+  get_class_name (object, &class_name, &is_scripted);
+  old_chain = make_cleanup (free_current_contents, &class_name);
+
+  sprintf (class_all_fields_name, "%s_AllFields", class_name);
+  type = lookup_typename (class_all_fields_name, (struct block *)NULL, 1);
+
+  /* Get pointer to object's fields.
+     FIXME: ADDR is actually an (ObjectHeader *); should use normal expression
+     evaluator to extract the length member, rather than hardwiring the 
+     format of the structure in this code.  */
+
+  addr = get_base_ptr (object);
+  object_length = read_memory_unsigned_integer (addr, 4);
+  object_length -= kSizeOfObjectHeader;
+  addr += kSizeOfObjectHeader;
+
+  if (type == NULL || (TYPE_CODE (type) != TYPE_CODE_UNDEF
+                      && !(TYPE_FLAGS (type) & TYPE_FLAG_STUB)))
     {
-      msymbol = lookup_minimal_symbol ("RemoteGetBasePtr", "",  (struct objfile *) NULL);
-      if (msymbol != NULL)
+      if (dump)
        {
-         type = lookup_pointer_type (builtin_type_char);
-         type = lookup_function_type (type);
-         type = lookup_pointer_type (type);
-         maddr = (LONGEST) SYMBOL_VALUE_ADDRESS (msymbol);
-         val = value_from_longest (type, maddr);
+         unsigned long fixed_length;
+
+         printf_filtered ("Object 0x%08lx%s at address 0x%08lx of class %s\n", 
+                          object, (is_scripted) ? " (scripted)" : "",
+                          addr, class_name);
+
+         /* If the object has fixed fields, dump them.  */
+
+         if (type != NULL)
+           {
+             value_ptr valptr = value_at_lazy (type, addr);
+             int histindex = record_latest_value (valptr);
+
+             if (histindex >= 0)
+               printf_filtered ("$%d = ", histindex);
+
+             value_print (valptr, gdb_stdout, 0, Val_prettyprint);
+             puts_filtered ("\n");
+             fixed_length = TYPE_LENGTH (type);
+           }
+         else
+           fixed_length = 0;
+
+         /* If the object's length is less than that of its fixed fields,
+            warn the user.  */
+
+         if (object_length < fixed_length)
+           {
+             error ("Warning: object is too small (should be at least %d bytes, is %d bytes).",
+                    fixed_length, object_length);
+           }
+
+         /* Dump the object's extra data, if any.  should_dump_extra_data ()
+            filters out classes (e.g. Cluster) that have too much extra data
+            to be dumped usefully in this format.  */
+
+         if (should_dump_extra_data (class_name))
+           {
+             dump_extra_data (addr + fixed_length,
+                              object_length - fixed_length);
+           }
        }
       else
        {
-         error ("evaluation of this expression requires the program to have a function \"RemoteGetBasePtr\".");
-       }
-    }
+         struct type *pointer_type;
+         value_ptr valptr;
+         int histindex;
 
-  blocklen = value_from_longest (builtin_type_int, (LONGEST) objectID);
-  val = call_function_by_hand (val, 1, &blocklen);
-  if (value_logical_not (val))
-    {
-      error ("Could not get base pointer to object.");
+         pointer_type = lookup_pointer_type ((type == NULL) ?
+                                             builtin_type_void : type);
+         valptr = value_from_longest (pointer_type, addr);
+                                               
+         histindex = record_latest_value (valptr);
+         if (histindex >= 0)
+           printf_filtered ("$%d = ", histindex);
+
+         value_print (valptr, gdb_stdout, 0, Val_prettyprint);
+         puts_filtered ("\n");
+       }
     }
-       return value_as_pointer(val);
+  do_cleanups (old_chain);
 }
 
+/* Get the name of the class of the object referenced by OBJECTID.
+   *NAME is set to a pointer to the string containing the class
+   name; it is the caller's responsibility to free the memory for
+   the string.  *IS_SCRIPTED is set to nonzero if the object is
+   scripted, zero otherwise.  */
+
 static void
-dump_extra_data(CORE_ADDR addr, ulong length)
+get_class_name (objectID, name, is_scripted)
+     unsigned long objectID;
+     char **name;
+     int *is_scripted;
 {
-       ulong buf[5], chunk, i;
-       char *p;
-
-       while (length > 3) {
-               chunk = (length > 16) ? 16 : length;
-
-               memset(buf, 0, 5*sizeof(long));
-               read_memory(addr, &buf, chunk);
-               fprintf(gdb_stdout, "%08lx %08lx %08lx %08lx | ", buf[0], 
-                       buf[1], buf[2], buf[3]);
-               for (i = 0, p = (char*)buf; i < chunk; i++, p++) {
-                       if (!isprint(*p))
-                               *p = '.';
-               }
-               fprintf(gdb_stdout, "%s |\n", buf);
-               addr += chunk;
-               length -= chunk;
+  value_ptr val;
+  int errno_val;
+
+  val = call_function_by_value (remote_get_class_name_val, 1, objectID);
+
+  /* As RemoteGetClassName() is currently (9/21/95) written, an empty string,
+     rather than a nil pointer, is returned upon failure.  I'm leaving the
+     value_logical_not test in anyway, though, just for added robustness.  */
+     
+  if (!value_logical_not (val))
+    {
+      (void)target_read_string (value_as_pointer (val), name, 256, &errno_val);
+      if (errno_val)
+       error ("Can't read class name for object 0x%08lx.", objectID);
+
+      if (**name)
+       {
+         char *scripted_suffix;
+
+         if ((scripted_suffix = strstr (*name, " (scripted)")) != NULL)
+           {
+             *scripted_suffix = '\0';
+             *is_scripted = 1;
+           }
+         else
+           *is_scripted = 0;
+
+          return;
        }
+      else
+       free (*name);
+    }
+
+  error ("Bad object ID: 0x%08lx.", objectID);
 }
 
-struct type *type_of_object(CORE_ADDR object)
+/* Given an object ID, return a pointer to the object's data.  */
+
+static CORE_ADDR
+get_base_ptr (objectID)
+     unsigned long objectID;
 {
-       char className[32], classAllFieldsName[128];
-       struct type *type = NULL;
-       GetClassName(object, className);
-       sprintf(classAllFieldsName, "%s_AllFields", className);
+  register value_ptr val;
+
+  val = call_function_by_value (remote_get_base_ptr_val, 1, objectID);
+
+  if (value_logical_not (val))
+    error ("Could not get base pointer to object.");
 
-       type = lookup_typename(classAllFieldsName, (struct block *)NULL, 0);
-       return lookup_pointer_type(type);
+  return value_as_pointer (val);
 }
 
-CORE_ADDR baseptr_of_object(ulong object)
+/* Return nonzero if we should dump the extra data for an object 
+   of class CLASS_NAME.
+
+   FIXME this only works for explicitly named classes, and doesn't
+   handle subclasses.  */
+
+static int
+should_dump_extra_data (class_name)
+     char *class_name;
 {
-       return GetBasePtr(object) + 12;
+  int i;
+  char **name;
+  static char *dont_dump_extra_classes[] =
+    {
+      "Cluster"
+    };
+
+  for (i = 0, name = dont_dump_extra_classes;
+       i < ARRAY_NELEMENTS(dont_dump_extra_classes);
+       i++, name++)
+    {
+      if (!strcmp (class_name, *name))
+       return 0;
+    }
+
+  return 1;
 }
 
-/* ARGSUSED */
+/* Given ADDR, the address of an object's extra data block, and LENGTH,
+   the length of that block in bytes, dump the object's extra data to
+   standard output.  */
+
 static void
-print_object (arg, dump)
-     char *arg;
-        int dump;
+dump_extra_data (addr, length)
+     CORE_ADDR addr;
+     unsigned long length;
 {
-       CORE_ADDR addr;
-       ulong object, objectLength, typeLength = 0;
-       char className[32], classAllFieldsName[128];
-       struct type* type = NULL;
-
-       object = parse_and_eval_address(arg);
-
-       GetClassName(object, className);
-       sprintf(classAllFieldsName, "%s_AllFields", className);
-
-       type = lookup_typename(classAllFieldsName, (struct block *)NULL, 0);
-       typeLength = TYPE_LENGTH(type);
-       addr = GetBasePtr(object);
-       read_memory(addr, &objectLength, 4);
-       objectLength -= 12;
-       addr += 12;
-       if (TYPE_CODE(type) != TYPE_CODE_UNDEF && !(TYPE_FLAGS(type)&TYPE_FLAG_STUB)) {
-               if (dump) {
-                       value_ptr valptr = value_at_lazy(type, addr);
-                       int histindex = record_latest_value(valptr);
-                       printf_filtered("Object 0x%08lx at address 0x%08lx of class %s\n", 
-                                       object, addr, className);
-                       if (histindex >= 0) printf_filtered ("$%d = ", histindex);
-                       value_print(valptr, gdb_stdout, 0, Val_prettyprint);
-                       objectLength -= typeLength;
-                       addr += typeLength;
-                       printf_filtered("\n");
-                       dump_extra_data(addr, objectLength);
-                       printf_filtered("\n");
-               } else {
-                       value_ptr valptr = value_from_longest(lookup_pointer_type(type), addr);
-                       int histindex = record_latest_value(valptr);
-                       if (histindex >= 0) printf_filtered ("$%d = ", histindex);
-                       value_print(valptr, gdb_stdout, 0, Val_prettyprint);
-                       printf_filtered("\n");
-               }
+  unsigned long buf[5];
+  int chunk;
+  int chunk_longs;
+  int i;
+  int bytes_printed;
+  char *p;
+
+  bytes_printed = 0;
+
+  while (length > 3 && bytes_printed < extra_data_max)
+    {
+      QUIT;            /* allow user to interrupt dump */
+
+      /* read a chunk of extra data */
+
+      chunk = (length > 16) ? 16 : length;
+      memset (buf, 0, sizeof (buf));
+      read_memory (addr, (char *) &buf, chunk);
+
+      /* format data as hex longwords */
+
+      chunk_longs = chunk >> 2;
+      for (i = 0; i < chunk_longs; i++)
+       printf_filtered ("%08lx ",
+                        extract_unsigned_integer (buf + i, sizeof (long)));
+
+      /* pad to 4 longs */
+
+      for (i = chunk_longs; i < 4; i++)
+       puts_filtered ("         ");
+
+      puts_filtered ("| ");
+
+      /* format data as ascii bytes */
+
+      for (i = 0, p = (char*)buf; i < chunk; i++, p++)
+       {
+         if (!isprint (*p))
+           *p = '.';
        }
-}
+      printf_filtered ("%s |\n", buf);
 
-/* ARGSUSED */
-static void
-dobj_command (arg, from_tty)
-     char *arg;
-     int from_tty;
-{
-       print_object(arg, 1);
+      addr += chunk;
+      length -= chunk;
+      bytes_printed += chunk;
+    }
+
+  if (length > 0)
+    printf_filtered ("(%d bytes of extra data remaining but not displayed.)\n",
+                    length);
 }
 
-/* ARGSUSED */
-static void
-pobj_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+/* Given the name of a function in the target program and a list of
+   long arguments, call the function and return a pointer to a value
+   object describing the function's return value.  NAME is a string
+   containing the name of the function to be called; NARGS is the
+   number of arguments to the function; and the remaining parameters
+   are the arguments to passed to the function, all assumed to be of
+   type long.  */
+
+static value_ptr
+#ifdef ANSI_PROTOTYPES
+call_function_by_name (char *function_name, int nargs, ...)
+#else
+call_function_by_name (va_alist)
+     va_dcl
+#endif
 {
-       print_object(arg, 0);
+  va_list args;
+  value_ptr return_value;
+  value_ptr function_value;
+#ifndef ANSI_PROTOTYPES
+  char *function_name;
+  int nargs;
+
+  va_start (args);
+  function_name = va_arg (args, char *);
+  nargs = va_arg (args, int);
+#else
+  va_start (args, nargs);
+#endif
+
+  /* Find the address of function NAME in the inferior.  */
+
+  if (!lookup_text_label (function_name, &function_value))
+    error ("Execution of this command requires the debugged program to have a function \"%s.\"",
+          function_name);
+
+  /* Call the function.  */
+
+  return_value = vcall_function_by_value (function_value, nargs, args);
+  va_end (args);
+
+  return return_value;
 }
 
-/* ARGSUSED */
-static void
-getint_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+/* Given a value object describing a function in the target program and
+   a list of long arguments, call the function and return a pointer to a
+   value object describing the function's return value.  FUNCTION_VALUE
+   is a pointer to a value struct describing the function; NARGS is the
+   number of arguments to the function; and the remaining parameters are
+   the arguments to passed to the function, all assumed to be of type long.  */
+
+static value_ptr
+#ifdef ANSI_PROTOTYPES
+call_function_by_value (value_ptr function_value, int nargs, ...)
+#else
+call_function_by_value (va_alist)
+     va_dcl
+#endif
 {
-       char shellCommand[128];
-       
-       sprintf(shellCommand, "getint %s", arg);
-       local_shell_escape(shellCommand);
+  va_list args;
+  value_ptr return_value;
+#ifndef ANSI_PROTOTYPES
+  value_ptr function_value;
+  int nargs;
+
+  va_start (args);
+  function_value = va_arg (args, value_ptr);
+  nargs = va_arg (args, int);
+#else
+  va_start (args, nargs);
+#endif
+
+  /* Call the function and return its return value.  */
+
+  return_value = vcall_function_by_value (function_value, nargs, args);
+  va_end (args);
+
+  return return_value;
 }
 
-/* ARGSUSED */
-static void
-getindexical_command (arg, from_tty)
-     char *arg;
-     int from_tty;
+/* Helper routine for call_function_by_name and call_function_by_value 
+   above.  This function does the work of collecting the function
+   arguments into an array of value objects, and then invoking 
+   call_function_by_hand to do the real work.  FUNCTION_VALUE is a 
+   pointer to a value object describing the function to be called,
+   NARGS is the number of arguments to the function, and ARGS is a
+   list (va_list) of the arguments to the function, all assumed to
+   be of type long.
+
+   Returns a pointer to a value object describing the return value
+   of the function.  */
+
+static value_ptr
+vcall_function_by_value (function_value, nargs, args)
+     value_ptr function_value;
+     int nargs;
+     va_list args;
 {
-       char shellCommand[128];
+  value_ptr *arg_values;
+  value_ptr return_value;
+  struct cleanup *old_chain;
+  int i;
+
+  /* Construct a vector of value objects describing the arguments
+     to the function to be called.  */
+
+  arg_values = (value_ptr *) xmalloc (nargs * sizeof (value_ptr));
+  old_chain = make_cleanup (free_current_contents, &arg_values);
+
+  for (i = 0; i < nargs; i++)
+    arg_values[i] = value_from_longest (builtin_type_long,
+                                       (LONGEST) va_arg (args, unsigned long));
+
+  /* Call the function and return its return value.  */
 
-       sprintf(shellCommand, "getindexical %s", arg);
-       local_shell_escape(shellCommand);
+  return_value = call_function_by_hand (function_value, nargs, arg_values);
+  do_cleanups (old_chain);
+  return return_value;
 }
 
-/* ARGSUSED */
+/* Invoke a shell, supplying ARG as the command to be executed.  */
+
 static void
-exc_command (arg, from_tty)
+local_shell_escape (arg)
      char *arg;
-     int from_tty;
 {
-       char shellCommand[128];
-       ulong exception;
-       
-       sprintf(shellCommand, "getexc %s", arg);
-       local_shell_escape(shellCommand);
+#ifdef CANT_FORK
+  /* FIXME: what about errors (I don't know how GO32 system() handles
+     them)?  */
+  system (arg);
+#else /* Can fork.  */
+  int rc, status, pid;
+  char *p, *user_shell;
+
+  if ((user_shell = (char *) getenv ("SHELL")) == NULL)
+    user_shell = "/bin/sh";
+
+  /* Get the name of the shell for arg0 */
+  if ((p = strrchr (user_shell, '/')) == NULL)
+    p = user_shell;
+  else
+    p++;                       /* Get past '/' */
+
+  if ((pid = fork()) == 0)
+    {
+      if (!arg)
+       execl (user_shell, p, 0);
+      else
+       execl (user_shell, p, "-c", arg, 0);
+
+      fprintf_unfiltered (gdb_stderr, "Cannot execute %s: %s\n", user_shell,
+                         safe_strerror (errno));
+      gdb_flush (gdb_stderr);
+      _exit (0177);
+    }
+
+  if (pid != -1)
+    while ((rc = wait (&status)) != pid && rc != -1)
+      ;
+  else
+    error ("Fork failed");
+#endif /* Can fork.  */
 }
 
-static CORE_ADDR dispatch_method_addr = -1, dispatch_inherited_addr = -1, dispatch_delegated_addr = -1, dispatch_intrinsic_addr = -1;
-CORE_ADDR do_dispatch_method_addr = -1, do_dispatch_intrinsic_addr = -1;
+/* Lookup NAME as a text label in the target program.  If NAME is the
+   name of a function, and VAL_PTRPTR is not NULL, a pointer to a value
+   object describing the function is stored at VAL_PTRPTR.
+
+   Returns the text address to which the label refers, or 0 if the
+   label is not found in the target program.  */
 
 static CORE_ADDR
-lookup_address(const char *name)
+lookup_text_label (name, val_ptrptr)
+     char *name;
+     value_ptr *val_ptrptr;
 {
-  struct symbol *sym = lookup_symbol(name, NULL, VAR_NAMESPACE, NULL, NULL);
-  if (sym)
-    return BLOCK_START(SYMBOL_BLOCK_VALUE(sym));
+  struct symbol *sym;
+  CORE_ADDR addr;
+
+  addr = 0;
+
+  /* Try looking up NAME as a first-class symbol.  */
+
+  sym = lookup_symbol (name, 0, VAR_NAMESPACE, 0, NULL);
+  if (sym != NULL)
+    {
+      switch (SYMBOL_CLASS (sym))
+       {
+       case LOC_BLOCK:
+         addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
+         if (val_ptrptr != NULL)
+           *val_ptrptr = value_of_variable (sym, NULL);
+
+         break;
+
+       case LOC_STATIC:
+       case LOC_LABEL:
+         addr = SYMBOL_VALUE_ADDRESS (sym);
+         break;
+       }
+    }
   else
     {
-/*      printf("Couldn't find %s!\n", name); */
-      return -1;
+      struct minimal_symbol *msymbol;
+      struct type *type;
+
+      /* Try to find a minimal symbol for NAME.  */
+
+      msymbol = lookup_minimal_symbol (name, "", (struct objfile *) NULL);
+      if (msymbol != NULL)
+       {
+         addr = SYMBOL_VALUE_ADDRESS (msymbol);
+         if (val_ptrptr != NULL)
+           {
+             type = lookup_pointer_type (builtin_type_char);
+             type = lookup_function_type (type);
+             type = lookup_pointer_type (type);
+             *val_ptrptr = value_from_longest (type, addr);
+           }
+       }
     }
+  return addr;
 }
 
-void
-init_magic()
-{
-  dispatch_method_addr = lookup_address("__DispatchMethod");
-  dispatch_inherited_addr = lookup_address("__DispatchInherited");
-  dispatch_delegated_addr = lookup_address("__DispatchDelegated");
-  dispatch_intrinsic_addr = lookup_address("__DispatchIntrinsic");
-  do_dispatch_method_addr = lookup_address("__DoTheDispatch");
-  do_dispatch_intrinsic_addr = lookup_address("__DoDispatchIntrinsic");
-} 
+/* The following two routines adapt GDB's framework for stepping over
+   shared library trampoline code to the problem of stepping over the
+   Magic Cap method dispatcher.  While the method dispatcher is not a
+   shared library trampoline, we can use the interfaces for controlling
+   stepping over trampolines to do what we want.  */
 
-int
-is_dispatch(CORE_ADDR pc)
-{
-  return (pc == dispatch_method_addr) || (pc == dispatch_inherited_addr) || (pc == dispatch_delegated_addr);
-}
+/* Return nonzero if STOP_PC is within the Magic Cap method dispatcher.
+   NAME is unused.  This function serves as the implementation of both
+   IN_SOLIB_CALL_TRAMPOLINE() and IN_SOLIB_RETURN_TRAMPOLINE() when GDB
+   is configured to target Magic Cap.  We don't need to distinguish
+   between the two types of trampolines (because they're not really
+   trampolines); we just need to tell GDB to set a breakpoint at the
+   site of the next "hop" on our way through the dispatcher, and to
+   keep going.  */
 
 int
-is_dispatch_intrinsic(CORE_ADDR pc)
+magic_in_dispatcher (stop_pc, name)
+     CORE_ADDR stop_pc;
+     char *name;
 {
-  return pc == dispatch_intrinsic_addr;
+  return magic_step_enabled
+        && (is_dispatcher_entry (stop_pc) || is_dispatcher_exit (stop_pc));
 }
 
-/* If we are stopped at one of the entry points to the dispatcher, we want to continue until just
-   before we jump to the implementation.  If we are at that point, we want to continue until we
-   actually get to the implementation.  Likewise for the intrinsic dispatcher
-   */
+/* Determine if STOP_PC is an address within the Magic Cap method
+   dispatcher, and if so, return the address at which GDB should set
+   a step resume breakpoint in order to skip over the dispatcher code.
+   In fact, we have to skip over the dispatcher in two separate "hops:"
+   the first hop gets us from a dispatcher entry point to the dispatcher
+   exit site; the second hop gets us from this exit site to the first
+   instruction of the method.
+
+   This function serves as the implementation of SKIP_TRAMPOLINE_CODE()
+   when GDB is configured to target Magic Cap.  */
+
 CORE_ADDR 
-deal_with_dispatch(CORE_ADDR stop_pc)
+magic_skip_dispatcher (stop_pc)
+     CORE_ADDR stop_pc;
 {
-  if (is_dispatch(stop_pc))
-    return do_dispatch_method_addr;
-  else if (is_dispatch_intrinsic(stop_pc))
-    return do_dispatch_intrinsic_addr;
-  else if (stop_pc == do_dispatch_method_addr)
-    /* This assumes that we branch through t6 */
-    return read_register(14);
-  else if (stop_pc == do_dispatch_intrinsic_addr)
-    /* This assumes that we branch through t0 */
-    return read_register(8);
+  /* If magic stepping is disabled, return 0, indicating that GDB should
+     process this step event normally.  This will have the effect of
+     allowing the user to step through the dispatcher code itself.  */
+
+  if (!magic_step_enabled)
+    return 0;
+
+  /* If the program is stopped at an entry point to the dispatcher,
+     tell GDB to set a breakpoint at a well-known label in the
+     dispatcher where we will be able to determine the address of
+     the method to which we are dispatching.  Note that the dispatcher
+     has hair to ensure that the code at this label is executed when we
+     are completing a top-level dispatch; recursive dispatches generated
+     from within the dispatcher do not exit through this code.  */
+
+  if (is_dispatcher_entry (stop_pc))
+    return DO_DISPATCH_METHOD_ADDR;
+
+  /* If we have hit the breakpoint set previously at a dispatcher exit site,
+     determine the method address and tell GDB to set a breakpoint there.  */
+
+  else if (is_dispatcher_exit (stop_pc))
+    return read_register (14); /* assumes that we branch through t6 */
   else
     return 0;
 }
 
+/* Return nonzero if PC is an entry point to the Magic Cap method
+   dispatcher.  */
+
+static int
+is_dispatcher_entry (pc)
+     CORE_ADDR pc;
+{
+  return pc == DISPATCH_METHOD_ADDR
+        || pc == DISPATCH_INTRINSIC_ADDR
+        || pc == DISPATCH_INHERITED_ADDR
+        || pc == DISPATCH_DELEGATED_ADDR;
+}
+
+/* Return nonzero if PC is an exit site from the Magic Cap method
+   dispatcher.  */
+
+static int
+is_dispatcher_exit (pc)
+     CORE_ADDR pc;
+{
+  return pc == DO_DISPATCH_METHOD_ADDR;
+}
+
+/* Store away addresses in the inferior we need to control single-stepping
+   through Magic Cap method dispatches, as well as other addresses of
+   interest in Magic Cap.  */
+
 void
-magic_create_inferior_hook()
+init_magic ()
 {
-       struct symbol *sym = lookup_symbol("gHandleError", NULL, VAR_NAMESPACE, NULL, NULL);
-       if (sym)
-               {
-                       CORE_ADDR addr = SYMBOL_VALUE(sym);
-                       unsigned long errorDebugger = 2;
-                       target_write_memory(addr, &errorDebugger, 4);
-               }
-
-       init_magic ();
+  struct text_label *label;
+  int i;
+
+  /* Cache method dispatch label addresses.  */
+
+  for (i = 0, label = dispatch_labels;
+       i < ARRAY_NELEMENTS (dispatch_labels);
+       i++, label++)
+    {
+      if (!(label->addr = lookup_text_label (label->name, NULL)))
+       {
+         /* If we can't find all of the dispatcher addresses, don't attempt
+            to do magic stepping.  */
+
+         magic_step_enabled = 0;
+         break;
+       }
+    }
+
+  /* Cache value objects for RemoteGetClassName () and RemoteGetBasePtr (),
+     which are used to implement the "dobj" and "pobj" commands.  Note that
+     we must call release_value () on these values to prevent GDB from freeing
+     them automatically.  */
+
+  if (remote_get_class_name_val != NULL)
+    {
+      value_free (remote_get_class_name_val);
+      remote_get_class_name_val = NULL;
+    }
+
+  if (remote_get_base_ptr_val != NULL)
+    {
+      value_free (remote_get_base_ptr_val);
+      remote_get_base_ptr_val = NULL;
+    }
+
+  if (lookup_text_label ("RemoteGetClassName", &remote_get_class_name_val))
+    {
+      release_value (remote_get_class_name_val);
+
+      if (lookup_text_label ("RemoteGetBasePtr", &remote_get_base_ptr_val))
+       release_value (remote_get_base_ptr_val);
+    }
+} 
+
+/* Hook routine called when an inferior (i.e., debugged) process is
+   created.  */
+
+void
+magic_create_inferior_hook ()
+{
+  struct symbol *sym = lookup_symbol ("gHandleError", NULL, VAR_NAMESPACE,
+                                     NULL, NULL);
+  if (sym)
+    {
+      CORE_ADDR addr = SYMBOL_VALUE (sym);
+      unsigned long errorDebugger = 2;
+
+      target_write_memory (addr, (char *) &errorDebugger, 4);
+    }
 }
 
+/* Initialization routine for magic.c.  This is where we define debugger
+   commands specific to Magic Cap.  */
 
+void
 _initialize_magic ()
 {
-       add_com ("dobj", class_support, dobj_command, "Display Object Contents");
-       add_com ("pobj", class_support, pobj_command, "Print object base pointer");
-       add_com ("getint", class_support, getint_command, "Convert intrinsic name to number or vice versa.");
-       add_com ("getindexical", class_support, getindexical_command, "Convert indexical name to number or vice versa.");
-       add_com ("exc", class_support, exc_command, "Convert exception name to number or vice versa.");
+  add_com ("dobj", class_support, dobj_command,
+          "Display object contents.\n\
+Usage: dobj <objectID>\n\
+Where: <objectID> is an expression for the object ID to dump.");
+
+  add_com ("pobj", class_support, pobj_command,
+          "Print object base pointer.\n\
+Usage: pobj <objectID>\n\
+Where: <objectID> is an expression for the object ID to examine.");
+
+  add_com ("cdump", class_support, cdump_command,
+          concat ("Display the contents of a cluster.\n\
+Usage: cdump <contextSlot> [/l[ocked]] [/s[tartAddr] <addr>]\n\
+                          [/c[lass] <classNumber>]\n\
+Where: <contextSlot> is an expression describing the cluster to dump;\n\
+           if <contextSlot> is a number between 0x8 and 0xf, it is \n\
+           interpreted as the high-order nibble of an object ID\n\
+           belonging to the cluster to dump, with the second highest-\n\
+           order nibble assumed to be 0.  (For example, \"cdump 8\" and \n\
+           \"cdump 0xa\" dump the System Persistent and Persistent RAM\n\
+           clusters, respectively.)\n",
+                   "\n\
+           if <contextSlot> is a number between 0xf0 and 0x100, it is\n\
+           interpreted as the high-order byte of an object ID belonging to\n\
+           the cluster to dump.  (For example, \"cdump 0x88\" and \n\
+           \"cdump 0xa8\" dump the Locked Persistent and Transient RAM\n\
+           clusters, respectively.)\n",
+                   "\n\
+       /locked or /l indicates that only locked objects are to be displayed.\n\
+\n\
+       /startAddr or /s indicates that only objects whose base pointers are\n\
+           greater than or equal to the address specified by the following\n\
+           expression (<startAddr>) are to be displayed.\n\
+\n\
+       /class or /c indicates that only objects of the class specified by\n\
+           the following expression <classNumber> are to be displayed.",
+                  NULL));
+
+  add_com ("esc", class_support, esc_command,
+          "List all the exception handlers for a given actor.\n\
+Usage: esc <objectID>\n\
+Where: <objectID> is an expression for the object ID of the actor\n\
+           whose exception handlers are to be listed.");
+
+  add_com ("cnum", class_support, cnum_command,
+          "Convert class number to name.\n\
+Usage: cnum <classNumber>\n\
+Where: <classNumber> is an expression for the class number to convert.");
+
+  add_com ("getint", class_support, getint_command,
+          "Convert intrinsic name to number or vice versa.\n\
+Usage: getint <intrinsicName> | <intrinsicNumber>\n\
+Where: <intrinsicName> | <intrinsicNumber> is an intrinsic operation name\n\
+           to be converted to an operation number, or an intrinsic operation\n\
+           number to be converted to an operation name.");
+
+  add_com ("getop", class_support, getop_command,
+          "Convert operation name to number or vice versa.\n\
+Usage: getop <operationName> | <operationNumber>\n\
+Where: <operationName> | <operationNumber> is an operation name to be\n\
+           converted to an operation number, or an operation number to\n\
+           be converted to an operation name.");
+
+  add_com ("getindexical", class_support, getindexical_command,
+          "Convert indexical name to number or vice versa.\n\
+Usage: getindexical <indexicalName> | <indexicalNumber>\n\
+Where: <indexicalName> | <indexicalNumber> is an indexical name to be\n\
+           converted to an an indexical number, or an indexical number\n\
+           to be converted to an indexical name.");
+
+  add_com ("exc", class_support, exc_command,
+          "Convert exception name to number or vice versa.\n\
+Usage: exc <exceptionName> | <exceptionNumber>\n\
+Where: <exceptionName> | <exceptionNumber> is an exception name to be\n\
+           converted to an an exception number, or an exception number\n\
+           to be converted to an exception name.");
+
+  add_show_from_set
+    (add_set_cmd ("extra-data-max", class_support, var_uinteger,
+                 (char *) &extra_data_max,
+                 "Set limit on number of bytes of extra data to print.\n\
+This command sets an upper limit on the number of bytes of extra\n\
+data displayed by the \"dobj\" command when dumping a Magic Cap\n\
+object.  \"set extra-data-max 0\" causes there to be no limit.",
+                 &setlist),
+     &showlist);
+
+  extra_data_max = EXTRA_DATA_MAX_DEFAULT;
+
+  add_show_from_set
+    (add_set_cmd ("magic-step", class_support, var_boolean,
+                 (char *) &magic_step_enabled,
+                 "Set stepping over Magic Cap method dispatches.\n\
+When set to \"on\" (the default), issuing a \"step\" command at a Magic Cap\n\
+operation call site will cause the program to stop at the first line of\n\
+the corresponding method.  Set this to \"off\" only if you need to debug\n\
+the dispatcher itself.",
+                 &setlist),
+     &showlist);
+
+  magic_step_enabled = 1;
 
 #ifdef DYNAMIC_COMMAND_SUPPORT
   add_com ("dlopen", class_support, dlopen_command,
-          "Load the dynamic library specified and execute the specified symbol");
+        "Load the dynamic library specified and execute the specified symbol");
 #endif
 }
index 7ff366c..ef8cf2e 100644 (file)
@@ -1,6 +1,32 @@
 /* magic.h - Interface to the General Magic debugger extras */
 
-extern void init_magic();
-extern CORE_ADDR deal_with_dispatch(CORE_ADDR pc);
-extern struct type *type_of_object(CORE_ADDR object);
-extern CORE_ADDR baseptr_of_object(CORE_ADDR object);
+/* object framework definitions, from FrameworkDefines.asm.h and Generic.h */
+
+#define        kIDBitObject            31      /* set for valid object IDs */
+#define        kIDBitUsable            26      /* set if objectID is usable */
+
+/* Return nonzero if <object> is a valid ObjectID */
+
+#define IsObjectID(object)     (((unsigned long)(object) & 0x80000000) != 0)
+
+#define kSizeOfObjectHeader    12      /* size of object header in bytes */
+
+/* public interfaces */
+
+extern void
+init_magic PARAMS ((void));
+
+extern void
+magic_create_inferior_hook PARAMS ((void));
+
+extern struct type *
+type_of_object PARAMS ((CORE_ADDR object));
+
+extern CORE_ADDR
+baseptr_of_object PARAMS ((CORE_ADDR object));
+
+extern int
+magic_in_dispatcher PARAMS ((CORE_ADDR stop_pc, char *name));
+
+extern CORE_ADDR
+magic_skip_dispatcher PARAMS ((CORE_ADDR stop_pc));
index f22814b..316ab53 100644 (file)
@@ -600,9 +600,9 @@ length_of_subexp (expr, endpos)
     case STRUCTOP_STRUCT:
     case STRUCTOP_PTR:
 /* start-sanitize-gm */
-#ifdef GENERAL_MAGIC_HACKS
+#ifdef GENERAL_MAGIC
     case STRUCTOP_FIELD:
-#endif /* GENERAL_MAGIC_HACKS */
+#endif /* GENERAL_MAGIC */
 /* end-sanitize-gm */
       args = 1;
       /* fall through */
index 7514aa9..3265599 100644 (file)
@@ -1016,14 +1016,15 @@ mips_initialize_cleanups (arg)
 static void
 mips_initialize ()
 {
-  char cr, cc;
   char buff[DATA_MAXLEN + 1];
   int err;
   struct cleanup *old_cleanups = make_cleanup (mips_initialize_cleanups, NULL);
+  int j;
 
   /* What is this code doing here?  I don't see any way it can happen, and
      it might mean mips_initializing didn't get cleared properly.
      So I'll make it a warning.  */
+
   if (mips_initializing)
     {
       warning ("internal error: mips_initialize called twice");
@@ -1036,50 +1037,50 @@ mips_initialize ()
   mips_send_seq = 0;
   mips_receive_seq = 0;
 
-  if (mips_receive_packet (buff, 0, 3) < 0)
-    {
-      char cc;
-      int i, j;
-      char srec[10];
-
-      /* We did not receive the packet we expected; try resetting the
-        board and trying again.  */
+  /* At this point, the packit protocol isn't responding.  We'll try getting
+     into the monitor, and restarting the protocol.  */
 
-      /* Force the system into the IDT monitor.  After this we *should* be at
-        the <IDT> prompt.  */
+  /* Force the system into the IDT monitor.  After this we *should* be at the
+     <IDT> prompt.  */
 
-      for (j = 1; j <= 4; j++)
+  for (j = 1; j <= 4; j++)
+    {
+      switch (j)
        {
-         switch (j)
-           {
-           case 1:             /* First, try sending a break */
-             SERIAL_SEND_BREAK (mips_desc);
-             break;
-           case 2:             /* Then, try a ^C */
-             SERIAL_WRITE (mips_desc, "\003", 1); /* Send a ^C to wake up the monitor */
-             break;
-           case 3:             /* Then, try escaping from download */
-             /* We are possibly in binary download mode, having aborted in the middle
-                of an S-record.  ^C won't work because of binary mode.  The only
-                reliable way out is to send enough termination packets (8 bytes) to
-                fill up and then overflow the largest size S-record (255 bytes in this
-                case).  This amounts to 256/8 + 1 packets.  */
-
-             mips_make_srec (srec, '7', 0, NULL, 0);
-
-             for (i = 1; i <= 33; i++)
-               {
-                 SERIAL_WRITE (mips_desc, srec, 8);
-
-                 if (SERIAL_READCHAR (mips_desc, 0) >= 0)
-                   break;      /* Break immediatly if we get something from
+       case 1:                 /* First, try sending a break */
+         SERIAL_SEND_BREAK (mips_desc);
+         break;
+       case 2:                 /* Then, try a ^C */
+         SERIAL_WRITE (mips_desc, "\003", 1);
+         break;
+       case 3:                 /* Then, try escaping from download */
+         {
+           int i;
+           char srec[10];
+
+           /* We are possibly in binary download mode, having aborted in the
+              middle of an S-record.  ^C won't work because of binary mode.
+              The only reliable way out is to send enough termination packets
+              (8 bytes) to fill up and then overflow the largest size S-record
+              (255 bytes in this case).  This amounts to 256/8 + 1 packets.
+              */
+
+           mips_make_srec (srec, '7', 0, NULL, 0);
+
+           for (i = 1; i <= 33; i++)
+             {
+               SERIAL_WRITE (mips_desc, srec, 8);
+
+               if (SERIAL_READCHAR (mips_desc, 0) >= 0)
+                 break;        /* Break immediatly if we get something from
                                   the board. */
-               }
-             break;
-           case 4:
-             mips_error ("Failed to initialize.");
-           }
-         if (mips_expect ("\015\012<IDT>"))
+             }
+           break;
+         case 4:
+           mips_error ("Failed to initialize.");
+         }
+
+         if (mips_expect (TARGET_MONITOR_PROMPT))
            break;
        }
 
@@ -1101,6 +1102,7 @@ mips_initialize ()
 
   /* If this doesn't call error, we have connected; we don't care if
      the request itself succeeds or fails.  */
+
   mips_request ('r', (unsigned int) 0, (unsigned int) 0, &err,
                mips_receive_wait, NULL);
   set_current_frame (create_new_frame (read_fp (), read_pc ()));
@@ -1219,12 +1221,12 @@ mips_resume (pid, step, siggnal)
 {
 
 /* start-sanitize-gm */
-#ifndef GENERAL_MAGIC_HACKS
+#ifndef GENERAL_MAGIC
   if (siggnal != TARGET_SIGNAL_0)
     warning
       ("Can't send signals to a remote system.  Try `handle %s ignore'.",
        target_signal_to_name (siggnal));
-#endif /* GENERAL_MAGIC_HACKS */
+#endif /* GENERAL_MAGIC */
 /* end-sanitize-gm */
 
   mips_request (step ? 's' : 'c',
@@ -1677,14 +1679,14 @@ Can't pass arguments to remote MIPS board; arguments ignored.");
   /* FIXME: Should we set inferior_pid here?  */
 
 /* start-sanitize-gm */
-#ifdef GENERAL_MAGIC_HACKS
+#ifdef GENERAL_MAGIC
   magic_create_inferior_hook ();
   proceed (entry_pt, TARGET_SIGNAL_PWR, 0);
 #else
 /* end-sanitize-gm */
   proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0);
 /* start-sanitize-gm */
-#endif
+#endif /* GENERAL_MAGIC */
 /* end-sanitize-gm */
 }
 
@@ -1863,7 +1865,7 @@ common_breakpoint (cmd, addr, mask, flags)
 
   if (rerrflg != 0)
     {
-      if (rerrflg != EINVAL)
+      if (rresponse != EINVAL)
        fprintf_unfiltered (stderr, "common_breakpoint (0x%x):  Got error: 0x%x\n",
                            addr, rresponse);
       return 1;