aboutsummaryrefslogtreecommitdiff
path: root/gdb/RCS
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/RCS')
-rw-r--r--gdb/RCS/Makefile,v367
-rw-r--r--gdb/RCS/blockframe.c,v606
-rw-r--r--gdb/RCS/coffread.c,v2047
-rwxr-xr-xgdb/RCS/config.gdb,v229
-rw-r--r--gdb/RCS/core.c,v651
-rw-r--r--gdb/RCS/dbxread.c,v4610
-rw-r--r--gdb/RCS/default-dep.c,v731
-rw-r--r--gdb/RCS/findvar.c,v584
-rw-r--r--gdb/RCS/gdb.texinfo,v3009
-rw-r--r--gdb/RCS/gdbcore.h,v105
-rw-r--r--gdb/RCS/inflow.c,v636
-rw-r--r--gdb/RCS/infrun.c,v1855
-rw-r--r--gdb/RCS/m-aux.h,v591
-rw-r--r--gdb/RCS/m-hp9k320.h,v607
-rw-r--r--gdb/RCS/m-sparc.h,v747
-rw-r--r--gdb/RCS/m68k-pinsn.c,v824
-rw-r--r--gdb/RCS/main.c,v1348
-rwxr-xr-xgdb/RCS/munch,v75
-rw-r--r--gdb/RCS/printcmd.c,v1707
-rw-r--r--gdb/RCS/remote.c,v662
-rw-r--r--gdb/RCS/source.c,v990
-rw-r--r--gdb/RCS/sparc-dep.c,v1091
-rw-r--r--gdb/RCS/stack.c,v882
-rw-r--r--gdb/RCS/utils.c,v726
-rw-r--r--gdb/RCS/valprint.c,v1117
-rw-r--r--gdb/RCS/values.c,v1047
26 files changed, 0 insertions, 27844 deletions
diff --git a/gdb/RCS/Makefile,v b/gdb/RCS/Makefile,v
deleted file mode 100644
index fd71c1c..0000000
--- a/gdb/RCS/Makefile,v
+++ /dev/null
@@ -1,367 +0,0 @@
-head 1.4;
-access ;
-symbols ;
-locks ; strict;
-comment @# @;
-
-
-1.4
-date 89.03.27.21.28.33; author gnu; state Exp;
-branches ;
-next 1.3;
-
-1.3
-date 89.03.27.18.33.31; author gnu; state Exp;
-branches ;
-next 1.2;
-
-1.2
-date 89.03.13.19.02.58; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.02.09.03.15.53; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.4
-log
-@More general support for ALLOCA and other local library routines;
-other minor cleanup.
-@
-text
-@# On HPUX, you need to add -Ihp-include to CFLAGS.
-# The headers in the directory hp-include override system headers
-# and tell GDB to use BSD executable file format.
-# You must also define REGEX & REGEX1 below and ALLOCA & ALLOCA1 (get
-# alloca.c from the emacs distribution) to the CLIBS.
-# If you compile GDB with GCC on HPUX, you must make sure that the "nm" used
-# in "munch" is GNU's nm. This is because gcc uses a different .o
-# file format than the native HPUX compiler.
-
-# On USG (System V) machines, you must make sure to setup REGEX &
-# REGEX1 to point at regex.o and use the USG version of CLIBS.
-# If your system has a broken alloca() -- most do -- then get
-# alloca.c from the GNU Emacs distribution and set ALLOCA & ALLOCA1.
-# Also, if you compile gdb with a compiler which uses the coff
-# encapsulation feature (this is a function of the compiler used, NOT
-# of the m-?.h file selected by config.gdb), you must make sure that
-# the GNU nm is the one that is used by munch.
-
-# On Sunos 4.0 machines, make sure to compile *without* shared
-# libraries if you want to run gdb on itself. Make sure to compile
-# any program on which you want to run gdb without shared libraries.
-
-# If you are compiling with GCC, make sure that either 1) You use the
-# -traditional flag, or 2) You have the fixed include files where GCC
-# can reach them. Otherwise the ioctl calls in inflow.c will be
-# incorrectly compiled. The "fixincludes" script in the gcc
-# distribution will probably fix your include files up.
-
-CC=cc
-SHELL=/bin/sh
-
-# Set this up with gcc if you have gnu ld and the loader will print out
-# line numbers for undefinded refs.
-CC-LD=${CC}
-
-# -I. for "#include <obstack.h>". Possibly regex.h also.
-#CFLAGS = -g -pg -I. -O
-CFLAGS = -I. -g
-#LDFLAGS = -pg -g
-LDFLAGS = -g
-
-# define this to be "obstack.o" if you don't have the obstack library installed
-# you must at the same time define OBSTACK1 as "obstack.o"
-# so that the dependencies work right. Similarly with REGEX and "regex.o".
-# You must define REGEX and REGEX1 on USG machines.
-# If your system is missing alloca(), or, more likely, it's there but it
-# doesn't work, define ALLOCA and ALLOCA1.
-OBSTACK = obstack.o
-OBSTACK1 = obstack.o
-REGEX = regex.o
-REGEX1 = regex.o
-ALLOCA = alloca.o
-ALLOCA1 = alloca.o
-ADD_FILES = $(OBSTACK) $(REGEX) $(ALLOCA) $(GNU_MALLOC)
-ADD_DEPS = $(OBSTACK1) $(REGEX1) $(ALLOCA1) $(GNU_MALLOC)
-
-#
-# define this to be "malloc.o" if you want to use the gnu malloc routine
-# (useful for debugging memory allocation problems in gdb). Otherwise, leave
-# it blank.
-GNU_MALLOC =
-#GNU_MALLOC = malloc.o
-
-# Flags to be used in compiling malloc.o
-# Specify range checking for storage allocation.
-MALLOC_FLAGS =
-#MALLOC_FLAGS = ${CFLAGS} -Drcheck -Dbotch=fatal -DMSTATS
-
-# for BSD
-CLIBS = $(ADD_FILES)
-# for USG
-#CLIBS= $(ADD_FILES) -lPW
-
-SFILES = blockframe.c breakpoint.c coffread.c command.c core.c dbxread.c \
- environ.c eval.c expprint.c findvar.c infcmd.c inflow.c infrun.c \
- kdb-start.c main.c printcmd.c \
- remote.c source.c stack.c standalone.c stuff.c symmisc.c symtab.c \
- utils.c valarith.c valops.c valprint.c values.c version.c expread.y \
- xgdb.c
-
-DEPFILES = convex-dep.c umax-dep.c gould-dep.c default-dep.c sun3-dep.c \
- sparc-dep.c hp9k320-dep.c news-dep.c i386-dep.c
-
-PINSNS = gld-pinsn.c i386-pinsn.c sparc-pinsn.c vax-pinsn.c m68k-pinsn.c \
- ns32k-pinsn.c
-
-HFILES = command.h defs.h environ.h expression.h frame.h getpagesize.h \
- inferior.h symseg.h symtab.h value.h wait.h \
- a.out.encap.h a.out.gnu.h stab.gnu.h
-
-OPCODES = m68k-opcode.h pn-opcode.h sparc-opcode.h npl-opcode.h vax-opcode.h \
- ns32k-opcode.h
-
-MFILES = m-hp9k320.h m-i386.h m-i386gas.h m-isi.h m-merlin.h m-news.h \
- m-npl.h m-pn.h m-sparc.h m-sun2.h m-sun3.h m-sun2os4.h \
- m-sun3os4.h m-sun4os4.h m-umax.h m-vax.h
-
-POSSLIBS = obstack.h obstack.c regex.c regex.h malloc.c
-
-TESTS = testbpt.c testfun.c testrec.c testreg.c testregs.c
-
-OTHERS = Makefile createtags munch config.gdb ChangeLog README TAGS \
- gdb.texinfo .gdbinit COPYING expread.tab.c stab.def hp-include
-
-TAGFILES = ${SFILES} ${DEPFILES} ${PINSNS} ${HFILES} ${OPCODES} ${MFILES} \
- ${POSSLIBS}
-TARFILES = ${TAGFILES} ${OTHERS}
-
-OBS = main.o blockframe.o breakpoint.o findvar.o stack.o source.o \
- values.o eval.o valops.o valarith.o valprint.o printcmd.o \
- symtab.o symmisc.o coffread.o dbxread.o infcmd.o infrun.o remote.o \
- command.o utils.o expread.o expprint.o pinsn.o environ.o version.o
-
-TSOBS = core.o inflow.o dep.o
-
-NTSOBS = standalone.o
-
-TSSTART = /lib/crt0.o
-
-NTSSTART = kdb-start.o
-
-gdb : $(OBS) $(TSOBS) $(ADD_DEPS)
- -rm -f init.c
- ./munch $(OBS) $(TSOBS) > init.c
- ${CC-LD} $(LDFLAGS) -o gdb init.c $(OBS) $(TSOBS) $(CLIBS)
-
-xgdb : $(OBS) $(TSOBS) xgdb.o $(ADD_DEPS)
- -rm -f init.c
- ./munch $(OBS) $(TSOBS) xgdb.o > init.c
- $(CC-LD) $(LDFLAGS) -o xgdb init.c $(OBS) $(TSOBS) xgdb.o \
- -lXaw -lXt -lX11 $(CLIBS)
-
-kdb : $(NTSSTART) $(OBS) $(NTSOBS) $(ADD_DEPS)
- -rm -f init.c
- ./munch $(OBS) $(NTSOBS) > init.c
- $(CC-LD) $(LDFLAGS) -c init.c $(CLIBS)
- ld -o kdb $(NTSSTART) $(OBS) $(NTSOBS) init.o -lc $(CLIBS)
-
-# If it can figure out the appropriate order, createtags will make sure
-# that the proper m-*, *-dep, *-pinsn, and *-opcode files come first
-# in the tags list. It will attempt to do the same for dbxread.c and
-# coffread.c. This makes using M-. on machine dependent routines much
-# easier.
-#
-TAGS: ${TAGFILES}
- createtags ${TAGFILES}
-tags: TAGS
-
-gdb.tar: ${TARFILES}
- rm -f gdb.tar
- mkdir dist-gdb
- cd dist-gdb ; for i in ${TARFILES} ; do ln -s ../$$i . ; done
- tar chf gdb.tar dist-gdb
- rm -rf dist-gdb
-
-gdb.tar.Z: gdb.tar
- compress gdb.tar
-
-clean:
- -rm -f ${OBS} ${TSOBS} ${NTSOBS} ${OBSTACK} ${REGEX}
- -rm -f init.c init.o
- -rm -f gdb
-
-realclean: clean
- -rm -f expread.tab.c tags TAGS
-
-xgdb.o : xgdb.c defs.h param.h symtab.h frame.h
- $(CC) -c $(CFLAGS) xgdb.c -o $@@
-
-expread.tab.c : expread.y
- @@echo 'Expect 101 shift/reduce conflicts and 1 reduce/reduce conflict.'
- yacc expread.y
- mv y.tab.c expread.tab.c
-
-expread.o : expread.tab.c defs.h param.h symtab.h frame.h expression.h
- $(CC) -c ${CFLAGS} expread.tab.c
- mv expread.tab.o expread.o
-
-#
-# Only useful if you are using the gnu malloc routines.
-#
-malloc.o : malloc.c
- ${CC} -c ${MALLOC_FLAGS} malloc.c
-
-#
-# dep.o depends on ALL the dep files since we don't know which one
-# is really being used.
-#
-dep.o : ${DEPFILES} defs.h param.h frame.h inferior.h obstack.h \
- a.out.encap.h
-
-# pinsn.o depends on ALL the opcode printers
-# since we don't know which one is really being used.
-pinsn.o : ${PINSNS} defs.h param.h symtab.h obstack.h symseg.h frame.h \
- ${OPCODES}
-
-#
-# The rest of this is a standard dependencies list (hand edited output of
-# cpp -M). It does not include dependencies of .o files on .c files.
-#
-blockframe.o : defs.h param.h symtab.h obstack.h symseg.h frame.h
-breakpoint.o : defs.h param.h symtab.h obstack.h symseg.h frame.h
-coffread.o : defs.h param.h
-command.o : command.h defs.h
-core.o : defs.h param.h a.out.encap.h
-dbxread.o : param.h defs.h symtab.h obstack.h symseg.h a.out.encap.h \
- stab.gnu.h
-environ.o : environ.h
-eval.o : defs.h param.h symtab.h obstack.h symseg.h value.h expression.h
-expprint.o : defs.h symtab.h obstack.h symseg.h param.h expression.h
-findvar.o : defs.h param.h symtab.h obstack.h symseg.h frame.h value.h
-infcmd.o : defs.h param.h symtab.h obstack.h symseg.h frame.h inferior.h \
- environ.h value.h
-inflow.o : defs.h param.h frame.h inferior.h
-infrun.o : defs.h param.h symtab.h obstack.h symseg.h frame.h inferior.h \
- wait.h
-kdb-start.o : defs.h param.h
-main.o : defs.h command.h param.h
-malloc.o : getpagesize.h
-obstack.o : obstack.h
-printcmd.o : defs.h param.h frame.h symtab.h obstack.h symseg.h value.h \
- expression.h
-regex.o : regex.h
-remote.o : defs.h param.h frame.h inferior.h wait.h
-source.o : defs.h symtab.h obstack.h symseg.h param.h
-stack.o : defs.h param.h symtab.h obstack.h symseg.h frame.h
-standalone.o : defs.h param.h symtab.h obstack.h symseg.h frame.h \
- inferior.h wait.h
-symmisc.o : defs.h symtab.h obstack.h symseg.h obstack.h
-symtab.o : defs.h symtab.h obstack.h symseg.h param.h obstack.h
-utils.o : defs.h param.h
-valarith.o : defs.h param.h symtab.h obstack.h symseg.h value.h expression.h
-valops.o : defs.h param.h symtab.h obstack.h symseg.h value.h frame.h \
- inferior.h
-valprint.o : defs.h param.h symtab.h obstack.h symseg.h value.h
-values.o : defs.h param.h symtab.h obstack.h symseg.h value.h
-
-robotussin.h : getpagesize.h
-symtab.h : obstack.h symseg.h
-a.out.encap.h : a.out.gnu.h
-@
-
-
-1.3
-log
-@A/UX changes. Use cc, use local regex.o, use local alloca.o
-@
-text
-@d4 2
-a5 2
-# You must also define REGEX & REGEX1 below and add alloca.o (from
-# the emacs distribution) to the CLIBS.
-d12 2
-d26 2
-a27 1
-# incorrectly compiled.
-d46 2
-d52 4
-d70 1
-a70 1
-#CLIBS = $(OBSTACK) $(REGEX) $(GNU_MALLOC)
-d72 1
-a72 1
-CLIBS= $(OBSTACK) $(REGEX) $(GNU_MALLOC) alloca.o
-d122 1
-a122 1
-gdb : $(OBS) $(TSOBS) $(OBSTACK1) $(REGEX1) ${GNU_MALLOC}
-d127 1
-a127 1
-xgdb : $(OBS) $(TSOBS) xgdb.o $(OBSTACK1) $(REGEX1) ${GNU_MALLOC}
-d133 1
-a133 1
-kdb : $(NTSSTART) $(OBS) $(NTSOBS) $(OBSTACK1) $(REGEX1) ${GNU_MALLOC}
-d161 1
-a161 1
- -rm -f init.c
-d165 1
-a165 1
- -rm -f expread.tab.c
-@
-
-
-1.2
-log
-@All rm's to rm -f's.
-@
-text
-@d26 1
-a26 1
-CC=gcc
-d45 2
-a46 2
-REGEX =
-REGEX1 =
-d61 1
-a61 1
-CLIBS = $(OBSTACK) $(REGEX) $(GNU_MALLOC)
-d63 1
-a63 1
-#CLIBS= $(OBSTACK) $(REGEX) $(GNU_MALLOC) -lPW
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d26 1
-a26 1
-CC=/bin/cc
-d114 1
-a114 1
- -rm init.c
-d119 1
-a119 1
- -rm init.c
-d125 1
-a125 1
- -rm init.c
-d151 3
-a153 3
- -rm ${OBS} ${TSOBS} ${NTSOBS} ${OBSTACK} ${REGEX}
- -rm init.c
- -rm gdb
-d156 1
-a156 1
- -rm expread.tab.c
-@
diff --git a/gdb/RCS/blockframe.c,v b/gdb/RCS/blockframe.c,v
deleted file mode 100644
index fc64e2f..0000000
--- a/gdb/RCS/blockframe.c,v
+++ /dev/null
@@ -1,606 +0,0 @@
-head 1.3;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.3
-date 89.03.16.21.09.52; author gnu; state Exp;
-branches ;
-next 1.2;
-
-1.2
-date 89.02.09.23.21.53; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.02.09.15.15.16; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.3
-log
-@Don't stop the stack trace until the "next frame pointer" is zero.
-@
-text
-@/* Get info from stack frames;
- convert between frames, blocks, functions and pc values.
- Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#include "defs.h"
-#include "param.h"
-#include "symtab.h"
-#include "frame.h"
-
-/* Address of end of first object file.
- This file is assumed to be a startup file
- and frames with pc's inside it
- are treated as nonexistent. */
-
-CORE_ADDR first_object_file_end;
-
-/* Address of innermost stack frame (contents of FP register) */
-
-static FRAME current_frame;
-
-struct block *block_for_pc ();
-CORE_ADDR get_pc_function_start ();
-
-/*
- * Cache for frame addresses already read by gdb. Valid only while
- * inferior is stopped. Control variables for the frame cache should
- * be local to this module.
- */
-struct obstack frame_cache_obstack;
-
-/* Return the innermost (currently executing) stack frame. */
-
-FRAME
-get_current_frame ()
-{
- /* We assume its address is kept in a general register;
- param.h says which register. */
-
- return current_frame;
-}
-
-void
-set_current_frame (frame)
- FRAME frame;
-{
- current_frame = frame;
-}
-
-FRAME
-create_new_frame (addr, pc)
- FRAME_ADDR addr;
- CORE_ADDR pc;
-{
- struct frame_info *fci; /* Same type as FRAME */
-
- fci = (struct frame_info *)
- obstack_alloc (&frame_cache_obstack,
- sizeof (struct frame_info));
-
- /* Arbitrary frame */
- fci->next = (struct frame_info *) 0;
- fci->prev = (struct frame_info *) 0;
- fci->frame = addr;
- fci->next_frame = 0; /* Since arbitrary */
- fci->pc = pc;
-
-#ifdef INIT_EXTRA_FRAME_INFO
- INIT_EXTRA_FRAME_INFO (fci);
-#endif
-
- return fci;
-}
-
-/* Return the frame that called FRAME.
- If FRAME is the original frame (it has no caller), return 0. */
-
-FRAME
-get_prev_frame (frame)
- FRAME frame;
-{
- /* We're allowed to know that FRAME and "struct frame_info *" are
- the same */
- return get_prev_frame_info (frame);
-}
-
-/*
- * Flush the entire frame cache.
- */
-void
-flush_cached_frames ()
-{
- /* Since we can't really be sure what the first object allocated was */
- obstack_free (&frame_cache_obstack, 0);
- obstack_init (&frame_cache_obstack);
-
- current_frame = (struct frame_info *) 0; /* Invalidate cache */
-}
-
-/* Return a structure containing various interesting information
- about a specified stack frame. */
-/* How do I justify including this function? Well, the FRAME
- identifier format has gone through several changes recently, and
- it's not completely inconceivable that it could happen again. If
- it does, have this routine around will help */
-
-struct frame_info *
-get_frame_info (frame)
- FRAME frame;
-{
- return frame;
-}
-
-/* Return a structure containing various interesting information
- about the frame that called NEXT_FRAME. */
-
-struct frame_info *
-get_prev_frame_info (next_frame)
- FRAME next_frame;
-{
- FRAME_ADDR address;
- struct frame_info *prev;
- int fromleaf = 0;
-
- /* If we are within "start" right now, don't go any higher. */
- /* This truncates stack traces of things at sigtramp() though,
- because sigtramp() doesn't have a normal return PC, it has
- garbage or a small value (seen: 3) in the return PC slot.
- It's VITAL to see where the signal occurred, so punt this. */
-#if 0
- if (next_frame && next_frame->pc < first_object_file_end)
- return 0;
-#endif
-
- /* If the requested entry is in the cache, return it.
- Otherwise, figure out what the address should be for the entry
- we're about to add to the cache. */
-
- if (!next_frame)
- {
- if (!current_frame)
- error ("No frame is currently selected.");
-
- return current_frame;
- }
- else
- {
- /* If we have the prev one, return it */
- if (next_frame->prev)
- return next_frame->prev;
-
- /* There is a questionable, but probably always correct
- assumption being made here. The assumption is that if
- functions on a specific machine has a FUNCTION_START_OFFSET,
- then this is used by the function call instruction for some
- purpose. If the function call instruction has this much hair
- in it, it probably also sets up the frame pointer
- automatically (ie. we'll never have what I am calling a
- "leaf node", one which shares a frame pointer with it's
- calling function). This is true on a vax. The only other
- way to find this out would be to setup a seperate macro
- "FUNCTION_HAS_FRAME_POINTER", which would often be equivalent
- to SKIP_PROLOGUE modifying a pc value. */
-
-#if FUNCTION_START_OFFSET == 0
- if (!(next_frame->next))
- {
- /* Innermost */
- CORE_ADDR func_start, after_prologue;
-
- func_start = (get_pc_function_start (next_frame->pc) +
- FUNCTION_START_OFFSET);
- after_prologue = func_start;
- SKIP_PROLOGUE (after_prologue);
- if (after_prologue == func_start)
- {
- fromleaf = 1;
- address = next_frame->frame;
- }
- }
-#endif
-
- if (!fromleaf)
- {
- /* Two macros defined in param.h specify the machine-dependent
- actions to be performed here. */
- /* First, get the frame's chain-pointer.
- If that is zero, the frame is the outermost frame. */
- address = FRAME_CHAIN (next_frame);
- if (!FRAME_CHAIN_VALID (address, next_frame))
- return 0;
-
- /* If frame has a caller, combine the chain pointer and
- the frame's own address to get the address of the caller. */
- address = FRAME_CHAIN_COMBINE (address, next_frame);
- }
- }
-
- prev = (struct frame_info *)
- obstack_alloc (&frame_cache_obstack,
- sizeof (struct frame_info));
-
- if (next_frame)
- next_frame->prev = prev;
- prev->next = next_frame;
- prev->prev = (struct frame_info *) 0;
- prev->frame = address;
- prev->next_frame = prev->next ? prev->next->frame : 0;
-
-#ifdef INIT_EXTRA_FRAME_INFO
- INIT_EXTRA_FRAME_INFO(prev);
-#endif
-
- /* This entry is in the frame queue now, which is good since
- FRAME_SAVED_PC may use that queue to figure out it's value
- (see m-sparc.h). We want the pc saved in the inferior frame. */
- prev->pc = (fromleaf ? SAVED_PC_AFTER_CALL (next_frame) :
- next_frame ? FRAME_SAVED_PC (next_frame) : read_pc ());
-
- return prev;
-}
-
-CORE_ADDR
-get_frame_pc (frame)
- FRAME frame;
-{
- struct frame_info *fi;
- fi = get_frame_info (frame);
- return fi->pc;
-}
-
-/* Find the addresses in which registers are saved in FRAME. */
-
-void
-get_frame_saved_regs (frame_info_addr, saved_regs_addr)
- struct frame_info *frame_info_addr;
- struct frame_saved_regs *saved_regs_addr;
-{
-#if 1
- FRAME_FIND_SAVED_REGS (frame_info_addr, *saved_regs_addr);
-#else
- {
- register int regnum;
- register int regmask;
- register CORE_ADDR next_addr;
- register CORE_ADDR pc;
- int nextinsn;
- bzero (&*saved_regs_addr, sizeof *saved_regs_addr);
- if ((frame_info_addr)->pc >= ((frame_info_addr)->frame
- - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4)
- && (frame_info_addr)->pc <= (frame_info_addr)->frame)
- {
- next_addr = (frame_info_addr)->frame;
- pc = (frame_info_addr)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4;
- }
- else
- {
- pc = get_pc_function_start ((frame_info_addr)->pc);
- /* Verify we have a link a6 instruction next;
- if not we lose. If we win, find the address above the saved
- regs using the amount of storage from the link instruction. */
- if (044016 == read_memory_integer (pc, 2))
- {
- next_addr = (frame_info_addr)->frame + read_memory_integer (pc += 2, 4);
- pc += 4;
- }
- else if (047126 == read_memory_integer (pc, 2))
- {
- next_addr = (frame_info_addr)->frame + read_memory_integer (pc += 2, 2);
- pc+=2;
- }
- else goto lose;
-
- /* If have an addal #-n, sp next, adjust next_addr. */
- if ((0177777 & read_memory_integer (pc, 2)) == 0157774)
- {
- next_addr += read_memory_integer (pc += 2, 4);
- pc += 4;
- }
- }
- /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */
- regmask = read_memory_integer (pc + 2, 2);
-
- /* But before that can come an fmovem. Check for it. */
- nextinsn = 0xffff & read_memory_integer (pc, 2);
- if (0xf227 == nextinsn
- && (regmask & 0xff00) == 0xe000)
- {
- pc += 4; /* Regmask's low bit is for register fp7, the first pushed */
- for (regnum = FP0_REGNUM + 7;
- regnum >= FP0_REGNUM;
- regnum--, regmask >>= 1)
- if (regmask & 1)
- (*saved_regs_addr).regs[regnum] = (next_addr -= 12);
- regmask = read_memory_integer (pc + 2, 2);
- }
- if (0044327 == read_memory_integer (pc, 2))
- {
- pc += 4; /* Regmask's low bit is for register 0, the first written */
- for (regnum = 0; regnum < 16; regnum++, regmask >>= 1)
- if (regmask & 1)
- (*saved_regs_addr).regs[regnum] = (next_addr += 4) - 4;
- }
- else if (0044347 == read_memory_integer (pc, 2))
- { pc += 4; /* Regmask's low bit is for register 15, the first pushed */
- for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1)
- if (regmask & 1)
- (*saved_regs_addr).regs[regnum] = (next_addr -= 4); }
- else if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2)))
- { regnum = 0xf & read_memory_integer (pc, 2); pc += 2;
- (*saved_regs_addr).regs[regnum] = (next_addr -= 4); }
- /* fmovemx to index of sp may follow. */
- regmask = read_memory_integer (pc + 2, 2);
- nextinsn = 0xffff & read_memory_integer (pc, 2);
- if (0xf236 == nextinsn
- && (regmask & 0xff00) == 0xf000)
- {
- pc += 10; /* Regmask's low bit is for register fp0, the first written */
- for (regnum = FP0_REGNUM + 7;
- regnum >= FP0_REGNUM;
- regnum--, regmask >>= 1)
- if (regmask & 1)
- (*saved_regs_addr).regs[regnum] = (next_addr += 12) - 12;
- regmask = read_memory_integer (pc + 2, 2);
- }
- /* clrw -(sp); movw ccr,-(sp) may follow. */
- if (0x426742e7 == read_memory_integer (pc, 4))
- (*saved_regs_addr).regs[PS_REGNUM] = (next_addr -= 4);
- lose: ;
- (*saved_regs_addr).regs[SP_REGNUM] = (frame_info_addr)->frame + 8;
- (*saved_regs_addr).regs[FP_REGNUM] = (frame_info_addr)->frame;
- (*saved_regs_addr).regs[PC_REGNUM] = (frame_info_addr)->frame + 4;
- }
-#endif
-}
-
-/* Return the innermost lexical block in execution
- in a specified stack frame. The frame address is assumed valid. */
-
-struct block *
-get_frame_block (frame)
- FRAME frame;
-{
- struct frame_info *fi;
-
- fi = get_frame_info (frame);
- return block_for_pc (fi->pc);
-}
-
-struct block *
-get_current_block ()
-{
- return block_for_pc (read_pc ());
-}
-
-CORE_ADDR
-get_pc_function_start (pc)
- CORE_ADDR pc;
-{
- register struct block *bl = block_for_pc (pc);
- register struct symbol *symbol;
- if (bl == 0 || (symbol = block_function (bl)) == 0)
- {
- register int misc_index = find_pc_misc_function (pc);
- if (misc_index >= 0)
- return misc_function_vector[misc_index].address;
- return 0;
- }
- bl = SYMBOL_BLOCK_VALUE (symbol);
- return BLOCK_START (bl);
-}
-
-/* Return the symbol for the function executing in frame FRAME. */
-
-struct symbol *
-get_frame_function (frame)
- FRAME frame;
-{
- register struct block *bl = get_frame_block (frame);
- if (bl == 0)
- return 0;
- return block_function (bl);
-}
-
-/* Return the innermost lexical block containing the specified pc value,
- or 0 if there is none. */
-
-extern struct symtab *psymtab_to_symtab ();
-
-struct block *
-block_for_pc (pc)
- register CORE_ADDR pc;
-{
- register struct block *b;
- register int bot, top, half;
- register struct symtab *s;
- register struct partial_symtab *ps;
- struct blockvector *bl;
-
- /* First search all symtabs for one whose file contains our pc */
-
- for (s = symtab_list; s; s = s->next)
- {
- bl = BLOCKVECTOR (s);
- b = BLOCKVECTOR_BLOCK (bl, 0);
- if (BLOCK_START (b) <= pc
- && BLOCK_END (b) > pc)
- break;
- }
-
- if (s == 0)
- for (ps = partial_symtab_list; ps; ps = ps->next)
- {
- if (ps->textlow <= pc
- && ps->texthigh > pc)
- {
- s = psymtab_to_symtab (ps);
- bl = BLOCKVECTOR (s);
- b = BLOCKVECTOR_BLOCK (bl, 0);
- break;
- }
- }
-
- if (s == 0)
- return 0;
-
- /* Then search that symtab for the smallest block that wins. */
- /* Use binary search to find the last block that starts before PC. */
-
- bot = 0;
- top = BLOCKVECTOR_NBLOCKS (bl);
-
- while (top - bot > 1)
- {
- half = (top - bot + 1) >> 1;
- b = BLOCKVECTOR_BLOCK (bl, bot + half);
- if (BLOCK_START (b) <= pc)
- bot += half;
- else
- top = bot + half;
- }
-
- /* Now search backward for a block that ends after PC. */
-
- while (bot >= 0)
- {
- b = BLOCKVECTOR_BLOCK (bl, bot);
- if (BLOCK_END (b) > pc)
- return b;
- bot--;
- }
-
- return 0;
-}
-
-/* Return the function containing pc value PC.
- Returns 0 if function is not known. */
-
-struct symbol *
-find_pc_function (pc)
- CORE_ADDR pc;
-{
- register struct block *b = block_for_pc (pc);
- if (b == 0)
- return 0;
- return block_function (b);
-}
-
-/* Find the misc function whose address is the largest
- while being less than PC. Return its index in misc_function_vector.
- Returns -1 if PC is not in suitable range. */
-
-int
-find_pc_misc_function (pc)
- register CORE_ADDR pc;
-{
- register int lo = 0;
- register int hi = misc_function_count-1;
- register int new;
- register int distance;
-
- /* Note that the last thing in the vector is always _etext. */
-
- /* Above statement is not *always* true - fix for case where there are */
- /* no misc functions at all (ie no symbol table has been read). */
- if (hi < 0) return -1; /* no misc functions recorded */
-
- /* trivial reject range test */
- if (pc < misc_function_vector[0].address ||
- pc > misc_function_vector[hi].address)
- return -1;
-
- do {
- new = (lo + hi) >> 1;
- distance = misc_function_vector[new].address - pc;
- if (distance == 0)
- return new; /* an exact match */
- else if (distance > 0)
- hi = new;
- else
- lo = new;
- } while (hi-lo != 1);
-
- /* if here, we had no exact match, so return the lower choice */
- return lo;
-}
-
-/* Return the innermost stack frame executing inside of the specified block,
- or zero if there is no such frame. */
-
-FRAME
-block_innermost_frame (block)
- struct block *block;
-{
- struct frame_info *fi;
- register FRAME frame;
- register CORE_ADDR start = BLOCK_START (block);
- register CORE_ADDR end = BLOCK_END (block);
-
- frame = 0;
- while (1)
- {
- frame = get_prev_frame (frame);
- if (frame == 0)
- return 0;
- fi = get_frame_info (frame);
- if (fi->pc >= start && fi->pc < end)
- return frame;
- }
-}
-
-void
-_initialize_blockframe ()
-{
- obstack_init (&frame_cache_obstack);
-}
-@
-
-
-1.2
-log
-@Avoid fatal error for simple user error
-@
-text
-@d142 5
-d149 1
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d152 1
-a152 1
- fatal ("get_prev_frame_info: Called before cache primed");
-@
diff --git a/gdb/RCS/coffread.c,v b/gdb/RCS/coffread.c,v
deleted file mode 100644
index 9c45395..0000000
--- a/gdb/RCS/coffread.c,v
+++ /dev/null
@@ -1,2047 +0,0 @@
-head 1.5;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.5
-date 89.03.27.18.38.25; author gnu; state Exp;
-branches ;
-next 1.4;
-
-1.4
-date 89.03.27.18.37.20; author gnu; state Exp;
-branches ;
-next 1.3;
-
-1.3
-date 89.03.27.18.36.15; author gnu; state Exp;
-branches ;
-next 1.2;
-
-1.2
-date 89.02.10.01.38.05; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.02.10.01.32.45; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.5
-log
-@Remake A/UX changes.
-@
-text
-@/* Read coff symbol tables and convert to internal format, for GDB.
- Design and support routines derived from dbxread.c, and UMAX COFF
- specific routines written 9/1/87 by David D. Johnson, Brown University.
- Revised 11/27/87 ddj@@cs.brown.edu
- Copyright (C) 1987, 1988, 1989 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#include "defs.h"
-#include "param.h"
-#ifdef COFF_FORMAT
-#include "symtab.h"
-
-#ifdef USG
-#include <sys/types.h>
-#include <fcntl.h>
-#endif
-
-#include <a.out.h>
-#include <stdio.h>
-#include <obstack.h>
-#include <sys/param.h>
-#include <sys/file.h>
-
-/* Avoid problems with A/UX predefine */
-#undef aux
-
-static void add_symbol_to_list ();
-static void read_coff_symtab ();
-static void patch_opaque_types ();
-static struct type *decode_function_type ();
-static struct type *decode_type ();
-static struct type *decode_base_type ();
-static struct type *read_enum_type ();
-static struct type *read_struct_type ();
-static void finish_block ();
-static struct blockvector *make_blockvector ();
-static struct symbol *process_coff_symbol ();
-static int init_stringtab ();
-static void free_stringtab ();
-static char *getfilename ();
-static char *getsymname ();
-static int init_lineno ();
-static void enter_linenos ();
-
-extern void free_all_symtabs ();
-extern void free_all_psymtabs ();
-
-
-/* Name of source file whose symbol data we are now processing.
- This comes from a symbol named ".file". */
-
-static char *last_source_file;
-
-/* Core address of start and end of text of current source file.
- This comes from a ".text" symbol where x_nlinno > 0. */
-
-static CORE_ADDR cur_src_start_addr;
-static CORE_ADDR cur_src_end_addr;
-
-/* End of the text segment of the executable file,
- as found in the symbol _etext. */
-
-static CORE_ADDR end_of_text_addr;
-
-/* The addresses of the symbol table stream and number of symbols
- of the object file we are reading (as copied into core). */
-
-static FILE *nlist_stream_global;
-static int nlist_nsyms_global;
-
-/* The file and text section headers of the symbol file */
-
-static FILHDR file_hdr;
-static SCNHDR text_hdr;
-
-/* The index in the symbol table of the last coff symbol that was processed. */
-
-static int symnum;
-
-/* Vector of types defined so far, indexed by their coff symnum. */
-
-static struct typevector *type_vector;
-
-/* Number of elements allocated for type_vector currently. */
-
-static int type_vector_length;
-
-/* Vector of line number information. */
-
-static struct linetable *line_vector;
-
-/* Index of next entry to go in line_vector_index. */
-
-static int line_vector_index;
-
-/* Last line number recorded in the line vector. */
-
-static int prev_line_number;
-
-/* Number of elements allocated for line_vector currently. */
-
-static int line_vector_length;
-
-/* Chain of typedefs of pointers to empty struct/union types.
- They are chained thru the SYMBOL_VALUE. */
-
-#define HASHSIZE 127
-static struct symbol *opaque_type_chain[HASHSIZE];
-
-/* Record the symbols defined for each context in a list.
- We don't create a struct block for the context until we
- know how long to make it. */
-
-struct pending
-{
- struct pending *next;
- struct symbol *symbol;
-};
-
-/* Here are the three lists that symbols are put on. */
-
-struct pending *file_symbols; /* static at top level, and types */
-
-struct pending *global_symbols; /* global functions and variables */
-
-struct pending *local_symbols; /* everything local to lexical context */
-
-/* List of unclosed lexical contexts
- (that will become blocks, eventually). */
-
-struct context_stack
-{
- struct context_stack *next;
- struct pending *locals;
- struct pending_block *old_blocks;
- struct symbol *name;
- CORE_ADDR start_addr;
- int depth;
-};
-
-struct context_stack *context_stack;
-
-/* Nonzero if within a function (so symbols should be local,
- if nothing says specifically). */
-
-int within_function;
-
-/* List of blocks already made (lexical contexts already closed).
- This is used at the end to make the blockvector. */
-
-struct pending_block
-{
- struct pending_block *next;
- struct block *block;
-};
-
-struct pending_block *pending_blocks;
-
-extern CORE_ADDR first_object_file_end; /* From blockframe.c */
-
-/* File name symbols were loaded from. */
-
-static char *symfile;
-
-/* Look up a coff type-number index. Return the address of the slot
- where the type for that index is stored.
- The type-number is in INDEX.
-
- This can be used for finding the type associated with that index
- or for associating a new type with the index. */
-
-static struct type **
-coff_lookup_type (index)
- register int index;
-{
- if (index >= type_vector_length)
- {
- int old_vector_length = type_vector_length;
-
- type_vector_length *= 2;
- if (type_vector_length < index) {
- type_vector_length = index * 2;
- }
- type_vector = (struct typevector *)
- xrealloc (type_vector, sizeof (struct typevector)
- + type_vector_length * sizeof (struct type *));
- bzero (&type_vector->type[ old_vector_length ],
- (type_vector_length - old_vector_length) * sizeof(struct type *));
- }
- return &type_vector->type[index];
-}
-
-/* Make sure there is a type allocated for type number index
- and return the type object.
- This can create an empty (zeroed) type object. */
-
-static struct type *
-coff_alloc_type (index)
- int index;
-{
- register struct type **type_addr = coff_lookup_type (index);
- register struct type *type = *type_addr;
-
- /* If we are referring to a type not known at all yet,
- allocate an empty type for it.
- We will fill it in later if we find out how. */
- if (type == 0)
- {
- type = (struct type *) obstack_alloc (symbol_obstack,
- sizeof (struct type));
- bzero (type, sizeof (struct type));
- *type_addr = type;
- }
- return type;
-}
-
-/* maintain the lists of symbols and blocks */
-
-/* Add a symbol to one of the lists of symbols. */
-static void
-add_symbol_to_list (symbol, listhead)
- struct symbol *symbol;
- struct pending **listhead;
-{
- register struct pending *link
- = (struct pending *) xmalloc (sizeof (struct pending));
-
- link->next = *listhead;
- link->symbol = symbol;
- *listhead = link;
-}
-
-/* Take one of the lists of symbols and make a block from it.
- Put the block on the list of pending blocks. */
-
-static void
-finish_block (symbol, listhead, old_blocks, start, end)
- struct symbol *symbol;
- struct pending **listhead;
- struct pending_block *old_blocks;
- CORE_ADDR start, end;
-{
- register struct pending *next, *next1;
- register struct block *block;
- register struct pending_block *pblock;
- struct pending_block *opblock;
- register int i;
-
- /* Count the length of the list of symbols. */
-
- for (next = *listhead, i = 0; next; next = next->next, i++);
-
- block = (struct block *)
- obstack_alloc (symbol_obstack, sizeof (struct block) + (i - 1) * sizeof (struct symbol *));
-
- /* Copy the symbols into the block. */
-
- BLOCK_NSYMS (block) = i;
- for (next = *listhead; next; next = next->next)
- BLOCK_SYM (block, --i) = next->symbol;
-
- BLOCK_START (block) = start;
- BLOCK_END (block) = end;
- BLOCK_SUPERBLOCK (block) = 0; /* Filled in when containing block is made */
-
- /* Put the block in as the value of the symbol that names it. */
-
- if (symbol)
- {
- SYMBOL_BLOCK_VALUE (symbol) = block;
- BLOCK_FUNCTION (block) = symbol;
- }
- else
- BLOCK_FUNCTION (block) = 0;
-
- /* Now free the links of the list, and empty the list. */
-
- for (next = *listhead; next; next = next1)
- {
- next1 = next->next;
- free (next);
- }
- *listhead = 0;
-
- /* Install this block as the superblock
- of all blocks made since the start of this scope
- that don't have superblocks yet. */
-
- opblock = 0;
- for (pblock = pending_blocks; pblock != old_blocks; pblock = pblock->next)
- {
- if (BLOCK_SUPERBLOCK (pblock->block) == 0)
- BLOCK_SUPERBLOCK (pblock->block) = block;
- opblock = pblock;
- }
-
- /* Record this block on the list of all blocks in the file.
- Put it after opblock, or at the beginning if opblock is 0.
- This puts the block in the list after all its subblocks. */
-
- pblock = (struct pending_block *) xmalloc (sizeof (struct pending_block));
- pblock->block = block;
- if (opblock)
- {
- pblock->next = opblock->next;
- opblock->next = pblock;
- }
- else
- {
- pblock->next = pending_blocks;
- pending_blocks = pblock;
- }
-}
-
-static struct blockvector *
-make_blockvector ()
-{
- register struct pending_block *next, *next1;
- register struct blockvector *blockvector;
- register int i;
-
- /* Count the length of the list of blocks. */
-
- for (next = pending_blocks, i = 0; next; next = next->next, i++);
-
- blockvector = (struct blockvector *)
- obstack_alloc (symbol_obstack, sizeof (struct blockvector) + (i - 1) * sizeof (struct block *));
-
- /* Copy the blocks into the blockvector.
- This is done in reverse order, which happens to put
- the blocks into the proper order (ascending starting address).
- finish_block has hair to insert each block into the list
- after its subblocks in order to make sure this is true. */
-
- BLOCKVECTOR_NBLOCKS (blockvector) = i;
- for (next = pending_blocks; next; next = next->next)
- BLOCKVECTOR_BLOCK (blockvector, --i) = next->block;
-
- /* Now free the links of the list, and empty the list. */
-
- for (next = pending_blocks; next; next = next1)
- {
- next1 = next->next;
- free (next);
- }
- pending_blocks = 0;
-
- return blockvector;
-}
-
-/* Manage the vector of line numbers. */
-
-static
-record_line (line, pc)
- int line;
- CORE_ADDR pc;
-{
- struct linetable_entry *e;
- /* Make sure line vector is big enough. */
-
- if (line_vector_index + 2 >= line_vector_length)
- {
- line_vector_length *= 2;
- line_vector = (struct linetable *)
- xrealloc (line_vector, sizeof (struct linetable)
- + (line_vector_length
- * sizeof (struct linetable_entry)));
- }
-
- e = line_vector->item + line_vector_index++;
- e->line = line; e->pc = pc;
-}
-
-/* Start a new symtab for a new source file.
- This is called when a COFF ".file" symbol is seen;
- it indicates the start of data for one original source file. */
-
-static void
-start_symtab ()
-{
- file_symbols = 0;
- global_symbols = 0;
- context_stack = 0;
- within_function = 0;
- last_source_file = 0;
-
- /* Initialize the source file information for this file. */
-
- line_vector_index = 0;
- line_vector_length = 1000;
- prev_line_number = -2; /* Force first line number to be explicit */
- line_vector = (struct linetable *)
- xmalloc (sizeof (struct linetable)
- + line_vector_length * sizeof (struct linetable_entry));
-}
-
-/* Save the vital information for use when closing off the current file.
- NAME is the file name the symbols came from, START_ADDR is the first
- text address for the file, and SIZE is the number of bytes of text. */
-
-static void
-complete_symtab (name, start_addr, size)
- char *name;
- CORE_ADDR start_addr;
- unsigned int size;
-{
- last_source_file = savestring (name, strlen (name));
- cur_src_start_addr = start_addr;
- cur_src_end_addr = start_addr + size;
-}
-
-/* Finish the symbol definitions for one main source file,
- close off all the lexical contexts for that file
- (creating struct block's for them), then make the
- struct symtab for that file and put it in the list of all such. */
-
-static void
-end_symtab ()
-{
- register struct symtab *symtab;
- register struct context_stack *cstk;
- register struct blockvector *blockvector;
- register struct linetable *lv;
-
- /* Finish the lexical context of the last function in the file. */
-
- if (context_stack)
- {
- cstk = context_stack;
- context_stack = 0;
- /* Make a block for the local symbols within. */
- finish_block (cstk->name, &local_symbols, cstk->old_blocks,
- cstk->start_addr, cur_src_end_addr);
- free (cstk);
- }
-
- /* Ignore a file that has no functions with real debugging info. */
- if (pending_blocks == 0 && file_symbols == 0 && global_symbols == 0)
- {
- free (line_vector);
- line_vector = 0;
- line_vector_length = -1;
- last_source_file = 0;
- return;
- }
-
- /* Create the two top-level blocks for this file. */
- finish_block (0, &file_symbols, 0, cur_src_start_addr, cur_src_end_addr);
- finish_block (0, &global_symbols, 0, cur_src_start_addr, cur_src_end_addr);
-
- /* Create the blockvector that points to all the file's blocks. */
- blockvector = make_blockvector ();
-
- /* Now create the symtab object for this source file. */
- symtab = (struct symtab *) xmalloc (sizeof (struct symtab));
- symtab->free_ptr = 0;
-
- /* Fill in its components. */
- symtab->blockvector = blockvector;
- symtab->free_code = free_linetable;
- symtab->filename = last_source_file;
- lv = line_vector;
- lv->nitems = line_vector_index;
- symtab->linetable = (struct linetable *)
- xrealloc (lv, (sizeof (struct linetable)
- + lv->nitems * sizeof (struct linetable_entry)));
- symtab->nlines = 0;
- symtab->line_charpos = 0;
-
- /* Link the new symtab into the list of such. */
- symtab->next = symtab_list;
- symtab_list = symtab;
-
- /* Reinitialize for beginning of new file. */
- line_vector = 0;
- line_vector_length = -1;
- last_source_file = 0;
-}
-
-/* Accumulate the misc functions in bunches of 127.
- At the end, copy them all into one newly allocated structure. */
-
-#define MISC_BUNCH_SIZE 127
-
-struct misc_bunch
-{
- struct misc_bunch *next;
- struct misc_function contents[MISC_BUNCH_SIZE];
-};
-
-/* Bunch currently being filled up.
- The next field points to chain of filled bunches. */
-
-static struct misc_bunch *misc_bunch;
-
-/* Number of slots filled in current bunch. */
-
-static int misc_bunch_index;
-
-/* Total number of misc functions recorded so far. */
-
-static int misc_count;
-
-static void
-init_misc_functions ()
-{
- misc_count = 0;
- misc_bunch = 0;
- misc_bunch_index = MISC_BUNCH_SIZE;
-}
-
-static void
-record_misc_function (name, address)
- char *name;
- CORE_ADDR address;
-{
- register struct misc_bunch *new;
-
- if (misc_bunch_index == MISC_BUNCH_SIZE)
- {
- new = (struct misc_bunch *) xmalloc (sizeof (struct misc_bunch));
- misc_bunch_index = 0;
- new->next = misc_bunch;
- misc_bunch = new;
- }
- misc_bunch->contents[misc_bunch_index].name = savestring (name, strlen (name));
- misc_bunch->contents[misc_bunch_index].address = address;
- misc_bunch_index++;
- misc_count++;
-}
-
-/* if we see a function symbol, we do record_misc_function.
- * however, if it turns out the next symbol is '.bf', then
- * we call here to undo the misc definition
- */
-static void
-unrecord_misc_function ()
-{
- if (misc_bunch_index == 0)
- error ("Internal error processing symbol table, at symbol %d.",
- symnum);
- misc_bunch_index--;
- misc_count--;
-}
-
-
-static int
-compare_misc_functions (fn1, fn2)
- struct misc_function *fn1, *fn2;
-{
- /* Return a signed result based on unsigned comparisons
- so that we sort into unsigned numeric order. */
- if (fn1->address < fn2->address)
- return -1;
- if (fn1->address > fn2->address)
- return 1;
- return 0;
-}
-
-static void
-discard_misc_bunches ()
-{
- register struct misc_bunch *next;
-
- while (misc_bunch)
- {
- next = misc_bunch->next;
- free (misc_bunch);
- misc_bunch = next;
- }
-}
-
-static void
-condense_misc_bunches ()
-{
- register int i, j;
- register struct misc_bunch *bunch;
-#ifdef NAMES_HAVE_UNDERSCORE
- int offset = 1;
-#else
- int offset = 0;
-#endif
-
- misc_function_vector
- = (struct misc_function *)
- xmalloc (misc_count * sizeof (struct misc_function));
-
- j = 0;
- bunch = misc_bunch;
- while (bunch)
- {
- for (i = 0; i < misc_bunch_index; i++)
- {
- register char *tmp;
-
- misc_function_vector[j] = bunch->contents[i];
- tmp = misc_function_vector[j].name;
- misc_function_vector[j].name = (tmp[0] == '_' ? tmp + offset : tmp);
- j++;
- }
- bunch = bunch->next;
- misc_bunch_index = MISC_BUNCH_SIZE;
- }
-
- misc_function_count = j;
-
- /* Sort the misc functions by address. */
-
- qsort (misc_function_vector, j, sizeof (struct misc_function),
- compare_misc_functions);
-}
-
-/* Call sort_syms to sort alphabetically
- the symbols of each block of each symtab. */
-
-static int
-compare_symbols (s1, s2)
- struct symbol **s1, **s2;
-{
- /* Names that are less should come first. */
- register int namediff = strcmp (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2));
- if (namediff != 0) return namediff;
- /* For symbols of the same name, registers should come first. */
- return ((SYMBOL_CLASS (*s2) == LOC_REGISTER)
- - (SYMBOL_CLASS (*s1) == LOC_REGISTER));
-}
-
-static void
-sort_syms ()
-{
- register struct symtab *s;
- register int i, nbl;
- register struct blockvector *bv;
- register struct block *b;
-
- for (s = symtab_list; s; s = s->next)
- {
- bv = BLOCKVECTOR (s);
- nbl = BLOCKVECTOR_NBLOCKS (bv);
- for (i = 0; i < nbl; i++)
- {
- b = BLOCKVECTOR_BLOCK (bv, i);
- if (BLOCK_SHOULD_SORT (b))
- qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b),
- sizeof (struct symbol *), compare_symbols);
- }
- }
-}
-
-/* This is the symbol-file command. Read the file, analyze its symbols,
- and add a struct symtab to symtab_list. */
-
-void
-symbol_file_command (name)
- char *name;
-{
- int desc;
- int num_symbols;
- int num_sections;
- int symtab_offset;
- extern void close ();
- register int val;
- struct cleanup *old_chain;
-
- dont_repeat ();
-
- if (name == 0)
- {
- if (symtab_list && !query ("Discard symbol table? ", 0))
- error ("Not confirmed.");
- if (symfile)
- free (symfile);
- symfile = 0;
- free_all_symtabs ();
- return;
- }
-
- if (symtab_list && !query ("Load new symbol table from \"%s\"? ", name))
- error ("Not confirmed.");
-
- if (symfile)
- free (symfile);
- symfile = 0;
-
- {
- char *absolute_name;
-
- desc = openp (getenv ("PATH"), 1, name, O_RDONLY, 0, &absolute_name);
- if (desc < 0)
- perror_with_name (name);
- else
- name = absolute_name;
- }
-
- old_chain = make_cleanup (close, desc);
- make_cleanup (free_current_contents, &name);
-
- if ((num_symbols = read_file_hdr (desc, &file_hdr)) < 0)
- error ("File \"%s\" not in executable format.", name);
-
- if (num_symbols == 0)
- {
- free_all_symtabs ();
- printf ("%s does not have a symbol-table.\n", name);
- fflush (stdout);
- return;
- }
-
- printf ("Reading symbol data from %s...", name);
- fflush (stdout);
-
- /* Throw away the old symbol table. */
-
- free_all_symtabs ();
- free_all_psymtabs (); /* Make sure that partial_symtab_list */
- /* is 0 also. */
-
- num_sections = file_hdr.f_nscns;
- symtab_offset = file_hdr.f_symptr;
-
- if (read_section_hdr (desc, _TEXT, &text_hdr, num_sections) < 0)
- error ("\"%s\": can't read text section header", name);
-
- /* Read the line number table, all at once. */
-
- val = init_lineno (desc, text_hdr.s_lnnoptr, text_hdr.s_nlnno);
- if (val < 0)
- error ("\"%s\": error reading line numbers\n", name);
-
- /* Now read the string table, all at once. */
-
- val = init_stringtab (desc, symtab_offset + num_symbols * SYMESZ);
- if (val < 0)
- {
- free_all_symtabs ();
- printf ("\"%s\": can't get string table", name);
- fflush (stdout);
- return;
- }
- make_cleanup (free_stringtab, 0);
-
- /* Position to read the symbol table. Do not read it all at once. */
- val = lseek (desc, (long)symtab_offset, 0);
- if (val < 0)
- perror_with_name (name);
-
- init_misc_functions ();
- make_cleanup (discard_misc_bunches, 0);
-
- /* Now that the executable file is positioned at symbol table,
- process it and define symbols accordingly. */
-
- read_coff_symtab (desc, num_symbols);
-
- patch_opaque_types ();
-
- /* Sort symbols alphabetically within each block. */
-
- sort_syms ();
-
- /* Go over the misc functions and install them in vector. */
-
- condense_misc_bunches ();
-
- /* Don't allow char * to have a typename (else would get caddr_t.) */
-
- TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0;
-
- /* Make a default for file to list. */
-
- select_source_symtab (symtab_list);
-
- symfile = savestring (name, strlen (name));
-
- do_cleanups (old_chain);
-
- printf ("done.\n");
- fflush (stdout);
-}
-
-/* Return name of file symbols were loaded from, or 0 if none.. */
-
-char *
-get_sym_file ()
-{
- return symfile;
-}
-
-/* Simplified internal version of coff symbol table information */
-
-struct coff_symbol {
- char *c_name;
- int c_symnum; /* symbol number of this entry */
- int c_nsyms; /* 1 if syment only, 2 if syment + auxent */
- long c_value;
- int c_sclass;
- int c_secnum;
- unsigned int c_type;
-};
-
-/* Given pointers to a symbol table in coff style exec file,
- analyze them and create struct symtab's describing the symbols.
- NSYMS is the number of symbols in the symbol table.
- We read them one at a time using read_one_sym (). */
-
-static void
-read_coff_symtab (desc, nsyms)
- int desc;
- int nsyms;
-{
- int newfd; /* Avoid multiple closes on same desc */
- FILE *stream;
- register struct context_stack *new;
- struct coff_symbol coff_symbol;
- register struct coff_symbol *cs = &coff_symbol;
- static SYMENT main_sym;
- static AUXENT main_aux;
- struct coff_symbol fcn_cs_saved;
- static SYMENT fcn_sym_saved;
- static AUXENT fcn_aux_saved;
-
- int num_object_files = 0;
- int next_file_symnum = -1;
- char *filestring;
- int depth;
- int fcn_first_line;
- int fcn_last_line;
- int fcn_start_addr;
- long fcn_line_ptr;
- struct cleanup *old_chain;
- int fclose();
-
- newfd = dup (desc);
- if (newfd == -1)
- fatal ("Too many open files");
- stream = fdopen (newfd, "r");
-
- old_chain = make_cleanup (free_all_symtabs, 0);
- make_cleanup (fclose, stream);
- nlist_stream_global = stream;
- nlist_nsyms_global = nsyms;
- last_source_file = 0;
- bzero (opaque_type_chain, sizeof opaque_type_chain);
-
- type_vector_length = 160;
- type_vector = (struct typevector *)
- xmalloc (sizeof (struct typevector)
- + type_vector_length * sizeof (struct type *));
- bzero (type_vector->type, type_vector_length * sizeof (struct type *));
-
- start_symtab ();
-
- symnum = 0;
- while (symnum < nsyms)
- {
- QUIT; /* Make this command interruptable. */
- read_one_sym (cs, &main_sym, &main_aux);
-
- if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)
- {
- CORE_ADDR last_file_end = cur_src_end_addr;
-
- if (last_source_file)
- end_symtab ();
-
- start_symtab ();
- complete_symtab ("_globals_", 0, first_object_file_end);
- /* done with all files, everything from here on out is globals */
- }
-
- /* Special case for file with type declarations only, no text. */
- if (!last_source_file && cs->c_type != T_NULL && cs->c_secnum == N_DEBUG)
- complete_symtab (filestring, 0, 0);
-
- /* Typedefs should not be treated as symbol definitions. */
- if (ISFCN (cs->c_type) && cs->c_sclass != C_TPDEF)
- {
- /* record as misc function. if we get '.bf' next,
- * then we undo this step
- */
- record_misc_function (cs->c_name, cs->c_value);
-
- fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
- fcn_start_addr = cs->c_value;
- fcn_cs_saved = *cs;
- fcn_sym_saved = main_sym;
- fcn_aux_saved = main_aux;
- continue;
- }
-
- switch (cs->c_sclass)
- {
- case C_EFCN:
- case C_EXTDEF:
- case C_ULABEL:
- case C_USTATIC:
- case C_LINE:
- case C_ALIAS:
- case C_HIDDEN:
- printf ("Bad n_sclass = %d\n", cs->c_sclass);
- break;
-
- case C_FILE:
- /*
- * c_value field contains symnum of next .file entry in table
- * or symnum of first global after last .file.
- */
- next_file_symnum = cs->c_value;
- filestring = getfilename (&main_aux);
- /*
- * Complete symbol table for last object file
- * containing debugging information.
- */
- if (last_source_file)
- {
- end_symtab ();
- start_symtab ();
- }
- num_object_files++;
- break;
-
- case C_STAT:
- if (cs->c_name[0] == '.') {
- if (strcmp (cs->c_name, _TEXT) == 0) {
- if (num_object_files == 1) {
- /* last address of startup file */
- first_object_file_end = cs->c_value +
- main_aux.x_scn.x_scnlen;
- }
- /* for some reason the old code didn't do
- * this if this section entry had
- * main_aux.x_scn.x_nlinno equal to 0
- */
- complete_symtab (filestring, cs->c_value,
- main_aux.x_scn.x_scnlen);
- }
- /* flush rest of '.' symbols */
- break;
- }
- /* fall in for static symbols that don't start with '.' */
- case C_EXT:
- if (cs->c_sclass == C_EXT &&
- cs->c_secnum == N_ABS &&
- strcmp (cs->c_name, _ETEXT) == 0)
- end_of_text_addr = cs->c_value;
- if (cs->c_type == T_NULL) {
- if (cs->c_secnum <= 1) { /* text or abs */
- record_misc_function (cs->c_name, cs->c_value);
- break;
- } else {
- cs->c_type = T_INT;
- }
- }
- (void) process_coff_symbol (cs, &main_aux);
- break;
-
- case C_FCN:
- if (strcmp (cs->c_name, ".bf") == 0)
- {
- unrecord_misc_function ();
-
- within_function = 1;
-
- /* value contains address of first non-init type code */
- /* main_aux.x_sym.x_misc.x_lnsz.x_lnno
- contains line number of '{' } */
- fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
-
- new = (struct context_stack *)
- xmalloc (sizeof (struct context_stack));
- new->depth = depth = 0;
- new->next = 0;
- context_stack = new;
- new->locals = 0;
- new->old_blocks = pending_blocks;
- new->start_addr = fcn_start_addr;
- fcn_cs_saved.c_name = getsymname (&fcn_sym_saved);
- new->name = process_coff_symbol (&fcn_cs_saved,
- &fcn_aux_saved);
- }
- else if (strcmp (cs->c_name, ".ef") == 0)
- {
- /* the value of .ef is the address of epilogue code;
- * not useful for gdb
- */
- /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
- contains number of lines to '}' */
- fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
- enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line);
- new = context_stack;
-
- if (new == 0)
- error ("Invalid symbol data; .bf/.ef/.bb/.eb symbol mismatch, at symbol %d.",
- symnum);
-
- finish_block (new->name, &local_symbols, new->old_blocks,
- new->start_addr,
- fcn_cs_saved.c_value +
- fcn_aux_saved.x_sym.x_misc.x_fsize);
- context_stack = 0;
- within_function = 0;
- free (new);
- }
- break;
-
- case C_BLOCK:
- if (strcmp (cs->c_name, ".bb") == 0)
- {
- new = (struct context_stack *)
- xmalloc (sizeof (struct context_stack));
- depth++;
- new->depth = depth;
- new->next = context_stack;
- context_stack = new;
- new->locals = local_symbols;
- new->old_blocks = pending_blocks;
- new->start_addr = cs->c_value;
- new->name = 0;
- local_symbols = 0;
- }
- else if (strcmp (cs->c_name, ".eb") == 0)
- {
- new = context_stack;
- if (new == 0 || depth != new->depth)
- error ("Invalid symbol data: .bb/.eb symbol mismatch at symbol %d.",
- symnum);
- if (local_symbols && context_stack->next)
- {
- /* Make a block for the local symbols within. */
- finish_block (0, &local_symbols, new->old_blocks,
- new->start_addr, cs->c_value);
- }
- depth--;
- local_symbols = new->locals;
- context_stack = new->next;
- free (new);
- }
- break;
-
- default:
- (void) process_coff_symbol (cs, &main_aux);
- break;
- }
- }
-
- if (last_source_file)
- end_symtab ();
- fclose (stream);
- discard_cleanups (old_chain);
-}
-
-/* Routines for reading headers and symbols from executable. */
-
-/* Read COFF file header, check magic number,
- and return number of symbols. */
-read_file_hdr (chan, file_hdr)
- int chan;
- FILHDR *file_hdr;
-{
- lseek (chan, 0L, 0);
- if (myread (chan, (char *)file_hdr, FILHSZ) < 0)
- return -1;
-
- switch (file_hdr->f_magic)
- {
-#ifdef NS32GMAGIC
- case NS32GMAGIC:
- case NS32SMAGIC:
-#endif
-#ifdef I386MAGIC
- case I386MAGIC:
-#endif
- return file_hdr->f_nsyms;
-
-
- default:
-#ifdef BADMAG
- if (BADMAG(file_hdr))
- return -1;
- else
- return file_hdr->f_nsyms;
-#else
- return -1;
-#endif
- }
-}
-
-read_aout_hdr (chan, aout_hdr, size)
- int chan;
- AOUTHDR *aout_hdr;
- int size;
-{
- lseek (chan, (long)FILHSZ, 0);
- if (size != sizeof (AOUTHDR))
- return -1;
- if (myread (chan, (char *)aout_hdr, size) != size)
- return -1;
- return 0;
-}
-
-read_section_hdr (chan, section_name, section_hdr, nsects)
- register int chan;
- register char *section_name;
- SCNHDR *section_hdr;
- register int nsects;
-{
- register int i;
-
- if (lseek (chan, FILHSZ + sizeof (AOUTHDR), 0) < 0)
- return -1;
-
- for (i = 0; i < nsects; i++)
- {
- if (myread (chan, (char *)section_hdr, SCNHSZ) < 0)
- return -1;
- if (strncmp (section_hdr->s_name, section_name, 8) == 0)
- return 0;
- }
- return -1;
-}
-
-read_one_sym (cs, sym, aux)
- register struct coff_symbol *cs;
- register SYMENT *sym;
- register AUXENT *aux;
-{
- cs->c_symnum = symnum;
- fread ((char *)sym, SYMESZ, 1, nlist_stream_global);
- cs->c_nsyms = (sym->n_numaux & 0xff) + 1;
- if (cs->c_nsyms == 2)
- {
- /* doc for coff says there is either no aux entry or just one */
- fread ((char *)aux, AUXESZ, 1, nlist_stream_global);
- }
- else if (cs->c_nsyms > 2)
- error ("more than one aux symbol table entry at symnum=%d\n", symnum);
-
- cs->c_name = getsymname (sym);
- cs->c_value = sym->n_value;
- cs->c_sclass = (sym->n_sclass & 0xff);
- cs->c_secnum = sym->n_scnum;
- cs->c_type = (unsigned) sym->n_type;
-
- symnum += cs->c_nsyms;
-}
-
-/* Support for string table handling */
-
-static char *stringtab = NULL;
-
-static int
-init_stringtab (chan, offset)
- int chan;
- long offset;
-{
- long buffer;
- int val;
-
- if (stringtab)
- {
- free (stringtab);
- stringtab = NULL;
- }
-
- if (lseek (chan, offset, 0) < 0)
- return -1;
-
- val = myread (chan, (char *)&buffer, sizeof buffer);
-
- /* If no string table is needed, then the file may end immediately
- after the symbols. Just return with `stringtab' set to null. */
- if (val != sizeof buffer || buffer == 0)
- return 0;
-
- stringtab = (char *) xmalloc (buffer);
- if (stringtab == NULL)
- return -1;
-
- bcopy (&buffer, stringtab, sizeof buffer);
-
- val = myread (chan, stringtab + sizeof buffer, buffer - sizeof buffer);
- if (val != buffer - sizeof buffer || stringtab[buffer - 1] != '\0')
- return -1;
-
- return 0;
-}
-
-static void
-free_stringtab ()
-{
- if (stringtab)
- free (stringtab);
- stringtab = NULL;
-}
-
-static char *
-getsymname (symbol_entry)
- SYMENT *symbol_entry;
-{
- static char buffer[SYMNMLEN+1];
- char *result;
-
- if (symbol_entry->n_zeroes == 0)
- {
- result = stringtab + symbol_entry->n_offset;
- }
- else
- {
- strncpy (buffer, symbol_entry->n_name, SYMNMLEN);
- buffer[SYMNMLEN] = '\0';
- result = buffer;
- }
- return result;
-}
-
-static char *
-getfilename (aux_entry)
- AUXENT *aux_entry;
-{
- static char buffer[BUFSIZ];
- register char *temp;
- char *result;
- extern char *rindex ();
-
-#ifndef COFF_NO_LONG_FILE_NAMES
- if (aux_entry->x_file.x_foff != 0)
- strcpy (buffer, stringtab + aux_entry->x_file.x_foff);
- else
-#endif
- {
- strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN);
- buffer[FILNMLEN] = '\0';
- }
- result = buffer;
- if ((temp = rindex (result, '/')) != NULL)
- result = temp + 1;
- return (result);
-}
-
-/* Support for line number handling */
-static char *linetab = NULL;
-static long linetab_offset;
-static int linetab_count;
-
-static int
-init_lineno (chan, offset, count)
- int chan;
- long offset;
- int count;
-{
- int val;
-
- if (lseek (chan, offset, 0) < 0)
- return -1;
-
- if (linetab)
- free (linetab);
- linetab = (char *) xmalloc (count * LINESZ);
-
- val = myread (chan, linetab, count * LINESZ);
- if (val != count * LINESZ)
- return -1;
-
- linetab_offset = offset;
- linetab_count = count;
- return 0;
-}
-
-static void
-enter_linenos (file_offset, first_line, last_line)
- long file_offset;
- register int first_line;
- register int last_line;
-{
- register char *rawptr = &linetab[file_offset - linetab_offset];
- register struct lineno *lptr;
-
- /* skip first line entry for each function */
- rawptr += LINESZ;
- /* line numbers start at one for the first line of the function */
- first_line--;
-
- for (lptr = (struct lineno *)rawptr;
- lptr->l_lnno && lptr->l_lnno <= last_line;
- rawptr += LINESZ, lptr = (struct lineno *)rawptr)
- {
- record_line (first_line + lptr->l_lnno, lptr->l_addr.l_paddr);
- }
-}
-
-static int
-hashname (name)
- char *name;
-{
- register char *p = name;
- register int total = p[0];
- register int c;
-
- c = p[1];
- total += c << 2;
- if (c)
- {
- c = p[2];
- total += c << 4;
- if (c)
- total += p[3] << 6;
- }
-
- return total % HASHSIZE;
-}
-
-static void
-patch_type (type, real_type)
- struct type *type;
- struct type *real_type;
-{
- register struct type *target = TYPE_TARGET_TYPE (type);
- register struct type *real_target = TYPE_TARGET_TYPE (real_type);
- int field_size = TYPE_NFIELDS (real_target) * sizeof (struct field);
-
- TYPE_LENGTH (target) = TYPE_LENGTH (real_target);
- TYPE_NFIELDS (target) = TYPE_NFIELDS (real_target);
- TYPE_FIELDS (target) = (struct field *)
- obstack_alloc (symbol_obstack, field_size);
-
- bcopy (TYPE_FIELDS (real_target), TYPE_FIELDS (target), field_size);
-
- if (TYPE_NAME (real_target))
- {
- if (TYPE_NAME (target))
- free (TYPE_NAME (target));
- TYPE_NAME (target) = concat (TYPE_NAME (real_target), "", "");
- }
-}
-
-/* Patch up all appropriate typdef symbols in the opaque_type_chains
- so that they can be used to print out opaque data structures properly */
-
-static void
-patch_opaque_types ()
-{
- struct symtab *s;
-
- /* Look at each symbol in the per-file block of each symtab. */
- for (s = symtab_list; s; s = s->next)
- {
- register struct block *b;
- register int i;
-
- /* Go through the per-file symbols only */
- b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), 1);
- for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--)
- {
- register struct symbol *real_sym;
-
- /* Find completed typedefs to use to fix opaque ones.
- Remove syms from the chain when their types are stored,
- but search the whole chain, as there may be several syms
- from different files with the same name. */
- real_sym = BLOCK_SYM (b, i);
- if (SYMBOL_CLASS (real_sym) == LOC_TYPEDEF &&
- SYMBOL_NAMESPACE (real_sym) == VAR_NAMESPACE &&
- TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&
- TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)
- {
- register char *name = SYMBOL_NAME (real_sym);
- register int hash = hashname (name);
- register struct symbol *sym, *prev;
-
- prev = 0;
- for (sym = opaque_type_chain[hash]; sym;)
- {
- if (name[0] == SYMBOL_NAME (sym)[0] &&
- !strcmp (name + 1, SYMBOL_NAME (sym) + 1))
- {
- if (prev)
- SYMBOL_VALUE (prev) = SYMBOL_VALUE (sym);
- else
- opaque_type_chain[hash]
- = (struct symbol *) SYMBOL_VALUE (sym);
-
- patch_type (SYMBOL_TYPE (sym), SYMBOL_TYPE (real_sym));
-
- if (prev)
- sym = (struct symbol *) SYMBOL_VALUE (prev);
- else
- sym = opaque_type_chain[hash];
- }
- else
- {
- prev = sym;
- sym = (struct symbol *) SYMBOL_VALUE (sym);
- }
- }
- }
- }
- }
-}
-
-static struct symbol *
-process_coff_symbol (cs, aux)
- register struct coff_symbol *cs;
- register AUXENT *aux;
-{
- register struct symbol *sym
- = (struct symbol *) obstack_alloc (symbol_obstack, sizeof (struct symbol));
- char *name;
- char *dot;
-#ifdef NAMES_HAVE_UNDERSCORE
- int offset = 1;
-#else
- int offset = 0;
-#endif
-
- bzero (sym, sizeof (struct symbol));
- name = cs->c_name;
- name = (name[0] == '_' ? name + offset : name);
- SYMBOL_NAME (sym) = obstack_copy0 (symbol_obstack, name, strlen (name));
-
- /* default assumptions */
- SYMBOL_VALUE (sym) = cs->c_value;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
-
- if (ISFCN (cs->c_type))
- {
- SYMBOL_TYPE (sym) =
- lookup_function_type (decode_function_type (cs, cs->c_type, aux));
- SYMBOL_CLASS (sym) = LOC_BLOCK;
- if (cs->c_sclass == C_STAT)
- add_symbol_to_list (sym, &file_symbols);
- else if (cs->c_sclass == C_EXT)
- add_symbol_to_list (sym, &global_symbols);
- }
- else
- {
- SYMBOL_TYPE (sym) = decode_type (cs, cs->c_type, aux);
- switch (cs->c_sclass)
- {
- case C_NULL:
- break;
-
- case C_AUTO:
- SYMBOL_CLASS (sym) = LOC_LOCAL;
- add_symbol_to_list (sym, &local_symbols);
- break;
-
- case C_EXT:
- SYMBOL_CLASS (sym) = LOC_STATIC;
- add_symbol_to_list (sym, &global_symbols);
- break;
-
- case C_STAT:
- SYMBOL_CLASS (sym) = LOC_STATIC;
- if (within_function) {
- /* Static symbol of local scope */
- add_symbol_to_list (sym, &local_symbols);
- }
- else {
- /* Static symbol at top level of file */
- add_symbol_to_list (sym, &file_symbols);
- }
- break;
-
- case C_REG:
- case C_REGPARM:
- SYMBOL_CLASS (sym) = LOC_REGISTER;
- add_symbol_to_list (sym, &local_symbols);
- break;
-
- case C_LABEL:
- break;
-
- case C_ARG:
- SYMBOL_CLASS (sym) = LOC_ARG;
- add_symbol_to_list (sym, &local_symbols);
- /* If PCC says a parameter is a short or a char,
- it is really an int. */
- if (SYMBOL_TYPE (sym) == builtin_type_char
- || SYMBOL_TYPE (sym) == builtin_type_short)
- SYMBOL_TYPE (sym) = builtin_type_int;
- else if (SYMBOL_TYPE (sym) == builtin_type_unsigned_char
- || SYMBOL_TYPE (sym) == builtin_type_unsigned_short)
- SYMBOL_TYPE (sym) = builtin_type_unsigned_int;
- break;
-
- case C_TPDEF:
- SYMBOL_CLASS (sym) = LOC_TYPEDEF;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
-
- /* If type has no name, give it one */
- if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0
- && (TYPE_FLAGS (SYMBOL_TYPE (sym)) & TYPE_FLAG_PERM) == 0)
- TYPE_NAME (SYMBOL_TYPE (sym))
- = concat (SYMBOL_NAME (sym), "", "");
-
- /* Keep track of any type which points to empty structured type,
- so it can be filled from a definition from another file */
- if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR &&
- TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0)
- {
- register int i = hashname (SYMBOL_NAME (sym));
-
- SYMBOL_VALUE (sym) = (int) opaque_type_chain[i];
- opaque_type_chain[i] = sym;
- }
- add_symbol_to_list (sym, &file_symbols);
- break;
-
- case C_STRTAG:
- case C_UNTAG:
- case C_ENTAG:
- SYMBOL_CLASS (sym) = LOC_TYPEDEF;
- SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
- if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0
- && (TYPE_FLAGS (SYMBOL_TYPE (sym)) & TYPE_FLAG_PERM) == 0)
- TYPE_NAME (SYMBOL_TYPE (sym))
- = concat ("",
- (cs->c_sclass == C_ENTAG
- ? "enum "
- : (cs->c_sclass == C_STRTAG
- ? "struct " : "union ")),
- SYMBOL_NAME (sym));
- add_symbol_to_list (sym, &file_symbols);
- break;
-
- default:
- break;
- }
- }
- return sym;
-}
-
-/* Decode a coff type specifier;
- return the type that is meant. */
-
-static
-struct type *
-decode_type (cs, c_type, aux)
- register struct coff_symbol *cs;
- unsigned int c_type;
- register AUXENT *aux;
-{
- register struct type *type = 0;
- register int n;
- unsigned int new_c_type;
-
- if (c_type & ~N_BTMASK)
- {
- new_c_type = DECREF (c_type);
- if (ISPTR (c_type))
- {
- type = decode_type (cs, new_c_type, aux);
- type = lookup_pointer_type (type);
- }
- else if (ISFCN (c_type))
- {
- type = decode_type (cs, new_c_type, aux);
- type = lookup_function_type (type);
- }
- else if (ISARY (c_type))
- {
- int i, n;
- register unsigned short *dim;
- struct type *base_type;
-
- /* Define an array type. */
- /* auxent refers to array, not base type */
- if (aux->x_sym.x_tagndx == 0)
- cs->c_nsyms = 1;
-
- /* shift the indices down */
- dim = &aux->x_sym.x_fcnary.x_ary.x_dimen[0];
- i = 1;
- n = dim[0];
- for (i = 0; *dim && i < DIMNUM - 1; i++, dim++)
- *dim = *(dim + 1);
- *dim = 0;
-
- type = (struct type *)
- obstack_alloc (symbol_obstack, sizeof (struct type));
- bzero (type, sizeof (struct type));
-
- base_type = decode_type (cs, new_c_type, aux);
-
- TYPE_CODE (type) = TYPE_CODE_ARRAY;
- TYPE_TARGET_TYPE (type) = base_type;
- TYPE_LENGTH (type) = n * TYPE_LENGTH (base_type);
- }
- return type;
- }
-
- /* Reference to existing type */
- if (cs->c_nsyms > 1 && aux->x_sym.x_tagndx != 0)
- {
- type = coff_alloc_type (aux->x_sym.x_tagndx);
- return type;
- }
-
- return decode_base_type (cs, BTYPE (c_type), aux);
-}
-
-/* Decode a coff type specifier for function definition;
- return the type that the function returns. */
-
-static
-struct type *
-decode_function_type (cs, c_type, aux)
- register struct coff_symbol *cs;
- unsigned int c_type;
- register AUXENT *aux;
-{
- if (aux->x_sym.x_tagndx == 0)
- cs->c_nsyms = 1; /* auxent refers to function, not base type */
-
- return decode_type (cs, DECREF (cs->c_type), aux);
-}
-
-/* basic C types */
-
-static
-struct type *
-decode_base_type (cs, c_type, aux)
- register struct coff_symbol *cs;
- unsigned int c_type;
- register AUXENT *aux;
-{
- struct type *type;
-
- switch (c_type)
- {
- case T_NULL:
- /* shows up with "void (*foo)();" structure members */
- return builtin_type_void;
-
- case T_ARG:
- /* shouldn't show up here */
- break;
-
- case T_CHAR:
- return builtin_type_char;
-
- case T_SHORT:
- return builtin_type_short;
-
- case T_INT:
- return builtin_type_int;
-
- case T_LONG:
- return builtin_type_long;
-
- case T_FLOAT:
- return builtin_type_float;
-
- case T_DOUBLE:
- return builtin_type_double;
-
- case T_STRUCT:
- if (cs->c_nsyms != 2)
- {
- /* anonymous structure type */
- type = coff_alloc_type (cs->c_symnum);
- TYPE_CODE (type) = TYPE_CODE_STRUCT;
- TYPE_NAME (type) = concat ("struct ", "<opaque>", "");
- TYPE_LENGTH (type) = 0;
- TYPE_FIELDS (type) = 0;
- TYPE_NFIELDS (type) = 0;
- }
- else
- {
- type = read_struct_type (cs->c_symnum,
- aux->x_sym.x_misc.x_lnsz.x_size,
- aux->x_sym.x_fcnary.x_fcn.x_endndx);
- }
- return type;
-
- case T_UNION:
- if (cs->c_nsyms != 2)
- {
- /* anonymous union type */
- type = coff_alloc_type (cs->c_symnum);
- TYPE_NAME (type) = concat ("union ", "<opaque>", "");
- TYPE_LENGTH (type) = 0;
- TYPE_FIELDS (type) = 0;
- TYPE_NFIELDS (type) = 0;
- }
- else
- {
- type = read_struct_type (cs->c_symnum,
- aux->x_sym.x_misc.x_lnsz.x_size,
- aux->x_sym.x_fcnary.x_fcn.x_endndx);
- }
- TYPE_CODE (type) = TYPE_CODE_UNION;
- return type;
-
- case T_ENUM:
- return read_enum_type (cs->c_symnum,
- aux->x_sym.x_misc.x_lnsz.x_size,
- aux->x_sym.x_fcnary.x_fcn.x_endndx);
-
- case T_MOE:
- /* shouldn't show up here */
- break;
-
- case T_UCHAR:
- return builtin_type_unsigned_char;
-
- case T_USHORT:
- return builtin_type_unsigned_short;
-
- case T_UINT:
- return builtin_type_unsigned_int;
-
- case T_ULONG:
- return builtin_type_unsigned_long;
- }
- printf ("unexpected type %d at symnum %d\n", c_type, cs->c_symnum);
- return builtin_type_void;
-}
-
-/* This page contains subroutines of read_type. */
-
-/* Read the description of a structure (or union type)
- and return an object describing the type. */
-
-static struct type *
-read_struct_type (index, length, lastsym)
- int index;
- int length;
- int lastsym;
-{
- struct nextfield
- {
- struct nextfield *next;
- struct field field;
- };
-
- register struct type *type;
- register struct nextfield *list = 0;
- struct nextfield *new;
- int nfields = 0;
- register int n;
- char *name;
-#ifdef NAMES_HAVE_UNDERSCORE
- int offset = 1;
-#else
- int offset = 0;
-#endif
- struct coff_symbol member_sym;
- register struct coff_symbol *ms = &member_sym;
- SYMENT sub_sym;
- AUXENT sub_aux;
- int done = 0;
-
- type = coff_alloc_type (index);
- TYPE_CODE (type) = TYPE_CODE_STRUCT;
- TYPE_LENGTH (type) = length;
-
- while (!done && symnum < lastsym && symnum < nlist_nsyms_global)
- {
- read_one_sym (ms, &sub_sym, &sub_aux);
- name = ms->c_name;
- name = (name[0] == '_' ? name + offset : name);
-
- switch (ms->c_sclass)
- {
- case C_MOS:
- case C_MOU:
-
- /* Get space to record the next field's data. */
- new = (struct nextfield *) alloca (sizeof (struct nextfield));
- new->next = list;
- list = new;
-
- /* Save the data. */
- list->field.name = savestring (name, strlen (name));
- list->field.type = decode_type (ms, ms->c_type, &sub_aux);
- list->field.bitpos = 8 * ms->c_value;
- list->field.bitsize = 0;
- nfields++;
- break;
-
- case C_FIELD:
-
- /* Get space to record the next field's data. */
- new = (struct nextfield *) alloca (sizeof (struct nextfield));
- new->next = list;
- list = new;
-
- /* Save the data. */
- list->field.name = savestring (name, strlen (name));
- list->field.type = decode_type (ms, ms->c_type, &sub_aux);
- list->field.bitpos = ms->c_value;
- list->field.bitsize = sub_aux.x_sym.x_misc.x_lnsz.x_size;
- nfields++;
- break;
-
- case C_EOS:
- done = 1;
- break;
- }
- }
- /* Now create the vector of fields, and record how big it is. */
-
- TYPE_NFIELDS (type) = nfields;
- TYPE_FIELDS (type) = (struct field *)
- obstack_alloc (symbol_obstack, sizeof (struct field) * nfields);
-
- /* Copy the saved-up fields into the field vector. */
-
- for (n = nfields; list; list = list->next)
- TYPE_FIELD (type, --n) = list->field;
-
- return type;
-}
-
-/* Read a definition of an enumeration type,
- and create and return a suitable type object.
- Also defines the symbols that represent the values of the type. */
-
-static struct type *
-read_enum_type (index, length, lastsym)
- int index;
- int length;
- int lastsym;
-{
- register struct symbol *sym;
- register struct type *type;
- int nsyms = 0;
- struct pending **symlist;
- struct coff_symbol member_sym;
- register struct coff_symbol *ms = &member_sym;
- SYMENT sub_sym;
- AUXENT sub_aux;
- struct pending *osyms, *syms;
- register int n;
- char *name;
-#ifdef NAMES_HAVE_UNDERSCORE
- int offset = 1;
-#else
- int offset = 0;
-#endif
-
- type = coff_alloc_type (index);
- if (within_function)
- symlist = &local_symbols;
- else
- symlist = &file_symbols;
- osyms = *symlist;
-
- while (symnum < lastsym && symnum < nlist_nsyms_global)
- {
- read_one_sym (ms, &sub_sym, &sub_aux);
- name = ms->c_name;
- name = (name[0] == '_' ? name + offset : name);
-
- switch (ms->c_sclass)
- {
- case C_MOE:
- sym = (struct symbol *) xmalloc (sizeof (struct symbol));
- bzero (sym, sizeof (struct symbol));
-
- SYMBOL_NAME (sym) = savestring (name, strlen (name));
- SYMBOL_CLASS (sym) = LOC_CONST;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- SYMBOL_VALUE (sym) = ms->c_value;
- add_symbol_to_list (sym, symlist);
- nsyms++;
- break;
-
- case C_EOS:
- break;
- }
- }
-
- /* Now fill in the fields of the type-structure. */
-
- TYPE_LENGTH (type) = sizeof (int);
- TYPE_CODE (type) = TYPE_CODE_ENUM;
- TYPE_NFIELDS (type) = nsyms;
- TYPE_FIELDS (type) = (struct field *)
- obstack_alloc (symbol_obstack, sizeof (struct field) * nsyms);
-
- /* Find the symbols for the values and put them into the type.
- The symbols can be found in the symlist that we put them on
- to cause them to be defined. osyms contains the old value
- of that symlist; everything up to there was defined by us. */
-
- for (syms = *symlist, n = nsyms; syms != osyms; syms = syms->next)
- {
- SYMBOL_TYPE (syms->symbol) = type;
- TYPE_FIELD_NAME (type, --n) = SYMBOL_NAME (syms->symbol);
- TYPE_FIELD_VALUE (type, n) = 0;
- TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (syms->symbol);
- TYPE_FIELD_BITSIZE (type, n) = 0;
- }
- return type;
-}
-
-/* This function is really horrible, but to avoid it, there would need
- to be more filling in of forward references. THIS SHOULD BE MOVED
- OUT OF COFFREAD.C AND DBXREAD.C TO SOME PLACE WHERE IT CAN BE SHARED. */
-int
-fill_in_vptr_fieldno (type)
- struct type *type;
-{
- if (TYPE_VPTR_FIELDNO (type) < 0)
- TYPE_VPTR_FIELDNO (type) =
- fill_in_vptr_fieldno (TYPE_BASECLASS (type, 1));
- return TYPE_VPTR_FIELDNO (type);
-}
-
-/* partial symbol tables are not implemented in coff, therefore
- block_for_pc() (and others) will never decide to call this. */
-
-extern struct symtab *
-psymtab_to_symtab ()
-{
- fatal ("error: Someone called psymtab_to_symtab\n");
-}
-
-/* These will stay zero all the time */
-struct partial_symbol *global_psymbols, *static_psymbols;
-
-_initialize_coff ()
-{
- symfile = 0;
-
- static_psymbols = global_psymbols = (struct partial_symbol *) 0;
-
- add_com ("symbol-file", class_files, symbol_file_command,
- "Load symbol table (in coff format) from executable file FILE.");
-}
-
-
-#endif /* COFF_FORMAT */
-
-@
-
-
-1.4
-log
-@Avoid A/UX change (#undef aux) for sending in to FSF.
-@
-text
-@d40 3
-@
-
-
-1.3
-log
-@A/UX and USG changes. If BADMAG defined, use it. Avoid <sys/fcntl.h>.
-Declare fclose(). #undef aux which we use as a var.
-@
-text
-@a39 3
-/* Avoid problems with A/UX predefine */
-#undef aux
-
-@
-
-
-1.2
-log
-@If discarding the symbol table, discard its name too, so "info files"
-will give the right answer.
-@
-text
-@d31 1
-a31 1
-#include <sys/fcntl.h>
-d40 3
-d847 1
-a847 1
-
-d1093 6
-d1100 1
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d5 1
-a5 1
- Copyright (C) 1987, 1988 Free Software Foundation, Inc.
-d684 3
-@
diff --git a/gdb/RCS/config.gdb,v b/gdb/RCS/config.gdb,v
deleted file mode 100755
index b569f62..0000000
--- a/gdb/RCS/config.gdb,v
+++ /dev/null
@@ -1,229 +0,0 @@
-head 1.2;
-access ;
-symbols ;
-locks ; strict;
-comment @@;
-
-
-1.2
-date 89.03.27.18.38.55; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.03.13.19.14.24; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.2
-log
-@Add A/UX option (config.gdb aux).
-@
-text
-@#!/bin/sh
-
-#
-# Shell script to create proper links to machine-dependent files in
-# preparation for compiling gdb.
-#
-# Usage: config.gdb machine [operating-system]
-#
-# If config.gdb succeeds, it leaves its status in config.status.
-# If config.gdb fails after disturbing the status quo,
-# config.status is removed.
-#
-
-progname=$0
-
-case $# in
-1)
- machine=$1
- os="none"
- ;;
-2)
- machine=$1
- os=$2
- ;;
-*)
- echo "Usage: $progname machine [operating-system]"
- echo "Available machine types:"
- echo m-*.h | sed 's/m-//g' | sed 's/\.h//g'
- if [ -r config.status ]
- then
- cat config.status
- fi
- exit 1
- ;;
-esac
-
-paramfile=m-${machine}.h
-pinsnfile=${machine}-pinsn.c
-opcodefile=${machine}-opcode.h
-if [ -r ${machine}-dep.c ]
-then
- depfile=${machine}-dep.c
-else
- depfile=default-dep.c
-fi
-
-#
-# Special cases.
-# If a file is not needed, set the filename to 'skip' and it will be
-# ignored.
-#
-case $machine in
-aux)
- pinsnfile=m68k-pinsn.c
- opcodefile=m68k-opcode.h
- ;;
-vax)
- pinsnfile=vax-pinsn.c
- opcodefile=vax-opcode.h
- ;;
-hp9k320)
- pinsnfile=m68k-pinsn.c
- opcodefile=m68k-opcode.h
- ;;
-isi)
- pinsnfile=m68k-pinsn.c
- opcodefile=m68k-opcode.h
- ;;
-i386)
- echo "Note: i386 users need to modify \`CLIBS' & \`REGEX*' in the Makefile"
- opcodefile=skip
- ;;
-i386gas)
- echo "Note: i386 users need to modify \`CLIBS' & \`REGEX*' in the Makefile"
- echo "Use of the coff encapsulation features also requires the GNU binutils utilities"
- echo "to be ahead of their System V counterparts in your path."
- pinsnfile=i386-pinsn.c
- depfile=i386-dep.c
- opcodefile=skip
- ;;
-merlin)
- pinsnfile=ns32k-pinsn.c
- opcodefile=ns32k-opcode.h
- ;;
-news)
- pinsnfile=m68k-pinsn.c
- opcodefile=m68k-opcode.h
- ;;
-npl)
- pinsnfile=gld-pinsn.c
- ;;
-pn)
- pinsnfile=gld-pinsn.c
- ;;
-sun2)
- case $os in
- os4|sunos4)
- paramfile=m-sun2os4.h
- ;;
- os2|sunos2)
- paramfile=m-sun2os2.h
- esac
- pinsnfile=m68k-pinsn.c
- opcodefile=m68k-opcode.h
- ;;
-sun2os2)
- pinsnfile=m68k-pinsn.c
- opcodefile=m68k-opcode.h
- ;;
-sun2os4)
- pinsnfile=m68k-pinsn.c
- opcodefile=m68k-opcode.h
- ;;
-sun3)
- case $os in
- os4|sunos4)
- paramfile=m-sun3os4.h
- esac
- pinsnfile=m68k-pinsn.c
- opcodefile=m68k-opcode.h
- ;;
-sun3os4)
- pinsnfile=m68k-pinsn.c
- opcodefile=m68k-opcode.h
- depfile=sun3-dep.c
- ;;
-sun4os4)
- pinsnfile=sparc-pinsn.c
- opcodefile=sparc-opcode.h
- depfile=sparc-dep.c
- ;;
-umax)
- pinsnfile=ns32k-pinsn.c
- opcodefile=ns32k-opcode.h
- ;;
-sparc|sun4)
- case $os in
- os4|sunos4)
- paramfile=m-sun4os4.h
- esac
- pinsnfile=sparc-pinsn.c
- opcodefile=sparc-opcode.h
- depfile=sparc-dep.c
- paramfile=m-sparc.h
- ;;
-test)
- paramfile=one
- pinsnfile=three
- opcodefile=four
- ;;
-*)
- echo "Unknown machine type: \`$machine'"
- echo "Available types:"
- echo m-*.h | sed 's/m-//g' | sed 's/\.h//g'
- exit 1
-esac
-
-files="$paramfile $pinsnfile $opcodefile $depfile"
-links="param.h pinsn.c opcode.h dep.c"
-
-while [ -n "$files" ]
-do
- # set file to car of files, files to cdr of files
- set $files; file=$1; shift; files=$*
- set $links; link=$1; shift; links=$*
-
- if [ "$file" != skip ]
- then
- if [ ! -r $file ]
- then
- echo "$progname: cannot create a link \`$link',"
- echo "since the file \`$file' does not exist."
- exit 1
- fi
-
- rm -f $link config.status
- # Make a symlink if possible, otherwise try a hard link
- ln -s $file $link 2>/dev/null || ln $file $link
-
- if [ ! -r $link ]
- then
- echo "$progname: unable to link \`$link' to \`$file'."
- exit 1
- fi
- echo "Linked \`$link' to \`$file'."
- fi
-done
-
-echo "Links are now set up for use with a $machine." \
- | tee config.status
-exit 0
-
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d53 4
-@
diff --git a/gdb/RCS/core.c,v b/gdb/RCS/core.c,v
deleted file mode 100644
index f63081d..0000000
--- a/gdb/RCS/core.c,v
+++ /dev/null
@@ -1,651 +0,0 @@
-head 1.4;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.4
-date 89.03.27.18.39.18; author gnu; state Exp;
-branches ;
-next 1.3;
-
-1.3
-date 89.02.10.01.39.45; author gnu; state Exp;
-branches ;
-next 1.2;
-
-1.2
-date 89.02.09.23.22.33; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.02.09.22.49.56; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.4
-log
-@Unisoft Assholes changes for user.ps. Avoid sys/fcntl.h.
-@
-text
-@/* Work with core dump and executable files, for GDB.
- Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#include "defs.h"
-#include "param.h"
-#include "gdbcore.h"
-
-#ifdef USG
-#include <sys/types.h>
-#include <fcntl.h>
-#endif
-
-#ifdef COFF_ENCAPSULATE
-#include "a.out.encap.h"
-#else
-#include <a.out.h>
-#endif
-
-#ifndef N_MAGIC
-#ifdef COFF_FORMAT
-#define N_MAGIC(exec) ((exec).magic)
-#else
-#define N_MAGIC(exec) ((exec).a_magic)
-#endif
-#endif
-
-#include <stdio.h>
-#include <signal.h>
-#include <sys/param.h>
-#include <sys/dir.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-
-#ifdef UNISOFT_ASSHOLES
-#define PMMU
-#define NEW_PMMU
-#include <sys/seg.h> /* Required for user.ps */
-#include <sys/time.h> /* '' */
-#include <sys/mmu.h> /* '' */
-#include <sys/reg.h>
-#define mc68881 /* Required to get float in user.ps */
-#endif
-
-#ifdef UMAX_CORE
-#include <sys/ptrace.h>
-#else
-#include <sys/user.h>
-#endif
-
-#ifndef N_TXTADDR
-#define N_TXTADDR(hdr) 0
-#endif /* no N_TXTADDR */
-
-#ifndef N_DATADDR
-#define N_DATADDR(hdr) hdr.a_text
-#endif /* no N_DATADDR */
-
-#ifndef COFF_FORMAT
-#define AOUTHDR struct exec
-#endif
-
-extern char *sys_siglist[];
-
-extern core_file_command (), exec_file_command ();
-
-/* Hook for `exec_file_command' command to call. */
-
-void (*exec_file_display_hook) ();
-
-/* File names of core file and executable file. */
-
-char *corefile;
-char *execfile;
-
-/* Descriptors on which core file and executable file are open.
- Note that the execchan is closed when an inferior is created
- and reopened if the inferior dies or is killed. */
-
-int corechan;
-int execchan;
-
-/* Last modification time of executable file.
- Also used in source.c to compare against mtime of a source file. */
-
-int exec_mtime;
-
-/* Virtual addresses of bounds of the two areas of memory in the core file. */
-
-CORE_ADDR data_start;
-CORE_ADDR data_end;
-CORE_ADDR stack_start;
-CORE_ADDR stack_end;
-
-/* Virtual addresses of bounds of two areas of memory in the exec file.
- Note that the data area in the exec file is used only when there is no core file. */
-
-CORE_ADDR text_start;
-CORE_ADDR text_end;
-
-CORE_ADDR exec_data_start;
-CORE_ADDR exec_data_end;
-
-/* Address in executable file of start of text area data. */
-
-int text_offset;
-
-/* Address in executable file of start of data area data. */
-
-int exec_data_offset;
-
-/* Address in core file of start of data area data. */
-
-int data_offset;
-
-/* Address in core file of start of stack area data. */
-
-int stack_offset;
-
-#ifdef COFF_FORMAT
-/* various coff data structures */
-
-FILHDR file_hdr;
-SCNHDR text_hdr;
-SCNHDR data_hdr;
-
-#endif /* not COFF_FORMAT */
-
-/* a.out header saved in core file. */
-
-AOUTHDR core_aouthdr;
-
-/* a.out header of exec file. */
-
-AOUTHDR exec_aouthdr;
-
-void validate_files ();
-unsigned int register_addr ();
-
-/* Call this to specify the hook for exec_file_command to call back.
- This is called from the x-window display code. */
-
-void
-specify_exec_file_hook (hook)
- void (*hook) ();
-{
- exec_file_display_hook = hook;
-}
-
-/* The exec file must be closed before running an inferior.
- If it is needed again after the inferior dies, it must
- be reopened. */
-
-void
-close_exec_file ()
-{
- if (execchan >= 0)
- close (execchan);
- execchan = -1;
-}
-
-void
-reopen_exec_file ()
-{
- if (execchan < 0 && execfile != 0)
- {
- char *filename = concat (execfile, "", "");
- exec_file_command (filename, 0);
- free (filename);
- }
-}
-
-/* If we have both a core file and an exec file,
- print a warning if they don't go together.
- This should really check that the core file came
- from that exec file, but I don't know how to do it. */
-
-void
-validate_files ()
-{
- if (execfile != 0 && corefile != 0)
- {
- struct stat st_core;
-
- fstat (corechan, &st_core);
-
- if (N_MAGIC (core_aouthdr) != 0
- && bcmp (&core_aouthdr, &exec_aouthdr, sizeof core_aouthdr))
- printf ("Warning: core file does not match specified executable file.\n");
- else if (exec_mtime > st_core.st_mtime)
- printf ("Warning: exec file is newer than core file.\n");
- }
-}
-
-/* Return the name of the executable file as a string.
- ERR nonzero means get error if there is none specified;
- otherwise return 0 in that case. */
-
-char *
-get_exec_file (err)
- int err;
-{
- if (err && execfile == 0)
- error ("No executable file specified.\n\
-Use the \"exec-file\" and \"symbol-file\" commands.");
- return execfile;
-}
-
-int
-have_core_file_p ()
-{
- return corefile != 0;
-}
-
-static void
-files_info ()
-{
- char *symfile;
- extern char *get_sym_file ();
-
- if (execfile)
- printf ("Executable file \"%s\".\n", execfile);
- else
- printf ("No executable file\n");
-
- if (corefile)
- printf ("Core dump file \"%s\".\n", corefile);
- else
- printf ("No core dump file\n");
-
- if (have_inferior_p ())
- printf ("Using the running image of the program, rather than these files.\n");
-
- symfile = get_sym_file ();
- if (symfile != 0)
- printf ("Symbols from \"%s\".\n", symfile);
-
- if (! have_inferior_p ())
- {
- if (execfile)
- {
- printf ("Text segment in executable from 0x%x to 0x%x.\n",
- text_start, text_end);
- printf ("Data segment in executable from 0x%x to 0x%x.\n",
- exec_data_start, exec_data_end);
- if (corefile)
- printf("(But since we have a core file, we're using...)\n");
- }
- if (corefile)
- {
- printf ("Data segment in core file from 0x%x to 0x%x.\n",
- data_start, data_end);
- printf ("Stack segment in core file from 0x%x to 0x%x.\n",
- stack_start, stack_end);
- }
- }
-}
-
-/* Read "memory data" from core file and/or executable file.
- Returns zero if successful, 1 if xfer_core_file failed, errno value if
- ptrace failed. */
-
-int
-read_memory (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
-{
- if (have_inferior_p ())
- return read_inferior_memory (memaddr, myaddr, len);
- else
- return xfer_core_file (memaddr, myaddr, len);
-}
-
-/* Write LEN bytes of data starting at address MYADDR
- into debugged program memory at address MEMADDR.
- Returns zero if successful, or an errno value if ptrace failed. */
-
-int
-write_memory (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
-{
- if (have_inferior_p ())
- return write_inferior_memory (memaddr, myaddr, len);
- else
- error ("Can write memory only when program being debugged is running.");
-}
-
-/* Read from the program's memory (except for inferior processes).
- This function is misnamed, since it only reads, never writes; and
- since it will use the core file and/or executable file as necessary.
-
- It should be extended to write as well as read, FIXME, for patching files.
-
- Return 0 if address could be read, 1 if not. */
-
-int
-xfer_core_file (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
-{
- register int i;
- register int val;
- int xferchan;
- char **xferfile;
- int fileptr;
- int returnval = 0;
-
- while (len > 0)
- {
- xferfile = 0;
- xferchan = 0;
-
- /* Determine which file the next bunch of addresses reside in,
- and where in the file. Set the file's read/write pointer
- to point at the proper place for the desired address
- and set xferfile and xferchan for the correct file.
-
- If desired address is nonexistent, leave them zero.
-
- i is set to the number of bytes that can be handled
- along with the next address.
-
- We put the most likely tests first for efficiency. */
-
- /* Note that if there is no core file
- data_start and data_end are equal. */
- if (memaddr >= data_start && memaddr < data_end)
- {
- i = min (len, data_end - memaddr);
- fileptr = memaddr - data_start + data_offset;
- xferfile = &corefile;
- xferchan = corechan;
- }
- /* Note that if there is no core file
- stack_start and stack_end are equal. */
- else if (memaddr >= stack_start && memaddr < stack_end)
- {
- i = min (len, stack_end - memaddr);
- fileptr = memaddr - stack_start + stack_offset;
- xferfile = &corefile;
- xferchan = corechan;
- }
- else if (corechan < 0
- && memaddr >= exec_data_start && memaddr < exec_data_end)
- {
- i = min (len, exec_data_end - memaddr);
- fileptr = memaddr - exec_data_start + exec_data_offset;
- xferfile = &execfile;
- xferchan = execchan;
- }
- else if (memaddr >= text_start && memaddr < text_end)
- {
- i = min (len, text_end - memaddr);
- fileptr = memaddr - text_start + text_offset;
- xferfile = &execfile;
- xferchan = execchan;
- }
- else if (memaddr < text_start)
- {
- i = min (len, text_start - memaddr);
- }
- else if (memaddr >= text_end
- && memaddr < (corechan >= 0? data_start : exec_data_start))
- {
- i = min (len, data_start - memaddr);
- }
- else if (memaddr >= (corechan >= 0 ? data_end : exec_data_end)
- && memaddr < stack_start)
- {
- i = min (len, stack_start - memaddr);
- }
- else if (memaddr >= stack_end && stack_end != 0)
- {
- i = min (len, - memaddr);
- }
- else
- {
- /* Address did not classify into one of the known ranges.
- This could be because data_start != exec_data_start
- or data_end similarly. */
- abort();
- }
-
- /* Now we know which file to use.
- Set up its pointer and transfer the data. */
- if (xferfile)
- {
- if (*xferfile == 0)
- if (xferfile == &execfile)
- error ("No program file to examine.");
- else
- error ("No core dump file or running program to examine.");
- val = lseek (xferchan, fileptr, 0);
- if (val < 0)
- perror_with_name (*xferfile);
- val = myread (xferchan, myaddr, i);
- if (val < 0)
- perror_with_name (*xferfile);
- }
- /* If this address is for nonexistent memory,
- read zeros if reading, or do nothing if writing.
- (FIXME we never write.) */
- else
- {
- bzero (myaddr, i);
- returnval = 1;
- }
-
- memaddr += i;
- myaddr += i;
- len -= i;
- }
- return returnval;
-}
-
-/* My replacement for the read system call.
- Used like `read' but keeps going if `read' returns too soon. */
-
-int
-myread (desc, addr, len)
- int desc;
- char *addr;
- int len;
-{
- register int val;
- int orglen = len;
-
- while (len > 0)
- {
- val = read (desc, addr, len);
- if (val < 0)
- return val;
- if (val == 0)
- return orglen - len;
- len -= val;
- addr += val;
- }
- return orglen;
-}
-
-#ifdef REGISTER_U_ADDR
-
-/* Return the address in the core dump or inferior of register REGNO.
- BLOCKEND is the address of the end of the user structure. */
-
-unsigned int
-register_addr (regno, blockend)
- int regno;
- int blockend;
-{
- int addr;
-
- if (regno < 0 || regno >= NUM_REGS)
- error ("Invalid register number %d.", regno);
-
- REGISTER_U_ADDR (addr, blockend, regno);
-
- return addr;
-}
-
-#endif /* REGISTER_U_ADDR */
-
-void
-_initialize_core()
-{
- corechan = -1;
- execchan = -1;
- corefile = 0;
- execfile = 0;
- exec_file_display_hook = 0;
-
- text_start = 0;
- text_end = 0;
- data_start = 0;
- data_end = 0;
- exec_data_start = 0;
- exec_data_end = 0;
- stack_start = STACK_END_ADDR;
- stack_end = STACK_END_ADDR;
-
- add_com ("core-file", class_files, core_file_command,
- "Use FILE as core dump for examining memory and registers.\n\
-No arg means have no core file.");
- add_com ("exec-file", class_files, exec_file_command,
- "Use FILE as program for getting contents of pure memory.\n\
-If FILE cannot be found as specified, your execution directory path\n\
-is searched for a command of that name.\n\
-No arg means have no executable file.");
- add_info ("files", files_info, "Names of files being debugged.");
-}
-
-@
-
-
-1.3
-log
-@Fix up "info files" some more, to give more information.
-Rearrange the tests in xfer_core_file to avoid dependencies
-between data_start and exec_data_start, and for efficiency
-and add an abort() to test correctness. (If you take out
-never mind...)
-@
-text
-@d27 1
-a27 1
-#include <sys/fcntl.h>
-d50 10
-@
-
-
-1.2
-log
-@Create gdbcore.h for externally visible variables;
-spiff up the "info files" output to make it easier to read and more
-informative.
-@
-text
-@d250 4
-d257 4
-a260 7
- printf ("Data segment in core file from 0x%x to 0x%x.\nStack segment in core file from 0x%x to 0x%x.\n",
- data_start, data_end, stack_start, stack_end);
- }
- else if (execfile)
- {
- printf ("Data segment in executable from 0x%x to 0x%x.\n",
- exec_data_start, exec_data_end);
-d297 3
-a299 1
-/* Return 0 if address could be read, 1 if not. */
-d301 4
-d327 1
-d329 1
-d331 3
-a333 1
- along with the next address. */
-a334 17
- if (memaddr < text_start)
- {
- i = min (len, text_start - memaddr);
- }
- else if (memaddr >= text_end && memaddr < data_start)
- {
- i = min (len, data_start - memaddr);
- }
- else if (memaddr >= (corechan >= 0 ? data_end : exec_data_end)
- && memaddr < stack_start)
- {
- i = min (len, stack_start - memaddr);
- }
- else if (memaddr >= stack_end && stack_end != 0)
- {
- i = min (len, - memaddr);
- }
-d337 1
-a337 1
- else if (memaddr >= data_start && memaddr < data_end)
-d368 25
-d411 2
-a412 1
- read zeros if reading, or do nothing if writing. */
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d2 1
-a2 1
- Copyright (C) 1986, 1987 Free Software Foundation, Inc.
-d23 1
-d35 1
-d43 1
-d231 4
-a234 1
- if (corefile == 0)
-a235 2
- else
- printf ("Core dump file \"%s\".\n", corefile);
-d242 1
-a242 1
- printf ("Symbols loaded from \"%s\".\n", symfile);
-d248 1
-a248 1
- printf ("Text segment from 0x%x to 0x%x.\n",
-d253 1
-a253 1
- printf ("Data segment from 0x%x to 0x%x.\nStack segment from 0x%x to 0x%x.\n",
-d256 1
-a256 1
- else
-@
diff --git a/gdb/RCS/dbxread.c,v b/gdb/RCS/dbxread.c,v
deleted file mode 100644
index eb9d1cd..0000000
--- a/gdb/RCS/dbxread.c,v
+++ /dev/null
@@ -1,4610 +0,0 @@
-head 1.3;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.3
-date 89.03.27.18.41.32; author gnu; state Exp;
-branches ;
-next 1.2;
-
-1.2
-date 89.02.10.01.38.34; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.02.10.01.30.11; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.3
-log
-@Avoid sys/fcntl.h.
-@
-text
-@/* Read dbx symbol tables and convert to internal format, for GDB.
- Copyright (C) 1986, 1987, 1988, 1989 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#include "param.h"
-
-#ifdef READ_DBX_FORMAT
-
-#ifdef USG
-#include <sys/types.h>
-#include <fcntl.h>
-#define L_SET 0
-#define L_INCR 1
-#endif
-
-#ifdef COFF_ENCAPSULATE
-#include "a.out.encap.h"
-#include "stab.gnu.h"
-#else
-#include <a.out.h>
-#include <stab.h>
-#endif
-
-/*
- * Define specifically gnu symbols here.
- */
-
-/* The following type indicates the definition of a symbol as being
- an indirect reference to another symbol. The other symbol
- appears as an undefined reference, immediately following this symbol.
-
- Indirection is asymmetrical. The other symbol's value will be used
- to satisfy requests for the indirect symbol, but not vice versa.
- If the other symbol does not have a definition, libraries will
- be searched to find a definition. */
-#ifndef N_INDR
-#define N_INDR 0xa
-#endif
-
-/* The following symbols refer to set elements.
- All the N_SET[ATDB] symbols with the same name form one set.
- Space is allocated for the set in the text section, and each set
- element's value is stored into one word of the space.
- The first word of the space is the length of the set (number of elements).
-
- The address of the set is made into an N_SETV symbol
- whose name is the same as the name of the set.
- This symbol acts like a N_DATA global symbol
- in that it can satisfy undefined external references. */
-
-#ifndef N_SETA
-#define N_SETA 0x14 /* Absolute set element symbol */
-#endif /* This is input to LD, in a .o file. */
-
-#ifndef N_SETT
-#define N_SETT 0x16 /* Text set element symbol */
-#endif /* This is input to LD, in a .o file. */
-
-#ifndef N_SETD
-#define N_SETD 0x18 /* Data set element symbol */
-#endif /* This is input to LD, in a .o file. */
-
-#ifndef N_SETB
-#define N_SETB 0x1A /* Bss set element symbol */
-#endif /* This is input to LD, in a .o file. */
-
-/* Macros dealing with the set element symbols defined in a.out.h */
-#define SET_ELEMENT_P(x) ((x)>=N_SETA&&(x)<=(N_SETB|N_EXT))
-#define TYPE_OF_SET_ELEMENT(x) ((x)-N_SETA+N_ABS)
-
-#ifndef N_SETV
-#define N_SETV 0x1C /* Pointer to set vector in data area. */
-#endif /* This is output from LD. */
-
-#ifndef N_WARNING
-#define N_WARNING 0x1E /* Warning message to print if file included */
-#endif /* This is input to ld */
-
-#ifndef __GNU_STAB__
-
-/* Line number for the data section. This is to be used to describe
- the source location of a variable declaration. */
-#ifndef N_DSLINE
-#define N_DSLINE (N_SLINE+N_DATA-N_TEXT)
-#endif
-
-/* Line number for the bss section. This is to be used to describe
- the source location of a variable declaration. */
-#ifndef N_BSLINE
-#define N_BSLINE (N_SLINE+N_BSS-N_TEXT)
-#endif
-
-#endif /* not __GNU_STAB__ */
-
-#include <stdio.h>
-#include <obstack.h>
-#include <sys/param.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include "defs.h"
-#include "symtab.h"
-
-#ifndef COFF_FORMAT
-#define AOUTHDR struct exec
-#endif
-
-static void add_symbol_to_list ();
-static void read_dbx_symtab ();
-static void process_one_symbol ();
-static void free_all_psymbols ();
-static struct type *read_type ();
-static struct type *read_range_type ();
-static struct type *read_enum_type ();
-static struct type *read_struct_type ();
-static struct type *read_array_type ();
-static long read_number ();
-static void finish_block ();
-static struct blockvector *make_blockvector ();
-static struct symbol *define_symbol ();
-static void start_subfile ();
-static int hashname ();
-static void hash_symsegs ();
-
-extern struct symtab *read_symsegs ();
-extern void free_all_symtabs ();
-extern void free_all_psymtabs ();
-extern void free_inclink_symtabs ();
-
-/* C++ */
-static struct type **read_args();
-
-/* Macro to determine which symbols to ignore when reading the first symbol
- of a file. Some machines override this definition. */
-#ifdef N_NSYMS
-#ifndef IGNORE_SYMBOL
-/* This code is used on Ultrix systems. Ignore it */
-#define IGNORE_SYMBOL(type) (type == N_NSYMS)
-#endif
-#else
-#ifndef IGNORE_SYMBOL
-/* Don't ignore any symbols. */
-#define IGNORE_SYMBOL(type) (0)
-#endif
-#endif /* not N_NSYMS */
-
-/* Macro for number of symbol table entries (in usual a.out format).
- Some machines override this definition. */
-#ifndef NUMBER_OF_SYMBOLS
-#ifdef COFF_HEADER
-#define NUMBER_OF_SYMBOLS \
- ((COFF_HEADER(hdr) ? hdr.coffhdr.filehdr.f_nsyms : hdr.a_syms) / \
- sizeof (struct nlist))
-#else
-#define NUMBER_OF_SYMBOLS (hdr.a_syms / sizeof (struct nlist))
-#endif
-#endif
-
-/* Macro for file-offset of symbol table (in usual a.out format). */
-#ifndef SYMBOL_TABLE_OFFSET
-#define SYMBOL_TABLE_OFFSET N_SYMOFF (hdr)
-#endif
-
-/* Macro for file-offset of string table (in usual a.out format). */
-#ifndef STRING_TABLE_OFFSET
-#define STRING_TABLE_OFFSET (N_SYMOFF (hdr) + hdr.a_syms)
-#endif
-
-/* Macro to store the length of the string table data in INTO. */
-#ifndef READ_STRING_TABLE_SIZE
-#define READ_STRING_TABLE_SIZE(INTO) \
-{ val = myread (desc, &INTO, sizeof INTO); \
- if (val < 0) perror_with_name (name); }
-#endif
-
-/* Macro to declare variables to hold the file's header data. */
-#ifndef DECLARE_FILE_HEADERS
-#define DECLARE_FILE_HEADERS AOUTHDR hdr
-#endif
-
-/* Macro to read the header data from descriptor DESC and validate it.
- NAME is the file name, for error messages. */
-#ifndef READ_FILE_HEADERS
-#ifdef HEADER_SEEK_FD
-#define READ_FILE_HEADERS(DESC, NAME) \
-{ HEADER_SEEK_FD (DESC); \
- val = myread (DESC, &hdr, sizeof hdr); \
- if (val < 0) perror_with_name (NAME); \
- if (N_BADMAG (hdr)) \
- error ("File \"%s\" not in executable format.", NAME); }
-#else
-#define READ_FILE_HEADERS(DESC, NAME) \
-{ val = myread (DESC, &hdr, sizeof hdr); \
- if (val < 0) perror_with_name (NAME); \
- if (N_BADMAG (hdr)) \
- error ("File \"%s\" not in executable format.", NAME); }
-#endif
-#endif
-
-/* Macro for size of text segment */
-#ifndef SIZE_OF_TEXT_SEGMENT
-#define SIZE_OF_TEXT_SEGMENT hdr.a_text
-#endif
-
-/* Macro for name of symbol to indicate a file compiled with gcc. */
-#ifndef GCC_COMPILED_FLAG_SYMBOL
-#define GCC_COMPILED_FLAG_SYMBOL "gcc_compiled."
-#endif
-
-/* Chain of symtabs made from reading the file's symsegs.
- These symtabs do not go into symtab_list themselves,
- but the information is copied from them when appropriate
- to make the symtabs that will exist permanently. */
-
-static struct symtab *symseg_chain;
-
-/* Symseg symbol table for the file whose data we are now processing.
- It is one of those in symseg_chain. Or 0, for a compilation that
- has no symseg. */
-
-static struct symtab *current_symseg;
-
-/* Name of source file whose symbol data we are now processing.
- This comes from a symbol of type N_SO. */
-
-static char *last_source_file;
-
-/* Core address of start of text of current source file.
- This too comes from the N_SO symbol. */
-
-static CORE_ADDR last_source_start_addr;
-
-/* End of the text segment of the executable file,
- as found in the symbol _etext. */
-
-static CORE_ADDR end_of_text_addr;
-
-/* The list of sub-source-files within the current individual compilation.
- Each file gets its own symtab with its own linetable and associated info,
- but they all share one blockvector. */
-
-struct subfile
-{
- struct subfile *next;
- char *name;
- struct linetable *line_vector;
- int line_vector_length;
- int line_vector_index;
- int prev_line_number;
-};
-
-static struct subfile *subfiles;
-
-static struct subfile *current_subfile;
-
-/* Count symbols as they are processed, for error messages. */
-
-static int symnum;
-
-/* Vector of types defined so far, indexed by their dbx type numbers.
- (In newer sun systems, dbx uses a pair of numbers in parens,
- as in "(SUBFILENUM,NUMWITHINSUBFILE)". Then these numbers must be
- translated through the type_translations hash table to get
- the index into the type vector.) */
-
-static struct typevector *type_vector;
-
-/* Number of elements allocated for type_vector currently. */
-
-static int type_vector_length;
-
-/* Vector of line number information. */
-
-static struct linetable *line_vector;
-
-/* Index of next entry to go in line_vector_index. */
-
-static int line_vector_index;
-
-/* Last line number recorded in the line vector. */
-
-static int prev_line_number;
-
-/* Number of elements allocated for line_vector currently. */
-
-static int line_vector_length;
-
-/* Hash table of global symbols whose values are not known yet.
- They are chained thru the SYMBOL_VALUE, since we don't
- have the correct data for that slot yet. */
-
-#define HASHSIZE 127
-static struct symbol *global_sym_chain[HASHSIZE];
-
-/* Record the symbols defined for each context in a list.
- We don't create a struct block for the context until we
- know how long to make it. */
-
-#define PENDINGSIZE 100
-
-struct pending
-{
- struct pending *next;
- int nsyms;
- struct symbol *symbol[PENDINGSIZE];
-};
-
-/* List of free `struct pending' structures for reuse. */
-struct pending *free_pendings;
-
-/* Here are the three lists that symbols are put on. */
-
-struct pending *file_symbols; /* static at top level, and types */
-
-struct pending *global_symbols; /* global functions and variables */
-
-struct pending *local_symbols; /* everything local to lexical context */
-
-/* Stack representing unclosed lexical contexts
- (that will become blocks, eventually). */
-
-struct context_stack
-{
- struct pending *locals;
- struct pending_block *old_blocks;
- struct symbol *name;
- CORE_ADDR start_addr;
- int depth;
-};
-
-struct context_stack *context_stack;
-
-/* Index of first unused entry in context stack. */
-int context_stack_depth;
-
-/* Currently allocated size of context stack. */
-
-int context_stack_size;
-
-/* Nonzero if within a function (so symbols should be local,
- if nothing says specifically). */
-
-int within_function;
-
-/* List of blocks already made (lexical contexts already closed).
- This is used at the end to make the blockvector. */
-
-struct pending_block
-{
- struct pending_block *next;
- struct block *block;
-};
-
-struct pending_block *pending_blocks;
-
-extern CORE_ADDR first_object_file_end; /* From blockframe.c */
-
-/* File name symbols were loaded from. */
-
-static char *symfile;
-
-/* Low and high symbol values (inclusive) for the global variable
- entries in the symbol file. */
-
-static int first_global_sym, last_global_sym;
-
-/* Partial symbol list for all of the global and static symbols found
- in a file */
-
-struct partial_symbol *global_psymbols, *static_psymbols;
-int global_psymbols_allocated, static_psymbols_allocated;
-
-/* Position for next psymbol to be added */
-
-struct partial_symbol *next_ps_global, *next_ps_static;
-
-/* Global variable which, when set, indicates that we are processing a
- .o file compiled with gcc */
-
-static unsigned char processing_gcc_compilation;
-
-static int
-xxmalloc (n)
-{
- int v = malloc (n);
- if (v == 0)
- abort ();
- return v;
-}
-
-/* Make a copy of the string at PTR with SIZE characters in the symbol obstack
- (and add a null character at the end in the copy).
- Returns the address of the copy. */
-
-static char *
-obsavestring (ptr, size)
- char *ptr;
- int size;
-{
- register char *p = (char *) obstack_alloc (symbol_obstack, size + 1);
- /* Open-coded bcopy--saves function call time.
- These strings are usually short. */
- {
- register char *p1 = ptr;
- register char *p2 = p;
- char *end = ptr + size;
- while (p1 != end)
- *p2++ = *p1++;
- }
- p[size] = 0;
- return p;
-}
-
-/* Concatenate strings S1, S2 and S3; return the new string.
- Space is found in the symbol_obstack. */
-
-static char *
-obconcat (s1, s2, s3)
- char *s1, *s2, *s3;
-{
- register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
- register char *val = (char *) obstack_alloc (symbol_obstack, len);
- strcpy (val, s1);
- strcat (val, s2);
- strcat (val, s3);
- return val;
-}
-
-/* Support for Sun changes to dbx symbol format */
-
-/* For each identified header file, we have a table of types defined
- in that header file.
-
- header_files maps header file names to their type tables.
- It is a vector of n_header_files elements.
- Each element describes one header file.
- It contains a vector of types.
-
- Sometimes it can happen that the same header file produces
- different results when included in different places.
- This can result from conditionals or from different
- things done before including the file.
- When this happens, there are multiple entries for the file in this table,
- one entry for each distinct set of results.
- The entries are distinguished by the INSTANCE field.
- The INSTANCE field appears in the N_BINCL and N_EXCL symbol table and is
- used to match header-file references to their corresponding data. */
-
-struct header_file
-{
- char *name; /* Name of header file */
- int instance; /* Numeric code distinguishing instances
- of one header file that produced
- different results when included.
- It comes from the N_BINCL or N_EXCL. */
- struct type **vector; /* Pointer to vector of types */
- int length; /* Allocated length (# elts) of that vector */
-};
-
-static struct header_file *header_files;
-
-static int n_header_files;
-
-static int n_allocated_header_files;
-
-/* During initial symbol readin, we need to have a structure to keep
- track of which psymtabs have which bincls in them. This structure
- is used during readin to setup the list of dependencies within each
- partial symbol table. */
-
-struct header_file_location
-{
- char *name; /* Name of header file */
- int instance; /* See above */
- struct partial_symtab *pst; /* Partial symtab that has the
- BINCL/EINCL defs for this file */
-};
-
-/* The actual list and controling variables */
-static struct header_file_location *bincl_list, *next_bincl;
-static int bincls_allocated;
-
-/* Within each object file, various header files are assigned numbers.
- A type is defined or referred to with a pair of numbers
- (FILENUM,TYPENUM) where FILENUM is the number of the header file
- and TYPENUM is the number within that header file.
- TYPENUM is the index within the vector of types for that header file.
-
- FILENUM == 1 is special; it refers to the main source of the object file,
- and not to any header file. FILENUM != 1 is interpreted by looking it up
- in the following table, which contains indices in header_files. */
-
-static int *this_object_header_files;
-
-static int n_this_object_header_files;
-
-static int n_allocated_this_object_header_files;
-
-/* When a header file is getting special overriding definitions
- for one source file, record here the header_files index
- of its normal definition vector.
- At other times, this is -1. */
-
-static int header_file_prev_index;
-
-/* At the start of reading dbx symbols, allocate our tables. */
-
-static void
-init_header_files ()
-{
- n_allocated_header_files = 10;
- header_files = (struct header_file *) xxmalloc (10 * sizeof (struct header_file));
- n_header_files = 0;
-
- n_allocated_this_object_header_files = 10;
- this_object_header_files = (int *) xxmalloc (10 * sizeof (int));
-}
-
-/* At the end of reading dbx symbols, free our tables. */
-
-static void
-free_header_files ()
-{
- register int i;
- for (i = 0; i < n_header_files; i++)
- free (header_files[i].name);
- if (header_files) free (header_files);
- if (this_object_header_files)
- free (this_object_header_files);
-}
-
-/* Called at the start of each object file's symbols.
- Clear out the mapping of header file numbers to header files. */
-
-static void
-new_object_header_files ()
-{
- /* Leave FILENUM of 0 free for builtin types and this file's types. */
- n_this_object_header_files = 1;
- header_file_prev_index = -1;
-}
-
-/* Add header file number I for this object file
- at the next successive FILENUM. */
-
-static void
-add_this_object_header_file (i)
- int i;
-{
- if (n_this_object_header_files == n_allocated_this_object_header_files)
- {
- n_allocated_this_object_header_files *= 2;
- this_object_header_files
- = (int *) xrealloc (this_object_header_files,
- n_allocated_this_object_header_files * sizeof (int));
- }
-
- this_object_header_files[n_this_object_header_files++] = i;
-}
-
-/* Add to this file an "old" header file, one already seen in
- a previous object file. NAME is the header file's name.
- INSTANCE is its instance code, to select among multiple
- symbol tables for the same header file. */
-
-static void
-add_old_header_file (name, instance)
- char *name;
- int instance;
-{
- register struct header_file *p = header_files;
- register int i;
-
- for (i = 0; i < n_header_files; i++)
- if (!strcmp (p[i].name, name) && instance == p[i].instance)
- {
- add_this_object_header_file (i);
- return;
- }
- error ("Invalid symbol data: \"repeated\" header file that hasn't been seen before, at symtab pos %d.",
- symnum);
-}
-
-/* Add to this file a "new" header file: definitions for its types follow.
- NAME is the header file's name.
- Most often this happens only once for each distinct header file,
- but not necessarily. If it happens more than once, INSTANCE has
- a different value each time, and references to the header file
- use INSTANCE values to select among them.
-
- dbx output contains "begin" and "end" markers for each new header file,
- but at this level we just need to know which files there have been;
- so we record the file when its "begin" is seen and ignore the "end". */
-
-static void
-add_new_header_file (name, instance)
- char *name;
- int instance;
-{
- register int i;
- register struct header_file *p = header_files;
- header_file_prev_index = -1;
-
-#if 0
- /* This code was used before I knew about the instance codes.
- My first hypothesis is that it is not necessary now
- that instance codes are handled. */
-
- /* Has this header file a previous definition?
- If so, make a new entry anyway so that this use in this source file
- gets a separate entry. Later source files get the old entry.
- Record here the index of the old entry, so that any type indices
- not previously defined can get defined in the old entry as
- well as in the new one. */
-
- for (i = 0; i < n_header_files; i++)
- if (!strcmp (p[i].name, name))
- {
- header_file_prev_index = i;
- }
-
-#endif
-
- /* Make sure there is room for one more header file. */
-
- if (n_header_files == n_allocated_header_files)
- {
- n_allocated_header_files *= 2;
- header_files = (struct header_file *)
- xrealloc (header_files,
- (n_allocated_header_files
- * sizeof (struct header_file)));
- }
-
- /* Create an entry for this header file. */
-
- i = n_header_files++;
- header_files[i].name = savestring (name, strlen(name));
- header_files[i].instance = instance;
- header_files[i].length = 10;
- header_files[i].vector
- = (struct type **) xxmalloc (10 * sizeof (struct type *));
- bzero (header_files[i].vector, 10 * sizeof (struct type *));
-
- add_this_object_header_file (i);
-}
-
-/* Look up a dbx type-number pair. Return the address of the slot
- where the type for that number-pair is stored.
- The number-pair is in TYPENUMS.
-
- This can be used for finding the type associated with that pair
- or for associating a new type with the pair. */
-
-static struct type **
-dbx_lookup_type (typenums)
- int typenums[2];
-{
- register int filenum = typenums[0], index = typenums[1];
-
- if (filenum < 0 || filenum >= n_this_object_header_files)
- error ("Invalid symbol data: type number (%d,%d) out of range at symtab pos %d.",
- filenum, index, symnum);
-
- if (filenum == 0)
- {
- /* Type is defined outside of header files.
- Find it in this object file's type vector. */
- if (index >= type_vector_length)
- {
- type_vector_length *= 2;
- type_vector = (struct typevector *)
- xrealloc (type_vector,
- (sizeof (struct typevector)
- + type_vector_length * sizeof (struct type *)));
- bzero (&type_vector->type[type_vector_length / 2],
- type_vector_length * sizeof (struct type *) / 2);
- }
- return &type_vector->type[index];
- }
- else
- {
- register int real_filenum = this_object_header_files[filenum];
- register struct header_file *f;
-
- if (real_filenum >= n_header_files)
- abort ();
-
- f = &header_files[real_filenum];
-
- if (index >= f->length)
- {
- f->length *= 2;
- f->vector = (struct type **)
- xrealloc (f->vector, f->length * sizeof (struct type *));
- bzero (&f->vector[f->length / 2],
- f->length * sizeof (struct type *) / 2);
- }
- return &f->vector[index];
- }
-}
-
-/* Make sure there is a type allocated for type numbers TYPENUMS
- and return the type object.
- This can create an empty (zeroed) type object. */
-
-static struct type *
-dbx_alloc_type (typenums)
- int typenums[2];
-{
- register struct type **type_addr = dbx_lookup_type (typenums);
- register struct type *type = *type_addr;
-
- /* If we are referring to a type not known at all yet,
- allocate an empty type for it.
- We will fill it in later if we find out how. */
- if (type == 0)
- {
- type = (struct type *) obstack_alloc (symbol_obstack,
- sizeof (struct type));
- bzero (type, sizeof (struct type));
- TYPE_VPTR_FIELDNO (type) = -1;
- *type_addr = type;
- }
- return type;
-}
-
-#if 0
-static struct type **
-explicit_lookup_type (real_filenum, index)
- int real_filenum, index;
-{
- register struct header_file *f = &header_files[real_filenum];
-
- if (index >= f->length)
- {
- f->length *= 2;
- f->vector = (struct type **)
- xrealloc (f->vector, f->length * sizeof (struct type *));
- bzero (&f->vector[f->length / 2],
- f->length * sizeof (struct type *) / 2);
- }
- return &f->vector[index];
-}
-#endif
-
-/* maintain the lists of symbols and blocks */
-
-/* Add a symbol to one of the lists of symbols. */
-static void
-add_symbol_to_list (symbol, listhead)
- struct symbol *symbol;
- struct pending **listhead;
-{
- /* We keep PENDINGSIZE symbols in each link of the list.
- If we don't have a link with room in it, add a new link. */
- if (*listhead == 0 || (*listhead)->nsyms == PENDINGSIZE)
- {
- register struct pending *link;
- if (free_pendings)
- {
- link = free_pendings;
- free_pendings = link->next;
- }
- else
- link = (struct pending *) xxmalloc (sizeof (struct pending));
-
- link->next = *listhead;
- *listhead = link;
- link->nsyms = 0;
- }
-
- (*listhead)->symbol[(*listhead)->nsyms++] = symbol;
-}
-
-/* At end of reading syms, or in case of quit,
- really free as many `struct pending's as we can easily find. */
-
-static void
-really_free_pendings ()
-{
- struct pending *next, *next1;
- struct pending_block *bnext, *bnext1;
-
- for (next = free_pendings; next; next = next1)
- {
- next1 = next->next;
- free (next);
- }
- free_pendings = 0;
-
- for (bnext = pending_blocks; bnext; bnext = bnext1)
- {
- bnext1 = bnext->next;
- free (bnext);
- }
- pending_blocks = 0;
-
- for (next = file_symbols; next; next = next1)
- {
- next1 = next->next;
- free (next);
- }
- for (next = global_symbols; next; next = next1)
- {
- next1 = next->next;
- free (next);
- }
-}
-
-/* Take one of the lists of symbols and make a block from it.
- Keep the order the symbols have in the list (reversed from the input file).
- Put the block on the list of pending blocks. */
-
-static void
-finish_block (symbol, listhead, old_blocks, start, end)
- struct symbol *symbol;
- struct pending **listhead;
- struct pending_block *old_blocks;
- CORE_ADDR start, end;
-{
- register struct pending *next, *next1;
- register struct block *block;
- register struct pending_block *pblock;
- struct pending_block *opblock;
- register int i;
-
- /* Count the length of the list of symbols. */
-
- for (next = *listhead, i = 0; next; i += next->nsyms, next = next->next);
-
- block = (struct block *) obstack_alloc (symbol_obstack,
- (sizeof (struct block)
- + ((i - 1)
- * sizeof (struct symbol *))));
-
- /* Copy the symbols into the block. */
-
- BLOCK_NSYMS (block) = i;
- for (next = *listhead; next; next = next->next)
- {
- register int j;
- for (j = next->nsyms - 1; j >= 0; j--)
- BLOCK_SYM (block, --i) = next->symbol[j];
- }
-
- BLOCK_START (block) = start;
- BLOCK_END (block) = end;
- BLOCK_SUPERBLOCK (block) = 0; /* Filled in when containing block is made */
- BLOCK_GCC_COMPILED (block) = processing_gcc_compilation;
-
- /* Put the block in as the value of the symbol that names it. */
-
- if (symbol)
- {
- SYMBOL_BLOCK_VALUE (symbol) = block;
- BLOCK_FUNCTION (block) = symbol;
- }
- else
- BLOCK_FUNCTION (block) = 0;
-
- /* Now "free" the links of the list, and empty the list. */
-
- for (next = *listhead; next; next = next1)
- {
- next1 = next->next;
- next->next = free_pendings;
- free_pendings = next;
- }
- *listhead = 0;
-
- /* Install this block as the superblock
- of all blocks made since the start of this scope
- that don't have superblocks yet. */
-
- opblock = 0;
- for (pblock = pending_blocks; pblock != old_blocks; pblock = pblock->next)
- {
- if (BLOCK_SUPERBLOCK (pblock->block) == 0)
- BLOCK_SUPERBLOCK (pblock->block) = block;
- opblock = pblock;
- }
-
- /* Record this block on the list of all blocks in the file.
- Put it after opblock, or at the beginning if opblock is 0.
- This puts the block in the list after all its subblocks. */
-
- /* Allocate in the symbol_obstack to save time.
- It wastes a little space. */
- pblock = (struct pending_block *)
- obstack_alloc (symbol_obstack,
- sizeof (struct pending_block));
- pblock->block = block;
- if (opblock)
- {
- pblock->next = opblock->next;
- opblock->next = pblock;
- }
- else
- {
- pblock->next = pending_blocks;
- pending_blocks = pblock;
- }
-}
-
-static struct blockvector *
-make_blockvector ()
-{
- register struct pending_block *next, *next1;
- register struct blockvector *blockvector;
- register int i;
-
- /* Count the length of the list of blocks. */
-
- for (next = pending_blocks, i = 0; next; next = next->next, i++);
-
- blockvector = (struct blockvector *)
- obstack_alloc (symbol_obstack,
- (sizeof (struct blockvector)
- + (i - 1) * sizeof (struct block *)));
-
- /* Copy the blocks into the blockvector.
- This is done in reverse order, which happens to put
- the blocks into the proper order (ascending starting address).
- finish_block has hair to insert each block into the list
- after its subblocks in order to make sure this is true. */
-
- BLOCKVECTOR_NBLOCKS (blockvector) = i;
- for (next = pending_blocks; next; next = next->next)
- BLOCKVECTOR_BLOCK (blockvector, --i) = next->block;
-
-#if 0 /* Now we make the links in the obstack, so don't free them. */
- /* Now free the links of the list, and empty the list. */
-
- for (next = pending_blocks; next; next = next1)
- {
- next1 = next->next;
- free (next);
- }
-#endif
- pending_blocks = 0;
-
- return blockvector;
-}
-
-/* Manage the vector of line numbers. */
-
-static void
-record_line (line, pc)
- int line;
- CORE_ADDR pc;
-{
- struct linetable_entry *e;
- /* Ignore the dummy line number in libg.o */
-
- if (line == 0xffff)
- return;
-
- /* Make sure line vector is big enough. */
-
- if (line_vector_index + 1 >= line_vector_length)
- {
- line_vector_length *= 2;
- line_vector = (struct linetable *)
- xrealloc (line_vector,
- (sizeof (struct linetable)
- + line_vector_length * sizeof (struct linetable_entry)));
- current_subfile->line_vector = line_vector;
- }
-
- e = line_vector->item + line_vector_index++;
- e->line = line; e->pc = pc;
-}
-
-/* Start a new symtab for a new source file.
- This is called when a dbx symbol of type N_SO is seen;
- it indicates the start of data for one original source file. */
-
-static void
-start_symtab (name, start_addr)
- char *name;
- CORE_ADDR start_addr;
-{
- register struct symtab *s;
-
- last_source_file = name;
- last_source_start_addr = start_addr;
- file_symbols = 0;
- global_symbols = 0;
- within_function = 0;
-
- /* Context stack is initially empty, with room for 10 levels. */
- context_stack
- = (struct context_stack *) xxmalloc (10 * sizeof (struct context_stack));
- context_stack_size = 10;
- context_stack_depth = 0;
-
- new_object_header_files ();
-
- for (s = symseg_chain; s; s = s->next)
- if (s->ldsymoff == symnum * sizeof (struct nlist))
- break;
- current_symseg = s;
- if (s != 0)
- return;
-
- type_vector_length = 160;
- type_vector = (struct typevector *)
- xxmalloc (sizeof (struct typevector)
- + type_vector_length * sizeof (struct type *));
- bzero (type_vector->type, type_vector_length * sizeof (struct type *));
-
- /* Initialize the list of sub source files with one entry
- for this file (the top-level source file). */
-
- subfiles = 0;
- current_subfile = 0;
- start_subfile (name);
-
- /* Set default for compiler to pcc; assume that we aren't processing
- a gcc compiled file until proved otherwise. */
-
- processing_gcc_compilation = 0;
-}
-
-/* Handle an N_SOL symbol, which indicates the start of
- code that came from an included (or otherwise merged-in)
- source file with a different name. */
-
-static void
-start_subfile (name)
- char *name;
-{
- register struct subfile *subfile;
-
- /* Save the current subfile's line vector data. */
-
- if (current_subfile)
- {
- current_subfile->line_vector_index = line_vector_index;
- current_subfile->line_vector_length = line_vector_length;
- current_subfile->prev_line_number = prev_line_number;
- }
-
- /* See if this subfile is already known as a subfile of the
- current main source file. */
-
- for (subfile = subfiles; subfile; subfile = subfile->next)
- {
- if (!strcmp (subfile->name, name))
- {
- line_vector = subfile->line_vector;
- line_vector_index = subfile->line_vector_index;
- line_vector_length = subfile->line_vector_length;
- prev_line_number = subfile->prev_line_number;
- current_subfile = subfile;
- return;
- }
- }
-
- /* This subfile is not known. Add an entry for it. */
-
- line_vector_index = 0;
- line_vector_length = 1000;
- prev_line_number = -2; /* Force first line number to be explicit */
- line_vector = (struct linetable *)
- xxmalloc (sizeof (struct linetable)
- + line_vector_length * sizeof (struct linetable_entry));
-
- /* Make an entry for this subfile in the list of all subfiles
- of the current main source file. */
-
- subfile = (struct subfile *) xxmalloc (sizeof (struct subfile));
- subfile->next = subfiles;
- subfile->name = savestring (name, strlen (name));
- subfile->line_vector = line_vector;
- subfiles = subfile;
- current_subfile = subfile;
-}
-
-/* Finish the symbol definitions for one main source file,
- close off all the lexical contexts for that file
- (creating struct block's for them), then make the struct symtab
- for that file and put it in the list of all such.
-
- END_ADDR is the address of the end of the file's text. */
-
-static void
-end_symtab (end_addr)
- CORE_ADDR end_addr;
-{
- register struct symtab *symtab;
- register struct blockvector *blockvector;
- register struct subfile *subfile;
- register struct linetable *lv;
- struct subfile *nextsub;
-
- if (current_symseg != 0)
- {
- last_source_file = 0;
- current_symseg = 0;
- return;
- }
-
- /* Finish the lexical context of the last function in the file;
- pop the context stack. */
-
- if (context_stack_depth > 0)
- {
- register struct context_stack *cstk;
- context_stack_depth--;
- cstk = &context_stack[context_stack_depth];
- /* Make a block for the local symbols within. */
- finish_block (cstk->name, &local_symbols, cstk->old_blocks,
- cstk->start_addr, end_addr);
- }
-
- /* Finish defining all the blocks of this symtab. */
- finish_block (0, &file_symbols, 0, last_source_start_addr, end_addr);
- finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr);
- blockvector = make_blockvector ();
-
- current_subfile->line_vector_index = line_vector_index;
-
- /* Now create the symtab objects proper, one for each subfile. */
- /* (The main file is one of them.) */
-
- for (subfile = subfiles; subfile; subfile = nextsub)
- {
- symtab = (struct symtab *) xxmalloc (sizeof (struct symtab));
- symtab->free_ptr = 0;
-
- /* Fill in its components. */
- symtab->blockvector = blockvector;
- type_vector->length = type_vector_length;
- symtab->typevector = type_vector;
- symtab->free_code = free_linetable;
- if (subfile->next == 0)
- symtab->free_ptr = (char *) type_vector;
-
- symtab->filename = subfile->name;
- lv = subfile->line_vector;
- lv->nitems = subfile->line_vector_index;
- symtab->linetable = (struct linetable *)
- xrealloc (lv, (sizeof (struct linetable)
- + lv->nitems * sizeof (struct linetable_entry)));
- symtab->nlines = 0;
- symtab->line_charpos = 0;
-
- /* Link the new symtab into the list of such. */
- symtab->next = symtab_list;
- symtab_list = symtab;
-
- nextsub = subfile->next;
- free (subfile);
- }
-
- type_vector = 0;
- type_vector_length = -1;
- line_vector = 0;
- line_vector_length = -1;
- last_source_file = 0;
-}
-
-#ifdef N_BINCL
-
-/* Handle the N_BINCL and N_EINCL symbol types
- that act like N_SOL for switching source files
- (different subfiles, as we call them) within one object file,
- but using a stack rather than in an arbitrary order. */
-
-struct subfile_stack
-{
- struct subfile_stack *next;
- char *name;
- int prev_index;
-};
-
-struct subfile_stack *subfile_stack;
-
-static void
-push_subfile ()
-{
- register struct subfile_stack *tem
- = (struct subfile_stack *) xxmalloc (sizeof (struct subfile_stack));
-
- tem->next = subfile_stack;
- subfile_stack = tem;
- if (current_subfile == 0 || current_subfile->name == 0)
- abort ();
- tem->name = current_subfile->name;
- tem->prev_index = header_file_prev_index;
-}
-
-static char *
-pop_subfile ()
-{
- register char *name;
- register struct subfile_stack *link = subfile_stack;
-
- if (link == 0)
- abort ();
-
- name = link->name;
- subfile_stack = link->next;
- header_file_prev_index = link->prev_index;
- free (link);
-
- return name;
-}
-#endif /* Have N_BINCL */
-
-/* Accumulate the misc functions in bunches of 127.
- At the end, copy them all into one newly allocated structure. */
-
-#define MISC_BUNCH_SIZE 127
-
-struct misc_bunch
-{
- struct misc_bunch *next;
- struct misc_function contents[MISC_BUNCH_SIZE];
-};
-
-/* Bunch currently being filled up.
- The next field points to chain of filled bunches. */
-
-static struct misc_bunch *misc_bunch;
-
-/* Number of slots filled in current bunch. */
-
-static int misc_bunch_index;
-
-/* Total number of misc functions recorded so far. */
-
-static int misc_count;
-
-static void
-init_misc_functions ()
-{
- misc_count = 0;
- misc_bunch = 0;
- misc_bunch_index = MISC_BUNCH_SIZE;
-}
-
-static void
-record_misc_function (name, address)
- char *name;
- CORE_ADDR address;
-{
- register struct misc_bunch *new;
-
- if (misc_bunch_index == MISC_BUNCH_SIZE)
- {
- new = (struct misc_bunch *) xxmalloc (sizeof (struct misc_bunch));
- misc_bunch_index = 0;
- new->next = misc_bunch;
- misc_bunch = new;
- }
- misc_bunch->contents[misc_bunch_index].name = name;
- misc_bunch->contents[misc_bunch_index].address = address;
- misc_bunch_index++;
- misc_count++;
-}
-
-static int
-compare_misc_functions (fn1, fn2)
- struct misc_function *fn1, *fn2;
-{
- /* Return a signed result based on unsigned comparisons
- so that we sort into unsigned numeric order. */
- if (fn1->address < fn2->address)
- return -1;
- if (fn1->address > fn2->address)
- return 1;
- return 0;
-}
-
-static void
-discard_misc_bunches ()
-{
- register struct misc_bunch *next;
-
- while (misc_bunch)
- {
- next = misc_bunch->next;
- free (misc_bunch);
- misc_bunch = next;
- }
-}
-
-/* INCLINK nonzero means bunches are from an incrementally-linked file.
- Add them to the existing bunches.
- Otherwise INCLINK is zero, and we start from scratch. */
-static void
-condense_misc_bunches (inclink)
- int inclink;
-{
- register int i, j;
- register struct misc_bunch *bunch;
-#ifdef NAMES_HAVE_UNDERSCORE
- int offset = 1;
-#else
- int offset = 0;
-#endif
-
- if (inclink)
- {
- misc_function_vector
- = (struct misc_function *)
- xrealloc (misc_function_vector, (misc_count + misc_function_count)
- * sizeof (struct misc_function));
- j = misc_function_count;
- }
- else
- {
- misc_function_vector
- = (struct misc_function *)
- xxmalloc (misc_count * sizeof (struct misc_function));
- j = 0;
- }
-
- bunch = misc_bunch;
- while (bunch)
- {
- for (i = 0; i < misc_bunch_index; i++)
- {
- misc_function_vector[j] = bunch->contents[i];
- misc_function_vector[j].name
- = obconcat (misc_function_vector[j].name
- + (misc_function_vector[j].name[0] == '_' ? offset : 0),
- "", "");
- j++;
- }
- bunch = bunch->next;
- misc_bunch_index = MISC_BUNCH_SIZE;
- }
-
- if (inclink)
- misc_function_count += misc_count;
- else
- misc_function_count = j;
-
- /* Sort the misc functions by address. */
-
- qsort (misc_function_vector, misc_function_count,
- sizeof (struct misc_function),
- compare_misc_functions);
-}
-
-/* Call sort_syms to sort alphabetically
- the symbols of each block of each symtab. */
-
-static int
-compare_symbols (s1, s2)
- struct symbol **s1, **s2;
-{
- register int namediff;
-
- /* Compare the initial characters. */
- namediff = SYMBOL_NAME (*s1)[0] - SYMBOL_NAME (*s2)[0];
- if (namediff != 0) return namediff;
-
- /* If they match, compare the rest of the names. */
- namediff = strcmp (SYMBOL_NAME (*s1), SYMBOL_NAME (*s2));
- if (namediff != 0) return namediff;
-
- /* For symbols of the same name, registers should come first. */
- return ((SYMBOL_CLASS (*s2) == LOC_REGISTER)
- - (SYMBOL_CLASS (*s1) == LOC_REGISTER));
-}
-
-static void sort_symtab_syms ();
-
-static void
-sort_syms ()
-{
- register struct symtab *s;
-
- for (s = symtab_list; s; s = s->next)
- sort_symtab_syms (s);
-}
-
-static void
-sort_symtab_syms (s)
- register struct symtab *s;
-{
- register struct blockvector *bv = BLOCKVECTOR (s);
- int nbl = BLOCKVECTOR_NBLOCKS (bv);
- int i;
- register struct block *b;
-
- /* Note that in the following sort, we always make sure that
- register debug symbol declarations always come before regular
- debug symbol declarations (as might happen when parameters are
- then put into registers by the compiler). We do this by a
- correct compare in compare_symbols, and by the reversal of the
- symbols if we don't sort. This works as long as a register debug
- symbol always comes after a parameter debug symbol. */
-
- /* This is no longer necessary; lookup_block_symbol now always
- prefers some other declaration over a parameter declaration. We
- still sort the thing (that is necessary), but we don't reverse it
- if we shouldn't sort it. */
-
- for (i = 0; i < nbl; i++)
- {
- b = BLOCKVECTOR_BLOCK (bv, i);
- if (BLOCK_SHOULD_SORT (b))
- qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b),
- sizeof (struct symbol *), compare_symbols);
- }
-}
-
-
-extern struct symtab *psymtab_to_symtab ();
-
-/* This is the symbol-file command. Read the file, analyze its symbols,
- and add a struct symtab to symtab_list. */
-
-void
-symbol_file_command (name)
- char *name;
-{
- register int desc;
- DECLARE_FILE_HEADERS;
- struct nlist *nlist;
- char *stringtab;
- long buffer;
- register int val;
- extern void close ();
- struct cleanup *old_chain;
- struct symtab *symseg;
- struct stat statbuf;
-
- dont_repeat ();
-
- if (name == 0)
- {
- if ((symtab_list || partial_symtab_list)
- && !query ("Discard symbol table? ", 0))
- error ("Not confirmed.");
- if (symfile)
- free (symfile);
- symfile = 0;
- free_all_symtabs ();
- free_all_psymtabs ();
- return;
- }
-
- if ((symtab_list || partial_symtab_list)
- && !query ("Load new symbol table from \"%s\"? ", name))
- error ("Not confirmed.");
-
- {
- char *absolute_name;
- desc = openp (getenv ("PATH"), 1, name, O_RDONLY, 0, &absolute_name);
- if (desc < 0)
- perror_with_name (name);
- else
- name = absolute_name;
- }
-
- old_chain = make_cleanup (close, desc);
- make_cleanup (free_current_contents, &name);
-
- READ_FILE_HEADERS (desc, name);
-
- if (NUMBER_OF_SYMBOLS == 0)
- {
- if (symfile)
- free (symfile);
- symfile = 0;
- free_all_symtabs ();
- free_all_psymtabs ();
- printf ("%s has no symbol-table; symbols discarded.\n", name);
- fflush (stdout);
- do_cleanups (old_chain);
- return;
- }
-
- printf ("Reading symbol data from %s...", name);
- fflush (stdout);
-
- /* Now read the string table, all at once. */
- val = lseek (desc, STRING_TABLE_OFFSET, 0);
- if (val < 0)
- perror_with_name (name);
- stat (name, &statbuf);
- READ_STRING_TABLE_SIZE (buffer);
- if (buffer >= 0 && buffer < statbuf.st_size)
- stringtab = (char *) alloca (buffer);
- else
- stringtab = NULL;
- if (stringtab == NULL)
- error ("ridiculous string table size: %d bytes", name, buffer);
-
- bcopy (&buffer, stringtab, sizeof buffer);
- val = myread (desc, stringtab + sizeof buffer, buffer - sizeof buffer);
- if (val < 0)
- perror_with_name (name);
-
- /* Throw away the old symbol table. */
-
- if (symfile)
- free (symfile);
- symfile = 0;
- free_all_symtabs ();
- free_all_psymtabs ();
-
- /* Empty the hash table of global syms looking for values. */
- bzero (global_sym_chain, sizeof global_sym_chain);
-
-#ifdef READ_GDB_SYMSEGS
- /* That puts us at the symsegs. Read them. */
- symseg_chain = read_symsegs (desc, name);
- hash_symsegs ();
-
- /* Free the symtabs made by read_symsegs, but not their contents,
- which have been copied into symtabs on symtab_list. */
- for (symseg = symseg_chain; symseg; symseg = symseg->next)
- {
- int i;
- struct sourcevector *sv = (struct sourcevector *) symseg->linetable;
-
- for (i = 0; i < sv->length; i++)
- {
- int j;
- struct source *source = sv->source[i];
- struct symtab *sp1
- = (struct symtab *) xxmalloc (sizeof (struct symtab));
-
- bcopy (symseg, sp1, sizeof (struct symtab));
- sp1->filename = savestring (source->name, strlen (source->name));
- sp1->linetable = &source->contents;
- sp1->free_code = free_nothing;
- sp1->free_ptr = (i == 0) ? (char *) symseg : 0;
-
- sp1->next = symtab_list;
- symtab_list = sp1;
- }
- }
-#else
- /* Where people are using the 4.2 ld program, must not check for
- symsegs, because that ld puts randonm garbage at the end of
- the output file and that would trigger an error message. */
- symseg_chain = 0;
-#endif
-
- /* Position to read the symbol table. Do not read it all at once. */
- val = lseek (desc, SYMBOL_TABLE_OFFSET, 0);
- if (val < 0)
- perror_with_name (name);
-
- /* Don't put these on the cleanup chain; they need to stick around
- until the next call to symbol_file_command. *Then* we'll free
- them. */
- free_header_files ();
- init_header_files ();
-
- init_misc_functions ();
- make_cleanup (discard_misc_bunches, 0);
-
- free_pendings = 0;
- pending_blocks = 0;
- file_symbols = 0;
- global_symbols = 0;
- make_cleanup (really_free_pendings, 0);
-
- /* Now that the symbol table data of the executable file are all in core,
- process them and define symbols accordingly. Closes desc. */
-
- read_dbx_symtab (desc, stringtab, NUMBER_OF_SYMBOLS, 0, 0, 0);
-
- /* Go over the misc functions and install them in vector. */
-
- condense_misc_bunches (0);
-
- /* Don't allow char * to have a typename (else would get caddr_t.) */
-
- TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0;
-
- /* Make a default for file to list. */
-
- symfile = savestring (name, strlen (name));
-
- /* Call to select_source_symtab used to be here; it was using too
- much time. I'll make sure that list_sources can handle the lack
- of current_source_symtab */
-
- do_cleanups (old_chain); /* Descriptor closed here */
-
- /* Free the symtabs made by read_symsegs, but not their contents,
- which have been copied into symtabs on symtab_list. */
- while (symseg_chain)
- {
- register struct symtab *s = symseg_chain->next;
- free (symseg_chain);
- symseg_chain = s;
- }
-
- if (!partial_symtab_list)
- printf ("\n(no debugging symbols found)...");
-
- printf ("done.\n");
- fflush (stdout);
-}
-
-/* Return name of file symbols were loaded from, or 0 if none.. */
-
-char *
-get_sym_file ()
-{
- return symfile;
-}
-
-/* Buffer for reading the symbol table entries. */
-static struct nlist symbuf[4096];
-static int symbuf_idx;
-static int symbuf_end;
-
-/* I/O descriptor for reading the symbol table. */
-static int symtab_input_desc;
-
-/* The address of the string table
- of the object file we are reading (as copied into core). */
-static char *stringtab_global;
-
-/* Refill the symbol table input buffer
- and set the variables that control fetching entries from it.
- Reports an error if no data available.
- This function can read past the end of the symbol table
- (into the string table) but this does no harm. */
-
-static int
-fill_symbuf ()
-{
- int nbytes = myread (symtab_input_desc, symbuf, sizeof (symbuf));
- if (nbytes <= 0)
- error ("error or end of file reading symbol table");
- symbuf_end = nbytes / sizeof (struct nlist);
- symbuf_idx = 0;
- return 1;
-}
-
-/* dbx allows the text of a symbol name to be continued into the
- next symbol name! When such a continuation is encountered
- (a \ at the end of the text of a name)
- call this function to get the continuation. */
-
-static char *
-next_symbol_text ()
-{
- if (symbuf_idx == symbuf_end)
- fill_symbuf ();
- symnum++;
- return symbuf[symbuf_idx++].n_un.n_strx + stringtab_global;
-}
-
-/*
- * Initializes storage for all of the partial symbols that will be
- * created by read_dbx_symtab and subsidiaries.
- */
-void
-init_psymbol_list (total_symbols)
- int total_symbols;
-{
- /* Current best guess is that there are approximately a twentieth
- of the total symbols (in a debugging file) are global or static
- oriented symbols */
- global_psymbols_allocated = total_symbols / 10;
- static_psymbols_allocated = total_symbols / 10;
- next_ps_global = global_psymbols = (struct partial_symbol *)
- xmalloc (global_psymbols_allocated * sizeof (struct partial_symbol));
- next_ps_static = static_psymbols = (struct partial_symbol *)
- xmalloc (static_psymbols_allocated * sizeof (struct partial_symbol));
-}
-
-/*
- * Initialize the list of bincls to contain none and have some
- * allocated.
- */
-static void
-init_bincl_list (number)
- int number;
-{
- bincls_allocated = number;
- next_bincl = bincl_list = (struct header_file_location *)
- xmalloc (bincls_allocated * sizeof(struct header_file_location));
-}
-
-/*
- * Add a bincl to the list.
- */
-static void
-add_bincl_to_list (pst, name, instance)
- struct partial_symtab *pst;
- char *name;
- int instance;
-{
- if (next_bincl >= bincl_list + bincls_allocated)
- {
- int offset = next_bincl - bincl_list;
- bincls_allocated *= 2;
- bincl_list = (struct header_file_location *)
- xrealloc (bincl_list,
- bincls_allocated * sizeof (struct header_file_location));
- next_bincl = bincl_list + offset;
- }
- next_bincl->pst = pst;
- next_bincl->instance = instance;
- next_bincl++->name = name;
-}
-
-/*
- * Given a name, value pair, find the corresponding
- * bincl in the list. Return the partial symtab associated
- * with that header_file_location.
- */
-struct partial_symtab *
-find_corresponding_bincl_psymtab (name, instance)
- char *name;
- int instance;
-{
- struct header_file_location *bincl;
-
- for (bincl = bincl_list; bincl < next_bincl; bincl++)
- if (bincl->instance == instance
- && !strcmp (name, bincl->name))
- return bincl->pst;
-
- return (struct partial_symtab *) 0;
-}
-
-/*
- * Free the storage allocated for the bincl list.
- */
-static void
-free_bincl_list ()
-{
- free (bincl_list);
- bincls_allocated = 0;
-}
-
-static struct partial_symtab *start_psymtab ();
-static void add_psymtab_dependency ();
-static void end_psymtab();
-
-/* Given pointers to an a.out symbol table in core containing dbx
- style data, setup partial_symtab's describing each source file for
- which debugging information is available. NLISTLEN is the number
- of symbols in the symbol table. All symbol names are given as
- offsets relative to STRINGTAB.
-
- I have no idea whether or not this routine should be setup to deal
- with inclinks. It seems reasonable to me that they be dealt with
- standardly, so I am not going to make a strong effort to deal with
- them here.
- */
-
-static void process_symbol_for_psymtab ();
-
-static void
-read_dbx_symtab (desc, stringtab, nlistlen, inclink, text_addr, text_size)
- int desc;
- register char *stringtab;
- register int nlistlen;
- int inclink;
- unsigned text_addr;
- int text_size;
-{
- register char *namestring;
- register struct symbol *sym, *prev;
- int hash;
- int num_object_files = 0;
- int past_first_source_file = 0;
- struct cleanup *old_chain;
- int current_text_start, current_file_symbol_start;
- struct pending *global_symbols, *static_symbols;
- int nsl; /* Length of namestring, when needed */
-
- /* Current partial symtab */
- struct partial_symtab *pst;
-
- /* List of current psymtab's include files */
- char **psymtab_include_list;
- int includes_allocated;
- int includes_used;
-
- /* Index within current psymtab dependency list */
- struct partial_symtab **dependency_list;
- int dependencies_used, dependencies_allocated;
-
- /* Setup a define to deal cleanly with the underscore problem */
-
-#ifdef NAMES_HAVE_UNDERSCORE
-#define HASH_OFFSET 1
-#else
-#define HASH_OFFSET 0
-#endif
-
- global_symbols = static_symbols =
- (struct pending *) 0;
- pst = (struct partial_symtab *) 0;
-
- includes_allocated = 30;
- includes_used = 0;
- psymtab_include_list = (char **) alloca (includes_allocated *
- sizeof (char *));
-
- dependencies_allocated = 30;
- dependencies_used = 0;
- dependency_list =
- (struct partial_symtab **) alloca (dependencies_allocated *
- sizeof (struct partial_symtab *));
-
- old_chain = make_cleanup (free_all_psymtabs, 0);
-
- /* Init bincl list */
- init_bincl_list (20);
- make_cleanup (free_bincl_list, 0);
-
- /* Setup global partial symbol list */
- init_psymbol_list (nlistlen);
-
- last_source_file = 0;
-
-#ifdef END_OF_TEXT_DEFAULT
- end_of_text_addr = END_OF_TEXT_DEFAULT;
-#endif
-
- symtab_input_desc = desc; /* This is needed for fill_symbuf below */
- symbuf_end = symbuf_idx = 0;
-
- for (symnum = 0; symnum < nlistlen; symnum++)
- {
- struct nlist *bufp;
- unsigned char type;
-
- /* Get the symbol for this run and pull out some info */
- QUIT; /* allow this to be interruptable */
- if (symbuf_idx == symbuf_end)
- fill_symbuf ();
- bufp = &symbuf[symbuf_idx++];
- type = bufp->n_type;
-
- /*
- * Special cases to speed up readin.
- */
- if (type == N_SLINE) continue;
-
- namestring = bufp->n_un.n_strx ? bufp->n_un.n_strx + stringtab : "";
-
- switch (type)
- {
- /*
- * Standard, non-debugger, symbols
- */
-
- case N_TEXT | N_EXT:
- /* Catch etext */
-
- if (!strcmp (namestring, "_etext"))
- end_of_text_addr = bufp->n_value;
- /* Fall through */
-
-#ifdef N_NBTEXT
- case N_NBTEXT | N_EXT:
-#endif
-#ifdef N_NBDATA
- case N_NBDATA | N_EXT:
-#endif
-#ifdef N_NBBSS
- case N_NBBSS | N_EXT:
-#endif
- case N_ABS | N_EXT:
- case N_DATA | N_EXT:
- case N_BSS | N_EXT:
- /* Figure out beginning and end of global linker symbol
- section and put non-debugger specified symbols on
- tmp_symchain */
-
- last_global_sym = symnum;
- if (!first_global_sym) first_global_sym = symnum;
-
- record_misc_function (namestring, bufp->n_value); /* Always */
-
- continue;
-
-#ifdef N_NBTEXT
- case N_NBTEXT:
-#endif
- case N_TEXT:
- if (!strcmp (namestring + strlen (namestring) - 2, ".o")
- || !strncmp (namestring, "-l", 2))
- {
- if (num_object_files++ == 1)
- first_object_file_end = bufp->n_value;
- if (past_first_source_file && pst)
- {
- end_psymtab (pst, psymtab_include_list, includes_used,
- symnum * sizeof (struct nlist), bufp->n_value,
- dependency_list, dependencies_used,
- next_ps_global, next_ps_static);
- pst = (struct partial_symtab *) 0;
- includes_used = 0;
- dependencies_used = 0;
- }
- else
- past_first_source_file = 1;
- }
- continue;
-
- case N_UNDF:
- case N_UNDF | N_EXT:
- case N_ABS:
- case N_DATA:
- case N_BSS:
-#ifdef N_NBDATA
- case N_NBDATA:
-#endif
-#ifdef N_NBBSS
- case N_NBBSS:
-#endif
- case N_FN:
- /* Keep going . . .*/
-
- /*
- * Special symbol types for GNU
- */
-#ifdef N_INDR
- case N_INDR:
- case N_INDR | N_EXT:
-#endif
-#ifdef N_SETA
- case N_SETA:
- case N_SETA | N_EXT:
- case N_SETT:
- case N_SETT | N_EXT:
- case N_SETD:
- case N_SETD | N_EXT:
- case N_SETB:
- case N_SETB | N_EXT:
- case N_SETV:
- case N_SETV | N_EXT:
-#endif
- continue;
-
- /*
- * Debugger symbols
- */
-
- case N_SO:
- /* End the current partial symtab and start a new one */
-
- if (past_first_source_file && pst)
- {
- end_psymtab (pst, psymtab_include_list, includes_used,
- symnum * sizeof (struct nlist), bufp->n_value,
- dependency_list, dependencies_used,
- next_ps_global, next_ps_static);
- pst = (struct partial_symtab *) 0;
- includes_used = 0;
- dependencies_used = 0;
- }
- else
- past_first_source_file = 1;
-
- pst = start_psymtab (namestring, bufp->n_value,
- symnum * sizeof (struct nlist),
- next_ps_global, next_ps_static);
-
- continue;
-
-#ifdef N_BINCL
- case N_BINCL:
- /* Add this bincl to the bincl_list for future EXCLs. No
- need to save the string; it'll be around until
- read_dbx_symtab function return */
- add_bincl_to_list (pst, namestring, bufp->n_value);
-
- /* Fall through */
-#endif
-
- case N_SOL:
- /* Mark down an include file in the current psymtab */
-
- psymtab_include_list[includes_used++] = namestring;
- if (includes_used >= includes_allocated)
- {
- char **orig = psymtab_include_list;
-
- psymtab_include_list = (char **)
- alloca ((includes_allocated *= 2) *
- sizeof (char *));
- bcopy (orig, psymtab_include_list,
- includes_used * sizeof (char *));
-#ifdef DEBUG_INFO
- fprintf (stderr, "Had to realloc includes. New size: %d\n",
- includes_allocated);
-#endif
- }
- continue;
-
- case N_FUN:
- case N_SSYM:
- case N_GSYM:
- case N_LSYM:
- case N_STSYM:
- case N_LCSYM:
- case N_ENTRY:
-#ifdef N_MAIN
- case N_MAIN:
-#endif
-#ifdef N_BSLINE
- case N_BSLINE:
-#endif
- case N_PC:
-#ifdef N_M2C
- case N_M2C:
- case N_SCOPE:
-#endif
- /* Process a symbol as appropriate for the type (this
- information is contained in the name of the symbol) */
-
- if (namestring[0] != '\0')
-#if 1
- process_symbol_for_psymtab (namestring);
-#else
- process_symbol_for_psymtab (namestring, tmp_symchain);
-#endif
- continue;
-
-#ifdef N_BINCL
- case N_EXCL:
- /* Find the corresponding bincl and mark that psymtab on the
- psymtab dependency list */
- {
- struct partial_symtab *needed_pst =
- find_corresponding_bincl_psymtab (namestring, bufp->n_value);
-
- /* If this include file was defined earlier in this file,
- leave it alone. */
- if (needed_pst == pst) continue;
-
- if (needed_pst)
- {
- int i;
- int found = 0;
-
- for (i = 0; i < dependencies_used; i++)
- if (dependency_list[i] == needed_pst)
- {
- found = 1;
- break;
- }
-
- /* If it's already in the list, skip the rest. */
- if (found) continue;
-
- dependency_list[dependencies_used++] = needed_pst;
- if (dependencies_used >= dependencies_allocated)
- {
- struct partial_symtab **orig = dependency_list;
- dependency_list =
- (struct partial_symtab **)
- alloca ((dependencies_allocated *= 2)
- * sizeof (struct partial_symtab *));
- bcopy (orig, dependency_list,
- (dependencies_used
- * sizeof (struct partial_symtab *)));
-#ifdef DEBUG_INFO
- fprintf (stderr, "Had to reallocate dependency list.\n");
- fprintf (stderr, "New dependencies allocated: %d\n",
- dependencies_allocated);
-#endif
- }
- }
- else
- error ("Invalid symbol data: \"repeated\" header file not previously seen, at symtab pos %d.",
- symnum);
- }
- continue;
-
- case N_EINCL:
-#endif
-#ifdef N_DSLINE
- case N_DSLINE:
-#endif
- case N_LENG:
- case N_BCOMM:
- case N_ECOMM:
- case N_ECOML:
- case N_FNAME:
- case N_SLINE:
- case N_RSYM:
- case N_PSYM:
- case N_LBRAC:
- case N_RBRAC:
- /* These symbols aren't interesting; don't worry about them */
-
- continue;
-
- default:
- /* If we haven't found it yet, we've got problems */
-
- if (IGNORE_SYMBOL (type))
- continue;
-
- fatal ("Bad symbol type 0x%x encountered in gdb scan", type);
- }
- }
-
- if (last_source_file)
- {
- end_psymtab (pst, psymtab_include_list, includes_used,
- symnum * sizeof (struct nlist), end_of_text_addr,
- dependency_list, dependencies_used,
- next_ps_global, next_ps_static);
- includes_used = 0;
- dependencies_used = 0;
- pst = (struct partial_symtab *) 0;
- }
-
- free_bincl_list ();
- discard_cleanups (old_chain);
-}
-
-/*
- * Take a single symbol (name: NAME) and process it (add it to the
- * app psymbol list or not).
- */
-static void
-process_symbol_for_psymtab (name)
- char *name;
-{
- char *p = (char *) index(name, ':') + 1;
- int deftype;
- struct partial_symbol *sym;
- enum { T_IGNORE, T_STATIC, T_GLOBAL } symbol_type;
- enum namespace ns = UNDEF_NAMESPACE;
- enum address_class class;
- int hash;
-
- if (p == (char *) 0x1)
- /* No ":" ; I guess it's not a debuggging symbol */
- return;
-
- if ((*p >= '0' && *p <= '9') || *p == '(')
- deftype = 'l';
- else
- deftype = *p;
-
- /* Figure out how to handle this symbol */
- switch (deftype)
- {
- /* T is a struct/union/enum, t is a typedef */
- case 'T':
- symbol_type = T_STATIC;
- ns = STRUCT_NAMESPACE;
- class = LOC_TYPEDEF;
- break;
- case 't':
- symbol_type = T_STATIC;
- ns = VAR_NAMESPACE;
- class = LOC_TYPEDEF;
- break;
- case 'c':
- symbol_type = T_STATIC;
- ns = VAR_NAMESPACE;
- class = LOC_CONST;
- break;
- case 'S':
- symbol_type = T_STATIC;
- ns = VAR_NAMESPACE;
- class = LOC_STATIC;
- break;
- case 'f':
- symbol_type = T_STATIC;
- ns = VAR_NAMESPACE;
- class = LOC_BLOCK;
- break;
- case 'F':
- symbol_type = T_GLOBAL;
- ns = VAR_NAMESPACE;
- class = LOC_BLOCK;
- break;
- case 'G':
- symbol_type = T_GLOBAL;
- ns = VAR_NAMESPACE;
- class = LOC_STATIC;
- break;
- default:
- return;
- }
-
- /* Create the symbol and store it on the list */
- /* There's a better algorithm possible for the allocation; figure
- out how far through the symbol table we are and do a reestimate */
- if (symbol_type == T_STATIC)
- {
- if (next_ps_static >= static_psymbols + static_psymbols_allocated)
- {
- static_psymbols = (struct partial_symbol *)
- xrealloc (static_psymbols,
- (static_psymbols_allocated * 2
- * sizeof (struct partial_symbol)));
- /* Next assumes we only went one over. Should be good if
- program works correctly */
- next_ps_static = static_psymbols + static_psymbols_allocated;
- static_psymbols_allocated *= 2;
-#ifdef DEBUGINFO
- fprintf(stderr, "debuginfo: Had to realloc statics\n");
-#endif
- }
- sym = next_ps_static++;
- }
- else
- {
- if (next_ps_global >= global_psymbols + global_psymbols_allocated)
- {
- global_psymbols = (struct partial_symbol *)
- xrealloc (global_psymbols,
- (global_psymbols_allocated * 2
- * sizeof (struct partial_symbol)));
- next_ps_global = global_psymbols + global_psymbols_allocated;
- global_psymbols_allocated *= 2;
-#ifdef DEBUGINFO
- fprintf(stderr, "debuginfo: Had to realloc globals\n");
-#endif
- }
- sym = next_ps_global++;
- }
-
- SYMBOL_NAME(sym) = (char *) obstack_alloc (psymbol_obstack,
- p - name);
- strncpy(SYMBOL_NAME(sym), name, p - name - 1);
- SYMBOL_NAME(sym)[p - name - 1] = '\0';
- SYMBOL_NAMESPACE(sym) = ns;
- SYMBOL_CLASS(sym) = class;
-}
-#undef HASH_OFFSET
-
-/*
- * Allocate and partially fill a partial symtab. It will be
- * completely filled at the end of the symbol list.
- */
-static struct partial_symtab *
-start_psymtab (filename, textlow, ldsymoff, global_syms, static_syms)
- char *filename;
- int textlow;
- int ldsymoff;
- struct partial_symbol *global_syms;
- struct partial_symbol *static_syms;
-{
- struct partial_symtab *result =
- (struct partial_symtab *) obstack_alloc (psymbol_obstack,
- sizeof (struct partial_symtab));
-
- result->filename =
- (char *) obstack_alloc (psymbol_obstack,
- strlen (filename) + 1);
- strcpy (result->filename, filename);
-
- result->textlow = textlow;
- result->ldsymoff = ldsymoff;
-
- result->readin = 0;
-
- result->globals_offset = global_syms - global_psymbols;
- result->statics_offset = static_syms - static_psymbols;
-
- result->n_global_syms = 0;
- result->n_static_syms = 0;
-
- return result;
-}
-
-static int
-compare_psymbols (s1, s2)
- register struct partial_symbol *s1, *s2;
-{
- register char
- *st1 = SYMBOL_NAME (s1),
- *st2 = SYMBOL_NAME (s2);
-
- return (st1[0] - st2[0] ? st1[0] - st2[0] :
- strcmp (st1 + 1, st2 + 1));
-}
-
-
-/* Close off the current usage of a partial_symbol table entry. This
- involves setting the correct number of includes (with a realloc),
- setting the high text mark, setting the symbol length in the
- executable, and setting the length of the global and static lists
- of psymbols.
-
- The global symbols and static symbols are then seperately sorted.
-
- Then the partial symtab is put on the global list.
- *** List variables and peculiarities of same. ***
- */
-static void
-end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
- capping_text, dependency_list, number_dependencies,
- capping_global, capping_static)
- struct partial_symtab *pst;
- char **include_list;
- int num_includes;
- int capping_symbol_offset;
- int capping_text;
- struct partial_symtab **dependency_list;
- int number_dependencies;
- struct partial_symbol *capping_global, *capping_static;
-{
- int i;
-
- pst->ldsymlen = capping_symbol_offset - pst->ldsymoff;
- pst->texthigh = capping_text;
-
- pst->n_global_syms =
- capping_global - (global_psymbols + pst->globals_offset);
- pst->n_static_syms =
- capping_static - (static_psymbols + pst->statics_offset);
-
- pst->dependencies = (struct partial_symtab **)
- obstack_alloc (psymbol_obstack,
- number_dependencies * sizeof (struct partial_symtab *));
- bcopy (dependency_list, pst->dependencies,
- number_dependencies * sizeof (struct partial_symtab *));
- pst->number_of_dependencies = number_dependencies;
-
- for (i = 0; i < num_includes; i++)
- {
- /* Eventually, put this on obstack */
- struct partial_symtab *subpst =
- (struct partial_symtab *)
- obstack_alloc (psymbol_obstack,
- sizeof (struct partial_symtab));
-
- subpst->filename =
- (char *) obstack_alloc (psymbol_obstack,
- strlen (include_list[i]) + 1);
- strcpy (subpst->filename, include_list[i]);
-
- subpst->ldsymoff =
- subpst->ldsymlen =
- subpst->textlow =
- subpst->texthigh = 0;
- subpst->readin = 0;
-
- subpst->dependencies = (struct partial_symtab **)
- obstack_alloc (psymbol_obstack,
- sizeof (struct partial_symtab *));
- subpst->dependencies[0] = pst;
- subpst->number_of_dependencies = 1;
-
- subpst->globals_offset =
- subpst->n_global_syms =
- subpst->statics_offset =
- subpst->n_static_syms = 0;
-
- subpst->next = partial_symtab_list;
- partial_symtab_list = subpst;
- }
-
- /* Sort the global list; don't sort the static list */
- qsort (global_psymbols + pst->globals_offset, pst->n_global_syms,
- sizeof (struct partial_symbol), compare_psymbols);
-
- /* Put the psymtab on the psymtab list */
- pst->next = partial_symtab_list;
- partial_symtab_list = pst;
-}
-
-/*
- * Read in all of the symbols for a given psymtab for real. Return
- * the value of the symtab you create. Do not free the storage
- * allocated to the psymtab; it may have pointers to it.
- */
-static void scan_file_globals ();
-static void read_ofile_symtab ();
-
-struct symtab *
-psymtab_to_symtab(pst)
- struct partial_symtab *pst;
-{
- int desc;
- DECLARE_FILE_HEADERS;
- char *stringtab;
- struct partial_symtab **list_patch;
- int stsize, val;
- struct stat statbuf;
- struct cleanup *old_chain;
- extern void close ();
- int i;
- struct symtab *result;
- char *name = symfile; /* Some of the macros require the */
- /* variable "name" to be defined in */
- /* the context in which they execute */
- /* (Yech!) */
-
- if (!pst)
- return 0;
-
- if (pst->readin)
- {
- fprintf (stderr, "Psymtab for %s already read in. Shouldn't happen.\n",
- pst->filename);
- return 0;
- }
-
- if (!name)
- error("No symbol file currently specified; use command symbol-file");
-
- /* Read in all partial symbtabs on which this one is dependent */
- for (i = 0; i < pst->number_of_dependencies; i++)
- if (!pst->dependencies[i]->readin)
- psymtab_to_symtab (pst->dependencies[i]);
-
- if (pst->ldsymlen) /* Otherwise it's a dummy */
- {
- /* Open symbol file and read in string table */
- stat (name, &statbuf);
- desc = open(name, O_RDONLY, 0); /* symbol_file_command
- guarrantees that the symbol file name
- will be absolute, so there is no
- need for openp */
-
- old_chain = make_cleanup (close, desc);
-
- if (desc < 0)
- error("Symbol file not readable");
-
- READ_FILE_HEADERS (desc, name);
-
- /* Read in the string table */
- lseek (desc, STRING_TABLE_OFFSET, L_SET);
- READ_STRING_TABLE_SIZE (stsize);
- if (stsize >= 0 && stsize < statbuf.st_size)
- stringtab = (char *) alloca (stsize);
- else
- stringtab = NULL;
- if (stringtab == NULL)
- error ("ridiculous string table size: %d bytes", name, stsize);
-
- bcopy (&stsize, stringtab, sizeof stsize);
- val = myread (desc, stringtab + sizeof stsize, stsize - sizeof stsize);
- if (val < 0)
- perror_with_name (name);
-
- /* Init stuff necessary for reading in symbols */
- free_pendings = 0;
- pending_blocks = 0;
- file_symbols = 0;
- global_symbols = 0;
- make_cleanup (really_free_pendings, 0);
-
- /* Read in this files symbols */
- lseek (desc, SYMBOL_TABLE_OFFSET, L_SET);
- read_ofile_symtab (desc, stringtab, pst->ldsymoff,
- pst->ldsymlen, pst->textlow,
- pst->texthigh - pst->textlow, 0);
- sort_symtab_syms (symtab_list); /* At beginning since just added */
-
- /* Match with global symbols */
- lseek (desc, SYMBOL_TABLE_OFFSET, L_SET);
- scan_file_globals (desc, stringtab,
- first_global_sym * sizeof(struct nlist),
- last_global_sym - first_global_sym + 1);
-
- do_cleanups (old_chain);
- }
-
- /* Find pst in list, prune it, and free it's storage */
- for (list_patch = &partial_symtab_list;
- *list_patch && *list_patch != pst;
- list_patch = &((*list_patch)->next))
- ;
-
- if (!(*list_patch)) /* pst not in list. Don't worry about it? */
- fatal ("internal: psymtab_to_symtab called with non-listed pst");
-
- *list_patch = (*list_patch)->next; /* Prune */
-
- pst->readin = 1; /* Mark as read in */
-
- /* It's the last one if we actually read something in */
- if (pst->ldsymlen)
- return symtab_list;
- else
- /* Search through list for correct name. */
- for (result = symtab_list; result; result = result->next)
- if (!strcmp (result->filename, pst->filename))
- return result;
-
- return 0;
-}
-
-/*
- * Scan through all of the global symbols defined in the object file,
- * assigning values to the debugging symbols that need to be assigned
- * to.
- *
- * DESC is the file descriptor of the symbol file, with the seek
- * pointer pointing at the beginning of the symbol table.
- * STRINGTAB is the file's string table, already read in.
- * OFFSET is the offset (in bytes) of the beginning of the global
- * symbols from the beginning of the symbol table.
- * NUMSYMS is the number of symbols that have to be checked.
- */
-static void
-scan_file_globals (desc, stringtab, offset, numsyms)
- int desc;
- char *stringtab;
- int offset;
- int numsyms;
-{
- int hash;
-
- lseek(desc, offset, L_INCR);
- symtab_input_desc = desc;
- symbuf_end = symbuf_idx = 0;
-
- for (symnum = 0; symnum < numsyms; symnum++)
- {
- struct nlist *bufp;
- unsigned char type;
- char *namestring;
-
- QUIT;
- if (symbuf_idx == symbuf_end)
- fill_symbuf ();
-
- bufp = &symbuf[symbuf_idx++];
- type = bufp->n_type;
-
- if (type & N_EXT && type != N_EXT)
- {
- struct symbol *sym, *prev;
-
- namestring = bufp->n_un.n_strx ?
- bufp->n_un.n_strx + stringtab : "";
- prev = (struct symbol *) 0;
-
- /* Get the hash index and check all the symbols
- under that hash index. */
-
-#ifdef NAMES_HAVE_UNDERSCORE
- hash = hashname (namestring + 1);
-#else /* ! NAMES_HAVE_UNDERSCORE */
- hash = hashname (namestring);
-#endif /* ! NAMES_HAVE_UNDERSCORE */
- for (sym = global_sym_chain[hash]; sym;)
- {
- if (
-#ifdef NAMES_HAVE_UNDERSCORE
- *namestring == '_'
- && namestring[1] == SYMBOL_NAME (sym)[0]
- && !strcmp(namestring + 2, SYMBOL_NAME (sym) + 1)
-#else /* ! NAMES_HAVE_UNDERSCORE */
- namestring[0] == SYMBOL_NAME (sym) [0]
- && !strcmp(namestring + 1, SYMBOL_NAME(sym) + 1)
-#endif /* ! NAMES_HAVE_UNDERSCORE */
- )
- {
- /* Splice this symbol out of the hash chain and
- assign the value we have to it. */
- if (prev)
- SYMBOL_VALUE (prev) = SYMBOL_VALUE (sym);
- else
- global_sym_chain[hash]
- = (struct symbol *) SYMBOL_VALUE (sym);
- SYMBOL_VALUE (sym) = bufp->n_value;
- if (prev)
- sym = (struct symbol *) SYMBOL_VALUE (prev);
- else
- sym = global_sym_chain[hash];
- break; /* Only one reference per file */
- }
- else
- {
- prev = sym;
- sym = (struct symbol *) SYMBOL_VALUE (sym);
- }
- }
- }
- }
- /* There shouldn't be anything left on the hash list at this point.
- If there is, we have done something wrong. For right now it's
- worth checking, until I get the bugs out. */
- /* Sigh. Unfortunately, the above is not true. If an extern
- variable is mentioned in an include file (or a program) and the
- variable is never either referenced or defined, there will be a
- debugger symbol with no "real" symbol. Oh well. */
-}
-
-/*
- * Read in a defined section of a specific object file's symbols.
- *
- * DESC is the file descriptor for the file, positioned at the
- * beginning of the symtab
- * STRINGTAB is a pointer to the files string
- * table, already read in
- * SYM_OFFSET is the offset within the file of
- * the beginning of the symbols we want to read, NUM_SUMBOLS is the
- * number of symbols to read
- * TEXT_OFFSET is the offset to be added to
- * all values of symbols coming in and
- * TEXT_SIZE is the size of the text segment read in.
- * OFFSET is a flag which indicates that the value of all of the
- * symbols should be offset by TEXT_OFFSET (for the purposes of
- * incremental linking).
- */
-
-static void
-read_ofile_symtab (desc, stringtab, sym_offset,
- sym_size, text_offset, text_size, offset)
- int desc;
- register char *stringtab;
- int sym_offset;
- int sym_size;
- int text_offset;
- int text_size;
- int offset;
-{
- register char *namestring;
- register struct symbol *sym, *prev;
- int hash;
- struct cleanup *old_chain;
- struct nlist *bufp;
- unsigned char type;
-#ifdef N_BINCL
- subfile_stack = 0;
-#endif
-
- stringtab_global = stringtab;
- last_source_file = 0;
-
- symtab_input_desc = desc;
- symbuf_end = symbuf_idx = 0;
- lseek(desc, sym_offset, L_INCR);
-
- fill_symbuf();
- bufp = &symbuf[symbuf_idx];
- if ((unsigned char) bufp->n_type != N_SO)
- fatal("First symbol in segment of executable not a source symbol");
-
- for (symnum = 0;
- symnum < sym_size / sizeof(struct nlist);
- symnum++)
- {
- QUIT; /* Allow this to be interruptable */
- if (symbuf_idx == symbuf_end)
- fill_symbuf();
- bufp = &symbuf[symbuf_idx++];
- type = bufp->n_type;
-
- if (offset &&
- (type == N_TEXT || type == N_DATA || type == N_BSS))
- bufp->n_value += text_offset;
-
- namestring = bufp->n_un.n_strx ? bufp->n_un.n_strx + stringtab : "";
-
- if (type & N_STAB)
- process_one_symbol(type, bufp->n_desc,
- bufp->n_value, namestring);
- /* We skip checking for a new .o or -l file; that should never
- happen in this routine. */
- else if (type == N_TEXT
- && !strcmp (namestring, GCC_COMPILED_FLAG_SYMBOL))
- processing_gcc_compilation = 1;
- else if (type & N_EXT || type == N_TEXT
-#ifdef N_NBTEXT
- || type == N_NBTEXT
-#endif
- )
- /* Global symbol: see if we came across a dbx defintion for
- a corresponding symbol. If so, store the value. Remove
- syms from the chain when their values are stored, but
- search the whole chain, as there may be several syms from
- different files with the same name. */
- /* This is probably not true. Since the files will be read
- in one at a time, each reference to a global symbol will
- be satisfied in each file as it appears. So we skip this
- section. */
- &stringtab_global; /* For debugger; am I right? */
- }
- end_symtab (text_offset + text_size);
-}
-
-static int
-hashname (name)
- char *name;
-{
- register char *p = name;
- register int total = p[0];
- register int c;
-
- c = p[1];
- total += c << 2;
- if (c)
- {
- c = p[2];
- total += c << 4;
- if (c)
- total += p[3] << 6;
- }
-
- /* Ensure result is positive. */
- if (total < 0) total += (1000 << 6);
- return total % HASHSIZE;
-}
-
-/* Put all appropriate global symbols in the symseg data
- onto the hash chains so that their addresses will be stored
- when seen later in loader global symbols. */
-
-static void
-hash_symsegs ()
-{
- /* Look at each symbol in each block in each symseg symtab. */
- struct symtab *s;
- for (s = symseg_chain; s; s = s->next)
- {
- register int n;
- for (n = BLOCKVECTOR_NBLOCKS (BLOCKVECTOR (s)) - 1; n >= 0; n--)
- {
- register struct block *b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), n);
- register int i;
- for (i = BLOCK_NSYMS (b) - 1; i >= 0; i--)
- {
- register struct symbol *sym = BLOCK_SYM (b, i);
-
- /* Put the symbol on a chain if its value is an address
- that is figured out by the loader. */
-
- if (SYMBOL_CLASS (sym) == LOC_EXTERNAL)
- {
- register int hash = hashname (SYMBOL_NAME (sym));
- SYMBOL_VALUE (sym) = (int) global_sym_chain[hash];
- global_sym_chain[hash] = sym;
- SYMBOL_CLASS (sym) = LOC_STATIC;
- }
- }
- }
- }
-}
-
-static void
-process_one_symbol (type, desc, value, name)
- int type, desc;
- CORE_ADDR value;
- char *name;
-{
- register struct context_stack *new;
-
- /* Something is wrong if we see real data before
- seeing a source file name. */
-
- if (last_source_file == 0 && type != N_SO)
- {
- /* Currently this ignores N_ENTRY on Gould machines, N_NSYM on machines
- where that code is defined, and all symbols on the Convex. */
- if (IGNORE_SYMBOL (type))
- return;
-
- error ("Invalid symbol data: does not start by identifying a source file.");
- }
-
- switch (type)
- {
- case N_FUN:
- case N_FNAME:
- /* Either of these types of symbols indicates the start of
- a new function. We must process its "name" normally for dbx,
- but also record the start of a new lexical context, and possibly
- also the end of the lexical context for the previous function. */
-
- within_function = 1;
- if (context_stack_depth > 0)
- {
- new = &context_stack[--context_stack_depth];
- /* Make a block for the local symbols within. */
- finish_block (new->name, &local_symbols, new->old_blocks,
- new->start_addr, value);
- }
- /* Stack must be empty now. */
- if (context_stack_depth != 0)
- error ("Invalid symbol data: unmatched N_LBRAC before symtab pos %d.",
- symnum);
-
- new = &context_stack[context_stack_depth++];
- new->old_blocks = pending_blocks;
- new->start_addr = value;
- new->name = define_symbol (value, name, desc);
- local_symbols = 0;
- break;
-
- case N_LBRAC:
- /* This "symbol" just indicates the start of an inner lexical
- context within a function. */
-
- if (context_stack_depth == context_stack_size)
- {
- context_stack_size *= 2;
- context_stack = (struct context_stack *)
- xrealloc (context_stack,
- (context_stack_size
- * sizeof (struct context_stack)));
- }
-
- new = &context_stack[context_stack_depth++];
- new->depth = desc;
- new->locals = local_symbols;
- new->old_blocks = pending_blocks;
- new->start_addr = value;
- new->name = 0;
- local_symbols = 0;
- break;
-
- case N_RBRAC:
- /* This "symbol" just indicates the end of an inner lexical
- context that was started with N_RBRAC. */
- new = &context_stack[--context_stack_depth];
- if (desc != new->depth)
- error ("Invalid symbol data: N_LBRAC/N_RBRAC symbol mismatch, symtab pos %d.", symnum);
- local_symbols = new->locals;
-
- /* If this is not the outermost LBRAC...RBRAC pair in the
- function, its local symbols preceded it, and are the ones
- just recovered from the context stack. Defined the block for them.
-
- If this is the outermost LBRAC...RBRAC pair, there is no
- need to do anything; leave the symbols that preceded it
- to be attached to the function's own block. */
- if (local_symbols && context_stack_depth > 1)
- {
- /* Muzzle a compiler bug that makes end > start. */
- if (new->start_addr > value)
- new->start_addr = value;
- /* Make a block for the local symbols within. */
- finish_block (0, &local_symbols, new->old_blocks,
- new->start_addr + last_source_start_addr,
- value + last_source_start_addr);
- }
- break;
-
- case N_FN:
- /* This kind of symbol supposedly indicates the start
- of an object file. In fact this type does not appear. */
- break;
-
- case N_SO:
- /* This type of symbol indicates the start of data
- for one source file.
- Finish the symbol table of the previous source file
- (if any) and start accumulating a new symbol table. */
- if (last_source_file)
- end_symtab (value);
- start_symtab (name, value);
- break;
-
- case N_SOL:
- /* This type of symbol indicates the start of data for
- a sub-source-file, one whose contents were copied or
- included in the compilation of the main source file
- (whose name was given in the N_SO symbol.) */
- start_subfile (name);
- break;
-
-#ifdef N_BINCL
- case N_BINCL:
- push_subfile ();
- add_new_header_file (name, value);
- start_subfile (name);
- break;
-
- case N_EINCL:
- start_subfile (pop_subfile ());
- break;
-
- case N_EXCL:
- add_old_header_file (name, value);
- break;
-#endif /* have N_BINCL */
-
- case N_SLINE:
- /* This type of "symbol" really just records
- one line-number -- core-address correspondence.
- Enter it in the line list for this symbol table. */
- record_line (desc, value);
- break;
-
- case N_BCOMM:
- case N_ECOMM:
- case N_ECOML:
- case N_LENG:
- break;
-
- default:
- if (name)
- define_symbol (value, name, desc);
- }
-}
-
-/* This function was added for C++ functionality. I presume that it
- condenses the bunches formed by reading in an additional .o file
- (incremental linking). */
-
-static void
-condense_addl_misc_bunches ()
-{
- register int i, j;
- register struct misc_bunch *bunch;
-#ifdef NAMES_HAVE_UNDERSCORE
- int offset = 1;
-#else
- int offset = 0;
-#endif
-
- misc_function_vector
- = (struct misc_function *) xrealloc (misc_function_vector,
- (misc_count + misc_function_count) * sizeof (struct misc_function));
-
- j = misc_function_count;
- bunch = misc_bunch;
- while (bunch)
- {
- for (i = 0; i < misc_bunch_index; i++)
- {
- misc_function_vector[j] = bunch->contents[i];
- misc_function_vector[j].name
- = concat (misc_function_vector[j].name
- + (misc_function_vector[j].name[0] == '_' ? offset : 0),
- "", "");
- j++;
- }
- bunch = bunch->next;
- misc_bunch_index = MISC_BUNCH_SIZE;
- }
-
- misc_function_count += misc_count;
-
- /* Sort the misc functions by address. */
-
- qsort (misc_function_vector, misc_function_count,
- sizeof (struct misc_function), compare_misc_functions);
-}
-
-
-/* Read in another .o file and create a symtab entry for it.*/
-
-static void
-read_addl_syms (desc, stringtab, nlistlen, text_addr, text_size)
- int desc;
- register char *stringtab;
- register int nlistlen;
- unsigned text_addr;
- int text_size;
-{
- FILE *stream = fdopen (desc, "r");
- register char *namestring;
- register struct symbol *sym, *prev;
- int hash;
- int num_object_files = 0;
-
-#ifdef N_BINCL
- subfile_stack = 0;
-#endif
-
- last_source_file = 0;
- bzero (global_sym_chain, sizeof global_sym_chain);
- symtab_input_desc = desc;
- stringtab_global = stringtab;
- fill_symbuf ();
-
- for (symnum = 0; symnum < nlistlen; symnum++)
- {
- struct nlist *bufp;
- unsigned char type;
-
- QUIT; /* allow this to be interruptable */
- if (symbuf_idx == symbuf_end)
- fill_symbuf ();
- bufp = &symbuf[symbuf_idx++];
- type = bufp->n_type & N_TYPE;
- namestring = bufp->n_un.n_strx ? bufp->n_un.n_strx + stringtab : "";
-
- if( (type == N_TEXT) || (type == N_DATA) || (type == N_BSS) )
- {
- /* Relocate this file's symbol table information
- to the address it has been loaded into. */
- bufp->n_value += text_addr;
- }
-
- type = bufp->n_type;
-
- if (type & N_STAB)
- process_one_symbol (type, bufp->n_desc,
- bufp->n_value, namestring);
- /* A static text symbol whose name ends in ".o"
- can only mean the start of another object file.
- So end the symtab of the source file we have been processing.
- This is how we avoid counting the libraries as part
- or the last source file.
- Also this way we find end of first object file (crt0). */
- else if ((type == N_TEXT
-#ifdef N_NBTEXT
- || type == N_NBTEXT
-#endif
- )
- && (!strcmp (namestring + strlen (namestring) - 2, ".o"))
- || ! strcmp (namestring, "-l", 2))
- {
- if (num_object_files++ == 1)
- first_object_file_end = bufp->n_value;
- if (last_source_file)
- end_symtab (bufp->n_value);
- }
- else if (type & N_EXT || type == N_TEXT
-#ifdef N_NBTEXT
- || type == N_NBTEXT
-#endif
- )
- {
- int used_up = 0;
-
- /* Record the location of _etext. */
- if (type == (N_TEXT | N_EXT)
- && !strcmp (namestring, "_etext"))
- end_of_text_addr = bufp->n_value;
-
- /* Global symbol: see if we came across a dbx definition
- for a corresponding symbol. If so, store the value.
- Remove syms from the chain when their values are stored,
- but search the whole chain, as there may be several syms
- from different files with the same name. */
- if (type & N_EXT)
- {
- prev = 0;
-#ifdef NAMES_HAVE_UNDERSCORE
- hash = hashname (namestring + 1);
-#else /* not NAMES_HAVE_UNDERSCORE */
- hash = hashname (namestring);
-#endif /* not NAMES_HAVE_UNDERSCORE */
- for (sym = global_sym_chain[hash];
- sym;)
- {
- if (
-#ifdef NAMES_HAVE_UNDERSCORE
- *namestring == '_'
- && namestring[1] == SYMBOL_NAME (sym)[0]
- &&
- !strcmp (namestring + 2, SYMBOL_NAME (sym) + 1)
-#else /* NAMES_HAVE_UNDERSCORE */
- namestring[0] == SYMBOL_NAME (sym)[0]
- &&
- !strcmp (namestring + 1, SYMBOL_NAME (sym) + 1)
-#endif /* NAMES_HAVE_UNDERSCORE */
- )
- {
- if (prev)
- SYMBOL_VALUE (prev) = SYMBOL_VALUE (sym);
- else
- global_sym_chain[hash]
- = (struct symbol *) SYMBOL_VALUE (sym);
- SYMBOL_VALUE (sym) = bufp->n_value;
- if (prev)
- sym = (struct symbol *) SYMBOL_VALUE (prev);
- else
- sym = global_sym_chain[hash];
-
- used_up = 1;
- }
- else
- {
- prev = sym;
- sym = (struct symbol *) SYMBOL_VALUE (sym);
- }
- }
- }
-
- /* Defined global or text symbol: record as a misc function
- if it didn't give its address to a debugger symbol above. */
- if (type <= (N_TYPE | N_EXT)
- && type != N_EXT
- && ! used_up)
- record_misc_function (namestring, bufp->n_value);
- }
- }
-
- if (last_source_file)
- end_symtab (text_addr + text_size);
-
- fclose (stream);
-}
-
-/* C++:
- This function allows the addition of incrementally linked object files.
- Since this has a fair amount of code in common with symbol_file_command,
- it might be worthwhile to consolidate things, as was done with
- read_dbx_symtab and condense_misc_bunches. */
-
-void
-add_file_command (arg_string)
- char* arg_string;
-{
- register int desc;
- DECLARE_FILE_HEADERS;
- struct nlist *nlist;
- char *stringtab;
- long buffer;
- register int val;
- extern void close ();
- struct cleanup *old_chain;
- struct symtab *symseg;
- struct stat statbuf;
- char *name;
- unsigned text_addr;
-
- if (arg_string == 0)
- error ("add-file takes a file name and an address");
-
- for( ; *arg_string == ' '; arg_string++ );
- name = arg_string;
- for( ; *arg_string && *arg_string != ' ' ; arg_string++ );
- *arg_string++ = (char) 0;
-
- if (name[0] == 0)
- error ("add-file takes a file name and an address");
-
- text_addr = parse_and_eval_address (arg_string);
-
- dont_repeat ();
-
- if (!query ("add symbol table from filename \"%s\" at text_addr = 0x%x\n",
- name, text_addr))
- error ("Not confirmed.");
-
- desc = open (name, O_RDONLY);
- if (desc < 0)
- perror_with_name (name);
-
- old_chain = make_cleanup (close, desc);
- make_cleanup (free_current_contents, &name);
-
- READ_FILE_HEADERS (desc, name);
-
- if (NUMBER_OF_SYMBOLS == 0)
- {
- printf ("%s does not have a symbol-table.\n", name);
- fflush (stdout);
- return;
- }
-
- printf ("Reading symbol data from %s...", name);
- fflush (stdout);
-
- /* Now read the string table, all at once. */
- val = lseek (desc, STRING_TABLE_OFFSET, 0);
- if (val < 0)
- perror_with_name (name);
- stat (name, &statbuf);
- READ_STRING_TABLE_SIZE (buffer);
- if (buffer >= 0 && buffer < statbuf.st_size)
- stringtab = (char *) alloca (buffer);
- else
- stringtab = NULL;
- if (stringtab == NULL)
- error ("ridiculous string table size: %d bytes", name, buffer);
-
- bcopy (&buffer, stringtab, sizeof buffer);
- val = myread (desc, stringtab + sizeof buffer, buffer - sizeof buffer);
- if (val < 0)
- perror_with_name (name);
-
-#ifdef READ_GDB_SYMSEGS
- /* That puts us at the symsegs. Read them. */
- symseg_chain = read_symsegs (desc, name);
- hash_symsegs ();
-
- /* Free the symtabs made by read_symsegs, but not their contents,
- which have been copied into symtabs on symtab_list. */
- for (symseg = symseg_chain; symseg; symseg = symseg->next)
- {
- int i;
- struct sourcevector *sv = (struct sourcevector *) symseg->linetable;
-
- for (i = 0; i < sv->length; i++)
- {
- int j;
- struct source *source = sv->source[i];
- struct symtab *sp1
- = (struct symtab *) xxmalloc (sizeof (struct symtab));
-
- bcopy (symseg, sp1, sizeof (struct symtab));
- sp1->filename = savestring (source->name, strlen (source->name));
- sp1->linetable = &source->contents;
- sp1->free_code = free_nothing;
- sp1->free_ptr = (i == 0) ? (char *) symseg : 0;
-
- sp1->next = symtab_list;
- symtab_list = sp1;
- }
- }
-#else
- /* Where people are using the 4.2 ld program, must not check for
- symsegs, because that ld puts randonm garbage at the end of
- the output file and that would trigger an error message. */
- symseg_chain = 0;
-#endif
-
- /* Position to read the symbol table. Do not read it all at once. */
- val = lseek (desc, SYMBOL_TABLE_OFFSET, 0);
- if (val < 0)
- perror_with_name (name);
-
- init_misc_functions ();
- make_cleanup (discard_misc_bunches, 0);
- init_header_files ();
- make_cleanup (free_header_files, 0);
- free_pendings = 0;
- pending_blocks = 0;
- file_symbols = 0;
- global_symbols = 0;
- make_cleanup (really_free_pendings, 0);
-
- read_addl_syms (desc, stringtab, NUMBER_OF_SYMBOLS, text_addr,
- SIZE_OF_TEXT_SEGMENT);
-
-
- /* Sort symbols alphabetically within each block. */
-
- sort_syms ();
-
- /* Go over the misc functions and install them in vector. */
-
- condense_addl_misc_bunches (1);
-
- /* Don't allow char * to have a typename (else would get caddr_t.) */
-
- TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0;
-
- /* Make a default for file to list. */
- /* Hmmm. I'd say we don't want this in add_file_command, but . . . */
-
- select_source_symtab (symtab_list);
-
- do_cleanups (old_chain);
-
- /* Free the symtabs made by read_symsegs, but not their contents,
- which have been copied into symtabs on symtab_list. */
- while (symseg_chain)
- {
- register struct symtab *s = symseg_chain->next;
- free (symseg_chain);
- symseg_chain = s;
- }
-
- printf ("done.\n");
- fflush (stdout);
-}
-
-static struct symbol *
-define_symbol (value, string, desc)
- int value;
- char *string;
- int desc;
-{
- register struct symbol *sym
- = (struct symbol *) obstack_alloc (symbol_obstack, sizeof (struct symbol));
- char *p = (char *) index (string, ':');
- int deftype;
- register int i;
-
- /* Ignore syms with empty names. */
- if (string[0] == 0)
- return 0;
-
- SYMBOL_NAME (sym)
- = (char *) obstack_alloc (symbol_obstack, ((p - string) + 1));
- /* Open-coded bcopy--saves function call time. */
- {
- register char *p1 = string;
- register char *p2 = SYMBOL_NAME (sym);
- while (p1 != p)
- *p2++ = *p1++;
- *p2++ = '\0';
- }
- p++;
- /* Determine the type of name being defined. */
- if ((*p >= '0' && *p <= '9') || *p == '(')
- deftype = 'l';
- else
- deftype = *p++;
-
- /* c is a special case, not followed by a type-number.
- SYMBOL:c=iVALUE for an integer constant symbol.
- SYMBOL:c=rVALUE for a floating constant symbol. */
- if (deftype == 'c')
- {
- if (*p++ != '=')
- error ("Invalid symbol data at symtab pos %d.", symnum);
- switch (*p++)
- {
- case 'r':
- {
- double d = atof (p);
- char *value;
-
- SYMBOL_TYPE (sym) = builtin_type_double;
- value = (char *) obstack_alloc (symbol_obstack, sizeof (double));
- bcopy (&d, value, sizeof (double));
- SYMBOL_VALUE_BYTES (sym) = value;
- SYMBOL_CLASS (sym) = LOC_CONST;
- }
- break;
- case 'i':
- {
- SYMBOL_TYPE (sym) = builtin_type_int;
- SYMBOL_VALUE (sym) = atoi (p);
- SYMBOL_CLASS (sym) = LOC_CONST_BYTES;
- }
- break;
- default:
- error ("Invalid symbol data at symtab pos %d.", symnum);
- }
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- add_symbol_to_list (sym, &file_symbols);
- return sym;
- }
-
- /* Now usually comes a number that says which data type,
- and possibly more stuff to define the type
- (all of which is handled by read_type) */
-
- if (deftype == 'p' && *p == 'F')
- /* pF is a two-letter code that means a function parameter in Fortran.
- The type-number specifies the type of the return value.
- Translate it into a pointer-to-function type. */
- {
- p++;
- SYMBOL_TYPE (sym)
- = lookup_pointer_type (lookup_function_type (read_type (&p)));
- }
- else
- {
- struct type *type = read_type (&p);
-
- if ((deftype == 'F' || deftype == 'f')
- && TYPE_CODE (type) != TYPE_CODE_FUNC)
- SYMBOL_TYPE (sym) = lookup_function_type (type);
- else
- SYMBOL_TYPE (sym) = type;
- }
-
- switch (deftype)
- {
- case 'f':
- SYMBOL_CLASS (sym) = LOC_BLOCK;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- add_symbol_to_list (sym, &file_symbols);
- break;
-
- case 'F':
- SYMBOL_CLASS (sym) = LOC_BLOCK;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- add_symbol_to_list (sym, &global_symbols);
- break;
-
- case 'G':
- /* For a class G (global) symbol, it appears that the
- value is not correct. It is necessary to search for the
- corresponding linker definition to find the value.
- These definitions appear at the end of the namelist. */
- i = hashname (SYMBOL_NAME (sym));
- SYMBOL_VALUE (sym) = (int) global_sym_chain[i];
- global_sym_chain[i] = sym;
- SYMBOL_CLASS (sym) = LOC_STATIC;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- add_symbol_to_list (sym, &global_symbols);
- break;
-
- /* This case is faked by a conditional above,
- when there is no code letter in the dbx data.
- Dbx data never actually contains 'l'. */
- case 'l':
- SYMBOL_CLASS (sym) = LOC_LOCAL;
- SYMBOL_VALUE (sym) = value;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- add_symbol_to_list (sym, &local_symbols);
- break;
-
- case 'p':
- SYMBOL_CLASS (sym) = LOC_ARG;
- SYMBOL_VALUE (sym) = value;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- add_symbol_to_list (sym, &local_symbols);
- /* DESC == 0 implies compiled with GCC.
- In this case, if it says `short', believe it. */
- if (desc == 0)
- break;
- /* If PCC says a parameter is a short or a char,
- it is really an int. */
- if (SYMBOL_TYPE (sym) == builtin_type_char
- || SYMBOL_TYPE (sym) == builtin_type_short)
- SYMBOL_TYPE (sym) = builtin_type_int;
- else if (SYMBOL_TYPE (sym) == builtin_type_unsigned_char
- || SYMBOL_TYPE (sym) == builtin_type_unsigned_short)
- SYMBOL_TYPE (sym) = builtin_type_unsigned_int;
- break;
-
- case 'P':
- SYMBOL_CLASS (sym) = LOC_REGPARM;
- SYMBOL_VALUE (sym) = value;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- add_symbol_to_list (sym, &local_symbols);
- break;
-
- case 'r':
- SYMBOL_CLASS (sym) = LOC_REGISTER;
- SYMBOL_VALUE (sym) = value;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- add_symbol_to_list (sym, &local_symbols);
- break;
-
- case 'S':
- /* Static symbol at top level of file */
- SYMBOL_CLASS (sym) = LOC_STATIC;
- SYMBOL_VALUE (sym) = value;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- add_symbol_to_list (sym, &file_symbols);
- break;
-
- case 't':
- SYMBOL_CLASS (sym) = LOC_TYPEDEF;
- SYMBOL_VALUE (sym) = value;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0
- && (TYPE_FLAGS (SYMBOL_TYPE (sym)) & TYPE_FLAG_PERM) == 0)
- TYPE_NAME (SYMBOL_TYPE (sym)) =
- obsavestring (SYMBOL_NAME (sym),
- strlen (SYMBOL_NAME (sym)));
- /* C++ vagaries: we may have a type which is derived from
- a base type which did not have its name defined when the
- derived class was output. We fill in the derived class's
- base part member's name here in that case. */
- else if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT
- || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION)
- && TYPE_N_BASECLASSES (SYMBOL_TYPE (sym)))
- {
- int i;
- for (i = TYPE_N_BASECLASSES (SYMBOL_TYPE (sym)); i > 0; i--)
- if (TYPE_FIELD_NAME (SYMBOL_TYPE (sym), i - 1) == 0)
- TYPE_FIELD_NAME (SYMBOL_TYPE (sym), i - 1) =
- TYPE_NAME (TYPE_BASECLASS (SYMBOL_TYPE (sym), i));
- }
-
- add_symbol_to_list (sym, &file_symbols);
- break;
-
- case 'T':
- SYMBOL_CLASS (sym) = LOC_TYPEDEF;
- SYMBOL_VALUE (sym) = value;
- SYMBOL_NAMESPACE (sym) = STRUCT_NAMESPACE;
- if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0
- && (TYPE_FLAGS (SYMBOL_TYPE (sym)) & TYPE_FLAG_PERM) == 0)
- TYPE_NAME (SYMBOL_TYPE (sym))
- = obconcat ("",
- (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_ENUM
- ? "enum "
- : (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT
- ? "struct " : "union ")),
- SYMBOL_NAME (sym));
- add_symbol_to_list (sym, &file_symbols);
- break;
-
- case 'V':
- case 'v':
- /* Static symbol of local scope */
- SYMBOL_CLASS (sym) = LOC_STATIC;
- SYMBOL_VALUE (sym) = value;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- add_symbol_to_list (sym, &local_symbols);
- break;
-
- default:
- error ("Invalid symbol data: unknown symbol-type code `%c' at symtab pos %d.", deftype, symnum);
- }
- return sym;
-}
-
-/* Read a number by which a type is referred to in dbx data,
- or perhaps read a pair (FILENUM, TYPENUM) in parentheses.
- Just a single number N is equivalent to (0,N).
- Return the two numbers by storing them in the vector TYPENUMS.
- TYPENUMS will then be used as an argument to dbx_lookup_type. */
-
-static void
-read_type_number (pp, typenums)
- register char **pp;
- register int *typenums;
-{
- if (**pp == '(')
- {
- (*pp)++;
- typenums[0] = read_number (pp, ',');
- typenums[1] = read_number (pp, ')');
- }
- else
- {
- typenums[0] = 0;
- typenums[1] = read_number (pp, 0);
- }
-}
-
-/* Read a dbx type reference or definition;
- return the type that is meant.
- This can be just a number, in which case it references
- a type already defined and placed in type_vector.
- Or the number can be followed by an =, in which case
- it means to define a new type according to the text that
- follows the =. */
-
-static
-struct type *
-read_type (pp)
- register char **pp;
-{
- register struct type *type = 0;
- register int n;
- struct type *type1;
- int typenums[2];
- int xtypenums[2];
-
- read_type_number (pp, typenums);
-
- /* Detect random reference to type not yet defined.
- Allocate a type object but leave it zeroed. */
- if (**pp != '=')
- return dbx_alloc_type (typenums);
-
- *pp += 2;
- switch ((*pp)[-1])
- {
- case 'x':
- type = dbx_alloc_type (typenums);
- /* Set the type code according to the following letter. */
- switch ((*pp)[0])
- {
- case 's':
- TYPE_CODE (type) = TYPE_CODE_STRUCT;
- break;
- case 'u':
- TYPE_CODE (type) = TYPE_CODE_UNION;
- break;
- case 'e':
- TYPE_CODE (type) = TYPE_CODE_ENUM;
- break;
- }
- /* Skip the name the cross-ref points to. */
- /* Note: for C++, the cross reference may be to a base type which
- has not yet been seen. In this case, we skip to the comma,
- which will mark the end of the base class name. (The ':'
- at the end of the base class name will be skipped as well.) */
- *pp = (char *) index (*pp, ',');
- /* Just allocate the type and leave it zero if nothing known */
- return dbx_alloc_type (typenums);
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- case '(':
- (*pp)--;
- read_type_number (pp, xtypenums);
- type = *dbx_lookup_type (xtypenums);
- if (type == 0)
- type = builtin_type_void;
- *dbx_lookup_type (typenums) = type;
- break;
-
- case '*':
- type1 = read_type (pp);
- if (TYPE_POINTER_TYPE (type1))
- {
- type = TYPE_POINTER_TYPE (type1);
- *dbx_lookup_type (typenums) = type;
- }
- else
- {
- type = dbx_alloc_type (typenums);
- smash_to_pointer_type (type, type1);
- }
- break;
-
- case '@@':
- {
- struct type *domain = read_type (pp);
- char c;
- struct type *memtype;
-
- if (*(*pp)++ != ',')
- error ("invalid member type data format, at symtab pos %d.",
- symnum);
-
- memtype = read_type (pp);
- type = dbx_alloc_type (typenums);
- smash_to_member_type (type, domain, memtype);
- }
- break;
-
- case '&':
- type1 = read_type (pp);
- if (TYPE_REFERENCE_TYPE (type1))
- {
- type = TYPE_REFERENCE_TYPE (type1);
- *dbx_lookup_type (typenums) = type;
- }
- else
- {
- type = dbx_alloc_type (typenums);
- smash_to_reference_type (type, type1);
- }
- break;
-
- case 'f':
- type1 = read_type (pp);
- if (TYPE_FUNCTION_TYPE (type1))
- {
- type = TYPE_FUNCTION_TYPE (type1);
- *dbx_lookup_type (typenums) = type;
- }
- else
- {
- type = dbx_alloc_type (typenums);
- smash_to_function_type (type, type1);
- }
- break;
-
- case 'r':
- type = read_range_type (pp, typenums);
- *dbx_lookup_type (typenums) = type;
- break;
-
- case 'e':
- type = dbx_alloc_type (typenums);
- type = read_enum_type (pp, type);
- *dbx_lookup_type (typenums) = type;
- break;
-
- case 's':
- type = dbx_alloc_type (typenums);
- type = read_struct_type (pp, type);
- break;
-
- case 'u':
- type = dbx_alloc_type (typenums);
- type = read_struct_type (pp, type);
- TYPE_CODE (type) = TYPE_CODE_UNION;
- break;
-
- case 'a':
- if (*(*pp)++ != 'r')
- error ("Invalid symbol data: unrecognized type-code `a%c' %s %d.",
- (*pp)[-1], "at symtab position", symnum);
-
- type = dbx_alloc_type (typenums);
- type = read_array_type (pp, type);
- break;
-
-#if 0
- /* Format of an array type:
- "ar<index type>;lower;upper;<array_contents_type>". Put code
- in to handle this. */
-
- /* dbx expresses array types in terms of a range type for the index,
- and that range type is specified right inside the array type spec
- making ar1;MIN;MAX;VALTYPE */
- if (!strncmp (*pp, "r1;0;", 5))
- (*pp) += 5;
- else if (!strncmp (*pp, "r(0,1);0;", 9))
- (*pp) += 9;
- else break;
-
- TYPE_CODE (type) = TYPE_CODE_ARRAY;
- /* In Fortran, an upper bound may be T... meaning a parameter specifies
- the length of the data. In this case, just pretend the bound is 1.
- This happens only for array parameters, which are really passed
- as pointers anyway, and we will translate them into such. */
- if (**pp == 'T')
- {
- n = 1;
- while (**pp != ';')
- (*pp)++;
- }
- else
- n = read_number (pp, ';') + 1;
- TYPE_TARGET_TYPE (type) = read_type (pp);
- TYPE_LENGTH (type) = TYPE_LENGTH (TYPE_TARGET_TYPE (type)) * n;
- break;
-#endif
-
- default:
- error ("Invalid symbol data: unrecognized type-code `%c' at symtab pos %d.",
- (*pp)[-1], symnum);
- }
-
- if (type == 0)
- abort ();
-
-#if 0
- /* If this is an overriding temporary alteration for a header file's
- contents, and this type number is unknown in the global definition,
- put this type into the global definition at this type number. */
- if (header_file_prev_index >= 0)
- {
- register struct type **tp
- = explicit_lookup_type (header_file_prev_index, typenums[1]);
- if (*tp == 0)
- *tp = type;
- }
-#endif
- return type;
-}
-
-/* This page contains subroutines of read_type. */
-
-/* Read the description of a structure (or union type)
- and return an object describing the type. */
-
-static struct type *
-read_struct_type (pp, type)
- char **pp;
- register struct type *type;
-{
- struct nextfield
- {
- struct nextfield *next;
- int visibility;
- struct field field;
- };
-
- struct next_fnfield
- {
- struct next_fnfield *next;
- int visibility;
- struct fn_field fn_field;
- };
-
- struct next_fnfieldlist
- {
- struct next_fnfieldlist *next;
- struct fn_fieldlist fn_fieldlist;
- };
-
- register struct nextfield *list = 0;
- struct nextfield *new;
- int totalsize;
- char *name;
- register char *p;
- int nfields = 0;
- register int n;
-
- register struct next_fnfieldlist *mainlist = 0;
- int nfn_fields = 0;
- struct type *baseclass = NULL;
- int read_possible_virtual_info = 0;
-
- TYPE_CODE (type) = TYPE_CODE_STRUCT;
-
- /* First comes the total size in bytes. */
-
- TYPE_LENGTH (type) = read_number (pp, 0);
-
- /* C++: Now, if the class is a derived class, then the next character
- will be a '!', followed by the number of base classes derived from.
- Each element in the list contains visibility information,
- the offset of this base class in the derived structure,
- and then the base type. */
- if (**pp == '!')
- {
- int i, n_baseclasses, offset;
- struct type **baseclass_vec;
- struct type *baseclass;
- int via_public, via_virtual;
-
- *pp += 1;
-
- n_baseclasses = read_number (pp, ',');
- baseclass_vec = (struct type **)
- obstack_alloc (symbol_obstack,
- (n_baseclasses) * sizeof (struct type **)) - 1;
-
- for (i = 1; i <= n_baseclasses; i++)
- {
- if (**pp == '\\')
- *pp = next_symbol_text ();
-
- switch (*(*pp)++)
- {
- case '0':
- via_virtual = 0;
- break;
- case '1':
- via_virtual = 1;
- break;
- default:
- error ("Invalid symbol data: bad visibility format at symtab pos %d",
- symnum);
- }
-
- switch (*(*pp)++)
- {
- case '0':
- via_public = 0;
- break;
- case '2':
- via_public = 1;
- break;
- default:
- error ("Invalid symbol data: bad visibility format at symtab pos %d.",
- symnum);
- }
- offset = read_number (pp, ',');
- baseclass = read_type (pp);
- *pp += 1; /* skip trailing ';' */
- baseclass_vec[i] = lookup_basetype_type (baseclass, offset, via_virtual, via_public);
-
- /* Make this baseclass visible for structure-printing purposes. */
- new = (struct nextfield *) alloca (sizeof (struct nextfield));
- new->next = list;
- list = new;
- list->field.type = baseclass_vec[i];
- list->field.name = TYPE_NAME (baseclass_vec[i]);
- list->field.bitpos = offset;
- list->field.bitsize = 0; /* this should be an unpacked field! */
- nfields++;
- }
- TYPE_N_BASECLASSES (type) = n_baseclasses;
- TYPE_BASECLASSES (type) = baseclass_vec;
- }
-
- /* Now come the fields, as NAME:?TYPENUM,BITPOS,BITSIZE; for each one.
- At the end, we see a semicolon instead of a field.
-
- In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for
- a static field.
-
- The `?' is a placeholder for one of '+' (public visibility),
- '0' (protected visibility), and '-' (private visibility). */
-
- while (**pp != ';')
- {
- int visibility;
-
- /* Check for and handle cretinous dbx symbol name continuation! */
- if (**pp == '\\') *pp = next_symbol_text ();
-
- /* Get space to record the next field's data. */
- new = (struct nextfield *) alloca (sizeof (struct nextfield));
- new->next = list;
- list = new;
-
- /* Read the data. */
- p = *pp;
- while (*p != ':') p++;
- list->field.name = obsavestring (*pp, p - *pp);
-
- /* C++: Check to see if we have hit the methods yet. */
- if (p[1] == ':')
- break;
-
- *pp = p + 1;
-
- /* This means we have a visibility for a field coming. */
- if (**pp == '/')
- {
- switch (*++*pp)
- {
- case '0':
- visibility = 0;
- *pp += 1;
- break;
-
- case '1':
- visibility = 1;
- *pp += 1;
- break;
-
- case '2':
- visibility = 2;
- *pp += 1;
- break;
- }
- }
- /* else normal dbx-style format. */
-
- list->field.type = read_type (pp);
- if (**pp == ':')
- {
- list->field.bitpos = (long)-1;
- p = ++(*pp);
- while (*p != ';') p++;
- list->field.bitsize = (long) savestring (*pp, p - *pp);
- *pp = p + 1;
- nfields++;
- continue;
- }
- else if (**pp != ',')
- error ("Invalid symbol data: bad structure-type format at symtab pos %d.",
- symnum);
- (*pp)++; /* Skip the comma. */
- list->field.bitpos = read_number (pp, ',');
- list->field.bitsize = read_number (pp, ';');
- /* Detect an unpacked field and mark it as such.
- dbx gives a bit size for all fields.
- Note that forward refs cannot be packed,
- and treat enums as if they had the width of ints. */
- if (TYPE_CODE (list->field.type) != TYPE_CODE_INT
- && TYPE_CODE (list->field.type) != TYPE_CODE_ENUM)
- list->field.bitsize = 0;
- if ((list->field.bitsize == 8 * TYPE_LENGTH (list->field.type)
- || (TYPE_CODE (list->field.type) == TYPE_CODE_ENUM
- && list->field.bitsize == 8 * TYPE_LENGTH (builtin_type_int)))
- &&
- list->field.bitpos % 8 == 0)
- list->field.bitsize = 0;
- nfields++;
- }
-
- /* Now come the method fields, as NAME::methods
- where each method is of the form TYPENUM,ARGS,...:PHYSNAME;
- At the end, we see a semicolon instead of a field.
-
- For the case of overloaded operators, the format is
- OPERATOR::*.methods, where OPERATOR is the string "operator",
- `*' holds the place for an operator name (such as `+=')
- and `.' marks the end of the operator name. */
- if (p[1] == ':')
- {
- /* Now, read in the methods. To simplify matters, we
- "unread" the name that has been read, so that we can
- start from the top. */
-
- p = *pp;
-
- /* chill the list of fields: the last entry (at the head)
- is a partially constructed entry which we now scrub. */
- list = list->next;
-
- /* For each list of method lists... */
- do
- {
- int i;
- struct next_fnfield *sublist = 0;
- struct fn_field *fn_fields = 0;
- int length = 0;
- struct next_fnfieldlist *new_mainlist =
- (struct next_fnfieldlist *)alloca (sizeof (struct next_fnfieldlist));
-
- /* read in the name. */
- while (*p != ':') p++;
- if ((*pp)[0] == 'o' && (*pp)[1] == 'p' && (*pp)[2] == '$')
- {
- static char opname[32] = "operator ";
- char *o = opname + 9;
-
- /* Skip past '::'. */
- p += 2;
- while (*p != '.')
- *o++ = *p++;
- new_mainlist->fn_fieldlist.name = savestring (opname, o - opname);
- /* Skip past '.' */
- *pp = p + 1;
- }
- else
- {
- i = 0;
- new_mainlist->fn_fieldlist.name = savestring (*pp, p - *pp);
- /* Skip past '::'. */
- *pp = p + 2;
- }
-
- do
- {
- struct next_fnfield *new_sublist =
- (struct next_fnfield *)alloca (sizeof (struct next_fnfield));
-
- /* Check for and handle cretinous dbx symbol name continuation! */
- if (**pp == '\\') *pp = next_symbol_text ();
-
- new_sublist->fn_field.type = read_type (pp);
- new_sublist->fn_field.args = read_args (pp, ':');
- p = *pp;
- while (*p != ';') p++;
- new_sublist->fn_field.physname = savestring (*pp, p - *pp);
- *pp = p + 1;
- new_sublist->visibility = *(*pp)++ - '0';
- if (**pp == '\\') *pp = next_symbol_text ();
-
- if (*(*pp)++ == '*')
- new_sublist->fn_field.voffset = read_number (pp, ';') + 1;
- else
- new_sublist->fn_field.voffset = 0;
-
- new_sublist->next = sublist;
- sublist = new_sublist;
- length++;
- }
- while (**pp != ';');
-
- *pp += 1;
-
- new_mainlist->fn_fieldlist.fn_fields =
- (struct fn_field *) obstack_alloc (symbol_obstack,
- sizeof (struct fn_field) * length);
- TYPE_FN_PRIVATE_BITS (new_mainlist->fn_fieldlist) =
- (int *) obstack_alloc (symbol_obstack,
- sizeof (int) * (1 + (length >> 5)));
-
- TYPE_FN_PROTECTED_BITS (new_mainlist->fn_fieldlist) =
- (int *) obstack_alloc (symbol_obstack,
- sizeof (int) * (1 + (length >> 5)));
-
- for (i = length; sublist; sublist = sublist->next)
- {
- new_mainlist->fn_fieldlist.fn_fields[--i] = sublist->fn_field;
- if (sublist->visibility == 0)
- B_SET (new_mainlist->fn_fieldlist.private_fn_field_bits, i);
- else if (sublist->visibility == 1)
- B_SET (new_mainlist->fn_fieldlist.protected_fn_field_bits, i);
- }
-
- new_mainlist->fn_fieldlist.length = length;
- new_mainlist->next = mainlist;
- mainlist = new_mainlist;
- nfn_fields++;
- }
- while (**pp != ';');
- }
-
- *pp += 1;
-
- /* Now create the vector of fields, and record how big it is. */
-
- TYPE_NFIELDS (type) = nfields;
- TYPE_FIELDS (type) = (struct field *) obstack_alloc (symbol_obstack,
- sizeof (struct field) * nfields);
- TYPE_FIELD_PRIVATE_BITS (type) =
- (int *) obstack_alloc (symbol_obstack,
- sizeof (int) * (1 + (nfields >> 5)));
- TYPE_FIELD_PROTECTED_BITS (type) =
- (int *) obstack_alloc (symbol_obstack,
- sizeof (int) * (1 + (nfields >> 5)));
-
- TYPE_NFN_FIELDS (type) = nfn_fields;
- TYPE_NFN_FIELDS_TOTAL (type) = nfn_fields;
- if (baseclass)
- TYPE_NFN_FIELDS_TOTAL (type) += TYPE_NFN_FIELDS_TOTAL (baseclass);
-
- TYPE_FN_FIELDLISTS (type) =
- (struct fn_fieldlist *) obstack_alloc (symbol_obstack,
- sizeof (struct fn_fieldlist) * nfn_fields);
-
- /* Copy the saved-up fields into the field vector. */
-
- for (n = nfields; list; list = list->next)
- {
- TYPE_FIELD (type, --n) = list->field;
- if (list->visibility == 0)
- SET_TYPE_FIELD_PRIVATE (type, n);
- else if (list->visibility == 1)
- SET_TYPE_FIELD_PROTECTED (type, n);
- }
-
- for (n = nfn_fields; mainlist; mainlist = mainlist->next)
- TYPE_FN_FIELDLISTS (type)[--n] = mainlist->fn_fieldlist;
-
- if (**pp == '~')
- {
- *pp += 1;
-
- if (**pp == '=')
- {
- TYPE_FLAGS (type)
- |= TYPE_FLAG_HAS_CONSTRUCTOR | TYPE_FLAG_HAS_DESTRUCTOR;
- *pp += 1;
- }
- else if (**pp == '+')
- {
- TYPE_FLAGS (type) |= TYPE_FLAG_HAS_CONSTRUCTOR;
- *pp += 1;
- }
- else if (**pp == '-')
- {
- TYPE_FLAGS (type) |= TYPE_FLAG_HAS_DESTRUCTOR;
- *pp += 1;
- }
-
- /* Read either a '%' or the final ';'. */
- if (*(*pp)++ == '%')
- {
- /* Now we must record the virtual function table pointer's
- field information. */
-
- struct type *t;
- int i;
-
- t = read_type (pp);
- p = (*pp)++;
- while (*p != ';') p++;
- TYPE_VPTR_BASETYPE (type) = t;
- if (type == t)
- {
- if (TYPE_FIELD_NAME (t, 0) == 0)
- TYPE_VPTR_FIELDNO (type) = i = 0;
- else for (i = TYPE_NFIELDS (t) - 1; i >= 0; --i)
- if (! strncmp (TYPE_FIELD_NAME (t, i), *pp,
- strlen (TYPE_FIELD_NAME (t, i))))
- {
- TYPE_VPTR_FIELDNO (type) = i;
- break;
- }
- if (i < 0)
- error ("virtual function table field not found");
- }
- else
- TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type, 1));
- *pp = p + 1;
- }
- else
- {
- TYPE_VPTR_BASETYPE (type) = 0;
- TYPE_VPTR_FIELDNO (type) = -1;
- }
- }
- else
- {
- TYPE_VPTR_BASETYPE (type) = 0;
- TYPE_VPTR_FIELDNO (type) = -1;
- }
-
- return type;
-}
-
-/* Read a definition of an enumberation type,
- and create and return a suitable type object.
- Also creates a range type which represents the bounds of that
- array. */
-static struct type *
-read_array_type (pp, type)
- register char **pp;
- register struct type *type;
-{
- struct type *index_type, *element_type, *range_type;
- int lower, upper;
-
- /* Format of an array type:
- "ar<index type>;lower;upper;<array_contents_type>". Put code in
- to handle this. */
-
- index_type = read_type (pp);
- if (*(*pp)++ != ';')
- error ("Invalid symbol data; improper format of array type decl.");
- lower = read_number (pp, ';');
- upper = read_number (pp, ';');
- element_type = read_type (pp);
-
- {
- /* Create range type. */
- range_type = (struct type *) obstack_alloc (symbol_obstack,
- sizeof (struct type));
- TYPE_CODE (range_type) = TYPE_CODE_RANGE;
- TYPE_TARGET_TYPE (range_type) = index_type;
-
- /* This should never be needed. */
- TYPE_LENGTH (range_type) = sizeof (int);
-
- TYPE_NFIELDS (range_type) = 2;
- TYPE_FIELDS (range_type) =
- (struct field *) obstack_alloc (symbol_obstack,
- 2 * sizeof (struct field));
- TYPE_FIELD_BITPOS (range_type, 0) = lower;
- TYPE_FIELD_BITPOS (range_type, 1) = upper;
- }
-
- TYPE_CODE (type) = TYPE_CODE_ARRAY;
- TYPE_TARGET_TYPE (type) = element_type;
- TYPE_LENGTH (type) = (upper - lower + 1) * TYPE_LENGTH (element_type);
- TYPE_NFIELDS (type) = 1;
- TYPE_FIELDS (type) =
- (struct field *) obstack_alloc (symbol_obstack,
- sizeof (struct field));
- TYPE_FIELD_TYPE (type, 0) = range_type;
-
- return type;
-}
-
-
-/* Read a definition of an enumeration type,
- and create and return a suitable type object.
- Also defines the symbols that represent the values of the type. */
-
-static struct type *
-read_enum_type (pp, type)
- register char **pp;
- register struct type *type;
-{
- register char *p;
- char *name;
- register long n;
- register struct symbol *sym;
- int nsyms = 0;
- struct pending **symlist;
- struct pending *osyms, *syms;
- int o_nsyms;
-
- if (within_function)
- symlist = &local_symbols;
- else
- symlist = &file_symbols;
- osyms = *symlist;
- o_nsyms = osyms ? osyms->nsyms : 0;
-
- /* Read the value-names and their values.
- The input syntax is NAME:VALUE,NAME:VALUE, and so on.
- A semicolon instead of a NAME means the end. */
- while (**pp && **pp != ';')
- {
- /* Check for and handle cretinous dbx symbol name continuation! */
- if (**pp == '\\') *pp = next_symbol_text ();
-
- p = *pp;
- while (*p != ':') p++;
- name = obsavestring (*pp, p - *pp);
- *pp = p + 1;
- n = read_number (pp, ',');
-
- sym = (struct symbol *) obstack_alloc (symbol_obstack, sizeof (struct symbol));
- bzero (sym, sizeof (struct symbol));
- SYMBOL_NAME (sym) = name;
- SYMBOL_CLASS (sym) = LOC_CONST;
- SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
- SYMBOL_VALUE (sym) = n;
- add_symbol_to_list (sym, symlist);
- nsyms++;
- }
-
- (*pp)++; /* Skip the semicolon. */
-
- /* Now fill in the fields of the type-structure. */
-
- TYPE_LENGTH (type) = sizeof (int);
- TYPE_CODE (type) = TYPE_CODE_ENUM;
- TYPE_NFIELDS (type) = nsyms;
- TYPE_FIELDS (type) = (struct field *) obstack_alloc (symbol_obstack, sizeof (struct field) * nsyms);
-
- /* Find the symbols for the values and put them into the type.
- The symbols can be found in the symlist that we put them on
- to cause them to be defined. osyms contains the old value
- of that symlist; everything up to there was defined by us. */
-
- for (syms = *symlist, n = nsyms; syms; syms = syms->next)
- {
- int j = 0;
- if (syms == osyms)
- j = o_nsyms;
- for (; j < syms->nsyms; j++)
- {
- struct symbol *sym = syms->symbol[j];
- SYMBOL_TYPE (sym) = type;
- TYPE_FIELD_NAME (type, --n) = SYMBOL_NAME (sym);
- TYPE_FIELD_VALUE (type, n) = 0;
- TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (sym);
- TYPE_FIELD_BITSIZE (type, n) = 0;
- }
- if (syms == osyms)
- break;
- }
-
- return type;
-}
-
-#define MAX_OF_TYPE(t) ((1 << (sizeof (t) - 1)) - 1)
-#define MIN_OF_TYPE(t) (-(1 << (sizeof (t) - 1)))
-
-static struct type *
-read_range_type (pp, typenums)
- char **pp;
- int typenums[2];
-{
- char *errp = *pp;
- int rangenums[2];
- int n2, n3;
- int self_subrange;
- struct type *result_type;
-
- /* First comes a type we are a subrange of.
- In C it is usually 0, 1 or the type being defined. */
- read_type_number (pp, rangenums);
- self_subrange = (rangenums[0] == typenums[0] &&
- rangenums[1] == typenums[1]);
-
- /* A semicolon should now follow; skip it. */
- if (**pp == ';')
- (*pp)++;
-
- /* The remaining two operands are usually lower and upper bounds
- of the range. But in some special cases they mean something else. */
- n2 = read_number (pp, ';');
- n3 = read_number (pp, ';');
-
- /* A type defined as a subrange of itself, with bounds both 0, is void. */
- if (self_subrange && n2 == 0 && n3 == 0)
- return builtin_type_void;
-
- /* If n3 is zero and n2 is not, we want a floating type,
- and n2 is the width in bytes.
-
- Fortran programs appear to use this for complex types also,
- and they give no way to distinguish between double and single-complex!
- We don't have complex types, so we would lose on all fortran files!
- So return type `double' for all of those. It won't work right
- for the complex values, but at least it makes the file loadable. */
-
- if (n3 == 0 && n2 > 0)
- {
- if (n2 == sizeof (float))
- return builtin_type_float;
- return builtin_type_double;
- }
-
- /* If the upper bound is -1, it must really be an unsigned int. */
-
- else if (n2 == 0 && n3 == -1)
- {
- if (sizeof (int) == sizeof (long))
- return builtin_type_unsigned_int;
- else
- return builtin_type_unsigned_long;
- }
-
- /* Special case: char is defined (Who knows why) as a subrange of
- itself with range 0-127. */
- else if (self_subrange && n2 == 0 && n3 == 127)
- return builtin_type_char;
-
- /* Assumptions made here: Subrange of self is equivalent to subrange
- of int. */
- else if (n2 == 0
- && (self_subrange ||
- *dbx_lookup_type (rangenums) == builtin_type_int))
- {
- /* an unsigned type */
- if (n3 == (1 << (8 * sizeof (int))) - 1)
- return builtin_type_unsigned_int;
- if (n3 == (1 << (8 * sizeof (short))) - 1)
- return builtin_type_unsigned_short;
- if (n3 == (1 << (8 * sizeof (char))) - 1)
- return builtin_type_unsigned_char;
- }
- else if (n2 == -n3 -1)
- {
- /* a signed type */
- if (n3 == (1 << (8 * sizeof (int) - 1)) - 1)
- return builtin_type_int;
- if (n3 == (1 << (8 * sizeof (long) - 1)) - 1)
- return builtin_type_long;
- if (n3 == (1 << (8 * sizeof (short) - 1)) - 1)
- return builtin_type_short;
- if (n3 == (1 << (8 * sizeof (char) - 1)) - 1)
- return builtin_type_char;
- }
-
- /* We have a real range type on our hands. Allocate space and
- return a real pointer. */
-
- /* At this point I don't have the faintest idea how to deal with
- a self_subrange type; I'm going to assume that this is used
- as an idiom, and that all of them are special cases. So . . . */
- if (self_subrange)
- error ("Type defined as subrange of itself.");
-
- result_type = (struct type *) obstack_alloc (symbol_obstack,
- sizeof (struct type));
- bzero (result_type, sizeof (struct type));
-
- TYPE_TARGET_TYPE (result_type) = (self_subrange ?
- builtin_type_int :
- *dbx_lookup_type(rangenums));
-
- /* We have to figure out how many bytes it takes to hold this
- range type. I'm going to assume that anything that is pushing
- the bounds of a long was taken care of above. */
- if (n2 >= MIN_OF_TYPE(char) && n3 <= MAX_OF_TYPE(char))
- TYPE_LENGTH (result_type) = 1;
- else if (n2 >= MIN_OF_TYPE(short) && n3 <= MAX_OF_TYPE(short))
- TYPE_LENGTH (result_type) = sizeof (short);
- else if (n2 >= MIN_OF_TYPE(int) && n3 <= MAX_OF_TYPE(int))
- TYPE_LENGTH (result_type) = sizeof (int);
- else if (n2 >= MIN_OF_TYPE(long) && n3 <= MAX_OF_TYPE(long))
- TYPE_LENGTH (result_type) = sizeof (long);
- else
- error ("Ranged type doesn't fit within known sizes.");
-
- TYPE_LENGTH (result_type) = TYPE_LENGTH (TYPE_TARGET_TYPE (result_type));
- TYPE_CODE (result_type) = TYPE_CODE_RANGE;
- TYPE_NFIELDS (result_type) = 2;
- TYPE_FIELDS (result_type) =
- (struct field *) obstack_alloc (symbol_obstack,
- 2 * sizeof (struct field));
- bzero (TYPE_FIELDS (result_type), 2 * sizeof (struct field));
- TYPE_FIELD_BITPOS (result_type, 0) = n2;
- TYPE_FIELD_BITPOS (result_type, 1) = n3;
-
- return result_type;
-}
-
-/* Read a number from the string pointed to by *PP.
- The value of *PP is advanced over the number.
- If END is nonzero, the character that ends the
- number must match END, or an error happens;
- and that character is skipped if it does match.
- If END is zero, *PP is left pointing to that character. */
-
-static long
-read_number (pp, end)
- char **pp;
- int end;
-{
- register char *p = *pp;
- register long n = 0;
- register int c;
- int sign = 1;
-
- /* Handle an optional leading minus sign. */
-
- if (*p == '-')
- {
- sign = -1;
- p++;
- }
-
- /* Read the digits, as far as they go. */
-
- while ((c = *p++) >= '0' && c <= '9')
- {
- n *= 10;
- n += c - '0';
- }
- if (end)
- {
- if (c && c != end)
- error ("Invalid symbol data: invalid character \\%03o at symbol pos %d.", c, symnum);
- }
- else
- --p;
-
- *pp = p;
- return n * sign;
-}
-
-/* Read in an argument list. This is a list of types. It is terminated with
- a ':', FYI. Return the list of types read in. */
-static struct type **
-read_args (pp, end)
- char **pp;
- int end;
-{
- struct type *types[1024], **rval; /* allow for fns of 1023 parameters */
- int n = 0;
-
- while (**pp != end)
- {
- if (**pp != ',')
- error ("Invalid argument list: no ',', at symtab pos %d", symnum);
- *pp += 1;
-
- /* Check for and handle cretinous dbx symbol name continuation! */
- if (**pp == '\\')
- *pp = next_symbol_text ();
-
- types[n++] = read_type (pp);
- }
- *pp += 1; /* get past `end' (the ':' character) */
-
- if (n == 1)
- {
- rval = (struct type **) xmalloc (2 * sizeof (struct type *));
- }
- else if (TYPE_CODE (types[n-1]) != TYPE_CODE_VOID)
- {
- rval = (struct type **) xmalloc ((n + 1) * sizeof (struct type *));
- bzero (rval + n, sizeof (struct type *));
- }
- else
- {
- rval = (struct type **) xmalloc (n * sizeof (struct type *));
- }
- bcopy (types, rval, n * sizeof (struct type *));
- return rval;
-}
-
-/* This function is really horrible, but to avoid it, there would need
- to be more filling in of forward references. THIS SHOULD BE MOVED OUT
- OF COFFREAD.C AND DBXREAD.C TO SOME PLACE WHERE IT CAN BE SHARED */
-int
-fill_in_vptr_fieldno (type)
- struct type *type;
-{
- if (TYPE_VPTR_FIELDNO (type) < 0)
- TYPE_VPTR_FIELDNO (type) =
- fill_in_vptr_fieldno (TYPE_BASECLASS (type, 1));
- return TYPE_VPTR_FIELDNO (type);
-}
-
-void
-_initialize_dbxread ()
-{
- symfile = 0;
- header_files = (struct header_file *) 0;
- this_object_header_files = (int *) 0;
-
- add_com ("symbol-file", class_files, symbol_file_command,
- "Load symbol table (in dbx format) from executable file FILE.");
-
- add_com ("add-file", class_files, add_file_command,
- "Load the symbols from FILE, assuming its code is at TEXT_START.") ;
-}
-
-#endif /* READ_DBX_FORMAT */
-@
-
-
-1.2
-log
-@If discarding the symbol table, discard its name too, so "info files"
-will give the right answer.
-@
-text
-@d27 1
-a27 1
-#include <sys/fcntl.h>
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d2 1
-a2 1
- Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
-d1457 3
-@
diff --git a/gdb/RCS/default-dep.c,v b/gdb/RCS/default-dep.c,v
deleted file mode 100644
index 81c18f3..0000000
--- a/gdb/RCS/default-dep.c,v
+++ /dev/null
@@ -1,731 +0,0 @@
-head 1.4;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.4
-date 89.03.27.20.08.50; author gnu; state Exp;
-branches ;
-next 1.3;
-
-1.3
-date 89.03.27.20.07.47; author gnu; state Exp;
-branches ;
-next 1.2;
-
-1.2
-date 89.03.27.18.49.06; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.03.20.19.47.11; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.4
-log
-@Restore A/UX-specific changes.
-@
-text
-@/* Low level interface to ptrace, for GDB when running under Unix.
- Copyright (C) 1988 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#include "defs.h"
-#include "param.h"
-#include "frame.h"
-#include "inferior.h"
-
-#ifdef USG
-#include <sys/types.h>
-#endif
-
-#ifdef UNISOFT_ASSHOLES
-#define PMMU
-#define NEW_PMMU
-#define mc68881 /* Needed to get float in user.h!!! */
-#include <sys/seg.h> /* For user.h */
-#include <sys/mmu.h>
-#include <sys/time.h>
-/* Things Unisoft defined differently from every other Unix system */
-#define NBPG PAGESIZE
-#define UPAGES USIZE
-#define KERNEL_U_ADDR UDOT
-#endif
-
-#include <stdio.h>
-#include <sys/param.h>
-#include <sys/dir.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-
-#ifdef COFF_ENCAPSULATE
-#include "a.out.encap.h"
-#else
-#include <a.out.h>
-#endif
-#ifndef N_SET_MAGIC
-#define N_SET_MAGIC(exec, val) ((exec).a_magic = (val))
-#endif
-
-#include <sys/user.h> /* After a.out.h */
-#include <sys/file.h>
-#include <sys/stat.h>
-
-extern int errno;
-
-/* This function simply calls ptrace with the given arguments.
- It exists so that all calls to ptrace are isolated in this
- machine-dependent file.
-
- If you are having trouble debugging ptrace calls, turn on DEBUG
- and every call to ptrace, in this module or elsewhere, will be
- logged to stderr. */
-int
-call_ptrace (request, pid, arg3, arg4)
- int request, pid, arg3, arg4;
-{
-#ifdef DEBUG
- int result;
-
- fprintf(stderr, "ptrace(%x,,%x, %x) = ", request, arg3, arg4);
- result=ptrace (request, pid, arg3, arg4);
- fprintf(stderr, "%x\n", result);
- return result;
-
-#define ptrace call_ptrace
-
-#else
- return ptrace (request, pid, arg3, arg4);
-#endif
-}
-
-kill_inferior ()
-{
- if (remote_debugging)
- return;
- if (inferior_pid == 0)
- return;
- ptrace (8, inferior_pid, 0, 0);
- wait (0);
- inferior_died ();
-}
-
-/* This is used when GDB is exiting. It gives less chance of error.*/
-
-kill_inferior_fast ()
-{
- if (remote_debugging)
- return;
- if (inferior_pid == 0)
- return;
- ptrace (8, inferior_pid, 0, 0);
- wait (0);
-}
-
-/* Resume execution of the inferior process.
- If STEP is nonzero, single-step it.
- If SIGNAL is nonzero, give it that signal. */
-
-void
-resume (step, signal)
- int step;
- int signal;
-{
- errno = 0;
- if (remote_debugging)
- remote_resume (step, signal);
- else
- {
- ptrace (step ? 9 : 7, inferior_pid, 1, signal);
- if (errno)
- perror_with_name ("ptrace");
- }
-}
-
-void
-fetch_inferior_registers ()
-{
- register int regno;
- register unsigned int regaddr;
- char buf[MAX_REGISTER_RAW_SIZE];
- register int i;
-
- struct user u;
- unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
- offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR;
-
- for (regno = 0; regno < NUM_REGS; regno++)
- {
- regaddr = register_addr (regno, offset);
- for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int))
- {
- *(int *) &buf[i] = ptrace (3, inferior_pid, regaddr, 0);
- regaddr += sizeof (int);
- }
- supply_register (regno, buf);
- }
-}
-
-/* Store our register values back into the inferior.
- If REGNO is -1, do this for all registers.
- Otherwise, REGNO specifies which register (so we can save time). */
-
-store_inferior_registers (regno)
- int regno;
-{
- register unsigned int regaddr;
- char buf[80];
-
- struct user u;
- unsigned int offset = (char *) &u.u_ar0 - (char *) &u;
- offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR;
-
- if (regno >= 0)
- {
- regaddr = register_addr (regno, offset);
- errno = 0;
-#ifdef UNISOFT_ASSHOLES
- /* You can't write the PC with ptrace 6, only with ptrace 11! */
- if (regno == PC_REGNUM)
- ptrace(11, inferior_pid, 16, read_register(regno));
- else
-#endif
- ptrace (6, inferior_pid, regaddr, read_register (regno));
- if (errno != 0)
- {
- sprintf (buf, "writing register number %d", regno);
- perror_with_name (buf);
- }
- }
- else for (regno = 0; regno < NUM_REGS; regno++)
- {
- regaddr = register_addr (regno, offset);
- errno = 0;
-#ifdef UNISOFT_ASSHOLES
- if (regno == PC_REGNUM)
- ptrace(11, inferior_pid, 16, read_register(regno));
- else
-#endif
- ptrace (6, inferior_pid, regaddr, read_register (regno));
- if (errno != 0)
- {
- sprintf (buf, "writing all regs, number %d", regno);
- perror_with_name (buf);
- }
- }
-}
-
-/* Copy LEN bytes from inferior's memory starting at MEMADDR
- to debugger memory starting at MYADDR.
- On failure (cannot read from inferior, usually because address is out
- of bounds) returns the value of errno. */
-
-int
-read_inferior_memory (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
-{
- register int i;
- /* Round starting address down to longword boundary. */
- register CORE_ADDR addr = memaddr & - sizeof (int);
- /* Round ending address up; get number of longwords that makes. */
- register int count
- = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
- /* Allocate buffer of that many longwords. */
- register int *buffer = (int *) alloca (count * sizeof (int));
- extern int errno;
-
- /* Read all the longwords */
- for (i = 0; i < count; i++, addr += sizeof (int))
- {
- errno = 0;
- if (remote_debugging)
- buffer[i] = remote_fetch_word (addr);
- else
- buffer[i] = ptrace (1, inferior_pid, addr, 0);
- if (errno)
- return errno;
- }
-
- /* Copy appropriate bytes out of the buffer. */
- bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
- return 0;
-}
-
-/* Copy LEN bytes of data from debugger memory at MYADDR
- to inferior's memory at MEMADDR.
- On failure (cannot write the inferior)
- returns the value of errno. */
-
-int
-write_inferior_memory (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
-{
- register int i;
- /* Round starting address down to longword boundary. */
- register CORE_ADDR addr = memaddr & - sizeof (int);
- /* Round ending address up; get number of longwords that makes. */
- register int count
- = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
- /* Allocate buffer of that many longwords. */
- register int *buffer = (int *) alloca (count * sizeof (int));
- extern int errno;
-
- /* Fill start and end extra bytes of buffer with existing memory data. */
-
- if (remote_debugging)
- buffer[0] = remote_fetch_word (addr);
- else
- buffer[0] = ptrace (1, inferior_pid, addr, 0);
-
- if (count > 1)
- {
- if (remote_debugging)
- buffer[count - 1]
- = remote_fetch_word (addr + (count - 1) * sizeof (int));
- else
- buffer[count - 1]
- = ptrace (1, inferior_pid,
- addr + (count - 1) * sizeof (int), 0);
- }
-
- /* Copy data to be written over corresponding part of buffer */
-
- bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
-
- /* Write the entire buffer. */
-
- for (i = 0; i < count; i++, addr += sizeof (int))
- {
- errno = 0;
- if (remote_debugging)
- remote_store_word (addr, buffer[i]);
- else
- ptrace (4, inferior_pid, addr, buffer[i]);
- if (errno)
- return errno;
- }
-
- return 0;
-}
-
-/* Work with core dump and executable files, for GDB.
- This code would be in core.c if it weren't machine-dependent. */
-
-/* Recognize COFF format systems because a.out.h defines AOUTHDR. */
-#ifdef AOUTHDR
-#define COFF_FORMAT
-#endif
-
-#ifndef N_TXTADDR
-#define N_TXTADDR(hdr) 0
-#endif /* no N_TXTADDR */
-
-#ifndef N_DATADDR
-#define N_DATADDR(hdr) hdr.a_text
-#endif /* no N_DATADDR */
-
-/* Make COFF and non-COFF names for things a little more compatible
- to reduce conditionals later. */
-
-#ifdef COFF_FORMAT
-#define a_magic magic
-#endif
-
-#ifndef COFF_FORMAT
-#define AOUTHDR struct exec
-#endif
-
-extern char *sys_siglist[];
-
-
-/* Hook for `exec_file_command' command to call. */
-
-extern void (*exec_file_display_hook) ();
-
-/* File names of core file and executable file. */
-
-extern char *corefile;
-extern char *execfile;
-
-/* Descriptors on which core file and executable file are open.
- Note that the execchan is closed when an inferior is created
- and reopened if the inferior dies or is killed. */
-
-extern int corechan;
-extern int execchan;
-
-/* Last modification time of executable file.
- Also used in source.c to compare against mtime of a source file. */
-
-extern int exec_mtime;
-
-/* Virtual addresses of bounds of the two areas of memory in the core file. */
-
-extern CORE_ADDR data_start;
-extern CORE_ADDR data_end;
-extern CORE_ADDR stack_start;
-extern CORE_ADDR stack_end;
-
-/* Virtual addresses of bounds of two areas of memory in the exec file.
- Note that the data area in the exec file is used only when there is no core file. */
-
-extern CORE_ADDR text_start;
-extern CORE_ADDR text_end;
-
-extern CORE_ADDR exec_data_start;
-extern CORE_ADDR exec_data_end;
-
-/* Address in executable file of start of text area data. */
-
-extern int text_offset;
-
-/* Address in executable file of start of data area data. */
-
-extern int exec_data_offset;
-
-/* Address in core file of start of data area data. */
-
-extern int data_offset;
-
-/* Address in core file of start of stack area data. */
-
-extern int stack_offset;
-
-#ifdef COFF_FORMAT
-/* various coff data structures */
-
-extern FILHDR file_hdr;
-extern SCNHDR text_hdr;
-extern SCNHDR data_hdr;
-
-#endif /* not COFF_FORMAT */
-
-/* a.out header saved in core file. */
-
-extern AOUTHDR core_aouthdr;
-
-/* a.out header of exec file. */
-
-extern AOUTHDR exec_aouthdr;
-
-extern void validate_files ();
-
-core_file_command (filename, from_tty)
- char *filename;
- int from_tty;
-{
- int val;
- extern char registers[];
-
- /* Discard all vestiges of any previous core file
- and mark data and stack spaces as empty. */
-
- if (corefile)
- free (corefile);
- corefile = 0;
-
- if (corechan >= 0)
- close (corechan);
- corechan = -1;
-
- data_start = 0;
- data_end = 0;
- stack_start = STACK_END_ADDR;
- stack_end = STACK_END_ADDR;
-
- /* Now, if a new core file was specified, open it and digest it. */
-
- if (filename)
- {
- if (have_inferior_p ())
- error ("To look at a core file, you must kill the inferior with \"kill\".");
- corechan = open (filename, O_RDONLY, 0);
- if (corechan < 0)
- perror_with_name (filename);
- /* 4.2-style (and perhaps also sysV-style) core dump file. */
- {
- struct user u;
-
- int reg_offset;
-
- val = myread (corechan, &u, sizeof u);
- if (val < 0)
- perror_with_name ("Not a core file: reading upage");
- if (val != sizeof u)
- error ("Not a core file: could only read %d bytes", val);
- data_start = exec_data_start;
-
- data_end = data_start + NBPG * u.u_dsize;
- stack_start = stack_end - NBPG * u.u_ssize;
- data_offset = NBPG * UPAGES;
- stack_offset = NBPG * (UPAGES + u.u_dsize);
-
- /* Some machines put an absolute address in here; Unisoft
- seems to put the offset in the upage of the regs. Sigh. */
- reg_offset = (int) u.u_ar0;
- if (reg_offset > NBPG * UPAGES)
- reg_offset -= KERNEL_U_ADDR;
-
- /* I don't know where to find this info.
- So, for now, mark it as not available. */
- N_SET_MAGIC (core_aouthdr, 0);
-
- /* Read the register values out of the core file and store
- them where `read_register' will find them. */
-
- {
- register int regno;
-
- for (regno = 0; regno < NUM_REGS; regno++)
- {
- char buf[MAX_REGISTER_RAW_SIZE];
-
- val = lseek (corechan, register_addr (regno, reg_offset), 0);
- if (val < 0)
- perror_with_name (reg_names[regno]);
-
- val = myread (corechan, buf, sizeof buf);
- if (val < 0)
- perror_with_name (reg_names[regno]);
- supply_register (regno, buf);
- }
- }
- }
- if (filename[0] == '/')
- corefile = savestring (filename, strlen (filename));
- else
- {
- corefile = concat (current_directory, "/", filename);
- }
-
- set_current_frame ( create_new_frame (read_register (FP_REGNUM),
- read_pc ()));
- select_frame (get_current_frame (), 0);
- validate_files ();
- }
- else if (from_tty)
- printf ("No core file now.\n");
-}
-
-exec_file_command (filename, from_tty)
- char *filename;
- int from_tty;
-{
- int val;
-
- /* Eliminate all traces of old exec file.
- Mark text segment as empty. */
-
- if (execfile)
- free (execfile);
- execfile = 0;
- data_start = 0;
- data_end -= exec_data_start;
- text_start = 0;
- text_end = 0;
- exec_data_start = 0;
- exec_data_end = 0;
- if (execchan >= 0)
- close (execchan);
- execchan = -1;
-
- /* Now open and digest the file the user requested, if any. */
-
- if (filename)
- {
- execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
- &execfile);
- if (execchan < 0)
- perror_with_name (filename);
-
-#ifdef COFF_FORMAT
- {
- int aout_hdrsize;
- int num_sections;
-
- if (read_file_hdr (execchan, &file_hdr) < 0)
- error ("\"%s\": not in executable format.", execfile);
-
- aout_hdrsize = file_hdr.f_opthdr;
- num_sections = file_hdr.f_nscns;
-
- if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0)
- error ("\"%s\": can't read optional aouthdr", execfile);
-
- if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections) < 0)
- error ("\"%s\": can't read text section header", execfile);
-
- if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
- error ("\"%s\": can't read data section header", execfile);
-
- text_start = exec_aouthdr.text_start;
- text_end = text_start + exec_aouthdr.tsize;
- text_offset = text_hdr.s_scnptr;
- exec_data_start = exec_aouthdr.data_start;
- exec_data_end = exec_data_start + exec_aouthdr.dsize;
- exec_data_offset = data_hdr.s_scnptr;
- data_start = exec_data_start;
- data_end += exec_data_start;
- exec_mtime = file_hdr.f_timdat;
- }
-#else /* not COFF_FORMAT */
- {
- struct stat st_exec;
-
-#ifdef HEADER_SEEK_FD
- HEADER_SEEK_FD (execchan);
-#endif
-
- val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR));
-
- if (val < 0)
- perror_with_name (filename);
-
- text_start = N_TXTADDR (exec_aouthdr);
- exec_data_start = N_DATADDR (exec_aouthdr);
-
- text_offset = N_TXTOFF (exec_aouthdr);
- exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
-
- text_end = text_start + exec_aouthdr.a_text;
- exec_data_end = exec_data_start + exec_aouthdr.a_data;
- data_start = exec_data_start;
- data_end += exec_data_start;
-
- fstat (execchan, &st_exec);
- exec_mtime = st_exec.st_mtime;
- }
-#endif /* not COFF_FORMAT */
-
- validate_files ();
- }
- else if (from_tty)
- printf ("No exec file now.\n");
-
- /* Tell display code (if any) about the changed file name. */
- if (exec_file_display_hook)
- (*exec_file_display_hook) (filename);
-}
-@
-
-
-1.3
-log
-@Remove A/UX-specific changes for shipping to FSF.
-@
-text
-@d30 13
-d176 7
-a182 1
- ptrace (6, inferior_pid, regaddr, read_register (regno));
-d193 6
-a198 1
- ptrace (6, inferior_pid, regaddr, read_register (regno));
-@
-
-
-1.2
-log
-@A/UX and USG changes, and a little better error reporting.
-@
-text
-@a29 13
-#ifdef UNISOFT_ASSHOLES
-#define PMMU
-#define NEW_PMMU
-#define mc68881 /* Needed to get float in user.h!!! */
-#include <sys/seg.h> /* For user.h */
-#include <sys/mmu.h>
-#include <sys/time.h>
-/* Things Unisoft defined differently from every other Unix system */
-#define NBPG PAGESIZE
-#define UPAGES USIZE
-#define KERNEL_U_ADDR UDOT
-#endif
-
-d163 1
-a163 7
-#ifdef UNISOFT_ASSHOLES
- /* You can't write the PC with ptrace 6, only with ptrace 11! */
- if (regno == PC_REGNUM)
- ptrace(11, inferior_pid, 16, read_register(regno));
- else
-#endif
- ptrace (6, inferior_pid, regaddr, read_register (regno));
-d174 1
-a174 6
-#ifdef UNISOFT_ASSHOLES
- if (regno == PC_REGNUM)
- ptrace(11, inferior_pid, 16, read_register(regno));
- else
-#endif
- ptrace (6, inferior_pid, regaddr, read_register (regno));
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d30 13
-a46 1
-#include <sys/user.h>
-d58 2
-d67 5
-a71 1
- machine-dependent file. */
-d76 11
-d88 1
-d176 7
-a182 1
- ptrace (6, inferior_pid, regaddr, read_register (regno));
-d193 6
-a198 1
- ptrace (6, inferior_pid, regaddr, read_register (regno));
-d201 1
-a201 1
- sprintf (buf, "writing register number %d", regno);
-d446 3
-a448 1
- perror_with_name (filename);
-d455 6
-a460 1
- reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR;
-d478 1
-a478 1
- perror_with_name (filename);
-d482 1
-a482 1
- perror_with_name (filename);
-@
diff --git a/gdb/RCS/findvar.c,v b/gdb/RCS/findvar.c,v
deleted file mode 100644
index 9095f2b..0000000
--- a/gdb/RCS/findvar.c,v
+++ /dev/null
@@ -1,584 +0,0 @@
-head 1.2;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.2
-date 89.04.26.01.06.46; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.04.25.15.38.48; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.2
-log
-@use XXX_BIG_ENDIAN macros rather than runtime tests.
-@
-text
-@/* Find a variable's value in memory, for GDB, the GNU debugger.
- Copyright (C) 1986, 1987 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#include "defs.h"
-#include "param.h"
-#include "symtab.h"
-#include "frame.h"
-#include "value.h"
-
-CORE_ADDR read_register ();
-
-/* Return the address in which frame FRAME's value of register REGNUM
- has been saved in memory. Or return zero if it has not been saved.
- If REGNUM specifies the SP, the value we return is actually
- the SP value, not an address where it was saved. */
-
-CORE_ADDR
-find_saved_register (frame, regnum)
- FRAME frame;
- int regnum;
-{
- struct frame_info *fi;
- struct frame_saved_regs saved_regs;
-
- register FRAME frame1 = 0;
- register CORE_ADDR addr = 0;
-
-#ifdef HAVE_REGISTER_WINDOWS
- /* We assume that a register in a register window will only be saved
- in one place (since the name changes and dissapears as you go
- towards inner frames), so we only call get_frame_saved_regs on
- the current frame. This is directly in contradiction to the
- usage below, which assumes that registers used in a frame must be
- saved in a lower (more interior) frame. This change is a result
- of working on a register window machine; get_frame_saved_regs
- always returns the registers saved within a frame, within the
- context (register namespace) of that frame. */
-
- if (REGISTER_IN_WINDOW_P(regnum))
- {
- fi = get_frame_info (frame);
- get_frame_saved_regs (fi, &saved_regs);
- return (saved_regs.regs[regnum] ?
- saved_regs.regs[regnum] : 0);
- }
-#endif /* HAVE_REGISTER_WINDOWS */
-
- /* Note that this next routine assumes that registers used in
- frame x will be saved only in the frame that x calls and
- frames interior to it. This is not true on the sparc, but the
- above macro takes care of it, so we should be all right. */
- while (1)
- {
- QUIT;
- frame1 = get_prev_frame (frame1);
- if (frame1 == 0 || frame1 == frame)
- break;
- fi = get_frame_info (frame1);
- get_frame_saved_regs (fi, &saved_regs);
- if (saved_regs.regs[regnum])
- addr = saved_regs.regs[regnum];
- }
-
- return addr;
-}
-
-/* Copy the bytes of register REGNUM, relative to the current stack frame,
- into our memory at MYADDR.
- The number of bytes copied is REGISTER_RAW_SIZE (REGNUM). */
-
-void
-read_relative_register_raw_bytes (regnum, myaddr)
- int regnum;
- char *myaddr;
-{
- register CORE_ADDR addr;
-
- if (regnum == FP_REGNUM)
- {
- bcopy (&FRAME_FP(selected_frame), myaddr, sizeof (CORE_ADDR));
- return;
- }
-
- addr = find_saved_register (selected_frame, regnum);
-
- if (addr)
- {
- if (regnum == SP_REGNUM)
- {
- CORE_ADDR buffer = addr;
- bcopy (&buffer, myaddr, sizeof (CORE_ADDR));
- }
- else
- read_memory (addr, myaddr, REGISTER_RAW_SIZE (regnum));
- return;
- }
- read_register_bytes (REGISTER_BYTE (regnum),
- myaddr, REGISTER_RAW_SIZE (regnum));
-}
-
-/* Return a `value' with the contents of register REGNUM
- in its virtual format, with the type specified by
- REGISTER_VIRTUAL_TYPE. */
-
-value
-value_of_register (regnum)
- int regnum;
-{
- register CORE_ADDR addr;
- register value val;
- char raw_buffer[MAX_REGISTER_RAW_SIZE];
- char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
-
- if (! (have_inferior_p () || have_core_file_p ()))
- error ("Can't get value of register without inferior or core file");
-
- addr = find_saved_register (selected_frame, regnum);
- if (addr)
- {
- if (regnum == SP_REGNUM)
- return value_from_long (builtin_type_int, (LONGEST) addr);
- read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum));
- }
- else
- read_register_bytes (REGISTER_BYTE (regnum), raw_buffer,
- REGISTER_RAW_SIZE (regnum));
-
- REGISTER_CONVERT_TO_VIRTUAL (regnum, raw_buffer, virtual_buffer);
- val = allocate_value (REGISTER_VIRTUAL_TYPE (regnum));
- bcopy (virtual_buffer, VALUE_CONTENTS (val), REGISTER_VIRTUAL_SIZE (regnum));
- VALUE_LVAL (val) = addr ? lval_memory : lval_register;
- VALUE_ADDRESS (val) = addr ? addr : REGISTER_BYTE (regnum);
- VALUE_REGNO (val) = regnum;
- return val;
-}
-
-/* Low level examining and depositing of registers.
-
- Note that you must call `fetch_registers' once
- before examining or depositing any registers. */
-
-char registers[REGISTER_BYTES];
-
-/* Copy LEN bytes of consecutive data from registers
- starting with the REGBYTE'th byte of register data
- into memory at MYADDR. */
-
-void
-read_register_bytes (regbyte, myaddr, len)
- int regbyte;
- char *myaddr;
- int len;
-{
- bcopy (&registers[regbyte], myaddr, len);
-}
-
-/* Copy LEN bytes of consecutive data from memory at MYADDR
- into registers starting with the REGBYTE'th byte of register data. */
-
-void
-write_register_bytes (regbyte, myaddr, len)
- int regbyte;
- char *myaddr;
- int len;
-{
- bcopy (myaddr, &registers[regbyte], len);
- if (have_inferior_p ())
- store_inferior_registers (-1);
-}
-
-/* Return the contents of register REGNO,
- regarding it as an integer. */
-
-CORE_ADDR
-read_register (regno)
- int regno;
-{
- /* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
- return *(int *) &registers[REGISTER_BYTE (regno)];
-}
-
-/* Store VALUE in the register number REGNO, regarded as an integer. */
-
-void
-write_register (regno, val)
- int regno, val;
-{
- /* This loses when REGISTER_RAW_SIZE (regno) != sizeof (int) */
-#if defined(sun4)
- /* This is a no-op on a Sun 4. */
- if (regno == 0)
- return;
-#endif
-
- *(int *) &registers[REGISTER_BYTE (regno)] = val;
-
- if (have_inferior_p ())
- store_inferior_registers (regno);
-}
-
-/* Record that register REGNO contains VAL.
- This is used when the value is obtained from the inferior or core dump,
- so there is no need to store the value there. */
-
-void
-supply_register (regno, val)
- int regno;
- char *val;
-{
- bcopy (val, &registers[REGISTER_BYTE (regno)], REGISTER_RAW_SIZE (regno));
-}
-
-/* Given a struct symbol for a variable,
- and a stack frame address, read the value of the variable
- and return a (pointer to a) struct value containing the value. */
-
-value
-read_var_value (var, frame)
- register struct symbol *var;
- FRAME frame;
-{
- register value v;
-
- struct frame_info *fi;
-
- struct type *type = SYMBOL_TYPE (var);
- register CORE_ADDR addr = 0;
- int val = SYMBOL_VALUE (var);
- register int len;
-
- v = allocate_value (type);
- VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */
- len = TYPE_LENGTH (type);
-
- if (frame == 0) frame = selected_frame;
-
- switch (SYMBOL_CLASS (var))
- {
- case LOC_CONST:
- case LOC_LABEL:
- bcopy (&val, VALUE_CONTENTS (v), len);
- VALUE_LVAL (v) = not_lval;
- return v;
-
- case LOC_CONST_BYTES:
- bcopy (val, VALUE_CONTENTS (v), len);
- VALUE_LVAL (v) = not_lval;
- return v;
-
- case LOC_STATIC:
- addr = val;
- break;
-
- case LOC_ARG:
- fi = get_frame_info (frame);
- addr = val + FRAME_ARGS_ADDRESS (fi);
- break;
-
- case LOC_LOCAL:
- fi = get_frame_info (frame);
- addr = val + FRAME_LOCALS_ADDRESS (fi);
- break;
-
- case LOC_TYPEDEF:
- error ("Cannot look up value of a typedef");
-
- case LOC_BLOCK:
- VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (var));
- return v;
-
- case LOC_REGISTER:
- case LOC_REGPARM:
- v = value_from_register (type, val, frame);
- return v;
- }
-
- read_memory (addr, VALUE_CONTENTS (v), len);
- VALUE_ADDRESS (v) = addr;
- return v;
-}
-
-/* Return a value of type TYPE, stored in register REGNUM, in frame
- FRAME. */
-
-value
-value_from_register (type, regnum, frame)
- struct type *type;
- int regnum;
- FRAME frame;
-{
- char raw_buffer [MAX_REGISTER_RAW_SIZE];
- char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
- CORE_ADDR addr;
- value v = allocate_value (type);
- int len = TYPE_LENGTH (type);
- char *value_bytes = 0;
- int value_bytes_copied = 0;
- int num_storage_locs;
-
- VALUE_REGNO (v) = regnum;
-
- num_storage_locs = (len > REGISTER_VIRTUAL_SIZE (regnum) ?
- ((len - 1) / REGISTER_RAW_SIZE (regnum)) + 1 :
- 1);
-
- if (num_storage_locs > 1)
- {
- /* Value spread across multiple storage locations. */
-
- int local_regnum;
- int mem_stor = 0, reg_stor = 0;
- int mem_tracking = 1;
- CORE_ADDR last_addr = 0;
-
- value_bytes = (char *) alloca (len + MAX_REGISTER_RAW_SIZE);
-
- /* Copy all of the data out, whereever it may be. */
-
- for (local_regnum = regnum;
- value_bytes_copied < len;
- (value_bytes_copied += REGISTER_RAW_SIZE (local_regnum),
- ++local_regnum))
- {
- int register_index = local_regnum - regnum;
- addr = find_saved_register (frame, local_regnum);
- if (addr == 0)
- {
- read_register_bytes (REGISTER_BYTE (local_regnum),
- value_bytes + value_bytes_copied,
- REGISTER_RAW_SIZE (local_regnum));
- reg_stor++;
- }
- else
- {
- read_memory (addr, value_bytes + value_bytes_copied,
- REGISTER_RAW_SIZE (local_regnum));
- mem_stor++;
- mem_tracking =
- (mem_tracking
- && (regnum == local_regnum
- || addr == last_addr));
- }
- last_addr = addr;
- }
-
- if ((reg_stor && mem_stor)
- || (mem_stor && !mem_tracking))
- /* Mixed storage; all of the hassle we just went through was
- for some good purpose. */
- {
- VALUE_LVAL (v) = lval_reg_frame_relative;
- VALUE_FRAME (v) = FRAME_FP (frame);
- VALUE_FRAME_REGNUM (v) = regnum;
- }
- else if (mem_stor)
- {
- VALUE_LVAL (v) = lval_memory;
- VALUE_ADDRESS (v) = find_saved_register (frame, regnum);
- }
- else if (reg_stor)
- {
- VALUE_LVAL (v) = lval_register;
- VALUE_ADDRESS (v) = REGISTER_BYTE (regnum);
- }
- else
- fatal ("value_from_register: Value not stored anywhere!");
-
- /* Any structure stored in more than one register will always be
- an inegral number of registers. Otherwise, you'd need to do
- some fiddling with the last register copied here for little
- endian machines. */
-
- /* Copy into the contents section of the value. */
- bcopy (value_bytes, VALUE_CONTENTS (v), len);
-
- return v;
- }
-
- /* Data is completely contained within a single register. Locate the
- register's contents in a real register or in core;
- read the data in raw format. */
-
- addr = find_saved_register (frame, regnum);
- if (addr == 0)
- {
- /* Value is really in a register. */
-
- VALUE_LVAL (v) = lval_register;
- VALUE_ADDRESS (v) = REGISTER_BYTE (regnum);
-
- read_register_bytes (REGISTER_BYTE (regnum),
- raw_buffer, REGISTER_RAW_SIZE (regnum));
- }
- else
- {
- /* Value was in a register that has been saved in memory. */
-
- read_memory (addr, raw_buffer, REGISTER_RAW_SIZE (regnum));
- VALUE_LVAL (v) = lval_memory;
- VALUE_ADDRESS (v) = addr;
- }
-
- /* Convert the raw contents to virtual contents.
- (Just copy them if the formats are the same.) */
-
- REGISTER_CONVERT_TO_VIRTUAL (regnum, raw_buffer, virtual_buffer);
-
- if (REGISTER_CONVERTIBLE (regnum))
- {
- /* When the raw and virtual formats differ, the virtual format
- corresponds to a specific data type. If we want that type,
- copy the data into the value.
- Otherwise, do a type-conversion. */
-
- if (type != REGISTER_VIRTUAL_TYPE (regnum))
- {
- /* eg a variable of type `float' in a 68881 register
- with raw type `extended' and virtual type `double'.
- Fetch it as a `double' and then convert to `float'. */
- v = allocate_value (REGISTER_VIRTUAL_TYPE (regnum));
- bcopy (virtual_buffer, VALUE_CONTENTS (v), len);
- v = value_cast (type, v);
- }
- else
- bcopy (virtual_buffer, VALUE_CONTENTS (v), len);
- }
- else
- {
- /* Raw and virtual formats are the same for this register. */
-
-#ifdef BYTES_BIG_ENDIAN
- if (len < REGISTER_RAW_SIZE (regnum))
- {
- /* Big-endian, and we want less than full size. */
- VALUE_OFFSET (v) = REGISTER_RAW_SIZE (regnum) - len;
- }
-#endif
-
- bcopy (virtual_buffer + VALUE_OFFSET (v),
- VALUE_CONTENTS (v), len);
- }
-
- return v;
-}
-
-/* Given a struct symbol for a variable,
- and a stack frame address,
- return a (pointer to a) struct value containing the variable's address. */
-
-value
-locate_var_value (var, frame)
- register struct symbol *var;
- FRAME frame;
-{
- register CORE_ADDR addr = 0;
- int val = SYMBOL_VALUE (var);
- struct frame_info *fi;
- struct type *type = SYMBOL_TYPE (var);
-
- if (frame == 0) frame = selected_frame;
-
- switch (SYMBOL_CLASS (var))
- {
- case LOC_CONST:
- case LOC_CONST_BYTES:
- error ("Address requested for identifier \"%s\" which is a constant.",
- SYMBOL_NAME (var));
-
- case LOC_REGISTER:
- case LOC_REGPARM:
- addr = find_saved_register (frame, val);
- if (addr != 0)
- {
- int len = TYPE_LENGTH (type);
-#ifdef BYTES_BIG_ENDIAN
- if (len < REGISTER_RAW_SIZE (val))
- /* Big-endian, and we want less than full size. */
- addr += REGISTER_RAW_SIZE (val) - len;
-#endif
- break;
- }
- error ("Address requested for identifier \"%s\" which is in a register.",
- SYMBOL_NAME (var));
-
- case LOC_STATIC:
- case LOC_LABEL:
- addr = val;
- break;
-
- case LOC_ARG:
- fi = get_frame_info (frame);
- addr = val + FRAME_ARGS_ADDRESS (fi);
- break;
-
- case LOC_LOCAL:
- fi = get_frame_info (frame);
- addr = val + FRAME_LOCALS_ADDRESS (fi);
- break;
-
- case LOC_TYPEDEF:
- error ("Address requested for identifier \"%s\" which is a typedef.",
- SYMBOL_NAME (var));
-
- case LOC_BLOCK:
- addr = BLOCK_START (SYMBOL_BLOCK_VALUE (var));
- break;
- }
-
- return value_cast (lookup_pointer_type (type),
- value_from_long (builtin_type_long, (LONGEST) addr));
-}
-
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d448 2
-a449 5
- union { int i; char c; } test;
- /* If we want less than the full size, we need to
- test for a big-endian or little-endian machine. */
- test.i = 1;
- if (test.c != 1 && len < REGISTER_RAW_SIZE (regnum))
-d454 2
-a455 1
-
-a490 1
- union { int i; char c; } test;
-d492 2
-a493 4
- /* If var is less than the full size of register, we need to
- test for a big-endian or little-endian machine. */
- test.i = 1;
- if (test.c != 1 && len < REGISTER_RAW_SIZE (val))
-d496 1
-@
diff --git a/gdb/RCS/gdb.texinfo,v b/gdb/RCS/gdb.texinfo,v
deleted file mode 100644
index ff38f18..0000000
--- a/gdb/RCS/gdb.texinfo,v
+++ /dev/null
@@ -1,3009 +0,0 @@
-head 1.2;
-access ;
-symbols ;
-locks ; strict;
-comment @@;
-
-
-1.2
-date 89.02.10.01.41.38; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.02.10.00.33.03; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.2
-log
-@Improve doc in various ways, mostly xref{Expressions} so you can
-find out what an expression is (I had trouble finding it, since
-it's in a nested menu somewhere.)
-@
-text
-@\input texinfo
-@@setfilename ../info/gdb
-@@settitle GDB, The GNU Debugger
-@@ifinfo
-This file documents the GNU debugger GDB.
-
-Copyright (C) 1988 Free Software Foundation, Inc.
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-@@ignore
-Permission is granted to process this file through Tex and print the
-results, provided the printed document carries copying permission
-notice identical to this one except for the removal of this paragraph
-(this paragraph not being relevant to the printed manual).
-
-@@end ignore
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided also that the
-sections entitled ``Distribution'' and ``GDB General Public License'' are
-included exactly as in the original, and provided that the entire resulting
-derived work is distributed under the terms of a permission notice
-identical to this one.
-
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions,
-except that the sections entitled ``Distribution'' and ``GDB General Public
-License'' may be included in a translation approved by the author instead
-of in the original English.
-@@end ifinfo
-
-@@setchapternewpage odd
-@@settitle GDB Manual
-@@titlepage
-@@sp 6
-@@center @@titlefont{GDB Manual}
-@@sp 1
-@@center The GNU Source-Level Debugger
-@@sp 4
-@@center Third Edition, GDB version 3.1
-@@sp 1
-@@center January 1989
-@@sp 5
-@@center Richard M. Stallman
-@@page
-@@vskip 0pt plus 1filll
-Copyright @@copyright{} 1988, 1989 Free Software Foundation, Inc.
-
-Permission is granted to make and distribute verbatim copies of
-this manual provided the copyright notice and this permission notice
-are preserved on all copies.
-
-Permission is granted to copy and distribute modified versions of this
-manual under the conditions for verbatim copying, provided also that the
-sections entitled ``Distribution'' and ``GDB General Public License'' are
-included exactly as in the original, and provided that the entire resulting
-derived work is distributed under the terms of a permission notice
-identical to this one.
-
-Permission is granted to copy and distribute translations of this manual
-into another language, under the above conditions for modified versions,
-except that the sections entitled ``Distribution'' and ``GDB General Public
-License'' may be included in a translation approved by the author instead
-of in the original English.
-@@end titlepage
-@@page
-
-@@node Top, Commands,, (DIR)
-@@unnumbered Summary of GDB
-
-The purpose of a debugger such as GDB is to allow you to execute another
-program while examining what is going on inside it. We call the other
-program ``your program'' or ``the program being debugged''.
-
-GDB can do four kinds of things (plus other things in support of these):
-
-@@enumerate
-@@item
-Start the program, specifying anything that might affect its behavior.
-
-@@item
-Make the program stop on specified conditions.
-
-@@item
-Examine what has happened, when the program has stopped, so that you
-can see bugs happen.
-
-@@item
-Change things in the program, so you can correct the effects of one bug
-and go on to learn about another without having to recompile first.
-@@end enumerate
-
-GDB can be used to debug programs written in C and C++. Pascal support
-is being implemented, and Fortran support will be added when a GNU
-Fortran compiler is written.
-
-@@menu
-* License:: The GDB General Public License gives you permission
- to redistribute GDB on certain terms; and also
- explains that there is no warranty.
-* Input:: GDB command syntax and input conventions.
-* Files:: Specifying files for GDB to operate on.
-* Options:: GDB arguments and options.
-* Compilation::Compiling your program so you can debug it.
-* Running:: Running your program under GDB.
-* Stopping:: Making your program stop. Why it may stop. What to do then.
-* Stack:: Examining your program's stack.
-* Source:: Examining your program's source files.
-* Data:: Examining data in your program.
-* Symbols:: Examining the debugger's symbol table.
-* Altering:: Altering things in your program.
-* Sequences:: Canned command sequences for repeated use.
-* Emacs:: Using GDB through GNU Emacs.
-* Remote:: Remote kernel debugging across a serial line.
-* Commands:: Index of GDB commands.
-* Concepts:: Index of GDB concepts.
-@@end menu
-
-@@node License, Input, Top, Top
-@@unnumbered GDB General Public License
-@@center (Clarified 11 Feb 1988)
-
- The license agreements of most software companies keep you at the mercy
-of those companies. By contrast, our general public license is intended to
-give everyone the right to share GDB. To make sure that you get the rights
-we want you to have, we need to make restrictions that forbid anyone to
-deny you these rights or to ask you to surrender the rights. Hence this
-license agreement.
-
- Specifically, we want to make sure that you have the right to give away
-copies of GDB, that you receive source code or else can get it if you want
-it, that you can change GDB or use pieces of it in new free programs, and
-that you know you can do these things.
-
- To make sure that everyone has such rights, we have to forbid you to
-deprive anyone else of these rights. For example, if you distribute copies
-of GDB, you must give the recipients all the rights that you have. You
-must make sure that they, too, receive or can get the source code. And you
-must tell them their rights.
-
- Also, for our own protection, we must make certain that everyone finds
-out that there is no warranty for GDB. If GDB is modified by someone else
-and passed on, we want its recipients to know that what they have is not
-what we distributed, so that any problems introduced by others will not
-reflect on our reputation.
-
- Therefore we (Richard Stallman and the Free Software Foundation,
-Inc.) make the following terms which say what you must do to be
-allowed to distribute or change GDB.
-
-@@unnumberedsec Copying Policies
-
-@@enumerate
-@@item
-You may copy and distribute verbatim copies of GDB source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each file a valid copyright notice ``Copyright
-@@copyright{} 1988 Free Software Foundation, Inc.'' (or with whatever year
-is appropriate); keep intact the notices on all files that
-refer to this License Agreement and to the absence of any warranty; and
-give any other recipients of the GDB program a copy of this License
-Agreement along with the program. You may charge a distribution fee
-for the physical act of transferring a copy.
-
-@@item
-You may modify your copy or copies of GDB source code or any portion
-of it, and copy and distribute such modifications under the terms of
-Paragraph 1 above, provided that you also do the following:
-
-@@itemize @@bullet
-@@item
-cause the modified files to carry prominent notices stating
-that you changed the files and the date of any change; and
-
-@@item
-cause the whole of any work that you distribute or publish, that
-in whole or in part contains or is a derivative of GDB or any
-part thereof, to be licensed at no charge to all third parties on
-terms identical to those contained in this License Agreement
-(except that you may choose to grant more extensive warranty
-protection to some or all third parties, at your option).
-
-@@item
-if the modified program serves as a debugger, cause it, when
-started running in the simplest and usual way, to print an
-announcement including a valid copyright notice ``Copyright
-@@copyright{} 1988 Free Software Foundation, Inc.'' (or with the
-year that is appropriate), saying that there is no warranty (or
-else, saying that you provide a warranty) and that users may
-redistribute the program under these conditions, and telling the
-user how to view a copy of this License Agreement.
-
-@@item
-You may charge a distribution fee for the physical act of
-transferring a copy, and you may at your option offer warranty
-protection in exchange for a fee.
-@@end itemize
-
-Mere aggregation of another unrelated program with this program (or its
-derivative) on a volume of a storage or distribution medium does not bring
-the other program under the scope of these terms.
-
-@@item
-You may copy and distribute GDB (or a portion or derivative of it,
-under Paragraph 2) in object code or executable form under the terms
-of Paragraphs 1 and 2 above provided that you also do one of the
-following:
-
-@@itemize @@bullet
-@@item
-accompany it with the complete corresponding machine-readable
-source code, which must be distributed under the terms of
-Paragraphs 1 and 2 above; or,
-
-@@item
-accompany it with a written offer, valid for at least three
-years, to give any third party free (except for a nominal
-shipping charge) a complete machine-readable copy of the
-corresponding source code, to be distributed under the terms of
-Paragraphs 1 and 2 above; or,
-
-@@item
-accompany it with the information you received as to where the
-corresponding source code may be obtained. (This alternative is
-allowed only for noncommercial distribution and only if you
-received the program in object code or executable form alone.)
-@@end itemize
-
-For an executable file, complete source code means all the source code
-for all modules it contains; but, as a special exception, it need not
-include source code for modules which are standard libraries that
-accompany the operating system on which the executable file runs.
-
-@@item
-You may not copy, sublicense, distribute or transfer GDB except as
-expressly provided under this License Agreement. Any attempt
-otherwise to copy, sublicense, distribute or transfer GDB is void and
-your rights to use GDB under this License agreement shall be
-automatically terminated. However, parties who have received computer
-software programs from you with this License Agreement will not have
-their licenses terminated so long as such parties remain in full
-compliance.
-
-@@item
-If you wish to incorporate parts of GDB into other free programs whose
-distribution conditions are different, write to the Free Software
-Foundation. We have not yet worked out a simple rule that can be
-stated here, but we will often permit this. We will be guided by the
-two goals of preserving the free status of all derivatives our free
-software and of promoting the sharing and reuse of software.
-@@end enumerate
-
-@@iftex
-@@vfil
-@@eject
-@@end iftex
-@@unnumberedsec NO WARRANTY
-
- BECAUSE GDB IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY
-NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
-WHEN OTHERWISE STATED IN WRITING, THE FREE SOFTWARE FOUNDATION, INC,
-RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE GDB ``AS IS''
-WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
-BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY
-AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE GDB
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
-SERVICING, REPAIR OR CORRECTION.
-
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL FREE SOFTWARE
-FOUNDATION, INC., RICHARD M. STALLMAN, AND/OR ANY OTHER PARTY WHO MAY
-MODIFY AND REDISTRIBUTE GDB AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER
-SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
-INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
-BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
-FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY
-FREE SOFTWARE FOUNDATION, INC.) THE PROGRAM, EVEN IF YOU HAVE BEEN
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY
-OTHER PARTY.
-
-@@node Input, Files, License, Top
-@@chapter GDB Input Conventions
-
-GDB is invoked with the shell command @@samp{gdb}. Once started, it reads
-commands from the terminal until you tell it to exit.
-
-A GDB command is a single line of input. There is no limit on how long
-it can be. It starts with a command name, which is followed by arguments
-whose meaning depends on the command name. Some command names do not
-allow arguments.
-
-GDB command names may always be abbreviated if the abbreviation is
-unambiguous. Sometimes even ambiguous abbreviations are allowed; for
-example, @@samp{s} is specially defined as equivalent to @@samp{step}
-even though there are other commands whose names start with @@samp{s}.
-Possible command abbreviations are often stated in the documentation
-of the individual commands.
-
-A blank line as input to GDB means to repeat the previous command verbatim.
-Certain commands do not allow themselves to be repeated this way; these are
-commands for which unintentional repetition might cause trouble and which
-you are unlikely to want to repeat. Certain others (@@samp{list} and
-@@samp{x}) act differently when repeated because that is more useful.
-
-A line of input starting with @@samp{#} is a comment; it does nothing.
-This is useful mainly in command files (@@xref{Command Files}).
-
-Occasionally it is useful to execute a shell command from within gdb.
-This can be done with the @@samp{shell} command, or the shell escape
-character @@samp{!}.
-
-@@table @@code
-@@item shell @@var{shell command string}
-@@kindex shell
-@@item !@@var{shell command string}
-@@kindex !
-@@cindex shell escape
-Directs GDB to invoke an inferior shell to execute @@samp{shell command string}.
-The environmental variable @@samp{SHELL} is used if it exists, otherwise gdb
-uses @@samp{/bin/sh}.
-@@end table
-
-GDB @@dfn{prompts} for commands with a string that is normally @@samp{(gdb)}.
-When debugging GDB with GDB, it is useful to change the prompt in one of
-the GDBs so that you can distinguish them. This can be done with the
-@@samp{set prompt} command.
-
-@@table @@code
-@@item set prompt @@var{newprompt}
-@@kindex set prompt
-Directs GDB to use @@var{newprompt} as its prompt string henceforth.
-@@end table
-
-@@cindex exiting GDB
-@@kindex quit
-To exit GDB, use the @@samp{quit} command (abbreviated @@samp{q}).
-@@kbd{Ctrl-c} will not exit from GDB, but rather will terminate the action
-of any GDB command that is in progress and return to GDB command level.
-It is safe to type @@kbd{Ctrl-c} at any time because GDB does not allow
-it to take effect until a time when it is safe.
-
-@@node Files, Options, Input, Top
-@@chapter Specifying GDB's Files
-
-@@cindex core dump file
-@@cindex executable file
-@@cindex symbol table
-GDB needs to know the filename of the program to be debugged. To debug a
-core dump of a previous run, GDB must be told the filename of the core
-dump.
-
-@@menu
-* Arguments: File Arguments. Specifying files with arguments
- (when you start GDB).
-* Commands: File Commands. Specifying files with GDB commands.
-@@end menu
-
-@@node File Arguments, File Commands, Files, Files
-@@section Specifying Files with Arguments
-
-The usual way to specify the executable and core dump file names is with
-two command arguments given when you start GDB. The first argument is used
-as the file for execution and symbols, and the second argument (if any) is
-used as the core dump file name. Thus,
-
-@@example
-gdb progm core
-@@end example
-
-@@noindent
-specifies @@file{progm} as the executable program and @@file{core} as a core
-dump file to examine. (You do not need to have a core dump file if what
-you plan to do is debug the program interactively.)
-
-@@xref{Options}, for full information on command options and arguments for
-GDB.
-
-@@node File Commands,, File Arguments, Files
-@@section Specifying Files with Commands
-
-Usually you specify the files for GDB to work with by giving arguments when
-you invoke GDB. But occasionally it is necessary to change to a different
-file during a GDB session. Or you may run GDB and forget to specify the
-files you want to use. In these situations the GDB commands to specify new
-files are useful.
-
-@@table @@code
-@@item exec-file @@var{filename}
-@@kindex exec-file
-Specify that the program to be run is found in @@var{filename}. If you
-do not specify a directory and the file is not found in GDB's working
-directory, GDB will use the environment variable @@samp{PATH} as a list
-of directories to search, just as the shell does when looking for a
-program to run.
-
-@@item symbol-file @@var{filename}
-@@kindex symbol-file
-Read symbol table information from file @@var{filename}. @@samp{PATH}
-is searched when necessary. Most of the time you will use both the
-@@samp{exec-file} and @@samp{symbol-file} commands on the same file.
-
-@@samp{symbol-file} with no argument clears out GDB's symbol table.
-
-@@item core-file @@var{filename}
-@@kindex core-file
-Specify the whereabouts of a core dump file to be used as the
-``contents of memory''. Note that the core dump contains only the
-writable parts of memory; the read-only parts must come from the
-executable file.
-
-@@samp{core-file} with no argument specifies that no core file is
-to be used.
-
-@@item add-file @@var{filename} @@var{address}
-@@kindex add-file
-The @@samp{add-file} command takes two arguments, a file name, and the
-address at which that file has been (or should be) dynamically loaded.
-GDB will then treat that file as though it had always been dynamically
-linked, and provide the user with all the normal GDB features, including
-symbolic debugging.
-
-With the @@samp{add-file} command, it is possible to debug code which was
-not present in the initial load image of the program under test.
-Suppose you have a program which can, while running, dynamically link a
-program fragment into its address space. One program which does this is
-KCL, a free common lisp implementation. The fragment will be loaded
-into the main program's address space at some address, and the main
-program can then call functions within the fragment by calculating (or
-otherwise obtaining) their addresses.
-
-@@item kill
-@@kindex kill
-Cancel running the program under GDB. This could be used if you wish
-to debug a core dump instead. GDB ignores any core dump file if it is
-actually running the program, so the @@samp{kill} command is the only
-sure way to go back to using the core dump file.
-
-@@item info files
-@@kindex info files
-Print the names of the executable and core dump files currently in
-use by GDB, and the file from which symbols were loaded.
-@@end table
-
-While all three file-specifying commands allow both absolute and relative
-file names as arguments, GDB always converts the file name to an absolute
-one and remembers it that way.
-
-The @@samp{symbol-file} command causes GDB to forget the contents of its
-convenience variables, the value history, and all breakpoints and
-auto-display expressions. This is because they may contain pointers to the
-internal data recording symbols and data types, which are part of the old
-symbol table data being discarded inside GDB.
-
-@@node Options, Compilation, Files, Top
-@@chapter Options and Arguments for GDB
-
-When you invoke GDB, you can pass commands telling it what files to
-operate on and what other things to do.
-
-@@menu
-* Mode Options:: Options controlling modes of operation.
-* File Options:: Options to specify files (executable, coredump, commands)
-* Other Arguments:: Any other arguments without options
- also specify files.
-@@end menu
-
-@@node Mode Options, File Options, Options, Options
-@@section Mode Options
-
-@@table @@samp
-@@item -nx
-Do not execute commands from the init files @@file{.gdbinit}.
-Normally, the commands in these files are executed after all the
-command options and arguments have been processed. @@xref{Command
-Files}.
-
-@@item -q
-``Quiet''. Do not print the usual introductory messages.
-
-@@item -batch
-Run in batch mode. Exit with code 1 after processing all the command
-files specified with @@samp{-x} (and @@file{.gdbinit}, if not
-inhibited). Exit also if, due to an error, GDB would otherwise
-attempt to read a command from the terminal.
-
-@@item -fullname
-This option is used when Emacs runs GDB as a subprocess. It tells GDB
-to output the full file name and line number in a standard,
-recognizable fashion each time a stack frame is displayed (which
-includes each time the program stops). This recognizable format looks
-like two @@samp{\032} characters, followed by the filename, line number
-and character position separated by colons, and a newline. The
-Emacs-to-GDB interface program uses the two @@samp{\032} characters as
-a signal to display the source code for the frame.
-@@end table
-
-@@node File Options, Other Arguments, Mode Options, Options
-@@section File-specifying Options
-
-All the options and command line arguments given are processed
-in sequential order. The order makes a difference when the
-@@samp{-x} command is used.
-
-@@table @@samp
-@@item -s @@var{file}
-Read symbol table from file @@var{file}.
-
-@@item -e @@var{file}
-Use file @@var{file} as the executable file to execute when
-appropriate, and for examining pure data in conjunction with a core
-dump.
-
-@@item -se @@var{file}
-Read symbol table from file @@var{file} and use it as the executable
-file.
-
-@@item -c @@var{file}
-Use file @@var{file} as a core dump to examine.
-
-@@item -x @@var{file}
-Execute GDB commands from file @@var{file}.
-
-@@item -d @@var{directory}
-Add @@var{directory} to the path to search for source files.
-@@end table
-
-@@node Other Arguments,, File Options, Options
-@@section Other Arguments
-
-If there are arguments to GDB that are not options or associated with
-options, the first one specifies the symbol table and executable file name
-(as if it were preceded by @@samp{-se}) and the second one specifies a core
-dump file name (as if it were preceded by @@samp{-c}).
-
-@@node Compilation, Running, Options, Top
-@@chapter Compiling Your Program for Debugging
-
-In order to debug a program effectively, you need to ask for debugging
-information when you compile it. This information in the object file
-describes the data type of each variable or function and the correspondence
-between source line numbers and addresses in the executable code.
-
-To request debugging information, specify the @@samp{-g} option when you run
-the compiler.
-
-The Unix C compiler is unable to handle the @@samp{-g} and @@samp{-O} options
-together. This means that you cannot ask for optimization if you ask for
-debugger information.
-
-The GNU C compiler supports @@samp{-g} with or without @@samp{-O}, making it
-possible to debug optimized code. We recommend that you @@emph{always} use
-@@samp{-g} whenever you compile a program. You may think the program is
-correct, but there's no sense in pushing your luck.
-
-If you are using the GNU C compiler, the GNU assembler and the GNU linker,
-you can choose between two formats of debugging information: the standard
-Unix format, which is what you get with @@samp{-g}, and GDB's own format,
-which you request by using @@samp{-gg} instead of @@samp{-g}. This stores
-debugging information in the executable file in a format much like that
-which is used inside GDB. This has these advantages and disadvantages:
-
-@@itemize @@bullet
-@@item
-GDB can read @@samp{-gg} format more than twice as fast as Unix
-@@samp{-g} format.
-
-@@item
-The @@samp{-gg} format uses much more disk space than Unix format.
-
-@@item
-The Unix debuggers can understand only Unix format, so you cannot use
-Unix source-level debuggers if you compile with @@samp{-gg}. (The
-@@code{adb} debugger works with either format; it does not use this
-information in any case.)
-@@end itemize
-
-@@node Running, Stopping, Compilation, Top
-@@chapter Running Your Program Under GDB
-
-@@cindex running
-@@kindex run
-To start your program under GDB, use the @@samp{run} command. The program
-must already have been specified using the @@samp{exec-file} command or with
-an argument to GDB (@@pxref{Files}); what @@samp{run} does is create an
-inferior process, load the program into it, and set it in motion.
-
-The execution of a program is affected by certain information it receives
-from its superior. GDB provides ways to specify them, which you must do
-@@i{before} starting the program. (You can change them after starting the
-program, but such changes do not affect the program unless you start it
-over again.)
-
-@@table @@asis
-@@item The @@i{arguments.}
-You specify the arguments to give the program as the arguments of the
-@@samp{run} command.
-
-@@item The @@i{environment.}
-The program normally inherits its environment from GDB, but you can
-use the GDB commands @@samp{set environment} and
-@@samp{unset environment} to change parts of the environment that will
-be given to the program.@@refill
-
-@@item The @@i{working directory.}
-The program inherits its working directory from GDB. You can set GDB's
-working directory with the @@samp{cd} command in GDB.
-@@end table
-
-After the @@samp{run} command, the debugger does nothing but wait for your
-program to stop. @@xref{Stopping}.
-
-Note that once your program has been started by the @@samp{run} command,
-you may evaluate expressions that involve calls to functions in the
-inferior. @@xref{Expressions}. If you wish to evaluate a function
-simply for it's side affects, you may use the @@samp{set} command.
-@@xref{Assignment}.
-
-@@menu
-* Arguments:: Specifying the arguments for your program.
-* Environment:: Specifying the environment for your program.
-* Working Directory:: Specifying the working directory for giving
- to your program when it is run.
-* Input/Output:: Specifying the program's standard input and output.
-* Attach:: Debugging a process started outside GDB.
-@@end menu
-
-@@node Arguments, Environment, Running, Running
-@@section Your Program's Arguments
-
-@@cindex arguments (to your program)
-You specify the arguments to give the program as the arguments of the
-@@samp{run} command. They are passed to a shell, which expands wildcard
-characters and performs redirection of I/O, and thence to the program.
-
-@@samp{run} with no arguments uses the same arguments used by the previous
-@@samp{run}.
-
-@@kindex set args
-The command @@samp{set args} can be used to specify the arguments to be used
-the next time the program is run. If @@samp{set args} has no arguments, it
-means to use no arguments the next time the program is run. If you have
-run your program with arguments and want to run it again with no arguments,
-this is the only way to do so.
-
-@@node Environment, Working Directory, Arguments, Running
-@@section Your Program's Environment
-
-@@cindex environment (of your program)
-The @@dfn{environment} consists of a set of @@dfn{environment variables} and
-their values. Environment variables conventionally record such things as
-your user name, your home directory, your terminal type, and your search
-path for programs to run. Usually you set up environment variables with
-the shell and they are inherited by all the other programs you run. When
-debugging, it can be useful to try running the program with different
-environments without having to start the debugger over again.
-
-@@table @@code
-@@item info environment @@var{varname}
-@@kindex info environment
-Print the value of environment variable @@var{varname} to be given to
-your program when it is started. This command can be abbreviated
-@@samp{i env @@var{varname}}.
-
-@@item info environment
-Print the names and values of all environment variables to be given to
-your program when it is started. This command can be abbreviated
-@@samp{i env}.
-
-@@item set environment @@var{varname} @@var{value}
-@@item set environment @@var{varname} = @@var{value}
-@@kindex set environment
-Sets environment variable @@var{varname} to @@var{value}, for your program
-only, not for GDB itself. @@var{value} may be any string; the values of
-environment variables are just strings, and any interpretation is
-supplied by your program itself. The @@var{value} parameter is optional;
-if it is eliminated, the variable is set to a null value. This command
-can be abbreviated as short as @@samp{set e}.
-
-@@item delete environment @@var{varname}
-@@kindex delete environment
-@@item unset environment @@var{varname}
-@@kindex unset environment
-Remove variable @@var{varname} from the environment to be passed to
-your program. This is different from @@samp{set env @@var{varname} =}
-because @@samp{delete environment} makes a variable not be defined at
-all, which is distinguishable from an empty value. This command can
-be abbreviated @@samp{d e}.
-@@end table
-
-@@node Working Directory, Input/Output, Environment, Running
-@@section Your Program's Working Directory
-
-@@cindex working directory (of your program)
-Each time you start your program with @@samp{run}, it inherits its working
-directory from the current working directory of GDB. GDB's working
-directory is initially whatever it inherited from its superior, but you can
-specify the working directory for GDB with the @@samp{cd} command.
-
-The GDB working directory also serves as a default for the commands
-that specify files for GDB to operate on. @@xref{Files}.
-
-@@table @@code
-@@item cd @@var{directory}
-@@kindex cd
-Set GDB's working directory to @@var{directory}.
-
-@@item pwd
-@@kindex pwd
-Print GDB's working directory.
-@@end table
-
-@@node Input/Output, Attach, Working Directory, Running
-@@section Your Program's Input and Output
-
-@@cindex redirection
-@@cindex controlling terminal
-By default, the program you run under GDB does input and output to the same
-terminal that GDB uses.
-
-You can redirect the program's input and/or output using @@samp{sh}-style
-redirection commands in the @@samp{run} command. For example,
-
-@@example
-run > outfile
-@@end example
-
-@@noindent
-starts the program, diverting its output to the file @@file{outfile}.
-
-@@kindex tty
-Another way to specify where the program should do input and output is with
-the @@samp{tty} command. This command accepts a file name as argument, and
-causes this file to be the default for future @@samp{run} commands. It also
-resets the controlling terminal for future @@samp{run} commands. For
-example,
-
-@@example
-tty /dev/ttyb
-@@end example
-
-@@noindent
-directs that processes started with subsequent @@samp{run} commands default
-to do input and output on the terminal @@file{/dev/ttyb} and sets the
-controlling terminal to @@file{/dev/ttyb}. An explicit redirection in
-@@samp{run} overrides the @@samp{tty} command's effect on input/output
-redirection.
-
-When you use the @@samp{tty} command or redirect input in the @@samp{run}
-command, the @@emph{input for your program} comes from the specified file,
-but the input for GDB still comes from your terminal.
-
-@@node Attach,, Input/Output, Running
-@@section Debugging an Already-Running Process
-@@kindex detach
-@@kindex attach
-@@cindex attach
-
-Some operating systems (in particular, Sun) allow GDB to begin debugging an
-already-running process that was started outside of GDB. To do this you
-must use the @@samp{attach} command instead of the @@samp{run} command.
-
-The @@samp{attach} command requires one argument, which is the process-id of
-the process you want to debug. (The usual way to find out the process-id
-of the process is with the @@samp{ps} utility.)
-
-The first thing GDB does after arranging to debug the process is to stop
-it. You can examine and modify an attached process with all the GDB
-commands that ordinarily available when you start processes with
-@@samp{run}. You can insert breakpoints; you can step and continue; you
-can modify storage. If you would rather the process continue running,
-use the @@samp{continue} command after attaching.
-
-When you are finished debugging the attached process, you can use the
-@@samp{detach} command to release it from GDB's control. Detaching
-the process continues its execution. After the @@samp{detach} command,
-that process and GDB become completely independent once more, and you
-are ready to @@samp{attach} another process or start one with @@samp{run}.
-
-If you exit GDB or use the @@samp{run} command while you have an attached
-process, you kill that process. You will be asked for confirmation if you
-try to do either of these things.
-
-@@node Stopping, Stack, Running, Top
-@@chapter Stopping and Continuing
-
-When you run a program normally, it runs until exiting. The purpose
-of using a debugger is so that you can stop it before that point;
-or so that if the program runs into trouble you can find out why.
-
-@@menu
-* Signals:: Fatal signals in your program just stop it;
- then you can use GDB to see what is going on.
-* Breakpoints:: Breakpoints let you stop your program when it
- reaches a specified point in the code.
-* Continuing:: Resuming execution until the next signal or breakpoint.
-* Stepping:: Stepping runs the program a short distance and
- then stops it wherever it has come to.
-@@end menu
-
-@@node Signals, Breakpoints, Stopping, Stopping
-@@section Signals
-
-A signal is an asynchronous event that can happen in a program. The
-operating system defines the possible kinds of signals, and gives each kind
-a name and a number. For example, @@code{SIGINT} is the signal a program
-gets when you type @@kbd{Ctrl-c}; @@code{SIGSEGV} is the signal a program
-gets from referencing a place in memory far away from all the areas in use;
-@@code{SIGALRM} occurs when the alarm clock timer goes off (which happens
-only if the program has requested an alarm).
-
-Some signals, including @@code{SIGALRM}, are a normal part of the
-functioning of the program. Others, such as @@code{SIGSEGV}, indicate
-errors; these signals are @@dfn{fatal} (kill the program immediately) if the
-program has not specified in advance some other way to handle the signal.
-@@code{SIGINT} does not indicate an error in the program, but it is normally
-fatal so it can carry out the purpose of @@kbd{Ctrl-c}: to kill the program.
-
-GDB has the ability to detect any occurrence of a signal in the program
-running under GDB's control. You can tell GDB in advance what to do for
-each kind of signal.
-
-Normally, GDB is set up to ignore non-erroneous signals like @@code{SIGALRM}
-(so as not to interfere with their role in the functioning of the program)
-but to stop the program immediately whenever an error signal happens.
-You can change these settings with the @@samp{handle} command. You must
-specify which signal you are talking about with its number.
-
-@@table @@code
-@@item info signal
-@@kindex info signal
-Print a table of all the kinds of signals and how GDB has been told to
-handle each one. You can use this to see the signal numbers of all
-the defined types of signals.
-
-@@item handle @@var{signalnum} @@var{keywords}@@dots{}
-@@kindex handle
-Change the way GDB handles signal @@var{signalnum}. The @@var{keywords}
-say what change to make.
-@@end table
-
-To use the @@samp{handle} command you must know the code number of the
-signal you are concerned with. To find the code number, type @@samp{info
-signal} which prints a table of signal names and numbers.
-
-The keywords allowed by the handle command can be abbreviated. Their full
-names are
-
-@@table @@code
-@@item stop
-GDB should stop the program when this signal happens. This implies
-the @@samp{print} keyword as well.
-
-@@item print
-GDB should print a message when this signal happens.
-
-@@item nostop
-GDB should not stop the program when this signal happens. It may
-still print a message telling you that the signal has come in.
-
-@@item noprint
-GDB should not mention the occurrence of the signal at all. This
-implies the @@samp{nostop} keyword as well.
-
-@@item pass
-GDB should allow the program to see this signal; the program will be
-able to handle the signal, or may be terminated if the signal is fatal
-and not handled.
-
-@@item nopass
-GDB should not allow the program to see this signal.
-@@end table
-
-When a signal has been set to stop the program, the program cannot see the
-signal until you continue. It will see the signal then, if @@samp{pass} is
-in effect for the signal in question @@i{at that time}. In other words,
-after GDB reports a signal, you can use the @@samp{handle} command with
-@@samp{pass} or @@samp{nopass} to control whether that signal will be seen by
-the program when you later continue it.
-
-You can also use the @@samp{signal} command to prevent the program from
-seeing a signal, or cause it to see a signal it normally would not see,
-or to give it any signal at any time. @@xref{Signaling}.
-
-@@node Breakpoints, Continuing, Signals, Stopping
-@@section Breakpoints
-
-@@cindex breakpoints
-A @@dfn{breakpoint} makes your program stop whenever a certain point in the
-program is reached. You set breakpoints explicitly with GDB commands,
-specifying the place where the program should stop by line number, function
-name or exact address in the program. You can add various other conditions
-to control whether the program will stop.
-
-Each breakpoint is assigned a number when it is created; these numbers are
-successive integers starting with 1. In many of the commands for controlling
-various features of breakpoints you use the breakpoint number to say which
-breakpoint you want to change. Each breakpoint may be @@dfn{enabled} or
-@@dfn{disabled}; if disabled, it has no effect on the program until you
-enable it again.
-
-@@kindex info break
-@@kindex $_
-The command @@samp{info break} prints a list of all breakpoints set and not
-cleared, showing their numbers, where in the program they are, and any
-special features in use for them. Disabled breakpoints are included in the
-list, but marked as disabled. @@samp{info break} with a breakpoint number
-as argument lists only that breakpoint. The convenience variable @@samp{$_}
-and the default examining-address for the @@samp{x} command are set to the
-address of the last breakpoint listed (@@pxref{Memory}).
-
-@@menu
-* Set Breaks:: How to establish breakpoints.
-* Clear Breaks:: How to remove breakpoints no longer needed.
-* Disabling:: How to disable breakpoints (turn them off temporarily).
-* Conditions:: Making extra conditions on whether to stop.
-* Break Commands:: Commands to be executed at a breakpoint.
-* Error in Breakpoints:: "Cannot insert breakpoints" error--why, what to do.
-@@end menu
-
-@@node Set Breaks, Clear Breaks, Breakpoints, Breakpoints
-@@subsection Setting Breakpoints
-
-@@kindex break
-Breakpoints are set with the @@samp{break} command (abbreviated @@samp{b}).
-You have several ways to say where the breakpoint should go.
-
-@@table @@code
-@@item break @@var{function}
-Set a breakpoint at entry to function @@var{function}.
-
-@@item break @@var{linenum}
-Set a breakpoint at line @@var{linenum} in the current source file.
-That file is the last file whose source text was printed. This
-breakpoint will stop the program just before it executes any of the
-code on that line.
-
-@@item break @@var{filename}:@@var{linenum}
-Set a breakpoint at line @@var{linenum} in source file @@var{filename}.
-
-@@item break @@var{filename}:@@var{function}
-Set a breakpoint at entry to function @@var{function} found in file
-@@var{filename}. Specifying a filename as well as a function name is
-superfluous except when multiple files contain similarly named
-functions.
-
-@@item break *@@var{address}
-Set a breakpoint at address @@var{address}. You can use this to set
-breakpoints in parts of the program which do not have debugging
-information or source files.
-
-@@item break
-Set a breakpoint at the next instruction to be executed in the selected
-stack frame (@@pxref{Stack}). In any selected frame but the innermost,
-this will cause the program to stop as soon as control returns to that
-frame. This is equivalent to a @@samp{finish} command in the frame
-inside the selected frame. If this is done in the innermost frame gdb
-will stop the next time it reaches the current location; this may be
-useful inside of loops. It does not stop at this breakpoint immediately
-upon continuation of the program since no code would be executed if it
-did.
-
-@@item break @@dots{} if @@var{cond}
-Set a breakpoint with condition @@var{cond}; evaluate the expression
-@@var{cond} each time the breakpoint is reached, and stop only if the
-value is nonzero. @@samp{@@dots{}} stands for one of the possible
-arguments described above (or no argument) specifying where to break.
-@@xref{Conditions}, for more information on breakpoint conditions.
-
-@@item tbreak @@var{args}
-@@kindex tbreak
-Set a breakpoint enabled only for one stop. @@var{args} are the
-same as in the @@samp{break} command, and the breakpoint is set in the same
-way, but the breakpoint is automatically @@dfn{disabled} the first time it
-is hit.
-@@end table
-
-GDB allows you to set any number of breakpoints at the same place in the
-program. There is nothing silly or meaningless about this. When the
-breakpoints are conditional, this is even useful (@@pxref{Conditions}).
-
-@@node Clear Breaks, Disabling, Set Breaks, Breakpoints
-@@subsection Clearing Breakpoints
-
-@@cindex clear breakpoint
-@@cindex delete breakpoints
-It is often necessary to eliminate a breakpoint once it has done its job
-and you no longer want the program to stop there. This is called
-@@dfn{clearing} or @@samp{deleting} the breakpoint. A breakpoint that
-has been cleared no longer exists in any sense.
-
-With the @@samp{clear} command you can clear breakpoints according to where
-they are in the program. With the @@samp{delete} command you can clear
-individual breakpoints by specifying their breakpoint numbers.
-
-@@b{It is not necessary to clear a breakpoint to proceed past it.} GDB
-automatically ignores breakpoints in the first instruction to be executed
-when you continue execution at the same address where the program stopped.
-
-@@table @@code
-@@item clear
-@@kindex clear
-Clear any breakpoints at the next instruction to be executed in the
-selected stack frame (@@pxref{Selection}). When the innermost frame
-is selected, this is a good way to clear a breakpoint that the program
-just stopped at.
-
-@@item clear @@var{function}
-@@itemx clear @@var{filename}:@@var{function}
-Clear any breakpoints set at entry to the function @@var{function}.
-
-@@item clear @@var{linenum}
-@@item clear @@var{filename}:@@var{linenum}
-Clear any breakpoints set at or within the code of the specified line.
-
-@@item delete @@var{bnums}@@dots{}
-@@kindex delete
-Delete the breakpoints of the numbers specified as arguments.
-A breakpoint deleted is forgotten completely.
-@@end table
-
-@@node Disabling, Conditions, Clear Breaks, Breakpoints
-@@subsection Disabling Breakpoints
-
-@@cindex disabled breakpoints
-@@cindex enabled breakpoints
-Rather than clearing a breakpoint, you might prefer to @@dfn{disable} it.
-This makes the breakpoint inoperative as if it had been cleared, but
-remembers the information on the breakpoint so that you can @@dfn{enable}
-it again later.
-
-You disable and enable breakpoints with the @@samp{enable} and
-@@samp{disable} commands, specifying one or more breakpoint numbers as
-arguments. Use @@samp{info break} to print a list of breakpoints if you
-don't know which breakpoint numbers to use.
-
-A breakpoint can have any of four different states of enablement:
-
-@@itemize @@bullet
-@@item
-Enabled. The breakpoint will stop the program. A breakpoint made
-with the @@samp{break} command starts out in this state.
-@@item
-Disabled. The breakpoint has no effect on the program.
-@@item
-Enabled once. The breakpoint will stop the program, but
-when it does so it will become disabled. A breakpoint made
-with the @@samp{tbreak} command starts out in this state.
-@@item
-Enabled for deletion. The breakpoint will stop the program, but
-immediately after it does so it will be deleted permanently.
-@@end itemize
-
-You change the state of enablement of a breakpoint with the following
-commands:
-
-@@table @@code
-@@item disable breakpoints @@var{bnums}@@dots{}
-@@kindex disable breakpoints
-@@item disable @@var{bnums}@@dots{}
-@@kindex disable
-Disable the specified breakpoints. A disabled breakpoint has no
-effect but is not forgotten. All options such as ignore-counts,
-conditions and commands are remembered in case the breakpoint is
-enabled again later.
-
-@@item enable breakpoints @@var{bnums}@@dots{}
-@@kindex enable breakpoints
-@@item enable @@var{bnums}@@dots{}
-@@kindex enable
-Enable the specified breakpoints. They become effective once again in
-stopping the program, until you specify otherwise.
-
-@@item enable breakpoints once @@var{bnums}@@dots{}
-@@item enable once @@var{bnums}@@dots{}
-Enable the specified breakpoints temporarily. Each will be disabled
-again the next time it stops the program (unless you have used one of
-these commands to specify a different state before that time comes).
-
-@@item enable breakpoints delete @@var{bnums}@@dots{}
-@@item enable delete @@var{bnums}@@dots{}
-Enable the specified breakpoints to work once and then die. Each of
-the breakpoints will be deleted the next time it stops the program
-(unless you have used one of these commands to specify a different
-state before that time comes).
-@@end table
-
-Aside from the automatic disablement or deletion of a breakpoint when it
-stops the program, which happens only in certain states, the state of
-enablement of a breakpoint changes only when one of the commands above
-is used.
-
-@@node Conditions, Break Commands, Disabling, Breakpoints
-@@subsection Break Conditions
-
-@@cindex conditions
-The simplest sort of breakpoint breaks every time the program reaches a
-specified place. You can also specify a @@dfn{condition} for a breakpoint.
-A condition is just a boolean expression in your programming language
-(@@xref{Expressions}). A breakpoint with a condition evaluates the
-expression each time the program reaches it, and the program stops
-only if the condition is true.
-
-Break conditions may have side effects, and may even call functions in your
-program. These may sound like strange things to do, but their effects are
-completely predictable unless there is another enabled breakpoint at the
-same address. (In that case, GDB might see the other breakpoint first and
-stop the program without checking the condition of this one.) Note that
-breakpoint commands are usually more convenient and flexible for the
-purpose of performing side effects when a breakpoint is reached
-(@@pxref{Break Commands}).
-
-Break conditions can be specified when a breakpoint is set, by using
-@@samp{if} in the arguments to the @@samp{break} command. @@xref{Set Breaks}.
-They can also be changed at any time with the @@samp{condition} command:
-
-@@table @@code
-@@item condition @@var{bnum} @@var{expression}
-@@kindex condition
-Specify @@var{expression} as the break condition for breakpoint number
-@@var{bnum}. From now on, this breakpoint will stop the program only if
-the value of @@var{expression} is true (nonzero, in C). @@var{expression}
-is not evaluated at the time the @@samp{condition} command is given.
-@@xref{Expressions}.
-
-@@item condition @@var{bnum}
-Remove the condition from breakpoint number @@var{bnum}. It becomes
-an ordinary unconditional breakpoint.
-@@end table
-
-@@cindex ignore count (of breakpoint)
-A special feature is provided for one kind of condition: to prevent the
-breakpoint from doing anything until it has been reached a certain number
-of times. This is done with the @@dfn{ignore count} of the breakpoint.
-When the program reaches a breakpoint whose ignore count is positive, then
-instead of stopping, it just decrements the ignore count by one and
-continues.
-
-@@table @@code
-@@item ignore @@var{bnum} @@var{count}
-@@kindex ignore
-Set the ignore count of breakpoint number @@var{bnum} to @@var{count}.
-The next @@var{count} times the breakpoint is reached, it will not stop.
-
-To make the breakpoint stop the next time it is reached, specify
-a count of zero.
-
-@@item cont @@var{count}
-Continue execution of the program, setting the ignore count of the
-breakpoint that the program stopped at to @@var{count} minus one.
-Continuing through the breakpoint does not itself count as one of
-@@var{count}. Thus, the program will not stop at this breakpoint until the
-@@var{count}'th time it is hit.
-
-This command is allowed only when the program stopped due to a
-breakpoint. At other times, the argument to @@samp{cont} is ignored.
-@@end table
-
-If a breakpoint has a positive ignore count and a condition, the condition
-is not checked. Once the ignore count reaches zero, the condition will
-start to be checked.
-
-Note that you could achieve the effect of the ignore count with a condition
-such as @@samp{$foo-- <= 0} using a debugger convenience variable that is
-decremented each time. That is why the ignore count is considered a
-special case of a condition. @@xref{Convenience Vars}.
-
-@@node Break Commands, Error in Breakpoints, Conditions, Breakpoints
-@@subsection Commands Executed on Breaking
-
-@@cindex breakpoint commands
-You can give any breakpoint a series of commands to execute when the
-program stops due to that breakpoint. For example, you might want to
-print the values of certain expressions, or enable other breakpoints.
-
-@@table @@code
-@@item commands @@var{bnum}
-Specify commands for breakpoint number @@var{bnum}. The commands
-themselves appear on the following lines. Type a line containing just
-@@samp{end} to terminate the commands.
-
-To remove all commands from a breakpoint, use the command
-@@samp{commands} and follow it immediately by @@samp{end}; that is, give
-no commands.
-
-With no arguments, @@samp{commands} refers to the last breakpoint set.
-@@end table
-
-It is possible for breakpoint commands to start the program up again.
-Simply use the @@samp{cont} command, or @@samp{step}, or any other command
-to resume execution. However, any remaining breakpoint commands are
-ignored. When the program stops again, GDB will act according to why
-that stop took place.
-
-@@kindex silent
-If the first command specified is @@samp{silent}, the usual message about
-stopping at a breakpoint is not printed. This may be desirable for
-breakpoints that are to print a specific message and then continue.
-If the remaining commands too print nothing, you will see no sign that
-the breakpoint was reached at all. @@samp{silent} is not really a command;
-it is meaningful only at the beginning of the commands for a breakpoint.
-
-The commands @@samp{echo} and @@samp{output} that allow you to print precisely
-controlled output are often useful in silent breakpoints. @@xref{Output}.
-
-For example, here is how you could use breakpoint commands to print the
-value of @@code{x} at entry to @@code{foo} whenever it is positive. We
-assume that the newly created breakpoint is number 4; @@samp{break} will
-print the number that is assigned.
-
-@@example
-break foo if x>0
-commands 4
-silent
-echo x is\040
-output x
-echo \n
-cont
-end
-@@end example
-
-One application for breakpoint commands is to correct one bug so you can
-test another. Put a breakpoint just after the erroneous line of code, give
-it a condition to detect the case in which something erroneous has been
-done, and give it commands to assign correct values to any variables that
-need them. End with the @@samp{cont} command so that the program does not
-stop, and start with the @@samp{silent} command so that no output is
-produced. Here is an example:
-
-@@example
-break 403
-commands 5
-silent
-set x = y + 4
-cont
-end
-@@end example
-
-One deficiency in the operation of automatically continuing breakpoints
-under Unix appears when your program uses raw mode for the terminal.
-GDB switches back to its own terminal modes (not raw) before executing
-commands, and then must switch back to raw mode when your program is
-continued. This causes any pending terminal input to be lost.
-
-In the GNU system, this will be fixed by changing the behavior of
-terminal modes.
-
-Under Unix, when you have this problem, you might be able to get around
-it by putting your actions into the breakpoint condition instead of
-commands. For example
-
-@@example
-condition 5 (x = y + 4), 0
-@@end example
-
-@@noindent
-is a condition expression (@@xref{Expressions}) that will change @@code{x}
-as needed, then always have the value 0 so the program will not stop.
-Loss of input is avoided here because break conditions are evaluated
-without changing the terminal modes. When you want to have nontrivial
-conditions for performing the side effects, the operators @@samp{&&},
-@@samp{||} and @@samp{?@@: @@dots{} :@@:} may be useful.
-
-@@node Error in Breakpoints,, Break Commands, Breakpoints
-@@subsection ``Cannot Insert Breakpoints'' Error
-
-Under some Unix systems, breakpoints cannot be used in a program if any
-other process is running that program. Attempting to run or continue
-the program with a breakpoint in this case will cause GDB to stop it.
-
-When this happens, you have three ways to proceed:
-
-@@enumerate
-@@item
-Remove or disable the breakpoints, then continue.
-
-@@item
-Suspend GDB, and copy the file containing the program to a new name.
-Resume GDB and use the @@samp{exec-file} command to specify that GDB
-should run the program under that name. Then start the program again.
-
-@@item
-Recompile the program so that the text is non-sharable (a.out format
-OMAGIC).
-@@end enumerate
-
-@@node Continuing, Stepping, Breakpoints, Stopping
-@@section Continuing
-
-After your program stops, most likely you will want it to run some more if
-the bug you are looking for has not happened yet.
-
-@@table @@code
-@@item cont
-@@kindex cont
-Continue running the program at the place where it stopped.
-@@end table
-
-If the program stopped at a breakpoint, the place to continue running
-is the address of the breakpoint. You might expect that continuing would
-just stop at the same breakpoint immediately. In fact, @@samp{cont}
-takes special care to prevent that from happening. You do not need
-to clear the breakpoint to proceed through it after stopping at it.
-
-You can, however, specify an ignore-count for the breakpoint that the
-program stopped at, by means of an argument to the @@samp{cont} command.
-@@xref{Conditions}.
-
-If the program stopped because of a signal other than @@code{SIGINT} or
-@@code{SIGTRAP}, continuing will cause the program to see that signal.
-You may not want this to happen. For example, if the program stopped
-due to some sort of memory reference error, you might store correct
-values into the erroneous variables and continue, hoping to see more
-execution; but the program would probably terminate immediately as
-a result of the fatal signal once it sees the signal. To prevent this,
-you can continue with @@samp{signal 0}. @@xref{Signaling}. You can
-also act in advance to prevent the program from seeing certain kinds
-of signals, using the @@samp{handle} command (@@pxref{Signals}).
-
-@@node Stepping,, Continuing, Stopping
-@@section Stepping
-
-@@cindex stepping
-@@dfn{Stepping} means setting your program in motion for a limited time, so
-that control will return automatically to the debugger after one line of
-code or one machine instruction. Breakpoints are active during stepping
-and the program will stop for them even if it has not gone as far as the
-stepping command specifies.
-
-@@table @@code
-@@item step
-@@kindex step
-Proceed the program until control reaches a different line, then stop
-it and return to the debugger. This command is abbreviated @@samp{s}.
-
-@@item step @@var{count}
-Proceed as in @@samp{step}, but do so @@var{count} times. If a breakpoint
-or a signal not related to stepping is reached before @@var{count} steps,
-stepping stops right away.
-
-This command may be given when control is within a routine for which
-there is no debugging information. In that case, execution will proceed
-until control reaches a different routine, or is about to return from
-this routine. An argument repeats this action.
-
-@@item next
-@@kindex next
-Similar to @@samp{step}, but any function calls appearing within the line of
-code are executed without stopping. Execution stops when control reaches a
-different line of code at the stack level which was executing when the
-@@samp{next} command was given. This command is abbreviated @@samp{n}.
-
-An argument is a repeat count, as in @@samp{step}.
-
-@@samp{next} within a routine without debugging information acts as does
-@@samp{step}, but any function calls appearing within the code of the
-routine are executed without stopping.
-
-@@item finish
-@@kindex finish
-Continue running until just after the selected stack frame returns
-(or until there is some other reason to stop, such as a fatal signal
-or a breakpoint). Print value returned by the selected stack frame (if
-any).
-
-Contrast this with the @@samp{return} command (@@pxref{Returning}).
-
-@@item until
-@@kindex until
-Proceed the program until control reaches a line greater than the current
-line, then stop is and return to the debugger. Control is also returned to
-the debugger if the program exits the current stack frame. Note that this
-form of the command uses single stepping, and hence is slower than
-@@samp{until} with an argument. This command is abbreviated @@samp{u}.
-
-@@item until @@var{location}
-Proceed the program until either the specified location is reached, or the
-current (innermost) stack frame returns. This form of the command uses
-breakpoints, and hence is quicker than @@samp{until} without an argument.
-
-@@item stepi
-@@itemx si
-@@kindex stepi
-@@kindex si
-Proceed one machine instruction, then stop and return to the debugger.
-
-It is often useful to do @@samp{display/i $pc} when stepping by machine
-instructions. This will cause the next instruction to be executed to
-be displayed automatically at each stop. @@xref{Auto Display}.
-
-An argument is a repeat count, as in @@samp{step}.
-
-@@item nexti
-@@itemx ni
-@@kindex nexti
-@@kindex ni
-Proceed one machine instruction, but if it is a subroutine call,
-proceed until the subroutine returns.
-
-An argument is a repeat count, as in @@samp{next}.
-@@end table
-
-A typical technique for using stepping is to put a breakpoint
-(@@pxref{Breakpoints}) at the beginning of the function or the section of
-the program in which a problem is believed to lie, and then step through
-the suspect area, examining the variables that are interesting, until the
-problem happens.
-
-The @@samp{cont} command can be used after stepping to resume execution
-until the next breakpoint or signal.
-
-@@node Stack, Source, Stopping, Top
-@@chapter Examining the Stack
-
-When your program has stopped, the first thing you need to know is where it
-stopped and how it got there.
-
-@@cindex call stack
-Each time your program performs a function call, the information about
-where in the program the call was made from is saved in a block of data
-called a @@dfn{stack frame}. The frame also contains the arguments of the
-call and the local variables of the function that was called. All the
-stack frames are allocated in a region of memory called the @@dfn{call
-stack}.
-
-When your program stops, the GDB commands for examining the stack allow you
-to see all of this information.
-
-One of the stack frames is @@dfn{selected} by GDB and many GDB commands
-refer implicitly to the selected frame. In particular, whenever you ask
-GDB for the value of a variable in the program, the value is found in the
-selected frame. There are special GDB commands to select whichever frame
-you are interested in.
-
-When the program stops, GDB automatically selects the currently executing
-frame and describes it briefly as the @@samp{frame} command does
-(@@pxref{Frame Info, Info}).
-
-@@menu
-* Frames:: Explanation of stack frames and terminology.
-* Backtrace:: Summarizing many frames at once.
-* Selection:: How to select a stack frame.
-* Info: Frame Info, Commands to print information on stack frames.
-@@end menu
-
-@@node Frames, Backtrace, Stack, Stack
-@@section Stack Frames
-
-@@cindex frame
-The call stack is divided up into contiguous pieces called @@dfn{frames};
-each frame is the data associated with one call to one function. The frame
-contains the arguments given to the function, the function's local
-variables, and the address at which the function is executing.
-
-@@cindex initial frame
-@@cindex outermost frame
-@@cindex innermost frame
-When your program is started, the stack has only one frame, that of the
-function @@code{main}. This is called the @@dfn{initial} frame or the
-@@dfn{outermost} frame. Each time a function is called, a new frame is
-made. Each time a function returns, the frame for that function invocation
-is eliminated. If a function is recursive, there can be many frames for
-the same function. The frame for the function in which execution is
-actually occurring is called the @@dfn{innermost} frame. This is the most
-recently created of all the stack frames that still exist.
-
-@@cindex frame pointer
-Inside your program, stack frames are identified by their addresses. A
-stack frame consists of many bytes, each of which has its own address; each
-kind of computer has a convention for choosing one of those bytes whose
-address serves as the address of the frame. Usually this address is kept
-in a register called the @@dfn{frame pointer register} while execution is
-going on in that frame.
-
-@@cindex frame number
-GDB assigns numbers to all existing stack frames, starting with zero for
-the innermost frame, one for the frame that called it, and so on upward.
-These numbers do not really exist in your program; they are to give you a
-way of talking about stack frames in GDB commands.
-
-@@cindex selected frame
-Many GDB commands refer implicitly to one stack frame. GDB records a stack
-frame that is called the @@dfn{selected} stack frame; you can select any
-frame using one set of GDB commands, and then other commands will operate
-on that frame. When your program stops, GDB automatically selects the
-innermost frame.
-
-@@node Backtrace, Selection, Frames, Stack
-@@section Backtraces
-
-A backtrace is a summary of how the program got where it is. It shows one
-line per frame, for many frames, starting with the currently executing
-frame (frame zero), followed by its caller (frame one), and on up the
-stack.
-
-@@table @@code
-@@item backtrace
-@@itemx bt
-Print a backtrace of the entire stack: one line per frame for all
-frames in the stack.
-
-You can stop the backtrace at any time by typing the system interrupt
-character, normally @@kbd{Control-C}.
-
-@@item backtrace @@var{n}
-@@itemx bt @@var{n}
-Similar, but stop after @@var{n} frames.
-
-@@item backtrace @@var{-n}
-@@itemx bt @@var{-n}
-Similar, but print the outermost @@var{n} frames instead of the
-innermost.
-@@end table
-
-Each line in a backtrace shows the frame number, the program counter, the
-function and its arguments, and the source file name and line number (if
-known). The program counter is omitted if is the beginning of the code for
-the source line. This is the same as the first of the two lines printed
-when you select a frame.
-
-@@node Selection, Frame Info, Backtrace, Stack
-@@section Selecting a Frame
-
-Most commands for examining the stack and other data in the program work on
-whichever stack frame is selected at the moment. Here are the commands for
-selecting a stack frame; all of them finish by printing a brief description
-of the stack frame just selected.
-
-@@table @@code
-@@item frame @@var{n}
-@@kindex frame
-Select frame number @@var{n}. Recall that frame zero is the innermost
-(currently executing) frame, frame one is the frame that called the
-innermost one, and so on. The highest-numbered frame is @@code{main}'s
-frame.
-
-@@item frame @@var{addr}
-Select the frame at address @@var{addr}. This is useful mainly if the
-chaining of stack frames has been damaged by a bug, making it
-impossible for GDB to assign numbers properly to all frames. In
-addition, this can be useful when the program has multiple stacks and
-switches between them.
-
-@@item up @@var{n}
-@@kindex up
-Select the frame @@var{n} frames up from the frame previously selected.
-For positive numbers @@var{n}, this advances toward the outermost
-frame, to higher frame numbers, to frames that have existed longer.
-@@var{n} defaults to one.
-
-@@item down @@var{n}
-@@kindex down
-Select the frame @@var{n} frames down from the frame previously
-selected. For positive numbers @@var{n}, this advances toward the
-innermost frame, to lower frame numbers, to frames that were created
-more recently. @@var{n} defaults to one.
-@@end table
-
-All of these commands end by printing some information on the frame that
-has been selected: the frame number, the function name, the arguments, the
-source file and line number of execution in that frame, and the text of
-that source line. For example:
-
-@@example
-#3 main (argc=3, argv=??, env=??) at main.c, line 67
-67 read_input_file (argv[i]);
-@@end example
-
-After such a printout, the @@samp{list} command with no arguments will print
-ten lines centered on the point of execution in the frame. @@xref{List}.
-
-@@node Frame Info,, Selection, Stack
-@@section Information on a Frame
-
-There are several other commands to print information about the selected
-stack frame.
-
-@@table @@code
-@@item frame
-This command prints a brief description of the selected stack frame.
-It can be abbreviated @@samp{f}. With an argument, this command is
-used to select a stack frame; with no argument, it does not change
-which frame is selected, but still prints the same information.
-
-@@item info frame
-@@kindex info frame
-This command prints a verbose description of the selected stack frame,
-including the address of the frame, the addresses of the next frame in
-(called by this frame) and the next frame out (caller of this frame),
-the address of the frame's arguments, the program counter saved in it
-(the address of execution in the caller frame), and which registers
-were saved in the frame. The verbose description is useful when
-something has gone wrong that has made the stack format fail to fit
-the usual conventions.
-
-@@item info frame @@var{addr}
-Print a verbose description of the frame at address @@var{addr},
-without selecting that frame. The selected frame remains unchanged by
-this command.
-
-@@item info args
-@@kindex info args
-Print the arguments of the selected frame, each on a separate line.
-
-@@item info locals
-@@kindex info locals
-Print the local variables of the selected frame, each on a separate
-line. These are all variables declared static or automatic within all
-program blocks that execution in this frame is currently inside of.
-@@end table
-
-@@node Source, Data, Stack, Top
-@@chapter Examining Source Files
-
-GDB knows which source files your program was compiled from, and
-can print parts of their text. When your program stops, GDB
-spontaneously prints the line it stopped in. Likewise, when you
-select a stack frame (@@pxref{Selection}), GDB prints the line
-which execution in that frame has stopped in. You can also
-print parts of source files by explicit command.
-
-@@menu
-* List:: Using the @@samp{list} command to print source files.
-* Search:: Commands for searching source files.
-* Source Path:: Specifying the directories to search for source files.
-@@end menu
-
-@@node List, Search, Source, Source
-@@section Printing Source Lines
-
-@@kindex list
-To print lines from a source file, use the @@samp{list} command
-(abbreviated @@samp{l}). There are several ways to specify what part
-of the file you want to print.
-
-Here are the forms of the @@samp{list} command most commonly used:
-
-@@table @@code
-@@item list @@var{linenum}
-Print ten lines centered around line number @@var{linenum} in the
-current source file.
-
-@@item list @@var{function}
-Print ten lines centered around the beginning of function
-@@var{function}.
-
-@@item list
-Print ten more lines. If the last lines printed were printed with a
-@@samp{list} command, this prints ten lines following the last lines
-printed; however, if the last line printed was a solitary line printed
-as part of displaying a stack frame (@@pxref{Stack}), this prints ten
-lines centered around that line.
-
-@@item list @@minus{}
-Print ten lines just before the lines last printed.
-@@end table
-
-Repeating a @@samp{list} command with @@key{RET} discards the argument,
-so it is equivalent to typing just @@samp{list}. This is more useful
-than listing the same lines again. An exception is made for an
-argument of @@samp{-}; that argument is preserved in repetition so that
-each repetition moves up in the file.
-
-In general, the @@samp{list} command expects you to supply zero, one or two
-@@dfn{linespecs}. Linespecs specify source lines; there are several ways
-of writing them but the effect is always to specify some source line.
-Here is a complete description of the possible arguments for @@samp{list}:
-
-@@table @@code
-@@item list @@var{linespec}
-Print ten lines centered around the line specified by @@var{linespec}.
-
-@@item list @@var{first},@@var{last}
-Print lines from @@var{first} to @@var{last}. Both arguments are
-linespecs.
-
-@@item list ,@@var{last}
-Print ten lines ending with @@var{last}.
-
-@@item list @@var{first},
-Print ten lines starting with @@var{first}.
-
-@@item list +
-Print ten lines just after the lines last printed.
-
-@@item list @@minus{}
-Print ten lines just before the lines last printed.
-
-@@item list
-As described in the preceding table.
-@@end table
-
-Here are the ways of specifying a single source line---all the
-kinds of linespec.
-
-@@table @@asis
-@@item @@var{linenum}
-Specifies line @@var{linenum} of the current source file.
-When a @@samp{list} command has two linespecs, this refers to
-the same source file as the first linespec.
-
-@@item +@@var{offset}
-Specifies the line @@var{offset} lines after the last line printed.
-When used as the second linespec in a @@samp{list} command that has
-two, this specifies the line @@var{offset} lines down from the
-first linespec.
-
-@@item @@minus{}@@var{offset}
-Specifies the line @@var{offset} lines before the last line printed.
-
-@@item @@var{filename}:@@var{linenum}
-Specifies line @@var{linenum} in the source file @@var{filename}.
-
-@@item @@var{function}
-Specifies the line of the open-brace that begins the body of the
-function @@var{function}.
-
-@@item @@var{filename}:@@var{function}
-Specifies the line of the open-brace that begins the body of the
-function @@var{function} in the file @@var{filename}. The file name is
-needed with a function name only for disambiguation of identically
-named functions in different source files.
-
-@@item *@@var{address}
-Specifies the line containing the program address @@var{address}.
-@@var{address} may be any expression.
-@@end table
-
-One other command is used to map source lines to program addresses.
-
-@@table @@code
-@@item info line @@var{linenum}
-@@kindex info line
-Print the starting and ending addresses of the compiled code for
-source line @@var{linenum}.
-
-@@kindex $_
-The default examine address for the @@samp{x} command is changed to the
-starting address of the line, so that @@samp{x/i} is sufficient to
-begin examining the machine code (@@pxref{Memory}). Also, this address
-is saved as the value of the convenience variable @@samp{$_}
-(@@pxref{Convenience Vars}).
-@@end table
-
-@@node Search, Source Path, List, Source
-@@section Searching Source Files
-@@cindex searching
-@@kindex forward-search
-@@kindex reverse-search
-
-There are two commands for searching through the current source file for a
-regular expression.
-
-The command @@samp{forward-search @@var{regexp}} checks each line, starting
-with the one following the last line listed, for a match for @@var{regexp}.
-It lists the line that is found. You can abbreviate the command name
-as @@samp{fo}.
-
-The command @@samp{reverse-search @@var{regexp}} checks each line, starting
-with the one before the last line listed and going backward, for a match
-for @@var{regexp}. It lists the line that is found. You can abbreviate
-this command with as little as @@samp{rev}.
-
-@@node Source Path,, Search, Source
-@@section Specifying Source Directories
-
-@@cindex source path
-@@cindex directories for source files
-Executable programs do not record the directories of the source files they
-were compiled from, just the names. GDB remembers a list of directories to
-search for source files; this is called the @@dfn{source path}. Each time
-GDB wants a source file, it tries all the directories in the list, in the
-order they are present in the list, until it finds a file with the desired
-name.
-
-@@kindex directory
-When you start GDB, its source path contains just the current working
-directory. To add other directories, use the @@samp{directory} command.
-@@b{Note that the search path for executable files and the working directory
-are @@i{not} used for finding source files.}
-
-@@table @@code
-@@item directory @@var{dirname}
-Add directory @@var{dirname} to the end of the source path.
-
-@@item directory
-Reset the source path to just the current working directory of GDB.
-This requires confirmation.
-
-@@samp{directory} with no argument can cause source files previously
-found by GDB to be found in a different directory. To make this work
-correctly, this command also clears out the tables GDB maintains
-about the source files it has already found.
-
-@@item info directories
-@@kindex info directories
-Print the source path: show which directories it contains.
-@@end table
-
-Because the @@samp{directory} command adds to the end of the source path,
-it does not affect any file that GDB has already found. If the source
-path contains directories that you do not want, and these directories
-contain misleading files with names matching your source files, the
-way to correct the situation is as follows:
-
-@@enumerate
-@@item
-Choose the directory you want at the beginning of the source path.
-Use the @@samp{cd} command to make that the current working directory.
-
-@@item
-Use @@samp{directory} with no argument to reset the source path to just
-that directory.
-
-@@item
-Use @@samp{directory} with suitable arguments to add any other
-directories you want in the source path.
-@@end enumerate
-
-@@node Data, Symbols, Source, Top
-@@chapter Examining Data
-
-@@cindex printing data
-@@cindex examining data
-@@kindex print
-The usual way of examining data in your program is with the @@samp{print}
-command (abbreviated @@samp{p}). It evaluates and prints the value of any
-valid expression of the language the program is written in (for now, C).
-You type
-
-@@example
-print @@var{exp}
-@@end example
-
-@@noindent
-where @@var{exp} is any valid expression, and the value of @@var{exp}
-is printed in a format appropriate to its data type.
-
-A more low-level way of examining data is with the @@samp{x} command.
-It examines data in memory at a specified address and prints it in a
-specified format.
-
-GDB supports one command to modify the default format of displayed data:
-
-@@table @@samp
-@@item set array-max
-@@kindex set array-max
-@@samp{set array-max} sets the maximum number of elements of an array which
-will be printed. This limit also applies to the display of strings.
-@@end table
-
-@@menu
-* Expressions:: Expressions that can be computed and printed.
-* Variables:: Using your program's variables in expressions.
-* Assignment:: Setting your program's variables.
-* Arrays:: Examining part of memory as an array.
-* Formats:: Specifying formats for printing values.
-* Memory:: Examining memory explicitly.
-* Auto Display:: Printing certain expressions whenever program stops.
-* Value History:: Referring to values previously printed.
-* Convenience Vars:: Giving names to values for future reference.
-* Registers:: Referring to and storing in machine registers.
-@@end menu
-
-@@node Expressions, Variables, Data, Data
-@@section Expressions
-
-@@cindex expressions
-Many different GDB commands accept an expression and compute its value.
-Any kind of constant, variable or operator defined by the programming
-language you are using is legal in an expression in GDB. This includes
-conditional expressions, function calls, casts and string constants.
-It unfortunately does not include symbols defined by preprocessor
-#define commands.
-
-Casts are supported in all languages, not just in C, because it is so
-useful to cast a number into a pointer so as to examine a structure
-at that address in memory.
-
-GDB supports three kinds of operator in addition to those of programming
-languages:
-
-@@table @@code
-@@item @@@@
-@@samp{@@@@} is a binary operator for treating parts of memory as arrays.
-@@xref{Arrays}, for more information.
-
-@@item ::
-@@samp{::} allows you to specify a variable in terms of the file or
-function it is defined in. @@xref{Variables}.
-
-@@item @@{@@var{type}@@} @@var{addr}
-Refers to an object of type @@var{type} stored at address @@var{addr} in
-memory. @@var{addr} may be any expression whose value is an integer or
-pointer (but parentheses are required around nonunary operators, just as in
-a cast). This construct is allowed regardless of what kind of data is
-officially supposed to reside at @@var{addr}.@@refill
-@@end table
-
-@@node Variables, Arrays, Expressions, Data
-@@section Program Variables
-
-The most common kind of expression to use is the name of a variable
-in your program.
-
-Variables in expressions are understood in the selected stack frame
-(@@pxref{Selection}); they must either be global (or static) or be visible
-according to the scope rules of the programming language from the point of
-execution in that frame. This means that in the function
-
-@@example
-foo (a)
- int a;
-@@{
- bar (a);
- @@{
- int b = test ();
- bar (b);
- @@}
-@@}
-@@end example
-
-@@noindent
-the variable @@code{a} is usable whenever the program is executing
-within the function @@code{foo}, but the variable @@code{b} is visible
-only while the program is executing inside the block in which @@code{b}
-is declared.
-
-As a special exception, you can refer to a variable or function whose
-scope is a single source file even if the current execution point is not
-in this file. But it is possible to have more than one such variable
-or function with the same name (if they are in different source files).
-In such a case, it is not defined which one you will get. If you wish,
-you can specify any one of them using the colon-colon construct:
-
-@@example
-@@var{block}::@@var{variable}
-@@end example
-
-@@noindent
-Here @@var{block} is the name of the source file whose variable you want.
-
-@@node Arrays, Formats, Variables, Data
-@@section Artificial Arrays
-
-@@cindex artificial array
-It is often useful to print out several successive objects of the
-same type in memory; a section of an array, or an array of
-dynamically determined size for which only a pointer exists in the
-program.
-
-This can be done by constructing an @@dfn{artificial array} with the
-binary operator @@samp{@@@@}. The left operand of @@samp{@@@@} should be
-the first element of the desired array, as an individual object.
-The right operand should be the length of the array. The result is
-an array value whose elements are all of the type of the left argument.
-The first element is actually the left argument; the second element
-comes from bytes of memory immediately following those that hold the
-first element, and so on. Here is an example. If a program says
-
-@@example
-int *array = (int *) malloc (len * sizeof (int));
-@@end example
-
-@@noindent
-you can print the contents of @@code{array} with
-
-@@example
-p *array@@@@len
-@@end example
-
-The left operand of @@samp{@@@@} must reside in memory. Array values made
-with @@samp{@@@@} in this way behave just like other arrays in terms of
-subscripting, and are coerced to pointers when used in expressions.
-(It would probably appear in an expression via the value history,
-after you had printed it out.)
-
-@@node Formats, Memory, Arrays, Data
-@@section Formats
-
-@@cindex formatted output
-@@cindex output formats
-GDB normally prints all values according to their data types. Sometimes
-this is not what you want. For example, you might want to print a number
-in hex, or a pointer in decimal. Or you might want to view data in memory
-at a certain address as a character string or an instruction. These things
-can be done with @@dfn{output formats}.
-
-The simplest use of output formats is to say how to print a value
-already computed. This is done by starting the arguments of the
-@@samp{print} command with a slash and a format letter. The format
-letters supported are:
-
-@@table @@samp
-@@item x
-Regard the bits of the value as an integer, and print the integer in
-hexadecimal.
-
-@@item d
-Print as integer in signed decimal.
-
-@@item u
-Print as integer in unsigned decimal.
-
-@@item o
-Print as integer in octal.
-
-@@item a
-Print as an address, both absolute in hex and then relative
-to a symbol defined as an address below it.
-
-@@item c
-Regard as an integer and print it as a character constant.
-
-@@item f
-Regard the bits of the value as a floating point number and print
-using typical floating point syntax.
-@@end table
-
-For example, to print the program counter in hex (@@pxref{Registers}), type
-
-@@example
-p/x $pc
-@@end example
-
-@@noindent
-Note that no space is required before the slash; this is because command
-names in GDB cannot contain a slash.
-
-To reprint the last value in the value history with a different format,
-you can use the @@samp{print} command with just a format and no
-expression. For example, @@samp{p/x} reprints the last value in hex.
-
-@@node Memory, Auto Display, Formats, Data
-@@subsection Examining Memory
-
-@@cindex examining memory
-@@kindex x
-The command @@samp{x} (for `examine') can be used to examine memory under
-explicit control of formats, without reference to the program's data types.
-
-@@samp{x} is followed by a slash and an output format specification,
-followed by an expression for an address. The expression need not have
-a pointer value (though it may); it is used as an integer, as the
-address of a byte of memory. @@xref{Expressions} for more information
-on expressions.
-
-The output format in this case specifies both how big a unit of memory
-to examine and how to print the contents of that unit. It is done
-with one or two of the following letters:
-
-These letters specify just the size of unit to examine:
-
-@@table @@samp
-@@item b
-Examine individual bytes.
-
-@@item h
-Examine halfwords (two bytes each).
-
-@@item w
-Examine words (four bytes each).
-
-@@cindex word
-Many assemblers and cpu designers still use `word' for a 16-bit quantity,
-as a holdover from specific predecessor machines of the 1970's that really
-did use two-byte words. But more generally the term `word' has always
-referred to the size of quantity that a machine normally operates on and
-stores in its registers. This is 32 bits for all the machines that GNU
-runs on.
-
-@@item g
-Examine giant words (8 bytes).
-@@end table
-
-These letters specify just the way to print the contents:
-
-@@table @@samp
-@@item x
-Print as integers in unsigned hexadecimal.
-
-@@item d
-Print as integers in signed decimal.
-
-@@item u
-Print as integers in unsigned decimal.
-
-@@item o
-Print as integers in unsigned octal.
-
-@@item a
-Print as an address, both absolute in hex and then relative
-to a symbol defined as an address below it.
-
-@@item c
-Print as character constants.
-
-@@item f
-Print as floating point. This works only with sizes @@samp{w} and
-@@samp{g}.
-
-@@item s
-Print a null-terminated string of characters. The specified unit size
-is ignored; instead, the unit is however many bytes it takes to reach
-a null character (including the null character).
-
-@@item i
-Print a machine instruction in assembler syntax (or nearly). The
-specified unit size is ignored; the number of bytes in an instruction
-varies depending on the type of machine, the opcode and the addressing
-modes used.
-@@end table
-
-If either the manner of printing or the size of unit fails to be specified,
-the default is to use the same one that was used last. If you don't want
-to use any letters after the slash, you can omit the slash as well.
-
-You can also omit the address to examine. Then the address used is
-just after the last unit examined. This is why string and instruction
-formats actually compute a unit-size based on the data: so that the
-next string or instruction examined will start in the right place.
-The @@samp{print} command sometimes sets the default address for
-the @@samp{x} command; when the value printed resides in memory, the
-default is set to examine the same location. @@samp{info line} also
-sets the default for @@samp{x}, to the address of the start of the
-machine code for the specified line and @@samp{info breakpoints} sets
-it to the address of the last breakpoint listed.
-
-When you use @@key{RET} to repeat an @@samp{x} command, it does not repeat
-exactly the same: the address specified previously (if any) is ignored, so
-that the repeated command examines the successive locations in memory
-rather than the same ones.
-
-You can examine several consecutive units of memory with one command by
-writing a repeat-count after the slash (before the format letters, if any).
-The repeat count must be a decimal integer. It has the same effect as
-repeating the @@samp{x} command that many times except that the output may
-be more compact with several units per line.
-
-@@example
-x/10i $pc
-@@end example
-
-@@noindent
-Prints ten instructions starting with the one to be executed next in the
-selected frame. After doing this, you could print another ten following
-instructions with
-
-@@example
-x/10
-@@end example
-
-@@noindent
-in which the format and address are allowed to default.
-
-@@kindex $_
-@@kindex $__
-The addresses and contents printed by the @@samp{x} command are not put in
-the value history because there is often too much of them and they would
-get in the way. Instead, GDB makes these values available for subsequent
-use in expressions as values of the convenience variables @@samp{$_} and
-@@samp{$__}.
-
-After an @@samp{x} command, the last address examined is available for use
-in expressions in the convenience variable @@samp{$_}. The contents of that
-address, as examined, are available in the convenience variable @@samp{$__}.
-
-If the @@samp{x} command has a repeat count, the address and contents saved
-are from the last memory unit printed; this is not the same as the last
-address printed if several units were printed on the last line of output.
-
-@@node Auto Display, Value History, Memory, Data
-@@section Automatic Display
-
-If you find that you want to print the value of an expression frequently
-(to see how it changes), you might want to add it to the @@dfn{automatic
-display list} so that GDB will print its value each time the program stops.
-Each expression added to the list is given a number to identify it;
-to remove an expression from the list, you specify that number.
-The automatic display looks like this:
-
-@@example
-2: foo = 38
-3: bar[5] = (struct hack *) 0x3804
-@@end example
-
-@@noindent
-showing item numbers, expressions and their current values.
-
-@@table @@code
-@@item display @@var{exp}
-@@kindex display
-Add the expression @@var{exp} to the list of expressions to display
-each time the program stops. @@xref{Expressions}.
-
-@@item display/@@var{fmt} @@var{exp}
-For @@var{fmt} specifying only a display format and not a size or
-count, add the expression @@var{exp} to the auto-display list but
-arranges to display it each time in the specified format @@var{fmt}.
-
-@@item display/@@var{fmt} @@var{addr}
-For @@var{fmt} @@samp{i} or @@samp{s}, or including a unit-size or a
-number of units, add the expression @@var{addr} as a memory address to
-be examined each time the program stops. Examining means in effect
-doing @@samp{x/@@var{fmt} @@var{addr}}. @@xref{Memory}.
-
-@@item undisplay @@var{dnums}@@dots{}
-@@kindex undisplay
-@@item delete display @@var{dnums}@@dots{}
-@@kindex delete display
-Remove item numbers @@var{dnums} from the list of expressions to display.
-
-@@item disable display @@var{dnums}@@dots{}
-@@kindex disable display
-Disable the display of item numbers @@var{dnums}. A disabled display item
-has no effect but is not forgotten. It may be later enabled.
-
-@@item enable display @@var{dnums}@@dots{}
-@@kindex enable display
-Enable display of item numbers @@var{dnums}. It becomes effective once
-again in auto display of its expression, until you specify otherwise.
-
-@@item display
-Display the current values of the expressions on the list, just as is
-done when the program stops.
-
-@@item info display
-@@kindex info display
-Print the list of expressions to display automatically, each one
-with its item number, but without showing the values.
-@@end table
-
-@@node Value History, Convenience Vars, Auto Display, Data
-@@section Value History
-
-@@cindex value history
-Every value printed by the @@samp{print} command is saved for the entire
-session in GDB's @@dfn{value history} so that you can refer to it in
-other expressions.
-
-@@cindex $
-@@cindex $$
-The values printed are given @@dfn{history numbers} for you to refer to them
-by. These are successive integers starting with 1. @@samp{print} shows you
-the history number assigned to a value by printing @@samp{$@@var{n} = }
-before the value; here @@var{n} is the history number.
-
-To refer to any previous value, use @@samp{$} followed by the value's
-history number. The output printed by @@samp{print} is designed to remind
-you of this. Just @@samp{$} refers to the most recent value in the history,
-and @@samp{$$} refers to the value before that.
-
-For example, suppose you have just printed a pointer to a structure and
-want to see the contents of the structure. It suffices to type
-
-@@example
-p *$
-@@end example
-
-If you have a chain of structures where the component @@samp{next} points
-to the next one, you can print the contents of the next one with
-
-@@example
-p *$.next
-@@end example
-
-It might be useful to repeat this command many times by typing @@key{RET}.
-
-Note that the history records values, not expressions. If the value of
-@@code{x} is 4 and you type
-
-@@example
-print x
-set x=5
-@@end example
-
-@@noindent
-then the value recorded in the value history by the @@samp{print} command
-remains 4 even though @@code{x}'s value has changed.
-
-@@table @@code
-@@item info history
-@@kindex info history
-Print the last ten values in the value history, with their item
-numbers. This is like @@samp{p $$9} repeated ten times, except that
-@@samp{info history} does not change the history.
-
-@@item info history @@var{n}
-Print ten history values centered on history item number @@var{n}.
-@@end table
-
-@@node Convenience Vars, Registers, Value History, Data
-@@section Convenience Variables
-
-@@cindex convenience variables
-GDB provides @@dfn{convenience variables} that you can use within GDB to
-hold on to a value and refer to it later. These variables exist entirely
-within GDB; they are not part of your program, and setting a convenience
-variable has no effect on further execution of your program. That's why
-you can use them freely.
-
-Convenience variables have names starting with @@samp{$}. Any name starting
-with @@samp{$} can be used for a convenience variable, unless it is one of
-the predefined set of register names (@@pxref{Registers}).
-
-You can save a value in a convenience variable with an assignment
-expression, just as you would set a variable in your program. Example:
-
-@@example
-set $foo = *object_ptr
-@@end example
-
-@@noindent
-would save in @@samp{$foo} the value contained in the object pointed to by
-@@code{object_ptr}.
-
-Using a convenience variable for the first time creates it; but its value
-is @@code{void} until you assign a new value. You can alter the value with
-another assignment at any time.
-
-Convenience variables have no fixed types. You can assign a convenience
-variable any type of value, even if it already has a value of a different
-type. The convenience variable as an expression has whatever type its
-current value has.
-
-@@table @@code
-@@item info convenience
-@@kindex info convenience
-Print a list of convenience variables used so far, and their values.
-Abbreviated @@samp{i con}.
-@@end table
-
-One of the ways to use a convenience variable is as a counter to be
-incremented or a pointer to be advanced. For example:
-
-@@example
-set $i = 0
-print bar[$i++]->contents
-@@i{@@dots{}repeat that command by typing @@key{RET}.}
-@@end example
-
-Some convenience variables are created automatically by GDB and given
-values likely to be useful.
-
-@@table @@samp
-@@item $_
-The variable @@samp{$_} is automatically set by the @@samp{x} command to
-the last address examined (@@pxref{Memory}). Other commands which
-provide a default address for @@samp{x} to examine also set @@samp{$_}
-to that address; these commands include @@samp{info line} and @@samp{info
-breakpoint}.
-
-@@item $__
-The variable @@samp{$__} is automatically set by the @@samp{x} command
-to the value found in the last address examined.
-@@end table
-
-@@node Registers,, Convenience Vars, Data
-@@section Registers
-
-@@cindex registers
-Machine register contents can be referred to in expressions as variables
-with names starting with @@samp{$}. The names of registers are different
-for each machine; use @@samp{info registers} to see the names used on your
-machine. The names @@samp{$pc} and @@samp{$sp} are used on all machines for
-the program counter register and the stack pointer. Often @@samp{$fp} is
-used for a register that contains a pointer to the current stack frame.
-
-GDB always considers the contents of an ordinary register as an integer
-when the register is examined in this way. Some machines have special
-registers which can hold nothing but floating point; these registers are
-considered floating point. There is no way to refer to the contents of an
-ordinary register as floating point value (although you can @@emph{print}
-it as a floating point value with @@samp{print/f $@@var{regname}}).
-
-Some registers have distinct ``raw'' and ``virtual'' data formats. This
-means that the data format in which the register contents are saved by the
-operating system is not the same one that your program normally sees. For
-example, the registers of the 68881 floating point coprocessor are always
-saved in ``extended'' format, but virtually all C programs expect to work with
-``double'' format. In such cases, GDB normally works with the virtual
-format only (the format that makes sense for your program), but the
-@@samp{info registers} command prints the data in both formats.
-
-Register values are relative to the selected stack frame
-(@@pxref{Selection}). This means that you get the value that the register
-would contain if all stack frames farther in were exited and their saved
-registers restored. In order to see the real contents of all registers,
-you must select the innermost frame (with @@samp{frame 0}).
-
-Some registers are never saved (typically those numbered zero or one)
-because they are used for returning function values; for these registers,
-relativization makes no difference.
-
-@@table @@code
-@@item info registers
-@@kindex info registers
-Print the names and relativized values of all registers.
-
-@@item info registers @@var{regname}
-Print the relativized value of register @@var{regname}. @@var{regname}
-may be any register name valid on the machine you are using, with
-or without the initial @@samp{$}.
-@@end table
-
-@@subsection Examples
-
-You could print the program counter in hex with
-
-@@example
-p/x $pc
-@@end example
-
-@@noindent
-or print the instruction to be executed next with
-
-@@example
-x/i $pc
-@@end example
-
-@@noindent
-or add four to the stack pointer with
-
-@@example
-set $sp += 4
-@@end example
-
-@@noindent
-The last is a way of removing one word from the stack, on machines where
-stacks grow downward in memory (most machines, nowadays). This assumes
-that the innermost stack frame is selected. Setting @@samp{$sp} is
-not allowed when other stack frames are selected.
-
-@@node Symbols, Altering, Data, Top
-@@chapter Examining the Symbol Table
-
-The commands described in this section allow you to make inquiries for
-information about the symbols (names of variables, functions and types)
-defined in your program. This information is found by GDB in the symbol
-table loaded by the @@samp{symbol-file} command; it is inherent in the text
-of your program and does not change as the program executes.
-
-@@table @@code
-@@item whatis @@var{exp}
-@@kindex whatis
-Print the data type of expression @@var{exp}. @@var{exp} is not
-actually evaluated, and any side-effecting operations (such as
-assignments or function calls) inside it do not take place.
-@@xref{Expressions}.
-
-@@item whatis
-Print the data type of @@samp{$}, the last value in the value history.
-
-@@item info address @@var{symbol}
-@@kindex info address
-Describe where the data for @@var{symbol} is stored. For register
-variables, this says which register. For other automatic variables,
-this prints the stack-frame offset at which the variable is always
-stored. Note the contrast with @@samp{print &@@var{symbol}}, which does
-not work at all for register variables and for automatic variables
-prints the exact address of the current instantiation of the variable.
-
-@@item ptype @@var{typename}
-@@kindex ptype
-Print a description of data type @@var{typename}. @@var{typename} may be
-the name of a type, or for C code it may have the form
-@@samp{struct @@var{struct-tag}}, @@samp{union @@var{union-tag}} or
-@@samp{enum @@var{enum-tag}}.@@refill
-
-@@item info sources
-@@kindex info sources
-Print the names of all source files in the program for which there
-is debugging information.
-
-@@item info functions
-@@kindex info functions
-Print the names and data types of all defined functions.
-
-@@item info functions @@var{regexp}
-Print the names and data types of all defined functions
-whose names contain a match for regular expression @@var{regexp}.
-Thus, @@samp{info fun step} finds all functions whose names
-include @@samp{step}; @@samp{info fun ^step} finds those whose names
-start with @@samp{step}.
-
-@@item info variables
-@@kindex info variables
-Print the names and data types of all variables that are declared
-outside of functions.
-
-@@item info variables @@var{regexp}
-Print the names and data types of all variables, declared outside of
-functions, whose names contain a match for regular expression
-@@var{regexp}.
-
-@@item info types
-@@kindex info types
-Print all data types that are defined in the program.
-
-@@item info types @@var{regexp}
-Print all data types that are defined in the program whose names
-contain a match for regular expression @@var{regexp}.
-
-@@item info methods
-@@item info methods @@var{regexp}
-@@kindex info methods
-The @@samp{info-methods} command permits the user to examine all defined
-methods within C@@code{++} program, or (with the @@var{regexp} argument) a
-specific set of methods found in the various C@@code{++} classes. Many
-C@@code{++} classes which implement a large number of differently typed
-methods implement a large number of methods as well. Thus, the
-@@samp{ptype} command can give the user a tremendous overdose of
-information about what methods are associated with a given class. The
-@@samp{info-methods} command filters these methods do to only those
-methods which match the regular-expression search key.
-
-@@item printsyms @@var{filename}
-@@kindex printsyms
-Write a complete dump of the debugger's symbol data into the
-file @@var{filename}.
-@@end table
-
-@@node Altering, Sequences, Symbols, Top
-@@chapter Altering Execution
-
-There are several ways to alter the execution of your program with GDB
-commands.
-
-@@menu
-* Assignment:: Altering variable values or memory contents.
-* Jumping:: Altering control flow.
-* Signaling:: Making signals happen in the program.
-* Returning:: Making a function return prematurely.
-@@end menu
-
-@@node Assignment, Jumping, Altering, Altering
-@@section Assignment to Variables
-
-@@cindex assignment
-@@cindex setting variables
-To alter the value of a variable, evaluate an assignment expression.
-@@xref{Expressions}. For example,
-
-@@example
-print x=4
-@@end example
-
-@@noindent
-would store the value 4 into the variable @@code{x}, and then print
-the value of the assignment expression (which is 4).
-
-@@kindex set
-@@kindex set variable
-If you are not interested in seeing the value of the assignment, use the
-@@samp{set} command instead of the @@samp{print} command. @@samp{set} is
-really the same as @@samp{print} except that the expression's value is not
-printed and is not put in the value history (@@pxref{Value History}). The
-expression is evaluated only for side effects.
-
-Note that if the beginning of the argument string of the @@samp{set} command
-appears identical to a @@samp{set} subcommand, it may be necessary to use
-the @@samp{set variable} command. This command is identical to @@samp{set}
-except for its lack of subcommands.
-
-GDB allows more implicit conversions in assignments than C does; you can
-freely store an integer value into a pointer variable or vice versa, and
-any structure can be converted to any other structure that is the same
-length or shorter.
-
-In C, all the other assignment operators such as @@samp{+=} and @@samp{++}
-are supported as well.
-
-To store into arbitrary places in memory, use the @@samp{@@{@@dots{}@@}}
-construct to generate a value of specified type at a specified address
-(@@pxref{Expressions}). For example,
-
-@@example
-set @@{int@@}0x83040 = 4
-@@end example
-
-@@node Jumping, Signaling, Assignment, Altering
-@@section Continuing at a Different Address
-
-@@table @@code
-@@item jump @@var{linenum}
-@@kindex jump
-Resume execution at line number @@var{linenum}. Execution may stop
-immediately if there is a breakpoint there.
-
-The @@samp{jump} command does not change the current stack frame, or
-the stack pointer, or the contents of any memory location or any
-register other than the program counter. If line @@var{linenum} is in
-a different function from the one currently executing, the results may
-be wild if the two functions expect different patterns of arguments or
-of local variables. For this reason, the @@samp{jump} command requests
-confirmation if the specified line is not in the function currently
-executing. However, even wild results are predictable based on
-changing the program counter.
-
-@@item jump *@@var{address}
-Resume execution at the instruction at address @@var{address}.
-@@end table
-
-A similar effect can be obtained by storing a new value into the register
-@@samp{$pc}, but not exactly the same.
-
-@@example
-set $pc = 0x485
-@@end example
-
-@@noindent
-specifies the address at which execution will resume, but does not resume
-execution. That does not happen until you use the @@samp{cont} command or a
-stepping command (@@pxref{Stepping}).
-
-@@node Signaling, Returning, Jumping, Altering
-@@section Giving the Program a Signal
-
-@@table @@code
-@@item signal @@var{signalnum}
-@@kindex signal
-Resume execution where the program stopped, but give it immediately
-the signal number @@var{signalnum}.
-
-Alternatively, if @@var{signalnum} is zero, continue execution and give
-no signal. This is useful when the program has received a signal
-but you don't want the program to see that signal; the @@samp{cont} command
-would signal the program.
-@@end table
-
-@@node Returning,, Signaling, Altering
-@@section Returning from a Function
-
-@@cindex returning from a function
-@@kindex return
-You can make any function call return immediately, using the @@samp{return}
-command.
-
-First select the stack frame that you wish to return from
-(@@pxref{Selection}). Then type the @@samp{return} command. If you wish to
-specify the value to be returned, give that as an argument.
-
-This pops the selected stack frame (and any other frames inside of it),
-leaving its caller as the innermost remaining frame. That frame becomes
-selected. The specified value is stored in the registers used for
-returning values of functions.
-
-The @@samp{return} command does not resume execution; it leaves the program
-stopped in the state that would exist if the function had just returned.
-Contrast this with the @@samp{finish} command (@@pxref{Stepping}), which
-resumes execution @@i{until} the selected stack frame returns naturally.
-
-@@node Sequences, Emacs, Altering, Top
-@@chapter Canned Sequences of Commands
-
-GDB provides two ways to store sequences of commands for execution as a
-unit: user-defined commands and command files.
-
-@@menu
-* Define:: User-defined commands.
-* Command Files:: Command files.
-* Output:: Controlled output commands useful in
- user-defined commands and command files.
-@@end menu
-
-@@node Define, Command Files, Sequences, Sequences
-@@section User-Defined Commands
-
-@@cindex user-defined commands
-A @@dfn{user-defined command} is a sequence of GDB commands to which you
-assign a new name as a command. This is done with the @@samp{define}
-command.
-
-@@table @@code
-@@item define @@var{commandname}
-@@kindex define
-Define a command named @@var{commandname}. If there is already a command
-by that name, you are asked to confirm that you want to redefine it.
-
-The definition of the command is made up of other GDB command lines,
-which are given following the @@samp{define} command. The end of these
-commands is marked by a line containing @@samp{end}.
-
-@@item document @@var{commandname}
-@@kindex document
-Give documentation to the user-defined command @@var{commandname}. The
-command @@var{commandname} must already be defined. This command reads
-lines of documentation just as @@samp{define} reads the lines of the
-command definition, ending with @@samp{end}. After the @@samp{document} command is finished,
-@@samp{help} on command @@var{commandname} will print the documentation
-you have specified.
-
-You may use the @@samp{document} command again to change the
-documentation of a command. Redefining the command with @@samp{define}
-does not change the documentation.
-@@end table
-
-User-defined commands do not take arguments. When they are executed, the
-commands of the definition are not printed. An error in any command
-stops execution of the user-defined command.
-
-Commands that would ask for confirmation if used interactively proceed
-without asking when used inside a user-defined command. Many GDB commands
-that normally print messages to say what they are doing omit the messages
-when used in user-defined command.
-
-@@node Command Files, Output, Define, Sequences
-@@section Command Files
-
-@@cindex command files
-A command file for GDB is a file of lines that are GDB commands. Comments
-(lines starting with @@samp{#}) may also be included. An empty line in a
-command file does nothing; it does not mean to repeat the last command, as
-it would from the terminal.
-
-@@cindex init file
-@@cindex .gdbinit
-When GDB starts, it automatically executes its @@dfn{init files}, command
-files named @@file{.gdbinit}. GDB reads the init file (if any) in your home
-directory and then the init file (if any) in the current working
-directory. (The init files are not executed if the @@samp{-nx} option
-is given.) You can also request the execution of a command file with the
-@@samp{source} command:
-
-@@table @@code
-@@item source @@var{filename}
-@@kindex source
-Execute the command file @@var{filename}.
-@@end table
-
-The lines in a command file are executed sequentially. They are not
-printed as they are executed. An error in any command terminates execution
-of the command file.
-
-Commands that would ask for confirmation if used interactively proceed
-without asking when used in a command file. Many GDB commands that
-normally print messages to say what they are doing omit the messages
-when used in a command file.
-
-@@node Output,, Command Files, Sequences
-@@section Commands for Controlled Output
-
-During the execution of a command file or a user-defined command, the only
-output that appears is what is explicitly printed by the commands of the
-definition. This section describes three commands useful for generating
-exactly the output you want.
-
-@@table @@code
-@@item echo @@var{text}
-@@kindex echo
-Print @@var{text}. Nonprinting characters can be included in
-@@var{text} using C escape sequences, such as @@samp{\n} to print a
-newline. @@b{No newline will be printed unless you specify one.}
-
-A backslash at the end of @@var{text} is ignored. It is useful for
-outputting a string ending in spaces, since trailing spaces are
-trimmed from all arguments. A backslash at the beginning preserves
-leading spaces in the same way, because @@samp{\ } as an escape
-sequence stands for a space. Thus, to print @@samp{ and foo = }, do
-
-@@example
-echo \ and foo = \
-@@end example
-
-@@item output @@var{expression}
-@@kindex output
-Print the value of @@var{expression} and nothing but that value: no
-newlines, no @@samp{$@@var{nn} = }. The value is not entered in the
-value history either. @@xref{Expressions} for more information
-on expressions.
-
-@@item output/@@var{fmt} @@var{expression}
-Print the value of @@var{expression} in format @@var{fmt}.
-@@xref{Formats}, for more information.
-
-@@item printf @@var{string}, @@var{expressions}@@dots{}
-@@kindex printf
-Print the values of the @@var{expressions} under the control of
-@@var{string}. The @@var{expressions} are separated by commas and may
-be either numbers or pointers. Their values are printed as specified
-by @@var{string}, exactly as if the program were to execute
-
-@@example
-printf (@@var{string}, @@var{expressions}@@dots{});
-@@end example
-
-For example, you can print two values in hex like this:
-
-@@example
-printf "foo, bar-foo = 0x%x, 0x%x\n", foo, bar-foo
-@@end example
-
-The only backslash-escape sequences that you can use in the string are
-the simple ones that consist of backslash followed by a letter.
-@@end table
-
-@@node Emacs, Remote, Sequences, Top
-@@chapter Using GDB under GNU Emacs
-
-A special interface allows you to use GNU Emacs to view (and
-edit) the source files for the program you are debugging with
-GDB.
-
-To use this interface, use the command @@kbd{M-x gdb} in Emacs.
-Give the executable file you want to debug as an argument. This
-command starts a GDB process as a subprocess of Emacs, with input
-and output through a newly created Emacs buffer.
-
-Using this GDB process is just like using GDB normally except for two things:
-
-@@itemize @@bullet
-@@item
-All ``terminal'' input and output goes through the Emacs buffer. This
-applies both to GDB commands and their output, and to the input and
-output done by the program you are debugging.
-
-This is useful because it means that you can copy the text of previous
-commands and input them again; you can even use parts of the output
-in this way.
-
-All the facilities of Emacs's Shell mode are available for this purpose.
-
-@@item
-GDB displays source code through Emacs. Each time GDB displays a
-stack frame, Emacs automatically finds the source file for that frame
-and puts an arrow (@@samp{=>}) at the left margin of the current line.
-
-Explicit GDB @@samp{list} or search commands still produce output as
-usual, but you probably will have no reason to use them.
-@@end itemize
-
-In the GDB I/O buffer, you can use these special Emacs commands:
-
-@@table @@kbd
-@@item M-s
-Execute to another source line, like the GDB @@samp{step} command.
-
-@@item M-n
-Execute to next source line in this function, skipping all function
-calls, like the GDB @@samp{next} command.
-
-@@item M-i
-Execute one instruction, like the GDB @@samp{stepi} command.
-
-@@item M-u
-Move up one stack frame (and display that frame's source file in
-Emacs), like the GDB @@samp{up} command.
-
-@@item M-d
-Move down one stack frame (and display that frame's source file in
-Emacs), like the GDB @@samp{down} command. (This means that you cannot
-delete words in the usual fashion in the GDB buffer; I am guessing you
-won't often want to do that.)
-
-@@item C-c C-f
-Execute until exit from the selected stack frame, like the GDB
-@@samp{finish} command.
-@@end table
-
-In any source file, the Emacs command @@kbd{C-x SPC} (@@code{gdb-break})
-tells GDB to set a breakpoint on the source line point is on.
-
-The source files displayed in Emacs are in ordinary Emacs buffers
-which are visiting the source files in the usual way. You can edit
-the files with these buffers if you wish; but keep in mind that GDB
-communicates with Emacs in terms of line numbers. If you add or
-delete lines from the text, the line numbers that GDB knows will cease
-to correspond properly to the code.
-
-@@node Remote, Commands, Emacs, Top
-@@chapter Remote Kernel Debugging
-
-GDB has a special facility for debugging a remote machine via a serial
-connection. This can be used for kernel debugging.
-
-The program to be debugged on the remote machine needs to contain a
-debugging device driver which talks to GDB over the serial line using the
-protocol described below. The same version of GDB that is used ordinarily
-can be used for this.
-
-@@menu
-* Remote Commands:: Commands used to start and finish remote debugging.
-@@end menu
-
-For details of the communication protocol, see the comments in the GDB
-source file @@file{remote.c}.
-
-@@node Remote Commands,, Remote, Remote
-@@section Commands for Remote Debugging
-
-To start remote debugging, first run GDB and specify as an executable file
-the program that is running in the remote machine. This tells GDB how
-to find the program's symbols and the contents of its pure text. Then
-establish communication using the @@samp{attach} command with a device
-name rather than a pid as an argument. For example:
-
-@@example
-attach /dev/ttyd
-@@end example
-
-@@noindent
-if the serial line is connected to the device named @@file{/dev/ttyd}. This
-will stop the remote machine if it is not already stopped.
-
-Now you can use all the usual commands to examine and change data and to
-step and continue the remote program.
-
-To resume the remote program and stop debugging it, use the @@samp{detach}
-command.
-
-@@node Commands, Concepts, Remote, Top
-@@unnumbered Command Index
-
-@@printindex ky
-
-@@node Concepts,, Commands, Top
-@@unnumbered Concept Index
-
-@@printindex cp
-
-@@contents
-@@bye
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d617 3
-a619 2
-inferior. If you wish to evaluate a function simply for it's side
-affects, you may use the @@samp{set} command. @@xref{Assignment}.
-d1101 4
-a1104 3
-A condition is just a boolean expression in your programming language.
-A breakpoint with a condition evaluates the expression each time the
-program reaches it, and the program stops only if the condition is true.
-d1126 1
-d1259 6
-a1264 5
-is a condition expression that will change @@code{x} as needed, then always
-have the value 0 so the program will not stop. Loss of input is avoided
-here because break conditions are evaluated without changing the terminal
-modes. When you want to have nontrivial conditions for performing the side
-effects, the operators @@samp{&&}, @@samp{||} and @@samp{?@@: @@dots{} :@@:} may be useful.
-d1269 3
-a1271 3
-Under Unix, breakpoints cannot be used in a program if any other process
-is running that program. Attempting to run or continue the program with
-a breakpoint in this case will cause GDB to stop it.
-d1875 2
-d2047 2
-a2048 1
-address of a byte of memory.
-d2196 1
-a2196 1
-each time the program stops.
-d2382 1
-a2382 1
-saved in ``extended'' format, but all C programs expect to work with
-d2451 1
-d2544 1
-a2544 1
-For example,
-d2628 3
-a2630 3
-no signal. This may be useful when the program has received a signal
-and the @@samp{cont} command would allow the program to see that
-signal.
-d2691 1
-a2691 1
-command definition. After the @@samp{document} command is finished,
-d2771 2
-a2772 1
-value history either.
-@
diff --git a/gdb/RCS/gdbcore.h,v b/gdb/RCS/gdbcore.h,v
deleted file mode 100644
index 872e5af9..0000000
--- a/gdb/RCS/gdbcore.h,v
+++ /dev/null
@@ -1,105 +0,0 @@
-head 1.2;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.2
-date 89.02.09.23.23.12; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.02.09.22.43.14; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.2
-log
-@Create gdbcore.h with external variables that relate to core files.
-@
-text
-@/* Machine independent variables that describe the core file under GDB.
- Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-/* File names of core file and executable file. */
-
-extern char *corefile;
-extern char *execfile;
-
-/* Descriptors on which core file and executable file are open.
- Note that the execchan is closed when an inferior is created
- and reopened if the inferior dies or is killed. */
-
-extern int corechan;
-extern int execchan;
-
-/* Last modification time of executable file.
- Also used in source.c to compare against mtime of a source file. */
-
-extern int exec_mtime;
-
-/* Virtual addresses of bounds of the two areas of memory in the core file. */
-
-extern CORE_ADDR data_start;
-extern CORE_ADDR data_end;
-extern CORE_ADDR stack_start;
-extern CORE_ADDR stack_end;
-
-/* Virtual addresses of bounds of two areas of memory in the exec file.
- Note that the data area in the exec file is used only when there is no core file. */
-
-extern CORE_ADDR text_start;
-extern CORE_ADDR text_end;
-
-extern CORE_ADDR exec_data_start;
-extern CORE_ADDR exec_data_end;
-
-/* Address in executable file of start of text area data. */
-
-extern int text_offset;
-
-/* Address in executable file of start of data area data. */
-
-extern int exec_data_offset;
-
-/* Address in core file of start of data area data. */
-
-extern int data_offset;
-
-/* Address in core file of start of stack area data. */
-
-extern int stack_offset;
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d1 68
-@
diff --git a/gdb/RCS/inflow.c,v b/gdb/RCS/inflow.c,v
deleted file mode 100644
index 972b615..0000000
--- a/gdb/RCS/inflow.c,v
+++ /dev/null
@@ -1,636 +0,0 @@
-head 1.3;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.3
-date 89.03.27.20.12.35; author gnu; state Exp;
-branches ;
-next 1.2;
-
-1.2
-date 89.02.09.23.23.40; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.02.09.22.28.04; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.3
-log
-@General portability changes. Make various local terminal control
-parameter processing #ifdef the particular IOCTL used to get them.
-This handles various Sys V/Berkeley merges. Also avoid vfork
-and <sys/fcntl.h>.
-@
-text
-@/* Low level interface to ptrace, for GDB when running under Unix.
- Copyright (C) 1986, 1987 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-#include "defs.h"
-#include "param.h"
-#include "frame.h"
-#include "inferior.h"
-
-#ifdef USG
-#include <sys/types.h>
-#include <fcntl.h>
-#endif
-
-#include <stdio.h>
-#include <sys/param.h>
-#include <sys/dir.h>
-#include <signal.h>
-
-#ifdef HAVE_TERMIO
-#include <termio.h>
-#undef TIOCGETP
-#define TIOCGETP TCGETA
-#undef TIOCSETN
-#define TIOCSETN TCSETA
-#undef TIOCSETP
-#define TIOCSETP TCSETAF
-#define TERMINAL struct termio
-#else
-#include <sys/ioctl.h>
-#include <fcntl.h>
-#include <sgtty.h>
-#define TERMINAL struct sgttyb
-#endif
-
-#ifdef SET_STACK_LIMIT_HUGE
-#include <sys/time.h>
-#include <sys/resource.h>
-extern int original_stack_limit;
-#endif /* SET_STACK_LIMIT_HUGE */
-
-extern int errno;
-
-/* Nonzero if we are debugging an attached outside process
- rather than an inferior. */
-
-int attach_flag;
-
-
-/* Record terminal status separately for debugger and inferior. */
-
-static TERMINAL sg_inferior;
-static TERMINAL sg_ours;
-
-static int tflags_inferior;
-static int tflags_ours;
-
-#ifdef TIOCGETC
-static struct tchars tc_inferior;
-static struct tchars tc_ours;
-#endif
-
-#ifdef TIOCGLTC
-static struct ltchars ltc_inferior;
-static struct ltchars ltc_ours;
-#endif /* TIOCGLTC */
-
-#ifdef TIOCLGET
-static int lmode_inferior;
-static int lmode_ours;
-#endif
-
-#ifdef TIOCGPGRP
-static int pgrp_inferior;
-static int pgrp_ours;
-#else
-static int (*sigint_ours) ();
-static int (*sigquit_ours) ();
-#endif /* TIOCGPGRP */
-
-/* Copy of inferior_io_terminal when inferior was last started. */
-static char *inferior_thisrun_terminal;
-
-static void terminal_ours_1 ();
-
-/* Nonzero if our terminal settings are in effect.
- Zero if the inferior's settings are in effect. */
-static int terminal_is_ours;
-
-/* Initialize the terminal settings we record for the inferior,
- before we actually run the inferior. */
-
-void
-terminal_init_inferior ()
-{
- if (remote_debugging)
- return;
-
- sg_inferior = sg_ours;
- tflags_inferior = tflags_ours;
-
-#ifdef TIOCGETC
- tc_inferior = tc_ours;
-#endif
-
-#ifdef TIOCGLTC
- ltc_inferior = ltc_ours;
-#endif
-
-#ifdef TIOCLGET
- lmode_inferior = lmode_ours;
-#endif
-
-#ifdef TIOCGPGRP
- pgrp_inferior = inferior_pid;
-#endif /* TIOCGPGRP */
-
- terminal_is_ours = 1;
-}
-
-/* Put the inferior's terminal settings into effect.
- This is preparation for starting or resuming the inferior. */
-
-void
-terminal_inferior ()
-{
- if (remote_debugging)
- return;
-
- if (terminal_is_ours) /* && inferior_thisrun_terminal == 0) */
- {
- fcntl (0, F_SETFL, tflags_inferior);
- fcntl (0, F_SETFL, tflags_inferior);
- ioctl (0, TIOCSETN, &sg_inferior);
-#ifdef TIOCGETC
- ioctl (0, TIOCSETC, &tc_inferior);
-#endif
-#ifdef TIOCGLTC
- ioctl (0, TIOCSLTC, &ltc_inferior);
-#endif
-#ifdef TIOCLGET
- ioctl (0, TIOCLSET, &lmode_inferior);
-#endif
-
-#ifdef TIOCGPGRP
- ioctl (0, TIOCSPGRP, &pgrp_inferior);
-#else
- sigint_ours = (int (*) ()) signal (SIGINT, SIG_IGN);
- sigquit_ours = (int (*) ()) signal (SIGQUIT, SIG_IGN);
-#endif /* TIOCGPGRP */
- }
- terminal_is_ours = 0;
-}
-
-/* Put some of our terminal settings into effect,
- enough to get proper results from our output,
- but do not change into or out of RAW mode
- so that no input is discarded.
-
- After doing this, either terminal_ours or terminal_inferior
- should be called to get back to a normal state of affairs. */
-
-void
-terminal_ours_for_output ()
-{
- if (remote_debugging)
- return;
-
- terminal_ours_1 (1);
-}
-
-/* Put our terminal settings into effect.
- First record the inferior's terminal settings
- so they can be restored properly later. */
-
-void
-terminal_ours ()
-{
- if (remote_debugging)
- return;
-
- terminal_ours_1 (0);
-}
-
-static void
-terminal_ours_1 (output_only)
- int output_only;
-{
-#ifdef TIOCGPGRP
- /* Ignore this signal since it will happen when we try to set the pgrp. */
- int (*osigttou) ();
-#endif /* TIOCGPGRP */
-
- if (!terminal_is_ours) /* && inferior_thisrun_terminal == 0) */
- {
- terminal_is_ours = 1;
-
-#ifdef TIOCGPGRP
- osigttou = signal (SIGTTOU, SIG_IGN);
-
- ioctl (0, TIOCGPGRP, &pgrp_inferior);
- ioctl (0, TIOCSPGRP, &pgrp_ours);
-
- signal (SIGTTOU, osigttou);
-#else
- signal (SIGINT, sigint_ours);
- signal (SIGQUIT, sigquit_ours);
-#endif /* TIOCGPGRP */
-
- tflags_inferior = fcntl (0, F_GETFL, 0);
- ioctl (0, TIOCGETP, &sg_inferior);
-
-#ifdef TIOCGETC
- ioctl (0, TIOCGETC, &tc_inferior);
-#endif
-#ifdef TIOCGLTC
- ioctl (0, TIOCGLTC, &ltc_inferior);
-#endif
-#ifdef TIOCLGET
- ioctl (0, TIOCLGET, &lmode_inferior);
-#endif
- }
-
-#ifdef HAVE_TERMIO
- sg_ours.c_lflag |= ICANON;
- if (output_only && !(sg_inferior.c_lflag & ICANON))
- sg_ours.c_lflag &= ~ICANON;
-#else /* not HAVE_TERMIO */
- sg_ours.sg_flags &= ~RAW & ~CBREAK;
- if (output_only)
- sg_ours.sg_flags |= (RAW | CBREAK) & sg_inferior.sg_flags;
-#endif /* not HAVE_TERMIO */
-
- fcntl (0, F_SETFL, tflags_ours);
- fcntl (0, F_SETFL, tflags_ours);
- ioctl (0, TIOCSETN, &sg_ours);
-
-#ifdef TIOCGETC
- ioctl (0, TIOCSETC, &tc_ours);
-#endif
-#ifdef TIOCGLTC
- ioctl (0, TIOCSLTC, &ltc_ours);
-#endif
-#ifdef TIOCLGET
- ioctl (0, TIOCLSET, &lmode_ours);
-#endif
-
-
-#ifdef HAVE_TERMIO
- sg_ours.c_lflag |= ICANON;
-#else /* not HAVE_TERMIO */
- sg_ours.sg_flags &= ~RAW & ~CBREAK;
-#endif /* not HAVE_TERMIO */
-}
-
-static void
-term_status_command ()
-{
- register int i;
-
- if (remote_debugging)
- {
- printf ("No terminal status when remote debugging.\n");
- return;
- }
-
- printf ("Inferior's terminal status (currently saved by GDB):\n");
-
-#ifdef HAVE_TERMIO
-
- printf ("fcntl flags = 0x%x, c_iflag = 0x%x, c_oflag = 0x%x,\n",
- tflags_inferior, sg_inferior.c_iflag, sg_inferior.c_oflag);
- printf ("c_cflag = 0x%x, c_lflag = 0x%x, c_line = 0x%x.\n",
- sg_inferior.c_cflag, sg_inferior.c_lflag, sg_inferior.c_line);
- printf ("c_cc: ");
- for (i = 0; (i < NCC); i += 1)
- printf ("0x%x ", sg_inferior.c_cc[i]);
- printf ("\n");
-
-#else /* not HAVE_TERMIO */
-
- printf ("fcntl flags = 0x%x, sgttyb.sg_flags = 0x%x, owner pid = %d.\n",
- tflags_inferior, sg_inferior.sg_flags, pgrp_inferior);
-
-#endif /* not HAVE_TERMIO */
-
-#ifdef TIOCGETC
- printf ("tchars: ");
- for (i = 0; i < sizeof (struct tchars); i++)
- printf ("0x%x ", ((char *)&tc_inferior)[i]);
- printf ("\n");
-#endif
-
-#ifdef TIOCGLTC
- printf ("ltchars: ");
- for (i = 0; i < sizeof (struct ltchars); i++)
- printf ("0x%x ", ((char *)&ltc_inferior)[i]);
- printf ("\n");
- ioctl (0, TIOCSLTC, &ltc_ours);
-#endif
-
-#ifdef TIOCLGET
- printf ("lmode: %x\n", lmode_inferior);
-#endif
-}
-
-static void
-new_tty (ttyname)
- char *ttyname;
-{
- register int tty;
- register int fd;
-
-#ifdef TIOCNOTTY
- /* Disconnect the child process from our controlling terminal. */
- tty = open("/dev/tty", O_RDWR);
- if (tty > 0)
- {
- ioctl(tty, TIOCNOTTY, 0);
- close(tty);
- }
-#endif
-
- /* Now open the specified new terminal. */
-
- tty = open(ttyname, O_RDWR);
- if (tty == -1)
- _exit(1);
-
- dup2(tty, 0);
- dup2(tty, 1);
- dup2(tty, 2);
- close(tty);
-}
-
-/* Start an inferior process and returns its pid.
- ALLARGS is a string containing shell command to run the program.
- ENV is the environment vector to pass. */
-
-#ifndef SHELL_FILE
-#define SHELL_FILE "/bin/sh"
-#endif
-
-int
-create_inferior (allargs, env)
- char *allargs;
- char **env;
-{
- int pid;
- char *shell_command;
- extern int sys_nerr;
- extern char *sys_errlist[];
- extern int errno;
-
- /* If desired, concat something onto the front of ALLARGS.
- SHELL_COMMAND is the result. */
-#ifdef SHELL_COMMAND_CONCAT
- shell_command = (char *) alloca (strlen (SHELL_COMMAND_CONCAT) + strlen (allargs) + 1);
- strcpy (shell_command, SHELL_COMMAND_CONCAT);
- strcat (shell_command, allargs);
-#else
- shell_command = allargs;
-#endif
-
- /* exec is said to fail if the executable is open. */
- close_exec_file ();
-
- pid = fork ();
- if (pid < 0)
- perror_with_name ("fork");
-
- if (pid == 0)
- {
-#ifdef TIOCGPGRP
- /* Run inferior in a separate process group. */
- setpgrp (getpid (), getpid ());
-#endif /* TIOCGPGRP */
-
-#ifdef SET_STACK_LIMIT_HUGE
- /* Reset the stack limit back to what it was. */
- {
- struct rlimit rlim;
-
- getrlimit (RLIMIT_STACK, &rlim);
- rlim.rlim_cur = original_stack_limit;
- setrlimit (RLIMIT_STACK, &rlim);
- }
-#endif /* SET_STACK_LIMIT_HUGE */
-
-
- inferior_thisrun_terminal = inferior_io_terminal;
- if (inferior_io_terminal != 0)
- new_tty (inferior_io_terminal);
-
-/* Not needed on Sun, at least, and loses there
- because it clobbers the superior. */
-/*??? signal (SIGQUIT, SIG_DFL);
- signal (SIGINT, SIG_DFL); */
-
- call_ptrace (0);
- execle (SHELL_FILE, "sh", "-c", shell_command, 0, env);
-
- fprintf (stderr, "Cannot exec %s: %s.\n", SHELL_FILE,
- errno < sys_nerr ? sys_errlist[errno] : "unknown error");
- fflush (stderr);
- _exit (0177);
- }
- return pid;
-}
-
-/* Kill the inferior process. Make us have no inferior. */
-
-static void
-kill_command ()
-{
- if (remote_debugging)
- return;
- if (inferior_pid == 0)
- error ("The program is not being run.");
- if (!query ("Kill the inferior process? "))
- error ("Not confirmed.");
- kill_inferior ();
-}
-
-void
-inferior_died ()
-{
- inferior_pid = 0;
- attach_flag = 0;
- mark_breakpoints_out ();
- select_frame ( (FRAME) 0, -1);
- reopen_exec_file ();
- if (have_core_file_p ())
- set_current_frame ( create_new_frame (read_register (FP_REGNUM),
- read_pc ()));
-}
-
-static void
-try_writing_regs_command ()
-{
- register int i;
- register int value;
- extern int errno;
-
- if (inferior_pid == 0)
- error ("There is no inferior process now.");
-
- for (i = 0; ; i += 2)
- {
- QUIT;
- errno = 0;
- value = call_ptrace (3, inferior_pid, i, 0);
- call_ptrace (6, inferior_pid, i, value);
- if (errno == 0)
- {
- printf (" Succeeded with address 0x%x; value 0x%x (%d).\n",
- i, value, value);
- }
- else if ((i & 0377) == 0)
- printf (" Failed at 0x%x.\n", i);
- }
-}
-
-void
-_initialize_inflow ()
-{
- add_com ("term-status", class_obscure, term_status_command,
- "Print info on inferior's saved terminal status.");
-
- add_com ("try-writing-regs", class_obscure, try_writing_regs_command,
- "Try writing all locations in inferior's system block.\n\
-Report which ones can be written.");
-
- add_com ("kill", class_run, kill_command,
- "Kill execution of program being debugged.");
-
- inferior_pid = 0;
-
- ioctl (0, TIOCGETP, &sg_ours);
- fcntl (0, F_GETFL, tflags_ours);
-
-#ifdef TIOCGETC
- ioctl (0, TIOCGETC, &tc_ours);
-#endif
-#ifdef TIOCGLTC
- ioctl (0, TIOCGLTC, &ltc_ours);
-#endif
-#ifdef TIOCLGET
- ioctl (0, TIOCLGET, &lmode_ours);
-#endif
-
-#ifdef TIOCGPGRP
- ioctl (0, TIOCGPGRP, &pgrp_ours);
-#endif /* TIOCGPGRP */
-
- terminal_is_ours = 1;
-}
-
-@
-
-
-1.2
-log
-@When the inferior process dies, deselect the current frame so that
-the "where" ("backtrace") command will not think there's a stack.
-@
-text
-@d27 1
-a27 1
-#include <sys/fcntl.h>
-a34 6
-/* May be unnecessary since many parts of inflow.c
- have migrated to *-infdep.c */
-#ifdef USG
-#include <sys/user.h>
-#endif
-
-d73 1
-a73 1
-#ifdef TIOCGLTC
-d76 3
-d81 3
-d86 1
-a86 1
-#endif /* TIOCGLTC */
-d117 4
-a121 1
- tc_inferior = tc_ours;
-d123 3
-d127 1
-a127 1
-#endif /* TIOCGLTC */
-d150 3
-a153 1
- ioctl (0, TIOCSETC, &tc_inferior);
-d155 2
-d158 1
-a158 1
-#endif /* TIOCGLTC */
-d228 3
-a231 1
- ioctl (0, TIOCGETC, &tc_inferior);
-d233 2
-d236 1
-a236 1
-#endif /* TIOCGLTC */
-d253 3
-a256 1
- ioctl (0, TIOCSETC, &tc_ours);
-d258 2
-d261 1
-a261 1
-#endif /* TIOCGLTC */
-d297 6
-a302 3
- printf ("fcntl flags = 0x%x, lmode = 0x%x,\nsgttyb.sg_flags = 0x%x, owner pid = %d.\n",
- tflags_inferior, lmode_inferior,
- sg_inferior.sg_flags, pgrp_inferior);
-d307 3
-d314 2
-d317 3
-a319 1
-#endif /* not HAVE_TERMIO */
-d383 1
-a383 1
- pid = vfork ();
-d385 1
-a385 1
- perror_with_name ("vfork");
-d497 3
-a500 1
- ioctl (0, TIOCGETC, &tc_ours);
-d502 2
-d505 1
-a505 1
-#endif /* TIOCGLTC */
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d418 1
-@
diff --git a/gdb/RCS/infrun.c,v b/gdb/RCS/infrun.c,v
deleted file mode 100644
index 983922f..0000000
--- a/gdb/RCS/infrun.c,v
+++ /dev/null
@@ -1,1855 +0,0 @@
-head 1.3;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.3
-date 89.03.27.20.15.05; author gnu; state Exp;
-branches ;
-next 1.2;
-
-1.2
-date 89.02.09.23.25.40; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.02.09.17.11.52; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.3
-log
-@A/UX-specific change: define X_OK since Apple fucked it up.
-@
-text
-@/* Start and stop the inferior process, for GDB.
- Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-/* Notes on the algorithm used in wait_for_inferior to determine if we
- just did a subroutine call when stepping. We have the following
- information at that point:
-
- Current and previous (just before this step) pc.
- Current and previous sp.
- Current and previous start of current function.
-
- If the start's of the functions don't match, then
-
- a) We did a subroutine call.
-
- In this case, the pc will be at the beginning of a function.
-
- b) We did a subroutine return.
-
- Otherwise.
-
- c) We did a longjmp.
-
- If we did a longjump, we were doing "nexti", since a next would
- have attempted to skip over the assembly language routine in which
- the longjmp is coded and would have simply been the equivalent of a
- continue. I consider this ok behaivior. We'd like one of two
- things to happen if we are doing a nexti through the longjmp()
- routine: 1) It behaves as a stepi, or 2) It acts like a continue as
- above. Given that this is a special case, and that anybody who
- thinks that the concept of sub calls is meaningful in the context
- of a longjmp, I'll take either one. Let's see what happens.
-
- Acts like a subroutine return. I can handle that with no problem
- at all.
-
- -->So: If the current and previous beginnings of the current
- function don't match, *and* the pc is at the start of a function,
- we've done a subroutine call. If the pc is not at the start of a
- function, we *didn't* do a subroutine call.
-
- -->If the beginnings of the current and previous function do match,
- either:
-
- a) We just did a recursive call.
-
- In this case, we would be at the very beginning of a
- function and 1) it will have a prologue (don't jump to
- before prologue, or 2) (we assume here that it doesn't have
- a prologue) there will have been a change in the stack
- pointer over the last instruction. (Ie. it's got to put
- the saved pc somewhere. The stack is the usual place. In
- a recursive call a register is only an option if there's a
- prologue to do something with it. This is even true on
- register window machines; the prologue sets up the new
- window. It might not be true on a register window machine
- where the call instruction moved the register window
- itself. Hmmm. One would hope that the stack pointer would
- also change. If it doesn't, somebody send me a note, and
- I'll work out a more general theory.
- randy@@wheaties.ai.mit.edu). This is true (albeit slipperly
- so) on all machines I'm aware of:
-
- m68k: Call changes stack pointer. Regular jumps don't.
-
- sparc: Recursive calls must have frames and therefor,
- prologues.
-
- vax: All calls have frames and hence change the
- stack pointer.
-
- b) We did a return from a recursive call. I don't see that we
- have either the ability or the need to distinguish this
- from an ordinary jump. The stack frame will be printed
- when and if the frame pointer changes; if we are in a
- function without a frame pointer, it's the users own
- lookout.
-
- c) We did a jump within a function. We assume that this is
- true if we didn't do a recursive call.
-
- d) We are in no-man's land ("I see no symbols here"). We
- don't worry about this; it will make calls look like simple
- jumps (and the stack frames will be printed when the frame
- pointer moves), which is a reasonably non-violent response.
-
-#if 0
- We skip this; it causes more problems than it's worth.
-#ifdef SUN4_COMPILER_FEATURE
- We do a special ifdef for the sun 4, forcing it to single step
- into calls which don't have prologues. This means that we can't
- nexti over leaf nodes, we can probably next over them (since they
- won't have debugging symbols, usually), and we can next out of
- functions returning structures (with a "call .stret4" at the end).
-#endif
-#endif
-*/
-
-
-
-
-
-#include "defs.h"
-#include "param.h"
-#include "symtab.h"
-#include "frame.h"
-#include "inferior.h"
-#include "wait.h"
-
-#include <stdio.h>
-#include <signal.h>
-
-/* unistd.h is needed to #define X_OK */
-#ifdef USG
-#include <unistd.h>
-#else
-#include <sys/file.h>
-#endif
-
-/* The idiots at Apple only define X_OK if POSIX is defined. Fuck 'em. */
-#ifndef X_OK
-#define X_OK 1 /* Execute permission for access() */
-#endif
-
-#ifdef UMAX_PTRACE
-#include <sys/param.h>
-#include <sys/ptrace.h>
-#endif /* UMAX_PTRACE */
-
-extern char *sys_siglist[];
-extern int errno;
-
-/* Tables of how to react to signals; the user sets them. */
-
-static char signal_stop[NSIG];
-static char signal_print[NSIG];
-static char signal_program[NSIG];
-
-/* Nonzero if breakpoints are now inserted in the inferior. */
-
-static int breakpoints_inserted;
-
-/* Function inferior was in as of last step command. */
-
-static struct symbol *step_start_function;
-
-/* This is the sequence of bytes we insert for a breakpoint. */
-
-static char break_insn[] = BREAKPOINT;
-
-/* Nonzero => address for special breakpoint for resuming stepping. */
-
-static CORE_ADDR step_resume_break_address;
-
-/* Original contents of the byte where the special breakpoint is. */
-
-static char step_resume_break_shadow[sizeof break_insn];
-
-/* Nonzero means the special breakpoint is a duplicate
- so it has not itself been inserted. */
-
-static int step_resume_break_duplicate;
-
-/* Nonzero if we are expecting a trace trap and should proceed from it.
- 2 means expecting 2 trace traps and should continue both times.
- That occurs when we tell sh to exec the program: we will get
- a trap after the exec of sh and a second when the program is exec'd. */
-
-static int trap_expected;
-
-/* Nonzero if the next time we try to continue the inferior, it will
- step one instruction and generate a spurious trace trap.
- This is used to compensate for a bug in HP-UX. */
-
-static int trap_expected_after_continue;
-
-/* Nonzero means expecting a trace trap
- and should stop the inferior and return silently when it happens. */
-
-int stop_after_trap;
-
-/* Nonzero means expecting a trace trap due to attaching to a process. */
-
-int stop_after_attach;
-
-/* Nonzero if pc has been changed by the debugger
- since the inferior stopped. */
-
-int pc_changed;
-
-/* Nonzero if debugging a remote machine via a serial link or ethernet. */
-
-int remote_debugging;
-
-/* Save register contents here when about to pop a stack dummy frame. */
-
-char stop_registers[REGISTER_BYTES];
-
-/* Nonzero if program stopped due to error trying to insert breakpoints. */
-
-static int breakpoints_failed;
-
-/* Nonzero if inferior is in sh before our program got exec'd. */
-
-static int running_in_shell;
-
-/* Nonzero after stop if current stack frame should be printed. */
-
-static int stop_print_frame;
-
-#ifdef NO_SINGLE_STEP
-extern int one_stepped; /* From machine dependent code */
-extern void single_step (); /* Same. */
-#endif /* NO_SINGLE_STEP */
-
-static void insert_step_breakpoint ();
-static void remove_step_breakpoint ();
-static void wait_for_inferior ();
-static void normal_stop ();
-
-
-/* Clear out all variables saying what to do when inferior is continued.
- First do this, then set the ones you want, then call `proceed'. */
-
-void
-clear_proceed_status ()
-{
- trap_expected = 0;
- step_range_start = 0;
- step_range_end = 0;
- step_frame_address = 0;
- step_over_calls = -1;
- step_resume_break_address = 0;
- stop_after_trap = 0;
- stop_after_attach = 0;
-
- /* Discard any remaining commands left by breakpoint we had stopped at. */
- clear_breakpoint_commands ();
-}
-
-/* Basic routine for continuing the program in various fashions.
-
- ADDR is the address to resume at, or -1 for resume where stopped.
- SIGNAL is the signal to give it, or 0 for none,
- or -1 for act according to how it stopped.
- STEP is nonzero if should trap after one instruction.
- -1 means return after that and print nothing.
- You should probably set various step_... variables
- before calling here, if you are stepping.
-
- You should call clear_proceed_status before calling proceed. */
-
-void
-proceed (addr, signal, step)
- CORE_ADDR addr;
- int signal;
- int step;
-{
- int oneproc = 0;
-
- if (step > 0)
- step_start_function = find_pc_function (read_pc ());
- if (step < 0)
- stop_after_trap = 1;
-
- if (addr == -1)
- {
- /* If there is a breakpoint at the address we will resume at,
- step one instruction before inserting breakpoints
- so that we do not stop right away. */
-
- if (!pc_changed && breakpoint_here_p (read_pc ()))
- oneproc = 1;
- }
- else
- {
- write_register (PC_REGNUM, addr);
-#ifdef NPC_REGNUM
- write_register (NPC_REGNUM, addr + 4);
-#endif
- }
-
- if (trap_expected_after_continue)
- {
- /* If (step == 0), a trap will be automatically generated after
- the first instruction is executed. Force step one
- instruction to clear this condition. This should not occur
- if step is nonzero, but it is harmless in that case. */
- oneproc = 1;
- trap_expected_after_continue = 0;
- }
-
- if (oneproc)
- /* We will get a trace trap after one instruction.
- Continue it automatically and insert breakpoints then. */
- trap_expected = 1;
- else
- {
- int temp = insert_breakpoints ();
- if (temp)
- {
- print_sys_errmsg ("ptrace", temp);
- error ("Cannot insert breakpoints.\n\
-The same program may be running in another process.");
- }
- breakpoints_inserted = 1;
- }
-
- /* Install inferior's terminal modes. */
- terminal_inferior ();
-
- if (signal >= 0)
- stop_signal = signal;
- /* If this signal should not be seen by program,
- give it zero. Used for debugging signals. */
- else if (stop_signal < NSIG && !signal_program[stop_signal])
- stop_signal= 0;
-
- /* Resume inferior. */
- resume (oneproc || step, stop_signal);
-
- /* Wait for it to stop (if not standalone)
- and in any case decode why it stopped, and act accordingly. */
-
- wait_for_inferior ();
- normal_stop ();
-}
-
-/* Writing the inferior pc as a register calls this function
- to inform infrun that the pc has been set in the debugger. */
-
-void
-writing_pc (val)
- CORE_ADDR val;
-{
- stop_pc = val;
- pc_changed = 1;
-}
-
-/* Start an inferior process for the first time.
- Actually it was started by the fork that created it,
- but it will have stopped one instruction after execing sh.
- Here we must get it up to actual execution of the real program. */
-
-void
-start_inferior ()
-{
- /* We will get a trace trap after one instruction.
- Continue it automatically. Eventually (after shell does an exec)
- it will get another trace trap. Then insert breakpoints and continue. */
-
-#ifdef START_INFERIOR_TRAPS_EXPECTED
- trap_expected = START_INFERIOR_TRAPS_EXPECTED;
-#else
- trap_expected = 2;
-#endif
-
- running_in_shell = 0; /* Set to 1 at first SIGTRAP, 0 at second. */
- trap_expected_after_continue = 0;
- breakpoints_inserted = 0;
- mark_breakpoints_out ();
-
- /* Set up the "saved terminal modes" of the inferior
- based on what modes we are starting it with. */
- terminal_init_inferior ();
-
- /* Install inferior's terminal modes. */
- terminal_inferior ();
-
- if (remote_debugging)
- {
- trap_expected = 0;
- fetch_inferior_registers();
- set_current_frame (create_new_frame (read_register (FP_REGNUM),
- read_pc ()));
- stop_frame_address = FRAME_FP (get_current_frame());
- inferior_pid = 3;
- if (insert_breakpoints())
- fatal("Can't insert breakpoints");
- breakpoints_inserted = 1;
- proceed(-1, -1, 0);
- }
- else
- {
- wait_for_inferior ();
- normal_stop ();
- }
-}
-
-/* Start remote-debugging of a machine over a serial link. */
-
-void
-start_remote ()
-{
- clear_proceed_status ();
- running_in_shell = 0;
- trap_expected = 0;
- inferior_pid = 3;
- breakpoints_inserted = 0;
- mark_breakpoints_out ();
- wait_for_inferior ();
- normal_stop();
-}
-
-#ifdef ATTACH_DETACH
-
-/* Attach to process PID, then initialize for debugging it
- and wait for the trace-trap that results from attaching. */
-
-void
-attach_program (pid)
- int pid;
-{
- attach (pid);
- inferior_pid = pid;
-
- mark_breakpoints_out ();
- terminal_init_inferior ();
- clear_proceed_status ();
- stop_after_attach = 1;
- /*proceed (-1, 0, -2);*/
- wait_for_inferior ();
- normal_stop ();
-}
-#endif /* ATTACH_DETACH */
-
-/* Wait for control to return from inferior to debugger.
- If inferior gets a signal, we may decide to start it up again
- instead of returning. That is why there is a loop in this function.
- When this function actually returns it means the inferior
- should be left stopped and GDB should read more commands. */
-
-static void
-wait_for_inferior ()
-{
- register int pid;
- WAITTYPE w;
- CORE_ADDR pc;
- int tem;
- int another_trap;
- int random_signal;
- CORE_ADDR stop_sp, prev_sp;
- CORE_ADDR prev_func_start, stop_func_start;
- CORE_ADDR prologue_pc;
- int stop_step_resume_break;
- CORE_ADDR step_resume_break_sp;
- int newmisc;
- int newfun_pc;
- struct symbol *newfun;
- struct symtab_and_line sal;
- int prev_pc;
- extern CORE_ADDR text_end;
-
- prev_pc = read_pc ();
- prev_func_start = get_pc_function_start (prev_pc) + FUNCTION_START_OFFSET;
- prev_sp = read_register (SP_REGNUM);
-
- while (1)
- {
- /* Clean up saved state that will become invalid */
- pc_changed = 0;
- flush_cached_frames ();
-
- if (remote_debugging)
- remote_wait (&w);
- else
- {
- pid = wait (&w);
- if (pid != inferior_pid)
- continue;
- }
-
- /* See if the process still exists; clean up if it doesn't. */
- if (WIFEXITED (w))
- {
- terminal_ours_for_output ();
- if (WRETCODE (w))
- printf ("\nProgram exited with code 0%o.\n", WRETCODE (w));
- else
- printf ("\nProgram exited normally.\n");
- fflush (stdout);
- inferior_died ();
-#ifdef NO_SINGLE_STEP
- one_stepped = 0; /* Clear single_step state since proc gone */
-#endif /* NO_SINGLE_STEP */
- stop_print_frame = 0;
- break;
- }
- else if (!WIFSTOPPED (w))
- {
- kill_inferior ();
- stop_print_frame = 0;
- stop_signal = WTERMSIG (w);
- terminal_ours_for_output ();
- printf ("\nProgram terminated with signal %d, %s\n",
- stop_signal,
- stop_signal < NSIG
- ? sys_siglist[stop_signal]
- : "(undocumented)");
- printf ("The inferior process no longer exists.\n");
- fflush (stdout);
-#ifdef NO_SINGLE_STEP
- one_stepped = 0; /* Clear single_step state since proc gone */
-#endif /* NO_SINGLE_STEP */
- break;
- }
-
-#ifdef NO_SINGLE_STEP
- if (one_stepped)
- single_step (0); /* This actually cleans up the ss */
-#endif /* NO_SINGLE_STEP */
-
- fetch_inferior_registers ();
- stop_pc = read_pc ();
- set_current_frame ( create_new_frame (read_register (FP_REGNUM),
- read_pc ()));
-#ifdef CONVEX_PTRACE
- /* pop frame stored by user-mode trap, if present */
- if (stop_pc == BREAK_TRAP_ADDR)
- {
- POP_FRAME;
- stop_pc = read_pc () - 2;
- write_register (PC_REGNUM, stop_pc);
-#ifdef NPC_REGNUM
- write_register (NPC_REGNUM, stop_pc + 4);
-#endif
- pc_changed = 0;
- }
- else if (stop_pc > STACK_END_ADDR)
- {
- POP_FRAME;
- stop_pc = read_pc ();
- }
-#endif /* CONVEX_PTRACE */
- stop_frame_address = FRAME_FP (get_current_frame ());
- stop_sp = read_register (SP_REGNUM);
- stop_func_start =
- get_pc_function_start (stop_pc) + FUNCTION_START_OFFSET;
- another_trap = 0;
- stop_breakpoint = 0;
- stop_step = 0;
- stop_stack_dummy = 0;
- stop_print_frame = 1;
- stop_step_resume_break = 0;
- random_signal = 0;
- stopped_by_random_signal = 0;
- breakpoints_failed = 0;
-
- /* Look at the cause of the stop, and decide what to do.
- The alternatives are:
- 1) break; to really stop and return to the debugger,
- 2) drop through to start up again
- (set another_trap to 1 to single step once)
- 3) set random_signal to 1, and the decision between 1 and 2
- will be made according to the signal handling tables. */
-
- stop_signal = WSTOPSIG (w);
-
- /* First, distinguish signals caused by the debugger from signals
- that have to do with the program's own actions.
- Note that breakpoint insns may cause SIGTRAP or SIGILL
- or SIGEMT, depending on the operating system version.
- Here we detect when a SIGILL or SIGEMT is really a breakpoint
- and change it to SIGTRAP. */
-
- if (stop_signal == SIGTRAP
-#ifndef CONVEX_PTRACE
- || (breakpoints_inserted &&
- (stop_signal == SIGILL
- || stop_signal == SIGEMT))
-#endif /* not CONVEX_PTRACE */
- || stop_after_attach)
- {
- if (stop_signal == SIGTRAP && stop_after_trap)
- {
- stop_print_frame = 0;
- break;
- }
- if (stop_after_attach)
- break;
- /* Don't even think about breakpoints
- if still running the shell that will exec the program
- or if just proceeded over a breakpoint. */
- if (stop_signal == SIGTRAP && trap_expected)
- stop_breakpoint = 0;
- else
- {
- /* See if there is a breakpoint at the current PC. */
-#if DECR_PC_AFTER_BREAK
- /* Notice the case of stepping through a jump
- that leads just after a breakpoint.
- Don't confuse that with hitting the breakpoint.
- What we check for is that 1) stepping is going on
- and 2) the pc before the last insn does not match
- the address of the breakpoint before the current pc. */
- if (!(prev_pc != stop_pc - DECR_PC_AFTER_BREAK
- && step_range_end && !step_resume_break_address))
-#endif /* DECR_PC_AFTER_BREAK not zero */
- {
- /* For condition exprs. */
- select_frame (get_current_frame (), 0);
- stop_breakpoint =
- breakpoint_stop_status (stop_pc, stop_frame_address);
- /* Following in case break condition called a
- function. */
- stop_print_frame = 1;
- if (stop_breakpoint && DECR_PC_AFTER_BREAK)
- {
- stop_pc -= DECR_PC_AFTER_BREAK;
- write_register (PC_REGNUM, stop_pc);
-#ifdef NPC_REGNUM
- write_register (NPC_REGNUM, stop_pc + 4);
-#endif
- pc_changed = 0;
- }
- }
- /* See if we stopped at the special breakpoint for
- stepping over a subroutine call. */
- if (stop_pc - DECR_PC_AFTER_BREAK
- == step_resume_break_address)
- {
- stop_step_resume_break = 1;
- if (DECR_PC_AFTER_BREAK)
- {
- stop_pc -= DECR_PC_AFTER_BREAK;
- write_register (PC_REGNUM, stop_pc);
- pc_changed = 0;
- }
- }
- }
-
- if (stop_signal == SIGTRAP)
- random_signal
- = !(stop_breakpoint || trap_expected
- || stop_step_resume_break
-#ifndef CONVEX_PTRACE
- || (stop_sp INNER_THAN stop_pc
- && stop_pc INNER_THAN stop_frame_address)
-#else
- || stop_pc == text_end - 2
-#endif
- || (step_range_end && !step_resume_break_address));
- else
- {
- random_signal
- = !(stop_breakpoint
- || stop_step_resume_break
-#ifdef news800
- || (stop_sp INNER_THAN stop_pc
- && stop_pc INNER_THAN stop_frame_address)
-#endif
-
- );
- if (!random_signal)
- stop_signal = SIGTRAP;
- }
- }
- else
- random_signal = 1;
-
- /* For the program's own signals, act according to
- the signal handling tables. */
-
- if (random_signal
- && !(running_in_shell && stop_signal == SIGSEGV))
- {
- /* Signal not for debugging purposes. */
- int printed = 0;
-
- stopped_by_random_signal = 1;
-
- if (stop_signal >= NSIG
- || signal_print[stop_signal])
- {
- printed = 1;
- terminal_ours_for_output ();
- printf ("\nProgram received signal %d, %s\n",
- stop_signal,
- stop_signal < NSIG
- ? sys_siglist[stop_signal]
- : "(undocumented)");
- fflush (stdout);
- }
- if (stop_signal >= NSIG
- || signal_stop[stop_signal])
- break;
- /* If not going to stop, give terminal back
- if we took it away. */
- else if (printed)
- terminal_inferior ();
- }
-
- /* Handle cases caused by hitting a breakpoint. */
-
- if (!random_signal
- && (stop_breakpoint || stop_step_resume_break))
- {
- /* Does a breakpoint want us to stop? */
- if (stop_breakpoint && stop_breakpoint != -1
- && stop_breakpoint != -0x1000001)
- {
- /* 0x1000000 is set in stop_breakpoint as returned by
- breakpoint_stop_status to indicate a silent
- breakpoint. */
- if ((stop_breakpoint > 0 ? stop_breakpoint :
- -stop_breakpoint)
- & 0x1000000)
- {
- stop_print_frame = 0;
- if (stop_breakpoint > 0)
- stop_breakpoint -= 0x1000000;
- else
- stop_breakpoint += 0x1000000;
- }
- break;
- }
- /* But if we have hit the step-resumption breakpoint,
- remove it. It has done its job getting us here.
- The sp test is to make sure that we don't get hung
- up in recursive calls in functions without frame
- pointers. If the stack pointer isn't outside of
- where the breakpoint was set (within a routine to be
- stepped over), we're in the middle of a recursive
- call. Not true for reg window machines (sparc)
- because the must change frames to call things and
- the stack pointer doesn't have to change if it
- the bp was set in a routine without a frame (pc can
- be stored in some other window).
-
- The removal of the sp test is to allow calls to
- alloca. Nasty things were happening. Oh, well,
- gdb can only handle one level deep of lack of
- frame pointer. */
- if (stop_step_resume_break
- && (step_frame_address == 0
- || (stop_frame_address == step_frame_address
-#if 0
-#ifndef HAVE_REGISTER_WINDOWS
- && step_resume_break_sp INNER_THAN stop_sp
-#endif
-#endif
- )))
- {
- remove_step_breakpoint ();
- step_resume_break_address = 0;
- }
- /* Otherwise, must remove breakpoints and single-step
- to get us past the one we hit. */
- else
- {
- remove_breakpoints ();
- remove_step_breakpoint ();
- breakpoints_inserted = 0;
- another_trap = 1;
- }
-
- /* We come here if we hit a breakpoint but should not
- stop for it. Possibly we also were stepping
- and should stop for that. So fall through and
- test for stepping. But, if not stepping,
- do not stop. */
- }
-
- /* If this is the breakpoint at the end of a stack dummy,
- just stop silently. */
-#ifndef CONVEX_PTRACE
- if (stop_sp INNER_THAN stop_pc
- && stop_pc INNER_THAN stop_frame_address)
-#else
- /* "stack" dummy must be in text segment for Convex Unix */
- if (stop_pc == text_end - 2)
-#endif
- {
- stop_print_frame = 0;
- stop_stack_dummy = 1;
-#ifdef HP9K320
- trap_expected_after_continue = 1;
-#endif
- break;
- }
-
- if (step_resume_break_address)
- /* Having a step-resume breakpoint overrides anything
- else having to do with stepping commands until
- that breakpoint is reached. */
- ;
- /* If stepping through a line, keep going if still within it. */
- else if (!random_signal
- && step_range_end
- && stop_pc >= step_range_start
- && stop_pc < step_range_end
- /* The step range might include the start of the
- function, so if we are at the start of the
- step range and either the stack or frame pointers
- just changed, we've stepped outside */
- && !(stop_pc == step_range_start
- && stop_frame_address
- && (stop_sp != prev_sp
- || stop_frame_address != step_frame_address)))
- {
- /* Don't step through the return from a function
- unless that is the first instruction stepped through. */
- if (ABOUT_TO_RETURN (stop_pc))
- {
- stop_step = 1;
- break;
- }
- }
-
- /* We stepped out of the stepping range. See if that was due
- to a subroutine call that we should proceed to the end of. */
- else if (!random_signal && step_range_end)
- {
- if (stop_func_start)
- {
- prologue_pc = stop_func_start;
- SKIP_PROLOGUE (prologue_pc);
- }
-
- /* ==> See comments at top of file on this algorithm. <==*/
-
- if (stop_pc == stop_func_start
- && (stop_func_start != prev_func_start
- || prologue_pc != stop_func_start
- || stop_sp != prev_sp))
- {
- newfun = find_pc_function (stop_pc);
- /* It's a subroutine call */
- if (step_over_calls > 0 || (step_over_calls && newfun == 0))
- {
- /* A subroutine call has happened. */
- /* Set a special breakpoint after the return */
- step_resume_break_address =
- SAVED_PC_AFTER_CALL (get_current_frame ());
- step_resume_break_duplicate
- = breakpoint_here_p (step_resume_break_address);
- step_resume_break_sp = stop_sp;
- if (breakpoints_inserted)
- insert_step_breakpoint ();
- }
- /* Subroutine call with source code we should not step over.
- Do step to the first line of code in it. */
- else if (step_over_calls)
- {
- SKIP_PROLOGUE (stop_func_start);
- sal = find_pc_line (stop_func_start, 0);
- /* Use the step_resume_break to step until
- the end of the prologue, even if that involves jumps
- (as it seems to on the vax under 4.2). */
- /* If the prologue ends in the middle of a source line,
- continue to the end of that source line.
- Otherwise, just go to end of prologue. */
-#ifdef convex
- /* no, don't either. It skips any code that's
- legitimately on the first line. */
-#else
- if (sal.end && sal.pc != stop_func_start)
- stop_func_start = sal.end;
-#endif
-
- if (stop_func_start == stop_pc)
- {
- /* We are already there: stop now. */
- stop_step = 1;
- break;
- }
- else
- /* Put the step-breakpoint there and go until there. */
- {
- step_resume_break_address = stop_func_start;
- step_resume_break_sp = stop_sp;
-
- step_resume_break_duplicate
- = breakpoint_here_p (step_resume_break_address);
- if (breakpoints_inserted)
- insert_step_breakpoint ();
- /* Do not specify what the fp should be when we stop
- since on some machines the prologue
- is where the new fp value is established. */
- step_frame_address = 0;
- /* And make sure stepping stops right away then. */
- step_range_end = step_range_start;
- }
- }
- else
- {
- /* We get here only if step_over_calls is 0 and we
- just stepped into a subroutine. I presume
- that step_over_calls is only 0 when we're
- supposed to be stepping at the assembly
- language level.*/
- stop_step = 1;
- break;
- }
- }
- /* No subroutince call; stop now. */
- else
- {
- stop_step = 1;
- break;
- }
- }
-
- /* Save the pc before execution, to compare with pc after stop. */
- prev_pc = read_pc (); /* Might have been DECR_AFTER_BREAK */
- prev_func_start = stop_func_start; /* Ok, since if DECR_PC_AFTER
- BREAK is defined, the
- original pc would not have
- been at the start of a
- function. */
- prev_sp = stop_sp;
-
- /* If we did not do break;, it means we should keep
- running the inferior and not return to debugger. */
-
- /* If trap_expected is 2, it means continue once more
- and insert breakpoints at the next trap.
- If trap_expected is 1 and the signal was SIGSEGV, it means
- the shell is doing some memory allocation--just resume it
- with SIGSEGV.
- Otherwise insert breakpoints now, and possibly single step. */
-
- if (trap_expected > 1)
- {
- trap_expected--;
- running_in_shell = 1;
- resume (0, 0);
- }
- else if (running_in_shell && stop_signal == SIGSEGV)
- {
- resume (0, SIGSEGV);
- }
- else
- {
- /* Here, we are not awaiting another exec to get
- the program we really want to debug.
- Insert breakpoints now, unless we are trying
- to one-proceed past a breakpoint. */
- running_in_shell = 0;
- if (!breakpoints_inserted && !another_trap)
- {
- insert_step_breakpoint ();
- breakpoints_failed = insert_breakpoints ();
- if (breakpoints_failed)
- break;
- breakpoints_inserted = 1;
- }
-
- trap_expected = another_trap;
-
- if (stop_signal == SIGTRAP)
- stop_signal = 0;
-
- resume ((step_range_end && !step_resume_break_address)
- || trap_expected,
- stop_signal);
- }
- }
-}
-
-/* Here to return control to GDB when the inferior stops for real.
- Print appropriate messages, remove breakpoints, give terminal our modes.
-
- RUNNING_IN_SHELL nonzero means the shell got a signal before
- exec'ing the program we wanted to run.
- STOP_PRINT_FRAME nonzero means print the executing frame
- (pc, function, args, file, line number and line text).
- BREAKPOINTS_FAILED nonzero means stop was due to error
- attempting to insert breakpoints. */
-
-/* FIXME, normal_stop is ALWAYS called immediately after wait_for_inferior.
- They should probably be merged into a single function, since that
- would avoid numerous tests (e.g. of inferior_pid). */
-
-static void
-normal_stop ()
-{
- /* Make sure that the current_frame's pc is correct. This
- is a correction for setting up the frame info before doing
- DECR_PC_AFTER_BREAK */
- if (inferior_pid)
- (get_current_frame ())->pc = read_pc ();
-
- if (breakpoints_failed)
- {
- terminal_ours_for_output ();
- print_sys_errmsg ("ptrace", breakpoints_failed);
- printf ("Stopped; cannot insert breakpoints.\n\
-The same program may be running in another process.\n");
- }
-
- if (inferior_pid)
- remove_step_breakpoint ();
-
- if (inferior_pid && breakpoints_inserted)
- if (remove_breakpoints ())
- {
- terminal_ours_for_output ();
- printf ("Cannot remove breakpoints because program is no longer writable.\n\
-It must be running in another process.\n\
-Further execution is probably impossible.\n");
- }
-
- breakpoints_inserted = 0;
-
- /* Delete the breakpoint we stopped at, if it wants to be deleted.
- Delete any breakpoint that is to be deleted at the next stop. */
-
- breakpoint_auto_delete (stop_breakpoint);
-
- /* If an auto-display called a function and that got a signal,
- delete that auto-display to avoid an infinite recursion. */
-
- if (stopped_by_random_signal)
- delete_current_display ();
-
- if (step_multi && stop_step)
- return;
-
- terminal_ours ();
-
- if (running_in_shell)
- {
- if (stop_signal == SIGSEGV)
- {
- char *exec_file = (char *) get_exec_file (1);
-
- if (access (exec_file, X_OK) != 0)
- printf ("The file \"%s\" is not executable.\n", exec_file);
- else
- printf ("\
-You have just encountered a bug in \"sh\". GDB starts your program\n\
-by running \"sh\" with a command to exec your program.\n\
-This is so that \"sh\" will process wildcards and I/O redirection.\n\
-This time, \"sh\" crashed.\n\
-\n\
-One known bug in \"sh\" bites when the environment takes up a lot of space.\n\
-Try \"info env\" to see the environment; then use \"unset-env\" to kill\n\
-some variables whose values are large; then do \"run\" again.\n\
-\n\
-If that works, you might want to put those \"unset-env\" commands\n\
-into a \".gdbinit\" file in this directory so they will happen every time.\n");
- }
- /* Don't confuse user with his program's symbols on sh's data. */
- stop_print_frame = 0;
- }
-
- if (inferior_pid == 0)
- return;
-
- /* Select innermost stack frame except on return from a stack dummy routine,
- or if the program has exited. */
- if (!stop_stack_dummy)
- {
- select_frame (get_current_frame (), 0);
-
- if (stop_print_frame)
- {
- if (stop_breakpoint > 0)
- printf ("\nBpt %d, ", stop_breakpoint);
- print_sel_frame (stop_step
- && step_frame_address == stop_frame_address
- && step_start_function == find_pc_function (stop_pc));
- /* Display the auto-display expressions. */
- do_displays ();
- }
- }
-
- /* Save the function value return registers
- We might be about to restore their previous contents. */
- read_register_bytes (0, stop_registers, REGISTER_BYTES);
-
- if (stop_stack_dummy)
- {
- /* Pop the empty frame that contains the stack dummy.
- POP_FRAME ends with a setting of the current frame, so we
- can use that next. */
- POP_FRAME;
- select_frame (get_current_frame (), 0);
- }
-}
-
-static void
-insert_step_breakpoint ()
-{
- if (step_resume_break_address && !step_resume_break_duplicate)
- {
- read_memory (step_resume_break_address,
- step_resume_break_shadow, sizeof break_insn);
- write_memory (step_resume_break_address,
- break_insn, sizeof break_insn);
- }
-}
-
-static void
-remove_step_breakpoint ()
-{
- if (step_resume_break_address && !step_resume_break_duplicate)
- write_memory (step_resume_break_address, step_resume_break_shadow,
- sizeof break_insn);
-}
-
-/* Specify how various signals in the inferior should be handled. */
-
-static void
-handle_command (args, from_tty)
- char *args;
- int from_tty;
-{
- register char *p = args;
- int signum = 0;
- register int digits, wordlen;
-
- if (!args)
- error_no_arg ("signal to handle");
-
- while (*p)
- {
- /* Find the end of the next word in the args. */
- for (wordlen = 0; p[wordlen] && p[wordlen] != ' ' && p[wordlen] != '\t';
- wordlen++);
- for (digits = 0; p[digits] >= '0' && p[digits] <= '9'; digits++);
-
- /* If it is all digits, it is signal number to operate on. */
- if (digits == wordlen)
- {
- signum = atoi (p);
- if (signum <= 0 || signum >= NSIG)
- {
- p[wordlen] = '\0';
- error ("Invalid signal %s given as argument to \"handle\".", p);
- }
- if (signum == SIGTRAP || signum == SIGINT)
- {
- if (!query ("Signal %d is used by the debugger.\nAre you sure you want to change it? ", signum))
- error ("Not confirmed.");
- }
- }
- else if (signum == 0)
- error ("First argument is not a signal number.");
-
- /* Else, if already got a signal number, look for flag words
- saying what to do for it. */
- else if (!strncmp (p, "stop", wordlen))
- {
- signal_stop[signum] = 1;
- signal_print[signum] = 1;
- }
- else if (wordlen >= 2 && !strncmp (p, "print", wordlen))
- signal_print[signum] = 1;
- else if (wordlen >= 2 && !strncmp (p, "pass", wordlen))
- signal_program[signum] = 1;
- else if (!strncmp (p, "ignore", wordlen))
- signal_program[signum] = 0;
- else if (wordlen >= 3 && !strncmp (p, "nostop", wordlen))
- signal_stop[signum] = 0;
- else if (wordlen >= 4 && !strncmp (p, "noprint", wordlen))
- {
- signal_print[signum] = 0;
- signal_stop[signum] = 0;
- }
- else if (wordlen >= 4 && !strncmp (p, "nopass", wordlen))
- signal_program[signum] = 0;
- else if (wordlen >= 3 && !strncmp (p, "noignore", wordlen))
- signal_program[signum] = 1;
- /* Not a number and not a recognized flag word => complain. */
- else
- {
- p[wordlen] = 0;
- error ("Unrecognized flag word: \"%s\".", p);
- }
-
- /* Find start of next word. */
- p += wordlen;
- while (*p == ' ' || *p == '\t') p++;
- }
-
- if (from_tty)
- {
- /* Show the results. */
- printf ("Number\tStop\tPrint\tPass to program\tDescription\n");
- printf ("%d\t", signum);
- printf ("%s\t", signal_stop[signum] ? "Yes" : "No");
- printf ("%s\t", signal_print[signum] ? "Yes" : "No");
- printf ("%s\t\t", signal_program[signum] ? "Yes" : "No");
- printf ("%s\n", sys_siglist[signum]);
- }
-}
-
-/* Print current contents of the tables set by the handle command. */
-
-static void
-signals_info (signum_exp)
- char *signum_exp;
-{
- register int i;
- printf ("Number\tStop\tPrint\tPass to program\tDescription\n");
-
- if (signum_exp)
- {
- i = parse_and_eval_address (signum_exp);
- printf ("%d\t", i);
- printf ("%s\t", signal_stop[i] ? "Yes" : "No");
- printf ("%s\t", signal_print[i] ? "Yes" : "No");
- printf ("%s\t\t", signal_program[i] ? "Yes" : "No");
- printf ("%s\n", sys_siglist[i]);
- return;
- }
-
- printf ("\n");
- for (i = 0; i < NSIG; i++)
- {
- QUIT;
- if (i > 0 && i % 16 == 0)
- {
- printf ("[Type Return to see more]");
- fflush (stdout);
- gdb_read_line (0, 0);
- }
- printf ("%d\t", i);
- printf ("%s\t", signal_stop[i] ? "Yes" : "No");
- printf ("%s\t", signal_print[i] ? "Yes" : "No");
- printf ("%s\t\t", signal_program[i] ? "Yes" : "No");
- printf ("%s\n", sys_siglist[i]);
- }
-
- printf ("\nUse the \"handle\" command to change these tables.\n");
-}
-
-/* Save all of the information associated with the inferior<==>gdb
- connection. INF_STATUS is a pointer to a "struct inferior_status"
- (defined in inferior.h). */
-
-struct command_line *get_breakpoint_commands ();
-
-void
-save_inferior_status (inf_status, restore_stack_info)
- struct inferior_status *inf_status;
- int restore_stack_info;
-{
- inf_status->pc_changed = pc_changed;
- inf_status->stop_signal = stop_signal;
- inf_status->stop_pc = stop_pc;
- inf_status->stop_frame_address = stop_frame_address;
- inf_status->stop_breakpoint = stop_breakpoint;
- inf_status->stop_step = stop_step;
- inf_status->stop_stack_dummy = stop_stack_dummy;
- inf_status->stopped_by_random_signal = stopped_by_random_signal;
- inf_status->trap_expected = trap_expected;
- inf_status->step_range_start = step_range_start;
- inf_status->step_range_end = step_range_end;
- inf_status->step_frame_address = step_frame_address;
- inf_status->step_over_calls = step_over_calls;
- inf_status->step_resume_break_address = step_resume_break_address;
- inf_status->stop_after_trap = stop_after_trap;
- inf_status->stop_after_attach = stop_after_attach;
- inf_status->breakpoint_commands = get_breakpoint_commands ();
- inf_status->restore_stack_info = restore_stack_info;
-
- bcopy (stop_registers, inf_status->stop_registers, REGISTER_BYTES);
-
- record_selected_frame (&(inf_status->selected_frame_address),
- &(inf_status->selected_level));
- return;
-}
-
-void
-restore_inferior_status (inf_status)
- struct inferior_status *inf_status;
-{
- FRAME fid;
- int level = inf_status->selected_level;
-
- pc_changed = inf_status->pc_changed;
- stop_signal = inf_status->stop_signal;
- stop_pc = inf_status->stop_pc;
- stop_frame_address = inf_status->stop_frame_address;
- stop_breakpoint = inf_status->stop_breakpoint;
- stop_step = inf_status->stop_step;
- stop_stack_dummy = inf_status->stop_stack_dummy;
- stopped_by_random_signal = inf_status->stopped_by_random_signal;
- trap_expected = inf_status->trap_expected;
- step_range_start = inf_status->step_range_start;
- step_range_end = inf_status->step_range_end;
- step_frame_address = inf_status->step_frame_address;
- step_over_calls = inf_status->step_over_calls;
- step_resume_break_address = inf_status->step_resume_break_address;
- stop_after_trap = inf_status->stop_after_trap;
- stop_after_attach = inf_status->stop_after_attach;
- set_breakpoint_commands (inf_status->breakpoint_commands);
-
- bcopy (inf_status->stop_registers, stop_registers, REGISTER_BYTES);
-
- if (inf_status->restore_stack_info)
- {
- fid = find_relative_frame (get_current_frame (),
- &level);
-
- if (FRAME_FP (fid) != inf_status->selected_frame_address ||
- level != 0)
- {
- fprintf (stderr, "Unable to restore previously selected frame.\n");
- select_frame (get_current_frame (), 0);
- return;
- }
-
- select_frame (fid, inf_status->selected_level);
- }
- return;
-}
-
-
-void
-_initialize_infrun ()
-{
- register int i;
-
- add_info ("signals", signals_info,
- "What debugger does when program gets various signals.\n\
-Specify a signal number as argument to print info on that signal only.");
-
- add_com ("handle", class_run, handle_command,
- "Specify how to handle a signal.\n\
-Args are signal number followed by flags.\n\
-Flags allowed are \"stop\", \"print\", \"pass\",\n\
- \"nostop\", \"noprint\" or \"nopass\".\n\
-Print means print a message if this signal happens.\n\
-Stop means reenter debugger if this signal happens (implies print).\n\
-Pass means let program see this signal; otherwise program doesn't know.\n\
-Pass and Stop may be combined.");
-
- for (i = 0; i < NSIG; i++)
- {
- signal_stop[i] = 1;
- signal_print[i] = 1;
- signal_program[i] = 1;
- }
-
- /* Signals caused by debugger's own actions
- should not be given to the program afterwards. */
- signal_program[SIGTRAP] = 0;
- signal_program[SIGINT] = 0;
-
- /* Signals that are not errors should not normally enter the debugger. */
-#ifdef SIGALRM
- signal_stop[SIGALRM] = 0;
- signal_print[SIGALRM] = 0;
-#endif /* SIGALRM */
-#ifdef SIGVTALRM
- signal_stop[SIGVTALRM] = 0;
- signal_print[SIGVTALRM] = 0;
-#endif /* SIGVTALRM */
-#ifdef SIGPROF
- signal_stop[SIGPROF] = 0;
- signal_print[SIGPROF] = 0;
-#endif /* SIGPROF */
-#ifdef SIGCHLD
- signal_stop[SIGCHLD] = 0;
- signal_print[SIGCHLD] = 0;
-#endif /* SIGCHLD */
-#ifdef SIGCLD
- signal_stop[SIGCLD] = 0;
- signal_print[SIGCLD] = 0;
-#endif /* SIGCLD */
-#ifdef SIGIO
- signal_stop[SIGIO] = 0;
- signal_print[SIGIO] = 0;
-#endif /* SIGIO */
-#ifdef SIGURG
- signal_stop[SIGURG] = 0;
- signal_print[SIGURG] = 0;
-#endif /* SIGURG */
-}
-
-@
-
-
-1.2
-log
-@Avoid accessing inferior process if it just exited or terminated with
-a signal. Clean up stack frame stuff in that case too, so that the
-various stack commands ("i frame", "up", "frame", "where") don't get
-confused.
-@
-text
-@d137 5
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d472 4
-d485 35
-a524 2
- pc_changed = 0;
- flush_cached_frames ();
-d569 1
-a569 30
- if (WIFEXITED (w))
- {
- terminal_ours_for_output ();
- if (WRETCODE (w))
- printf ("\nProgram exited with code 0%o.\n", WRETCODE (w));
- else
- printf ("\nProgram exited normally.\n");
- fflush (stdout);
- inferior_died ();
- stop_print_frame = 0;
- break;
- }
- else if (!WIFSTOPPED (w))
- {
- kill_inferior ();
- stop_print_frame = 0;
- stop_signal = WTERMSIG (w);
- terminal_ours_for_output ();
- printf ("\nProgram terminated with signal %d, %s\n",
- stop_signal,
- stop_signal < NSIG
- ? sys_siglist[stop_signal]
- : "(undocumented)");
- printf ("The inferior process no longer exists.\n");
- fflush (stdout);
- break;
- }
- else
- {
- stop_signal = WSTOPSIG (w);
-d571 6
-a576 6
- /* First, distinguish signals caused by the debugger from signals
- that have to do with the program's own actions.
- Note that breakpoint insns may cause SIGTRAP or SIGILL
- or SIGEMT, depending on the operating system version.
- Here we detect when a SIGILL or SIGEMT is really a breakpoint
- and change it to SIGTRAP. */
-d578 1
-a578 1
- if (stop_signal == SIGTRAP
-d580 3
-a582 3
- || (breakpoints_inserted &&
- (stop_signal == SIGILL
- || stop_signal == SIGEMT))
-d584 15
-a598 1
- || stop_after_attach)
-d600 1
-a600 15
- if (stop_signal == SIGTRAP && stop_after_trap)
- {
- stop_print_frame = 0;
- break;
- }
- if (stop_after_attach)
- break;
- /* Don't even think about breakpoints
- if still running the shell that will exec the program
- or if just proceeded over a breakpoint. */
- if (stop_signal == SIGTRAP && trap_expected)
- stop_breakpoint = 0;
- else
- {
- /* See if there is a breakpoint at the current PC. */
-d602 8
-a609 8
- /* Notice the case of stepping through a jump
- that leads just after a breakpoint.
- Don't confuse that with hitting the breakpoint.
- What we check for is that 1) stepping is going on
- and 2) the pc before the last insn does not match
- the address of the breakpoint before the current pc. */
- if (!(prev_pc != stop_pc - DECR_PC_AFTER_BREAK
- && step_range_end && !step_resume_break_address))
-d611 9
-d621 2
-a622 11
- /* For condition exprs. */
- select_frame (get_current_frame (), 0);
- stop_breakpoint =
- breakpoint_stop_status (stop_pc, stop_frame_address);
- /* Following in case break condition called a
- function. */
- stop_print_frame = 1;
- if (stop_breakpoint && DECR_PC_AFTER_BREAK)
- {
- stop_pc -= DECR_PC_AFTER_BREAK;
- write_register (PC_REGNUM, stop_pc);
-d624 1
-a624 1
- write_register (NPC_REGNUM, stop_pc + 4);
-d626 1
-a626 2
- pc_changed = 0;
- }
-d628 12
-a639 12
- /* See if we stopped at the special breakpoint for
- stepping over a subroutine call. */
- if (stop_pc - DECR_PC_AFTER_BREAK
- == step_resume_break_address)
- {
- stop_step_resume_break = 1;
- if (DECR_PC_AFTER_BREAK)
- {
- stop_pc -= DECR_PC_AFTER_BREAK;
- write_register (PC_REGNUM, stop_pc);
- pc_changed = 0;
- }
-d642 1
-d644 4
-a647 4
- if (stop_signal == SIGTRAP)
- random_signal
- = !(stop_breakpoint || trap_expected
- || stop_step_resume_break
-d649 2
-a650 2
- || (stop_sp INNER_THAN stop_pc
- && stop_pc INNER_THAN stop_frame_address)
-d652 1
-a652 1
- || stop_pc == text_end - 2
-d654 6
-a659 6
- || (step_range_end && !step_resume_break_address));
- else
- {
- random_signal
- = !(stop_breakpoint
- || stop_step_resume_break
-d661 2
-a662 2
- || (stop_sp INNER_THAN stop_pc
- && stop_pc INNER_THAN stop_frame_address)
-d665 3
-a667 4
- );
- if (!random_signal)
- stop_signal = SIGTRAP;
- }
-d669 3
-a671 2
- else
- random_signal = 1;
-d673 2
-a674 2
- /* For the program's own signals, act according to
- the signal handling tables. */
-d676 50
-a725 19
- if (random_signal
- && !(running_in_shell && stop_signal == SIGSEGV))
- {
- /* Signal not for debugging purposes. */
- int printed = 0;
-
- stopped_by_random_signal = 1;
-
- if (stop_signal >= NSIG
- || signal_print[stop_signal])
- {
- printed = 1;
- terminal_ours_for_output ();
- printf ("\nProgram received signal %d, %s\n",
- stop_signal,
- stop_signal < NSIG
- ? sys_siglist[stop_signal]
- : "(undocumented)");
- fflush (stdout);
-d727 1
-a727 7
- if (stop_signal >= NSIG
- || signal_stop[stop_signal])
- break;
- /* If not going to stop, give terminal back
- if we took it away. */
- else if (printed)
- terminal_inferior ();
-d729 20
-a748 45
-
- /* Handle cases caused by hitting a breakpoint. */
-
- if (!random_signal
- && (stop_breakpoint || stop_step_resume_break))
- {
- /* Does a breakpoint want us to stop? */
- if (stop_breakpoint && stop_breakpoint != -1
- && stop_breakpoint != -0x1000001)
- {
- /* 0x1000000 is set in stop_breakpoint as returned by
- breakpoint_stop_status to indicate a silent
- breakpoint. */
- if ((stop_breakpoint > 0 ? stop_breakpoint :
- -stop_breakpoint)
- & 0x1000000)
- {
- stop_print_frame = 0;
- if (stop_breakpoint > 0)
- stop_breakpoint -= 0x1000000;
- else
- stop_breakpoint += 0x1000000;
- }
- break;
- }
- /* But if we have hit the step-resumption breakpoint,
- remove it. It has done its job getting us here.
- The sp test is to make sure that we don't get hung
- up in recursive calls in functions without frame
- pointers. If the stack pointer isn't outside of
- where the breakpoint was set (within a routine to be
- stepped over), we're in the middle of a recursive
- call. Not true for reg window machines (sparc)
- because the must change frames to call things and
- the stack pointer doesn't have to change if it
- the bp was set in a routine without a frame (pc can
- be stored in some other window).
-
- The removal of the sp test is to allow calls to
- alloca. Nasty things were happening. Oh, well,
- gdb can only handle one level deep of lack of
- frame pointer. */
- if (stop_step_resume_break
- && (step_frame_address == 0
- || (stop_frame_address == step_frame_address
-d751 1
-a751 1
- && step_resume_break_sp INNER_THAN stop_sp
-d754 13
-a766 20
- )))
- {
- remove_step_breakpoint ();
- step_resume_break_address = 0;
- }
- /* Otherwise, must remove breakpoints and single-step
- to get us past the one we hit. */
- else
- {
- remove_breakpoints ();
- remove_step_breakpoint ();
- breakpoints_inserted = 0;
- another_trap = 1;
- }
-
- /* We come here if we hit a breakpoint but should not
- stop for it. Possibly we also were stepping
- and should stop for that. So fall through and
- test for stepping. But, if not stepping,
- do not stop. */
-d769 9
-a777 2
- /* If this is the breakpoint at the end of a stack dummy,
- just stop silently. */
-d779 2
-a780 2
- if (stop_sp INNER_THAN stop_pc
- && stop_pc INNER_THAN stop_frame_address)
-d782 2
-a783 2
- /* "stack" dummy must be in text segment for Convex Unix */
- if (stop_pc == text_end - 2)
-d785 3
-a787 3
- {
- stop_print_frame = 0;
- stop_stack_dummy = 1;
-d789 1
-a789 1
- trap_expected_after_continue = 1;
-d791 2
-a792 2
- break;
- }
-d794 22
-a815 18
- if (step_resume_break_address)
- /* Having a step-resume breakpoint overrides anything
- else having to do with stepping commands until
- that breakpoint is reached. */
- ;
- /* If stepping through a line, keep going if still within it. */
- else if (!random_signal
- && step_range_end
- && stop_pc >= step_range_start
- && stop_pc < step_range_end
- /* The step range might include the start of the
- function, so if we are at the start of the
- step range and either the stack or frame pointers
- just changed, we've stepped outside */
- && !(stop_pc == step_range_start
- && stop_frame_address
- && (stop_sp != prev_sp
- || stop_frame_address != step_frame_address)))
-d817 2
-a818 7
- /* Don't step through the return from a function
- unless that is the first instruction stepped through. */
- if (ABOUT_TO_RETURN (stop_pc))
- {
- stop_step = 1;
- break;
- }
-d820 1
-d822 43
-a864 43
- /* We stepped out of the stepping range. See if that was due
- to a subroutine call that we should proceed to the end of. */
- else if (!random_signal && step_range_end)
- {
- if (stop_func_start)
- {
- prologue_pc = stop_func_start;
- SKIP_PROLOGUE (prologue_pc);
- }
-
- /* ==> See comments at top of file on this algorithm. <==*/
-
- if (stop_pc == stop_func_start
- && (stop_func_start != prev_func_start
- || prologue_pc != stop_func_start
- || stop_sp != prev_sp))
- {
- newfun = find_pc_function (stop_pc);
- /* It's a subroutine call */
- if (step_over_calls > 0 || (step_over_calls && newfun == 0))
- {
- /* A subroutine call has happened. */
- /* Set a special breakpoint after the return */
- step_resume_break_address =
- SAVED_PC_AFTER_CALL (get_current_frame ());
- step_resume_break_duplicate
- = breakpoint_here_p (step_resume_break_address);
- step_resume_break_sp = stop_sp;
- if (breakpoints_inserted)
- insert_step_breakpoint ();
- }
- /* Subroutine call with source code we should not step over.
- Do step to the first line of code in it. */
- else if (step_over_calls)
- {
- SKIP_PROLOGUE (stop_func_start);
- sal = find_pc_line (stop_func_start, 0);
- /* Use the step_resume_break to step until
- the end of the prologue, even if that involves jumps
- (as it seems to on the vax under 4.2). */
- /* If the prologue ends in the middle of a source line,
- continue to the end of that source line.
- Otherwise, just go to end of prologue. */
-d866 2
-a867 2
- /* no, don't either. It skips any code that's
- legitimately on the first line. */
-d869 2
-a870 2
- if (sal.end && sal.pc != stop_func_start)
- stop_func_start = sal.end;
-d872 6
-a877 24
-
- if (stop_func_start == stop_pc)
- {
- /* We are already there: stop now. */
- stop_step = 1;
- break;
- }
- else
- /* Put the step-breakpoint there and go until there. */
- {
- step_resume_break_address = stop_func_start;
- step_resume_break_sp = stop_sp;
-
- step_resume_break_duplicate
- = breakpoint_here_p (step_resume_break_address);
- if (breakpoints_inserted)
- insert_step_breakpoint ();
- /* Do not specify what the fp should be when we stop
- since on some machines the prologue
- is where the new fp value is established. */
- step_frame_address = 0;
- /* And make sure stepping stops right away then. */
- step_range_end = step_range_start;
- }
-d880 1
-d882 13
-a894 7
- /* We get here only if step_over_calls is 0 and we
- just stepped into a subroutine. I presume
- that step_over_calls is only 0 when we're
- supposed to be stepping at the assembly
- language level.*/
- stop_step = 1;
- break;
-a896 1
- /* No subroutince call; stop now. */
-d899 5
-d908 6
-d983 4
-d993 2
-a994 1
- (get_current_frame ())->pc = read_pc ();
-@
diff --git a/gdb/RCS/m-aux.h,v b/gdb/RCS/m-aux.h,v
deleted file mode 100644
index 2bf0702..0000000
--- a/gdb/RCS/m-aux.h,v
+++ /dev/null
@@ -1,591 +0,0 @@
-head 1.4;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.4
-date 89.04.26.00.51.42; author gnu; state Exp;
-branches ;
-next 1.3;
-
-1.3
-date 89.03.27.20.16.05; author gnu; state Exp;
-branches ;
-next 1.2;
-
-1.2
-date 89.03.26.20.13.28; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.03.13.19.16.52; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.4
-log
-@(1) Defined the big-endianness of the target machine.
-(2) Define float to be IEEE compatible.
-(3) Define invalid floats to be NaNs.
-@
-text
-@/* Parameters for execution on A/UX, for GDB, the GNU debugger.
- Copyright (C) 1989 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#ifndef aux
-#define aux
-#endif
-
-/* It's a USG system */
-#define USG
-
-/* Assembler instructions in USG "SGS" (sw generation system) format */
-#define USG_SGS_ASM
-
-/* Debugger information will be in COFF format. */
-#define COFF_FORMAT
-#define COFF_NO_LONG_FILE_NAMES
-
-/* Terminal interface via termio */
-#define HAVE_TERMIO
-
-/* Unisoft fucked up the include files */
-#define UNISOFT_ASSHOLES
-
-/* Big or Little-Endian target machine
- BITS: defined if bit #0 is the high-order bit of a byte.
- BYTES:defined if byte#0 is the high-order byte of an int.
- WORDS:defined if word#0 is the high-order word of a double. */
-#define BITS_BIG_ENDIAN
-#define BYTES_BIG_ENDIAN
-#define WORDS_BIG_ENDIAN
-
-/* Floating point is IEEE compatible */
-#define IEEE_FLOAT
-
-/* Offset from address of function to start of its code.
- Zero on most machines. */
-
-#define FUNCTION_START_OFFSET 0
-
-/* Advance PC across any function entry prologue instructions
- to reach some "real" code. */
-
-#define SKIP_PROLOGUE(pc) \
-{ register int op = read_memory_integer (pc, 2); \
- if (op == 0047126) \
- pc += 4; /* Skip link #word */ \
- else if (op == 0044016) \
- pc += 6; /* Skip link #long */ \
-}
-
-/* Immediately after a function call, return the saved pc.
- Can't go through the frames for this because on some machines
- the new frame is not set up until the new function executes
- some instructions. */
-
-#define SAVED_PC_AFTER_CALL(frame) \
-read_memory_integer (read_register (SP_REGNUM), 4)
-
-/* Address of end of stack space. */
-
-#define STACK_END_ADDR 0x20000000
-
-/* Stack grows downward. */
-
-#define INNER_THAN <
-
-/* Sequence of bytes for breakpoint instruction. */
-/* A/UX uses "trap &1" */
-
-#define BREAKPOINT {0x4e, 0x41}
-
-/* Amount PC must be decremented by after a breakpoint.
- This is often the number of bytes in BREAKPOINT
- but not always. */
-
-#define DECR_PC_AFTER_BREAK 0
-
-/* Nonzero if instruction at PC is a return instruction. */
-
-#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e75)
-
-/* Return 1 if P points to an invalid floating point value. */
-/* FIXME, it's not clear what "invalid" means here. I take it to mean
- "something that coredumps gdb if gdb tries to manipulate it" */
-
-#define INVALID_FLOAT(p, len) is_nan(p, len)
-
-/* Largest integer type */
-#define LONGEST long
-
-/* Name of the builtin type for the LONGEST type above. */
-#define BUILTIN_TYPE_LONGEST builtin_type_long
-
-/* Say how long (ordinary) registers are. */
-
-#define REGISTER_TYPE long
-
-/* Number of machine registers */
-
-#define NUM_REGS 29
-
-/* Initializer for an array of names of registers.
- There should be NUM_REGS strings in this initializer. */
-
-#define REGISTER_NAMES \
- {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
- "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \
- "ps", "pc", \
- "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", \
- "fpcontrol", "fpstatus", "fpiaddr" }
-
-/* Register numbers of various important registers.
- Note that some of these values are "real" register numbers,
- and correspond to the general registers of the machine,
- and some are "phony" register numbers which are too large
- to be actual register numbers as far as the user is concerned
- but do serve to get the desired values when passed to read_register. */
-
-#define FP_REGNUM 14 /* Contains address of executing stack frame */
-#define SP_REGNUM 15 /* Contains address of top of stack */
-#define PS_REGNUM 16 /* Contains processor status */
-#define PC_REGNUM 17 /* Contains program counter */
-#define FP0_REGNUM 18 /* Floating point register 0 */
-#define FPC_REGNUM 26 /* 68881 control register */
-
-/* This is a piece of magic that is given a register number REGNO
- and as BLOCKEND the address in the system of the end of the user structure
- and stores in ADDR the address in the kernel or core dump
- of that register. */
-
-#define REGISTER_U_ADDR(addr, blockend, regno) { \
- struct user u; \
- if (regno <= SP_REGNUM) \
- addr = blockend + regno * 4; \
- else if (regno == PS_REGNUM) \
- addr = blockend + RPS * 4; /* From reg.h */ \
- else if (regno == PC_REGNUM) \
- addr = blockend + PC * 4; /* From reg.h */ \
- else if (regno < FPC_REGNUM) \
- addr = (char *) u.u_fpdreg [regno-FP0_REGNUM] - (char *)&u; \
- else \
- addr = (char *)&u.u_fpsysreg[regno-FPC_REGNUM] - (char *)&u; \
-}
-
-/* Describe the pointer in each stack frame to the previous stack frame
- (its caller). */
-/* Total amount of space needed to store our copies of the machine's
- register state, the array `registers'. */
-#define REGISTER_BYTES (16*4+8*12+8+20)
-
-/* Index within `registers' of the first byte of the space for
- register N. */
-
-#define REGISTER_BYTE(N) \
- ((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 168 \
- : (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 12) + 72 \
- : (N) * 4)
-
-/* Number of bytes of storage in the actual machine representation
- for register N. On the 68000, all regs are 4 bytes
- except the floating point regs which are 12 bytes. */
-/* Note that the unsigned cast here forces the result of the
- subtractiion to very high positive values if N < FP0_REGNUM */
-
-#define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 12 : 4)
-
-/* Number of bytes of storage in the program's representation
- for register N. On the 68000, all regs are 4 bytes
- except the floating point regs which are 8-byte doubles. */
-
-#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 8 : 4)
-
-/* Largest value REGISTER_RAW_SIZE can have. */
-
-#define MAX_REGISTER_RAW_SIZE 12
-
-/* Largest value REGISTER_VIRTUAL_SIZE can have. */
-
-#define MAX_REGISTER_VIRTUAL_SIZE 8
-
-/* Nonzero if register N requires conversion
- from raw format to virtual format. */
-
-#define REGISTER_CONVERTIBLE(N) (((unsigned)(N) - FP0_REGNUM) < 8)
-
-/* Convert data from raw format for register REGNUM
- to virtual format for register REGNUM. */
-
-#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
-{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
- convert_from_68881 ((FROM), (TO)); \
- else \
- bcopy ((FROM), (TO), 4); }
-
-/* Convert data from virtual format for register REGNUM
- to raw format for register REGNUM. */
-
-#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
-{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
- convert_to_68881 ((FROM), (TO)); \
- else \
- bcopy ((FROM), (TO), 4); }
-
-/* Return the GDB type object for the "standard" data type
- of data in register N. */
-
-#define REGISTER_VIRTUAL_TYPE(N) \
- (((unsigned)(N) - FP0_REGNUM) < 8 ? builtin_type_double : builtin_type_int)
-
-/* Store the address of the place in which to copy the structure the
- subroutine will return. This is called from call_function. */
-
-#define STORE_STRUCT_RETURN(ADDR, SP) \
- { write_register (9, (ADDR)); }
-
-/* Extract from an array REGBUF containing the (raw) register state
- a function return value of type TYPE, and copy that, in virtual format,
- into VALBUF. */
-
-#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
- bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
-
-/* Write into appropriate registers a function return value
- of type TYPE, given in virtual format. */
-
-#define STORE_RETURN_VALUE(TYPE,VALBUF) \
- write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
-
-/* Extract from an array REGBUF containing the (raw) register state
- the address in which a function should return its structure value,
- as a CORE_ADDR (or an expression that can be used as one). */
-
-#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
-
-
-/* Describe the pointer in each stack frame to the previous stack frame
- (its caller). */
-
-/* FRAME_CHAIN takes a frame's nominal address
- and produces the frame's chain-pointer.
-
- FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
- and produces the nominal address of the caller frame.
-
- However, if FRAME_CHAIN_VALID returns zero,
- it means the given frame is the outermost one and has no caller.
- In that case, FRAME_CHAIN_COMBINE is not used. */
-
-/* In the case of the 68k, the frame's nominal address
- is the address of a 4-byte word containing the calling frame's address. */
-
-#define FRAME_CHAIN(thisframe) (read_memory_integer ((thisframe)->frame, 4))
-
-#define FRAME_CHAIN_VALID(chain, thisframe) \
- (chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end))
-
-#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
-
-/* Define other aspects of the stack frame. */
-
-#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 4, 4))
-
-#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
-
-#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
-
-/* Set VAL to the number of args passed to frame described by FI.
- Can set VAL to -1, meaning no way to tell. */
-
-/* We can't tell how many args there are
- now that the C compiler delays popping them. */
-#define FRAME_NUM_ARGS(val,fi) (val = -1)
-
-#if 0
-#define FRAME_NUM_ARGS(val, fi) \
-{ register CORE_ADDR pc = FRAME_SAVED_PC (fi); \
- register int insn = 0177777 & read_memory_integer (pc, 2); \
- val = 0; \
- if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */ \
- val = read_memory_integer (pc + 2, 2); \
- else if ((insn & 0170777) == 0050217 /* addql #N, sp */ \
- || (insn & 0170777) == 0050117) /* addqw */ \
- { val = (insn >> 9) & 7; if (val == 0) val = 8; } \
- else if (insn == 0157774) /* addal #WW, sp */ \
- val = read_memory_integer (pc + 2, 4); \
- val >>= 2; }
-#endif
-
-/* Return number of bytes at start of arglist that are not really args. */
-
-#define FRAME_ARGS_SKIP 8
-
-/* Put here the code to store, into a struct frame_saved_regs,
- the addresses of the saved registers of frame described by FRAME_INFO.
- This includes special registers such as pc and fp saved in special
- ways in the stack frame. sp is even more special:
- the address we return for it IS the sp for the next frame. */
-
-#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
-{ register int regnum; \
- register int regmask; \
- register CORE_ADDR next_addr; \
- register CORE_ADDR pc; \
- int nextinsn; \
- bzero (&frame_saved_regs, sizeof frame_saved_regs); \
- if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \
- && (frame_info)->pc <= (frame_info)->frame) \
- { next_addr = (frame_info)->frame; \
- pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\
- else \
- { pc = get_pc_function_start ((frame_info)->pc); \
- /* Verify we have a link a6 instruction next; \
- if not we lose. If we win, find the address above the saved \
- regs using the amount of storage from the link instruction. */\
- if (044016 == read_memory_integer (pc, 2)) \
- next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 4), pc+=4; \
- else if (047126 == read_memory_integer (pc, 2)) \
- next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 2), pc+=2; \
- else goto lose; \
- /* If have an addal #-n, sp next, adjust next_addr. */ \
- if ((0177777 & read_memory_integer (pc, 2)) == 0157774) \
- next_addr += read_memory_integer (pc += 2, 4), pc += 4; \
- } \
- /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ \
- regmask = read_memory_integer (pc + 2, 2); \
- /* But before that can come an fmovem. Check for it. */ \
- nextinsn = 0xffff & read_memory_integer (pc, 2); \
- if (0xf227 == nextinsn \
- && (regmask & 0xff00) == 0xe000) \
- { pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ \
- for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
- if (regmask & 1) \
- (frame_saved_regs).regs[regnum] = (next_addr -= 12); \
- regmask = read_memory_integer (pc + 2, 2); } \
- if (0044327 == read_memory_integer (pc, 2)) \
- { pc += 4; /* Regmask's low bit is for register 0, the first written */ \
- for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \
- if (regmask & 1) \
- (frame_saved_regs).regs[regnum] = (next_addr += 4) - 4; } \
- else if (0044347 == read_memory_integer (pc, 2)) \
- { pc += 4; /* Regmask's low bit is for register 15, the first pushed */ \
- for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) \
- if (regmask & 1) \
- (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
- else if (0x2f00 == (0xfff0 & read_memory_integer (pc, 2))) \
- { regnum = 0xf & read_memory_integer (pc, 2); pc += 2; \
- (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
- /* fmovemx to index of sp may follow. */ \
- regmask = read_memory_integer (pc + 2, 2); \
- nextinsn = 0xffff & read_memory_integer (pc, 2); \
- if (0xf236 == nextinsn \
- && (regmask & 0xff00) == 0xf000) \
- { pc += 10; /* Regmask's low bit is for register fp0, the first written */ \
- for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
- if (regmask & 1) \
- (frame_saved_regs).regs[regnum] = (next_addr += 12) - 12; \
- regmask = read_memory_integer (pc + 2, 2); } \
- /* clrw -(sp); movw ccr,-(sp) may follow. */ \
- if (0x426742e7 == read_memory_integer (pc, 4)) \
- (frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4); \
- lose: ; \
- (frame_saved_regs).regs[SP_REGNUM] = (frame_info)->frame + 8; \
- (frame_saved_regs).regs[FP_REGNUM] = (frame_info)->frame; \
- (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 4; \
-}
-
-/* Things needed for making the inferior call functions. */
-
-/* Push an empty stack frame, to record the current PC, etc. */
-
-#define PUSH_DUMMY_FRAME \
-{ register CORE_ADDR sp = read_register (SP_REGNUM); \
- register int regnum; \
- char raw_buffer[12]; \
- sp = push_word (sp, read_register (PC_REGNUM)); \
- sp = push_word (sp, read_register (FP_REGNUM)); \
- write_register (FP_REGNUM, sp); \
- for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
- { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); \
- sp = push_bytes (sp, raw_buffer, 12); } \
- for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
- sp = push_word (sp, read_register (regnum)); \
- sp = push_word (sp, read_register (PS_REGNUM)); \
- write_register (SP_REGNUM, sp); }
-
-/* Discard from the stack the innermost frame,
- restoring all saved registers. */
-
-#define POP_FRAME \
-{ register FRAME frame = get_current_frame (); \
- register CORE_ADDR fp; \
- register int regnum; \
- struct frame_saved_regs fsr; \
- struct frame_info *fi; \
- char raw_buffer[12]; \
- fi = get_frame_info (frame); \
- fp = fi->frame; \
- get_frame_saved_regs (fi, &fsr); \
- for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
- if (fsr.regs[regnum]) \
- { read_memory (fsr.regs[regnum], raw_buffer, 12); \
- write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
- for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
- if (fsr.regs[regnum]) \
- write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
- if (fsr.regs[PS_REGNUM]) \
- write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
- write_register (FP_REGNUM, read_memory_integer (fp, 4)); \
- write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \
- write_register (SP_REGNUM, fp + 8); \
- flush_cached_frames (); \
- set_current_frame (create_new_frame (read_register (FP_REGNUM),\
- read_pc ())); }
-
-/* This sequence of words is the instructions
- fmovem 0xff,-(sp)
- moveml 0xfffc,-(sp)
- clrw -(sp)
- movew ccr,-(sp)
- /..* The arguments are pushed at this point by GDB;
- no code is needed in the dummy for this.
- The CALL_DUMMY_START_OFFSET gives the position of
- the following jsr instruction. *../
- jsr @@#32323232
- addl #69696969,sp
- trap #15
- nop
-Note this is 28 bytes.
-We actually start executing at the jsr, since the pushing of the
-registers is done by PUSH_DUMMY_FRAME. If this were real code,
-the arguments for the function called by the jsr would be pushed
-between the moveml and the jsr, and we could allow it to execute through.
-But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
-and we cannot allow the moveml to push the registers again lest they be
-taken for the arguments. */
-
-#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71}
-
-#define CALL_DUMMY_LENGTH 28
-
-#define CALL_DUMMY_START_OFFSET 12
-
-/* Insert the specified number of args and function address
- into a call sequence of the above form stored at DUMMYNAME. */
-
-#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, type) \
-{ *(int *)((char *) dummyname + 20) = nargs * 4; \
- *(int *)((char *) dummyname + 14) = fun; }
-
-/* Interface definitions for kernel debugger KDB. */
-
-/* Map machine fault codes into signal numbers.
- First subtract 0, divide by 4, then index in a table.
- Faults for which the entry in this table is 0
- are not handled by KDB; the program's own trap handler
- gets to handle then. */
-
-#define FAULT_CODE_ORIGIN 0
-#define FAULT_CODE_UNITS 4
-#define FAULT_TABLE \
-{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
- 0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- SIGILL }
-
-/* Start running with a stack stretching from BEG to END.
- BEG and END should be symbols meaningful to the assembler.
- This is used only for kdb. */
-
-#define INIT_STACK(beg, end) \
-{ asm (".globl end"); \
- asm ("movel #end, sp"); \
- asm ("movel #0,a6"); }
-
-/* Push the frame pointer register on the stack. */
-#define PUSH_FRAME_PTR \
- asm ("movel a6,sp@@-");
-
-/* Copy the top-of-stack to the frame pointer register. */
-#define POP_FRAME_PTR \
- asm ("movl sp@@,a6");
-
-/* After KDB is entered by a fault, push all registers
- that GDB thinks about (all NUM_REGS of them),
- so that they appear in order of ascending GDB register number.
- The fault code will be on the stack beyond the last register. */
-
-#define PUSH_REGISTERS \
-{ asm ("clrw -(sp)"); \
- asm ("pea sp@@(10)"); \
- asm ("movem #0xfffe,sp@@-"); }
-
-/* Assuming the registers (including processor status) have been
- pushed on the stack in order of ascending GDB register number,
- restore them and return to the address in the saved PC register. */
-
-#define POP_REGISTERS \
-{ asm ("subil #8,sp@@(28)"); \
- asm ("movem sp@@,#0xffff"); \
- asm ("rte"); }
-@
-
-
-1.3
-log
-@Fix DECR_PC_AFTER_BREAK; A/UX reports breaks at the breakpoint addr,
-not there+2.
-@
-text
-@d41 11
-d100 2
-d103 1
-a103 1
-#define INVALID_FLOAT(p, len) 1 /* FIXME! Just a first guess; not checked */
-@
-
-
-1.2
-log
-@Mostly works!
-@
-text
-@d82 1
-a82 1
-#define DECR_PC_AFTER_BREAK 2
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d1 504
-@
diff --git a/gdb/RCS/m-hp9k320.h,v b/gdb/RCS/m-hp9k320.h,v
deleted file mode 100644
index 8df1709..0000000
--- a/gdb/RCS/m-hp9k320.h,v
+++ /dev/null
@@ -1,607 +0,0 @@
-head 1.2;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.2
-date 89.03.27.20.17.11; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.03.20.19.29.58; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.2
-log
-@Change "HPUX_ASM" define to "USG_SGS_ASM", since it's really the USG
-Software Generation System assembler that we're fighting here.
-.,
-@
-text
-@/* Parameters for execution on an HP 9000 model 320, for GDB, the GNU debugger.
- Copyright (C) 1986, 1987 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#ifndef HP9K320
-#define HP9K320
-#endif
-
-/* Set flag to indicate whether HP's assembler is in use. */
-#ifdef __GNU__
-#ifdef __HPUX_ASM__
-#define USG_SGS_ASM
-#endif
-#else
-#define USG_SGS_ASM
-#endif
-
-/* Define this for versions of hp-ux older than 6.0 */
-/* #define HPUX_VERSION_5 */
-
-/* define USG if you are using sys5 /usr/include's */
-#define USG
-
-#define HAVE_TERMIO
-
-/* Get rid of any system-imposed stack limit if possible. */
-
-/* #define SET_STACK_LIMIT_HUGE */
-
-/* Define this if the C compiler puts an underscore at the front
- of external names before giving them to the linker. */
-
-#define NAMES_HAVE_UNDERSCORE
-
-/* Debugger information will be in DBX format. */
-
-#define READ_DBX_FORMAT
-
-/* Offset from address of function to start of its code.
- Zero on most machines. */
-
-#define FUNCTION_START_OFFSET 0
-
-/* Advance PC across any function entry prologue instructions
- to reach some "real" code. */
-
-#define SKIP_PROLOGUE(pc) \
-{ register int op = read_memory_integer (pc, 2); \
- if (op == 0047126) \
- pc += 4; /* Skip link #word */ \
- else if (op == 0044016) \
- pc += 6; /* Skip link #long */ \
-}
-
-/* Immediately after a function call, return the saved pc.
- Can't go through the frames for this because on some machines
- the new frame is not set up until the new function executes
- some instructions. */
-
-#define SAVED_PC_AFTER_CALL(frame) \
-read_memory_integer (read_register (SP_REGNUM), 4)
-
-/* This is the amount to subtract from u.u_ar0
- to get the offset in the core file of the register values. */
-
-#ifdef HPUX_VERSION_5
-#define KERNEL_U_ADDR 0x00979000
-#else
-#define KERNEL_U_ADDR 0x00C01000
-#endif
-
-/* Address of end of stack space. */
-
-#define STACK_END_ADDR 0xFFF00000
-
-/* Stack grows downward. */
-
-#define INNER_THAN <
-
-/* Sequence of bytes for breakpoint instruction. */
-
-#define BREAKPOINT {0x4e, 0x41}
-
-/* Amount PC must be decremented by after a breakpoint.
- This is often the number of bytes in BREAKPOINT
- but not always. */
-
-#define DECR_PC_AFTER_BREAK 2
-
-/* Nonzero if instruction at PC is a return instruction. */
-
-#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e75)
-
-/* Return 1 if P points to an invalid floating point value. */
-
-#define INVALID_FLOAT(p, len) 0 /* Just a first guess; not checked */
-
-/* Largest integer type */
-#define LONGEST long
-
-/* Name of the builtin type for the LONGEST type above. */
-#define BUILTIN_TYPE_LONGEST builtin_type_long
-
-/* Say how long (ordinary) registers are. */
-
-#define REGISTER_TYPE long
-
-/* Number of machine registers */
-
-#define NUM_REGS 29
-
-/* Initializer for an array of names of registers.
- There should be NUM_REGS strings in this initializer. */
-
-#define REGISTER_NAMES \
- {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \
- "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \
- "ps", "pc", \
- "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", \
- "fpcontrol", "fpstatus", "fpiaddr" }
-
-/* Register numbers of various important registers.
- Note that some of these values are "real" register numbers,
- and correspond to the general registers of the machine,
- and some are "phony" register numbers which are too large
- to be actual register numbers as far as the user is concerned
- but do serve to get the desired values when passed to read_register. */
-
-#define FP_REGNUM 14 /* Contains address of executing stack frame */
-#define SP_REGNUM 15 /* Contains address of top of stack */
-#define PS_REGNUM 16 /* Contains processor status */
-#define PC_REGNUM 17 /* Contains program counter */
-#define FP0_REGNUM 18 /* Floating point register 0 */
-#define FPC_REGNUM 26 /* 68881 control register */
-
-/* Total amount of space needed to store our copies of the machine's
- register state, the array `registers'. */
-#define REGISTER_BYTES (16*4+8*12+8+12)
-
-/* Index within `registers' of the first byte of the space for
- register N. */
-
-#define REGISTER_BYTE(N) \
- ((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 168 \
- : (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 12) + 72 \
- : (N) * 4)
-
-/* Number of bytes of storage in the actual machine representation
- for register N. On the 68000, all regs are 4 bytes
- except the floating point regs which are 12 bytes. */
-
-#define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 12 : 4)
-
-/* Number of bytes of storage in the program's representation
- for register N. On the 68000, all regs are 4 bytes
- except the floating point regs which are 8-byte doubles. */
-
-#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 8 : 4)
-
-/* Largest value REGISTER_RAW_SIZE can have. */
-
-#define MAX_REGISTER_RAW_SIZE 12
-
-/* Largest value REGISTER_VIRTUAL_SIZE can have. */
-
-#define MAX_REGISTER_VIRTUAL_SIZE 8
-
-/* Nonzero if register N requires conversion
- from raw format to virtual format. */
-
-#define REGISTER_CONVERTIBLE(N) (((unsigned)(N) - FP0_REGNUM) < 8)
-
-/* Convert data from raw format for register REGNUM
- to virtual format for register REGNUM. */
-
-#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
-{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
- convert_from_68881 ((FROM), (TO)); \
- else \
- bcopy ((FROM), (TO), 4); }
-
-/* Convert data from virtual format for register REGNUM
- to raw format for register REGNUM. */
-
-#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
-{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \
- convert_to_68881 ((FROM), (TO)); \
- else \
- bcopy ((FROM), (TO), 4); }
-
-/* Return the GDB type object for the "standard" data type
- of data in register N. */
-
-#define REGISTER_VIRTUAL_TYPE(N) \
- (((unsigned)(N) - FP0_REGNUM) < 8 ? builtin_type_double : builtin_type_int)
-
-/* Store the address of the place in which to copy the structure the
- subroutine will return. This is called from call_function. */
-
-#define STORE_STRUCT_RETURN(ADDR, SP) \
- { write_register (9, (ADDR)); }
-
-/* Extract from an array REGBUF containing the (raw) register state
- a function return value of type TYPE, and copy that, in virtual format,
- into VALBUF. */
-
-#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
- bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE))
-
-/* Write into appropriate registers a function return value
- of type TYPE, given in virtual format. */
-
-#define STORE_RETURN_VALUE(TYPE,VALBUF) \
- write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE))
-
-/* Extract from an array REGBUF containing the (raw) register state
- the address in which a function should return its structure value,
- as a CORE_ADDR (or an expression that can be used as one). */
-
-#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF))
-
-#define REGISTER_ADDR(u_ar0, regno) \
- (((regno) < PS_REGNUM) \
- ? (&((struct exception_stack *) (u_ar0))->e_regs[(regno + R0)]) \
- : (((regno) == PS_REGNUM) \
- ? ((int *) (&((struct exception_stack *) (u_ar0))->e_PS)) \
- : (&((struct exception_stack *) (u_ar0))->e_PC)))
-
-#define FP_REGISTER_ADDR(u, regno) \
- (((char *) \
- (((regno) < FPC_REGNUM) \
- ? (&u.u_pcb.pcb_mc68881[FMC68881_R0 + (((regno) - FP0_REGNUM) * 3)]) \
- : (&u.u_pcb.pcb_mc68881[FMC68881_C + ((regno) - FPC_REGNUM)]))) \
- - ((char *) (& u)))
-
-/* It is safe to look for symsegs on a Sun, because Sun's ld
- does not screw up with random garbage at end of file. */
-
-#define READ_GDB_SYMSEGS
-
-/* Describe the pointer in each stack frame to the previous stack frame
- (its caller). */
-
-/* FRAME_CHAIN takes a frame's nominal address
- and produces the frame's chain-pointer.
-
- FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
- and produces the nominal address of the caller frame.
-
- However, if FRAME_CHAIN_VALID returns zero,
- it means the given frame is the outermost one and has no caller.
- In that case, FRAME_CHAIN_COMBINE is not used. */
-
-/* In the case of the Sun, the frame's nominal address
- is the address of a 4-byte word containing the calling frame's address. */
-
-#define FRAME_CHAIN(thisframe) (read_memory_integer ((thisframe)->frame, 4))
-
-#define FRAME_CHAIN_VALID(chain, thisframe) \
- (chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end))
-
-#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
-
-/* Define other aspects of the stack frame. */
-
-#define FRAME_SAVED_PC(FRAME) (read_memory_integer ((FRAME)->frame + 4, 4))
-
-#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
-
-#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
-
-/* Set VAL to the number of args passed to frame described by FI.
- Can set VAL to -1, meaning no way to tell. */
-
-/* We can't tell how many args there are
- now that the C compiler delays popping them. */
-#define FRAME_NUM_ARGS(val,fi) (val = -1)
-
-#if 0
-#define FRAME_NUM_ARGS(val, fi) \
-{ register CORE_ADDR pc = FRAME_SAVED_PC (fi); \
- register int insn = 0177777 & read_memory_integer (pc, 2); \
- val = 0; \
- if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */ \
- val = read_memory_integer (pc + 2, 2); \
- else if ((insn & 0170777) == 0050217 /* addql #N, sp */ \
- || (insn & 0170777) == 0050117) /* addqw */ \
- { val = (insn >> 9) & 7; if (val == 0) val = 8; } \
- else if (insn == 0157774) /* addal #WW, sp */ \
- val = read_memory_integer (pc + 2, 4); \
- val >>= 2; }
-#endif
-
-/* Return number of bytes at start of arglist that are not really args. */
-
-#define FRAME_ARGS_SKIP 8
-
-/* Put here the code to store, into a struct frame_saved_regs,
- the addresses of the saved registers of frame described by FRAME_INFO.
- This includes special registers such as pc and fp saved in special
- ways in the stack frame. sp is even more special:
- the address we return for it IS the sp for the next frame. */
-
-#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \
-{ register int regnum; \
- register int regmask; \
- register CORE_ADDR next_addr; \
- register CORE_ADDR pc; \
- int nextinsn; \
- bzero (&frame_saved_regs, sizeof frame_saved_regs); \
- if ((frame_info)->pc >= (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \
- && (frame_info)->pc <= (frame_info)->frame) \
- { next_addr = (frame_info)->frame; \
- pc = (frame_info)->frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\
- else \
- { pc = get_pc_function_start ((frame_info)->pc); \
- /* Verify we have a link a6 instruction next; \
- if not we lose. If we win, find the address above the saved \
- regs using the amount of storage from the link instruction. */\
- if (044016 == read_memory_integer (pc, 2)) \
- next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 4), pc+=4; \
- else if (047126 == read_memory_integer (pc, 2)) \
- next_addr = (frame_info)->frame + read_memory_integer (pc += 2, 2), pc+=2; \
- else goto lose; \
- /* If have an addal #-n, sp next, adjust next_addr. */ \
- if ((0177777 & read_memory_integer (pc, 2)) == 0157774) \
- next_addr += read_memory_integer (pc += 2, 4), pc += 4; \
- } \
- /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ \
- regmask = read_memory_integer (pc + 2, 2); \
- /* But before that can come an fmovem. Check for it. */ \
- nextinsn = 0xffff & read_memory_integer (pc, 2); \
- if (0xf227 == nextinsn \
- && (regmask & 0xff00) == 0xe000) \
- { pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ \
- for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
- if (regmask & 1) \
- (frame_saved_regs).regs[regnum] = (next_addr -= 12); \
- regmask = read_memory_integer (pc + 2, 2); } \
- if (0044327 == read_memory_integer (pc, 2)) \
- { pc += 4; /* Regmask's low bit is for register 0, the first written */ \
- for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \
- if (regmask & 1) \
- (frame_saved_regs).regs[regnum] = (next_addr += 4) - 4; } \
- else if (0044347 == read_memory_integer (pc, 2)) \
- { pc += 4; /* Regmask's low bit is for register 15, the first pushed */ \
- for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) \
- if (regmask & 1) \
- (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
- else if (0x2f00 == 0xfff0 & read_memory_integer (pc, 2)) \
- { regnum = 0xf & read_memory_integer (pc, 2); pc += 2; \
- (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \
- /* fmovemx to index of sp may follow. */ \
- regmask = read_memory_integer (pc + 2, 2); \
- nextinsn = 0xffff & read_memory_integer (pc, 2); \
- if (0xf236 == nextinsn \
- && (regmask & 0xff00) == 0xf000) \
- { pc += 10; /* Regmask's low bit is for register fp0, the first written */ \
- for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \
- if (regmask & 1) \
- (frame_saved_regs).regs[regnum] = (next_addr += 12) - 12; \
- regmask = read_memory_integer (pc + 2, 2); } \
- /* clrw -(sp); movw ccr,-(sp) may follow. */ \
- if (0x426742e7 == read_memory_integer (pc, 4)) \
- (frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4); \
- lose: ; \
- (frame_saved_regs).regs[SP_REGNUM] = (frame_info)->frame + 8; \
- (frame_saved_regs).regs[FP_REGNUM] = (frame_info)->frame; \
- (frame_saved_regs).regs[PC_REGNUM] = (frame_info)->frame + 4; \
-}
-
-/* Things needed for making the inferior call functions. */
-
-/* Push an empty stack frame, to record the current PC, etc. */
-
-#define PUSH_DUMMY_FRAME \
-{ register CORE_ADDR sp = read_register (SP_REGNUM); \
- register int regnum; \
- char raw_buffer[12]; \
- sp = push_word (sp, read_register (PC_REGNUM)); \
- sp = push_word (sp, read_register (FP_REGNUM)); \
- write_register (FP_REGNUM, sp); \
- for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
- { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); \
- sp = push_bytes (sp, raw_buffer, 12); } \
- for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
- sp = push_word (sp, read_register (regnum)); \
- sp = push_word (sp, read_register (PS_REGNUM)); \
- write_register (SP_REGNUM, sp); }
-
-/* Discard from the stack the innermost frame,
- restoring all saved registers. */
-
-#define POP_FRAME \
-{ register FRAME frame = get_current_frame (); \
- register CORE_ADDR fp; \
- register int regnum; \
- struct frame_saved_regs fsr; \
- struct frame_info *fi; \
- char raw_buffer[12]; \
- fi = get_frame_info (frame); \
- fp = fi->frame; \
- get_frame_saved_regs (fi, &fsr); \
- for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \
- if (fsr.regs[regnum]) \
- { read_memory (fsr.regs[regnum], raw_buffer, 12); \
- write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\
- for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \
- if (fsr.regs[regnum]) \
- write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \
- if (fsr.regs[PS_REGNUM]) \
- write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
- write_register (FP_REGNUM, read_memory_integer (fp, 4)); \
- write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \
- write_register (SP_REGNUM, fp + 8); \
- flush_cached_frames (); \
- set_current_frame (create_new_frame (read_register (FP_REGNUM),\
- read_pc ()));}
-
-/* This sequence of words is the instructions
- fmovem 0xff,-(sp)
- moveml 0xfffc,-(sp)
- clrw -(sp)
- movew ccr,-(sp)
- /..* The arguments are pushed at this point by GDB;
- no code is needed in the dummy for this.
- The CALL_DUMMY_START_OFFSET gives the position of
- the following jsr instruction. *../
- jsr @@#32323232
- addl #69696969,sp
- bpt
- nop
-Note this is 28 bytes.
-We actually start executing at the jsr, since the pushing of the
-registers is done by PUSH_DUMMY_FRAME. If this were real code,
-the arguments for the function called by the jsr would be pushed
-between the moveml and the jsr, and we could allow it to execute through.
-But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done,
-and we cannot allow the moveml to push the registers again lest they be
-taken for the arguments. */
-
-#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e414e71}
-
-#define CALL_DUMMY_LENGTH 28
-
-#define CALL_DUMMY_START_OFFSET 12
-
-/* Insert the specified number of args and function address
- into a call sequence of the above form stored at DUMMYNAME. */
-
-#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, type) \
-{ *(int *)((char *) dummyname + 20) = nargs * 4; \
- *(int *)((char *) dummyname + 14) = fun; }
-
-/* Interface definitions for kernel debugger KDB. */
-
-/* Map machine fault codes into signal numbers.
- First subtract 0, divide by 4, then index in a table.
- Faults for which the entry in this table is 0
- are not handled by KDB; the program's own trap handler
- gets to handle then. */
-
-#define FAULT_CODE_ORIGIN 0
-#define FAULT_CODE_UNITS 4
-#define FAULT_TABLE \
-{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \
- 0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- SIGILL }
-
-#ifndef HPUX_ASM
-
-/* Start running with a stack stretching from BEG to END.
- BEG and END should be symbols meaningful to the assembler.
- This is used only for kdb. */
-
-#define INIT_STACK(beg, end) \
-{ asm (".globl end"); \
- asm ("movel $ end, sp"); \
- asm ("clrl fp"); }
-
-/* Push the frame pointer register on the stack. */
-#define PUSH_FRAME_PTR \
- asm ("movel fp, -(sp)");
-
-/* Copy the top-of-stack to the frame pointer register. */
-#define POP_FRAME_PTR \
- asm ("movl (sp), fp");
-
-/* After KDB is entered by a fault, push all registers
- that GDB thinks about (all NUM_REGS of them),
- so that they appear in order of ascending GDB register number.
- The fault code will be on the stack beyond the last register. */
-
-#define PUSH_REGISTERS \
-{ asm ("clrw -(sp)"); \
- asm ("pea 10(sp)"); \
- asm ("movem $ 0xfffe,-(sp)"); }
-
-/* Assuming the registers (including processor status) have been
- pushed on the stack in order of ascending GDB register number,
- restore them and return to the address in the saved PC register. */
-
-#define POP_REGISTERS \
-{ asm ("subil $8,28(sp)"); \
- asm ("movem (sp),$ 0xffff"); \
- asm ("rte"); }
-
-#else /* HPUX_ASM */
-
-/* Start running with a stack stretching from BEG to END.
- BEG and END should be symbols meaningful to the assembler.
- This is used only for kdb. */
-
-#define INIT_STACK(beg, end) \
-{ asm ("global end"); \
- asm ("mov.l &end,%sp"); \
- asm ("clr.l %a6"); }
-
-/* Push the frame pointer register on the stack. */
-#define PUSH_FRAME_PTR \
- asm ("mov.l %fp,-(%sp)");
-
-/* Copy the top-of-stack to the frame pointer register. */
-#define POP_FRAME_PTR \
- asm ("mov.l (%sp),%fp");
-
-/* After KDB is entered by a fault, push all registers
- that GDB thinks about (all NUM_REGS of them),
- so that they appear in order of ascending GDB register number.
- The fault code will be on the stack beyond the last register. */
-
-#define PUSH_REGISTERS \
-{ asm ("clr.w -(%sp)"); \
- asm ("pea 10(%sp)"); \
- asm ("movm.l &0xfffe,-(%sp)"); }
-
-/* Assuming the registers (including processor status) have been
- pushed on the stack in order of ascending GDB register number,
- restore them and return to the address in the saved PC register. */
-
-#define POP_REGISTERS \
-{ asm ("subi.l &8,28(%sp)"); \
- asm ("mov.m (%sp),&0xffff"); \
- asm ("rte"); }
-
-#endif /* HPUX_ASM */
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d28 1
-a28 1
-#define HPUX_ASM
-d31 1
-a31 1
-#define HPUX_ASM
-@
diff --git a/gdb/RCS/m-sparc.h,v b/gdb/RCS/m-sparc.h,v
deleted file mode 100644
index 1720dfe..0000000
--- a/gdb/RCS/m-sparc.h,v
+++ /dev/null
@@ -1,747 +0,0 @@
-head 1.3;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.3
-date 89.04.26.00.52.29; author gnu; state Exp;
-branches ;
-next 1.2;
-
-1.2
-date 89.03.16.21.10.29; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.03.14.15.28.32; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.3
-log
-@(1) Define big-endianness of SPARC.
-(2) Define IEEE compatible float.
-@
-text
-@/* Parameters for execution on a Sun 4, for GDB, the GNU debugger.
- Copyright (C) 1986, 1987 Free Software Foundation, Inc.
- Contributed by Michael Tiemann (tiemann@@mcc.com)
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#ifndef sun4
-#define sun4
-#endif
-
-/* Get rid of any system-imposed stack limit if possible. */
-
-#define SET_STACK_LIMIT_HUGE
-
-/* Define this if the C compiler puts an underscore at the front
- of external names before giving them to the linker. */
-
-#define NAMES_HAVE_UNDERSCORE
-
-/* Debugger information will be in DBX format. */
-
-#define READ_DBX_FORMAT
-
-/* Big or Little-Endian target machine
- BITS: defined if bit #0 is the high-order bit of a byte.
- BYTES:defined if byte#0 is the high-order byte of an int.
- WORDS:defined if word#0 is the high-order word of a double. */
-#define BITS_BIG_ENDIAN
-#define BYTES_BIG_ENDIAN
-#define WORDS_BIG_ENDIAN
-
-/* Floating point is IEEE compatible. */
-#define IEEE_FLOAT
-
-/* Offset from address of function to start of its code.
- Zero on most machines. */
-
-#define FUNCTION_START_OFFSET 0
-
-/* Advance PC across any function entry prologue instructions
- to reach some "real" code. */
-
-#define SKIP_PROLOGUE(pc) \
- { pc = skip_prologue (pc); }
-
-/* Immediately after a function call, return the saved pc.
- Can't go through the frames for this because on some machines
- the new frame is not set up until the new function executes
- some instructions. */
-
-/* On the Sun 4 under SunOS, the compile will leave a fake insn which
- encodes the structure size being returned. If we detect such
- a fake insn, step past it. */
-
-#define PC_ADJUST(pc) ((read_memory_integer (pc + 8, 4) & 0xfffffe00) == 0 ? \
- pc+12 : pc+8)
-
-#define SAVED_PC_AFTER_CALL(frame) PC_ADJUST (read_register (RP_REGNUM))
-
-/* Address of end of stack space. */
-
-#define STACK_END_ADDR 0xf8000000
-
-/* Stack grows downward. */
-
-#define INNER_THAN <
-
-/* Stack has strict alignment. */
-
-#define STACK_ALIGN(ADDR) (((ADDR)+7)&-8)
-
-/* Sequence of bytes for breakpoint instruction. */
-
-#define BREAKPOINT {0x91, 0xd0, 0x20, 0x01}
-
-/* Amount PC must be decremented by after a breakpoint.
- This is often the number of bytes in BREAKPOINT
- but not always. */
-
-#define DECR_PC_AFTER_BREAK 0
-
-/* Nonzero if instruction at PC is a return instruction. */
-/* For SPARC, this is either a "jmpl %o7+8,%g0" or "jmpl %i7+8,%g0".
-
- Note: this does not work for functions returning structures under SunOS. */
-#define ABOUT_TO_RETURN(pc) \
- ((read_memory_integer (pc, 4)|0x00040000) == 0x81c7e008)
-
-/* Return 1 if P points to an invalid floating point value. */
-
-#define INVALID_FLOAT(p, len) 0 /* Just a first guess; not checked */
-
-/* Largest integer type */
-#define LONGEST long
-
-/* Name of the builtin type for the LONGEST type above. */
-#define BUILTIN_TYPE_LONGEST builtin_type_long
-
-/* Say how long (ordinary) registers are. */
-
-#define REGISTER_TYPE long
-
-/* Number of machine registers */
-
-#define NUM_REGS 72
-
-/* Initializer for an array of names of registers.
- There should be NUM_REGS strings in this initializer. */
-
-#define REGISTER_NAMES \
-{ "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7", \
- "o0", "o1", "o2", "o3", "o4", "o5", "sp", "o7", \
- "l0", "l1", "l2", "l3", "l4", "l5", "l6", "l7", \
- "i0", "i1", "i2", "i3", "i4", "i5", "fp", "i7", \
- \
- "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \
- "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", \
- "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", \
- "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", \
- \
- "y", "psr", "wim", "tbr", "pc", "npc", "fpsr", "cpsr" };
-
-/* Register numbers of various important registers.
- Note that some of these values are "real" register numbers,
- and correspond to the general registers of the machine,
- and some are "phony" register numbers which are too large
- to be actual register numbers as far as the user is concerned
- but do serve to get the desired values when passed to read_register. */
-
-#define FP_REGNUM 30 /* Contains address of executing stack frame */
-#define RP_REGNUM 15 /* Contains return address value, *before* \
- any windows get switched. */
-#define SP_REGNUM 14 /* Contains address of top of stack, \
- which is also the bottom of the frame. */
-#define Y_REGNUM 64 /* Temp register for multiplication, etc. */
-#define PS_REGNUM 65 /* Contains processor status */
-#define PC_REGNUM 68 /* Contains program counter */
-#define NPC_REGNUM 69 /* Contains next PC */
-#define FP0_REGNUM 32 /* Floating point register 0 */
-#define FPS_REGNUM 70 /* Floating point status register */
-#define CPS_REGNUM 71 /* Coprocessor status register */
-
-/* Total amount of space needed to store our copies of the machine's
- register state, the array `registers'. */
-#define REGISTER_BYTES (32*4+32*4+8*4)
-
-/* Index within `registers' of the first byte of the space for
- register N. */
-/* ?? */
-#define REGISTER_BYTE(N) ((N)*4)
-
-/* The SPARC processor has register windows. */
-
-#define HAVE_REGISTER_WINDOWS
-
-/* Is this register part of the register window system? A yes answer
- implies that 1) The name of this register will not be the same in
- other frames, and 2) This register is automatically "saved" (out
- registers shifting into ins counts) upon subroutine calls and thus
- there is no need to search more than one stack frame for it. */
-
-#define REGISTER_IN_WINDOW_P(regnum) \
- ((regnum) >= 8 && (regnum) < 32)
-
-/* Number of bytes of storage in the actual machine representation
- for register N. */
-
-/* On the SPARC, all regs are 4 bytes. */
-
-#define REGISTER_RAW_SIZE(N) (4)
-
-/* Number of bytes of storage in the program's representation
- for register N. */
-
-/* On the SPARC, all regs are 4 bytes. */
-
-#define REGISTER_VIRTUAL_SIZE(N) (4)
-
-/* Largest value REGISTER_RAW_SIZE can have. */
-
-#define MAX_REGISTER_RAW_SIZE 8
-
-/* Largest value REGISTER_VIRTUAL_SIZE can have. */
-
-#define MAX_REGISTER_VIRTUAL_SIZE 8
-
-/* Nonzero if register N requires conversion
- from raw format to virtual format. */
-
-#define REGISTER_CONVERTIBLE(N) (0)
-
-/* Convert data from raw format for register REGNUM
- to virtual format for register REGNUM. */
-
-#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \
-{ bcopy ((FROM), (TO), 4); }
-
-/* Convert data from virtual format for register REGNUM
- to raw format for register REGNUM. */
-
-#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \
-{ bcopy ((FROM), (TO), 4); }
-
-/* Return the GDB type object for the "standard" data type
- of data in register N. */
-
-#define REGISTER_VIRTUAL_TYPE(N) \
- ((N) < 32 ? builtin_type_int : (N) < 64 ? builtin_type_float : \
- builtin_type_int)
-
-/* Store the address of the place in which to copy the structure the
- subroutine will return. This is called from call_function. */
-
-#define STORE_STRUCT_RETURN(ADDR, SP) \
- { write_memory ((SP)+(16*4), &(ADDR), 4); }
-
-/* Extract from an array REGBUF containing the (raw) register state
- a function return value of type TYPE, and copy that, in virtual format,
- into VALBUF. */
-
-#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
- bcopy (((int *)(REGBUF))+8, (VALBUF), TYPE_LENGTH (TYPE))
-
-/* Write into appropriate registers a function return value
- of type TYPE, given in virtual format. */
-/* On sparc, values are returned in register %o0. */
-#define STORE_RETURN_VALUE(TYPE,VALBUF) \
- write_register_bytes (REGISTER_BYTE (8), VALBUF, TYPE_LENGTH (TYPE))
-
-/* Extract from an array REGBUF containing the (raw) register state
- the address in which a function should return its structure value,
- as a CORE_ADDR (or an expression that can be used as one). */
-
-#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
- (read_memory_integer (((int *)(REGBUF))[SP_REGNUM]+(16*4), 4))
-
-/* Enable use of alternate code to read and write registers. */
-
-#define NEW_SUN_PTRACE
-
-/* Enable use of alternate code for Sun's format of core dump file. */
-
-#define NEW_SUN_CORE
-
-/* Do implement the attach and detach commands. */
-
-#define ATTACH_DETACH
-
-/* It is safe to look for symsegs on a Sun, because Sun's ld
- does not screw up with random garbage at end of file. */
-
-#define READ_GDB_SYMSEGS
-
-
-/* Describe the pointer in each stack frame to the previous stack frame
- (its caller). */
-#include <machine/reg.h>
-
-#define GET_RWINDOW_REG(FRAME, REG) \
- (read_memory_integer (&((struct rwindow *)FRAME)->REG, 4))
-
-/* FRAME_CHAIN takes a frame's nominal address
- and produces the frame's chain-pointer.
-
- FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address
- and produces the nominal address of the caller frame.
-
- However, if FRAME_CHAIN_VALID returns zero,
- it means the given frame is the outermost one and has no caller.
- In that case, FRAME_CHAIN_COMBINE is not used. */
-
-/* In the case of the Sun 4, the frame-chain's nominal address
- is held in the frame pointer register.
-
- On the Sun4, the frame (in %fp) is %sp for the previous frame.
- From the previous frame's %sp, we can find the previous frame's
- %fp: it is in the save area just above the previous frame's %sp.
-
- If we are setting up an arbitrary frame, we'll need to know where
- it ends. Hence the following. This part of the frame cache
- structure should be checked before it is assumed that this frame's
- bottom is in the stack pointer.
-
- If there isn't a frame below this one, the bottom of this frame is
- in the stack pointer.
-
- If there is a frame below this one, and the frame pointers are
- identical, it's a leaf frame and the bottoms are the same also.
-
- Otherwise the bottom of this frame is the top of the next frame. */
-
-#define EXTRA_FRAME_INFO FRAME_ADDR bottom;
-#define INIT_EXTRA_FRAME_INFO(fci) \
- (fci)->bottom = \
- ((fci)->next ? \
- ((fci)->frame == (fci)->next_frame ? \
- (fci)->next->bottom : (fci)->next->frame) : \
- read_register (SP_REGNUM));
-
-#define FRAME_CHAIN(thisframe) \
- GET_RWINDOW_REG ((thisframe)->frame, rw_in[6])
-
-/* Avoid checking FRAME_SAVED_PC since that screws us due to
- improperly set up saved PC on a signal trampoline call */
-#if 0
-#define FRAME_CHAIN_VALID(chain, thisframe) \
- (chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end))
-#else
-#define FRAME_CHAIN_VALID(chain, thisframe) \
- (chain != 0)
-#endif
-
-#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
-
-/* Define other aspects of the stack frame. */
-
-/* Where is the PC for a specific frame */
-
-#define FRAME_SAVED_PC(FRAME) frame_saved_pc (FRAME)
-
-/* If the argument is on the stack, it will be here. */
-#define FRAME_ARGS_ADDRESS(fi) ((fi)->frame)
-
-#define FRAME_STRUCT_ARGS_ADDRESS(fi) ((fi)->frame)
-
-#define FRAME_LOCALS_ADDRESS(fi) ((fi)->frame)
-
-/* Set VAL to the number of args passed to frame described by FI.
- Can set VAL to -1, meaning no way to tell. */
-
-/* We can't tell how many args there are
- now that the C compiler delays popping them. */
-#define FRAME_NUM_ARGS(val,fi) (val = -1)
-
-/* Return number of bytes at start of arglist that are not really args. */
-
-#define FRAME_ARGS_SKIP 68
-
-/* Put here the code to store, into a struct frame_saved_regs,
- the addresses of the saved registers of frame described by FRAME_INFO.
- This includes special registers such as pc and fp saved in special
- ways in the stack frame. sp is even more special:
- the address we return for it IS the sp for the next frame.
-
- Note that on register window machines, we are currently making the
- assumption that window registers are being saved somewhere in the
- frame in which they are being used. If they are stored in an
- inferior frame, find_saved_register will break.
-
- On the Sun 4, the only time all registers are saved is when
- a dummy frame is involved. Otherwise, the only saved registers
- are the LOCAL and IN registers which are saved as a result
- of the "save/restore" opcodes. This condition is determined
- by address rather than by value. */
-
-#define FRAME_FIND_SAVED_REGS(fi, frame_saved_regs) \
-{ register int regnum; \
- register CORE_ADDR pc; \
- FRAME_ADDR frame = read_register (FP_REGNUM); \
- FRAME fid = FRAME_INFO_ID (fi); \
- if (!fid) fatal ("Bad frame info struct in FRAME_FIND_SAVED_REGS"); \
- bzero (&(frame_saved_regs), sizeof (frame_saved_regs)); \
- if ((fi)->pc >= frame - CALL_DUMMY_LENGTH - 0x140 \
- && (fi)->pc <= frame) \
- { \
- for (regnum = 1; regnum < 8; regnum++) \
- (frame_saved_regs).regs[regnum] = \
- frame + regnum * 4 - 0xa0; \
- for (regnum = 24; regnum < 32; regnum++) \
- (frame_saved_regs).regs[regnum] = \
- frame + (regnum - 24) * 4 - 0xc0; \
- for (regnum = FP0_REGNUM; regnum < FP0_REGNUM + 32; regnum++) \
- (frame_saved_regs).regs[regnum] = \
- frame + (regnum - FP0_REGNUM) * 4 - 0x80; \
- for (regnum = 64; regnum < NUM_REGS; regnum++) \
- (frame_saved_regs).regs[regnum] = \
- frame + (regnum - 64) * 4 - 0xe0; \
- frame = (fi)->bottom ? \
- (fi)->bottom : read_register (SP_REGNUM); \
- } \
- else \
- { \
- frame = (fi)->bottom ? \
- (fi)->bottom : read_register (SP_REGNUM); \
- for (regnum = 16; regnum < 32; regnum++) \
- (frame_saved_regs).regs[regnum] = frame + (regnum-16) * 4; \
- } \
- if ((fi)->next) \
- { \
- /* Pull off either the next frame pointer or \
- the stack pointer */ \
- FRAME_ADDR next_next_frame = \
- ((fi)->next->bottom ? \
- (fi)->next->bottom : \
- read_register (SP_REGNUM)); \
- for (regnum = 8; regnum < 16; regnum++) \
- (frame_saved_regs).regs[regnum] = next_next_frame + regnum * 4; \
- } \
- /* Otherwise, whatever we would get from ptrace(GETREGS) */ \
- /* is accurate */ \
- for (regnum = 30; regnum < 32; regnum++) \
- (frame_saved_regs).regs[regnum] = frame + (regnum-16) * 4; \
- (frame_saved_regs).regs[SP_REGNUM] = frame; \
- (frame_saved_regs).regs[PC_REGNUM] = frame + 15*4; \
-}
-
-/* Things needed for making the inferior call functions. */
-/*
- * First of all, let me give my opinion of what the DUMMY_FRAME
- * actually looks like.
- *
- * | |
- * | |
- * + - - - - - - - - - - - - - - - - +<-- fp (level 0)
- * | |
- * | |
- * | |
- * | |
- * | Frame of innermost program |
- * | function |
- * | |
- * | |
- * | |
- * | |
- * | |
- * |---------------------------------|<-- sp (level 0), fp (c)
- * | |
- * DUMMY | fp0-31 |
- * | |
- * | ------ |<-- fp - 0x80
- * FRAME | g0-7 |<-- fp - 0xa0
- * | i0-7 |<-- fp - 0xc0
- * | other |<-- fp - 0xe0
- * | ? |
- * | ? |
- * |---------------------------------|<-- sp' = fp - 0x140
- * | |
- * xcution start | |
- * sp' + 0x94 -->| CALL_DUMMY (x code) |
- * | |
- * | |
- * |---------------------------------|<-- sp'' = fp - 0x200
- * | align sp to 8 byte boundary |
- * | ==> args to fn <== |
- * Room for | |
- * i & l's + agg | CALL_DUMMY_STACK_ADJUST = 0x0x44|
- * |---------------------------------|<-- final sp (variable)
- * | |
- * | Where function called will |
- * | build frame. |
- * | |
- * | |
- *
- * I understand everything in this picture except what the space
- * between fp - 0xe0 and fp - 0x140 is used for. Oh, and I don't
- * understand why there's a large chunk of CALL_DUMMY that never gets
- * executed (its function is superceeded by PUSH_DUMMY_FRAME; they
- * are designed to do the same thing).
- *
- * PUSH_DUMMY_FRAME saves the registers above sp' and pushes the
- * register file stack down one.
- *
- * call_function then writes CALL_DUMMY, pushes the args onto the
- * stack, and adjusts the stack pointer.
- *
- * run_stack_dummy then starts execution (in the middle of
- * CALL_DUMMY, as directed by call_function).
- */
-
-/* Push an empty stack frame, to record the current PC, etc. */
-
-/* Note: to be perfectly correct, we have to restore the
- IN registers (which were the OUT registers of the calling frame). */
-/* Note that the write's are of registers in the context of the newly
- pushed frame. Thus the the fp*'s, the g*'s, the i*'s, and
- the others, of the new frame, are being saved.
- The locals are new; they don't need to be saved. The i's and l's of
- the last frame were saved by the do_save_insn in the register
- file (ie. on the stack, since a context switch happended imm after) */
-/* We note that the return pointer register does not *need* to have
- the pc saved into it (return from this frame will be accomplished
- by a POP_FRAME), however, just in case it might be needed, we will
- leave it. However, we will write the original value of RP into the
- location on the stack for saving i7 (what rp turns into upon call);
- this way we don't loose the value with our function call. */
-/* Note that the pc saved must be 8 less than the actual pc, since
- both POP_FRAME and the normal return sequence on the sparc return
- to 8 more than the value of RP_REGNUM */
-
-#define PUSH_DUMMY_FRAME \
-{ extern char registers[]; \
- register int regnum; \
- CORE_ADDR fp = read_register (FP_REGNUM); \
- CORE_ADDR pc = read_register (PC_REGNUM) - 8; \
- CORE_ADDR rp = read_register (RP_REGNUM); \
- void do_save_insn (); \
- supply_register (RP_REGNUM, &pc); \
- do_save_insn (0x140); \
- fp = read_register (FP_REGNUM); \
- write_memory (fp - 0x80, &registers[REGISTER_BYTE (FP0_REGNUM)], 32 * 4);\
- write_memory (fp - 0xa0, &registers[REGISTER_BYTE (0)], 8 * 4); \
- write_memory (fp - 0xc0, &registers[REGISTER_BYTE (24)], 7 * 4); \
- write_memory (fp - 0xa4, &rp, 4); \
- write_memory (fp - 0xe0, &registers[REGISTER_BYTE (64)], 8 * 4); \
-}
-
-/* Discard from the stack the innermost frame,
- restoring all saved registers.
- Note that the values stored in fsr by get_frame_saved_regs are *in
- the context of the inferior frame*. What this means is that the i
- regs of fsr must be restored into the o regs of the frame popped
- into. We don't care about the output regs of the inferior frame.
-
- This is true for dummy frames. Is it true for normal frames? It
- really does appear so. */
-
-#define POP_FRAME \
-{ register FRAME frame = get_current_frame (); \
- register CORE_ADDR fp; \
- register CORE_ADDR pc; \
- register int regnum; \
- struct frame_saved_regs fsr; \
- struct frame_info *fi; \
- char raw_buffer[REGISTER_BYTES]; \
- void do_restore_insn (); \
- fi = get_frame_info (frame); \
- fp = fi->frame; \
- get_frame_saved_regs (fi, &fsr); \
- pc = read_memory_integer (fsr.regs[PC_REGNUM], 4); \
- do_restore_insn (PC_ADJUST (pc)); \
- if (fsr.regs[FP0_REGNUM]) \
- { \
- read_memory (fsr.regs[FP0_REGNUM], raw_buffer, 32 * 4); \
- write_register_bytes (REGISTER_BYTE (FP0_REGNUM), raw_buffer, 32 * 4); \
- } \
- if (fsr.regs[1]) \
- { \
- read_memory (fsr.regs[1], raw_buffer, 7 * 4); \
- write_register_bytes (REGISTER_BYTE (1), raw_buffer, 7 * 4); \
- } \
- if (fsr.regs[24]) \
- { \
- read_memory (fsr.regs[24], raw_buffer, 8 * 4); \
- write_register_bytes (REGISTER_BYTE (8), raw_buffer, 8 * 4); \
- } \
- if (fsr.regs[PS_REGNUM]) \
- write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \
- if (fsr.regs[Y_REGNUM]) \
- write_register (Y_REGNUM, read_memory_integer (fsr.regs[Y_REGNUM], 4)); \
- if (fsr.regs[NPC_REGNUM]) \
- write_register (NPC_REGNUM, read_memory_integer (fsr.regs[NPC_REGNUM], 4)); \
- flush_cached_frames (); \
- set_current_frame ( create_new_frame (read_register (FP_REGNUM), \
- read_pc ())); }
-
-/* This sequence of words is the instructions
-
- save %sp,-0x140,%sp
- std %f30,[%fp-0x08]
- std %f28,[%fp-0x10]
- std %f26,[%fp-0x18]
- std %f24,[%fp-0x20]
- std %f22,[%fp-0x28]
- std %f20,[%fp-0x30]
- std %f18,[%fp-0x38]
- std %f16,[%fp-0x40]
- std %f14,[%fp-0x48]
- std %f12,[%fp-0x50]
- std %f10,[%fp-0x58]
- std %f8,[%fp-0x60]
- std %f6,[%fp-0x68]
- std %f4,[%fp-0x70]
- std %f2,[%fp-0x78]
- std %f0,[%fp-0x80]
- std %g6,[%fp-0x88]
- std %g4,[%fp-0x90]
- std %g2,[%fp-0x98]
- std %g0,[%fp-0xa0]
- std %i6,[%fp-0xa8]
- std %i4,[%fp-0xb0]
- std %i2,[%fp-0xb8]
- std %i0,[%fp-0xc0]
- nop ! stcsr [%fp-0xc4]
- nop ! stfsr [%fp-0xc8]
- nop ! wr %npc,[%fp-0xcc]
- nop ! wr %pc,[%fp-0xd0]
- rd %tbr,%o0
- st %o0,[%fp-0xd4]
- rd %wim,%o1
- st %o0,[%fp-0xd8]
- rd %psr,%o0
- st %o0,[%fp-0xdc]
- rd %y,%o0
- st %o0,[%fp-0xe0]
-
- /..* The arguments are pushed at this point by GDB;
- no code is needed in the dummy for this.
- The CALL_DUMMY_START_OFFSET gives the position of
- the following ld instruction. *../
-
- ld [%sp+0x58],%o5
- ld [%sp+0x54],%o4
- ld [%sp+0x50],%o3
- ld [%sp+0x4c],%o2
- ld [%sp+0x48],%o1
- call 0x00000000
- ld [%sp+0x44],%o0
- nop
- ta 1
- nop
-
- note that this is 192 bytes, which is a multiple of 8 (not only 4) bytes.
- note that the `call' insn is a relative, not an absolute call.
- note that the `nop' at the end is needed to keep the trap from
- clobbering things (if NPC pointed to garbage instead).
-
-We actually start executing at the `sethi', since the pushing of the
-registers (as arguments) is done by PUSH_DUMMY_FRAME. If this were
-real code, the arguments for the function called by the CALL would be
-pushed between the list of ST insns and the CALL, and we could allow
-it to execute through. But the arguments have to be pushed by GDB
-after the PUSH_DUMMY_FRAME is done, and we cannot allow these ST
-insns to be performed again, lest the registers saved be taken for
-arguments. */
-
-#define CALL_DUMMY { 0x9de3bee0, 0xfd3fbff8, 0xf93fbff0, 0xf53fbfe8, \
- 0xf13fbfe0, 0xed3fbfd8, 0xe93fbfd0, 0xe53fbfc8, \
- 0xe13fbfc0, 0xdd3fbfb8, 0xd93fbfb0, 0xd53fbfa8, \
- 0xd13fbfa0, 0xcd3fbf98, 0xc93fbf90, 0xc53fbf88, \
- 0xc13fbf80, 0xcc3fbf78, 0xc83fbf70, 0xc43fbf68, \
- 0xc03fbf60, 0xfc3fbf58, 0xf83fbf50, 0xf43fbf48, \
- 0xf03fbf40, 0x01000000, 0x01000000, 0x01000000, \
- 0x01000000, 0x91580000, 0xd027bf50, 0x93500000, \
- 0xd027bf4c, 0x91480000, 0xd027bf48, 0x91400000, \
- 0xd027bf44, 0xda03a058, 0xd803a054, 0xd603a050, \
- 0xd403a04c, 0xd203a048, 0x40000000, 0xd003a044, \
- 0x01000000, 0x91d02001, 0x01000000, 0x01000000}
-
-#define CALL_DUMMY_LENGTH 192
-
-#define CALL_DUMMY_START_OFFSET 148
-
-#define CALL_DUMMY_STACK_ADJUST 68
-
-/* Insert the specified number of args and function address
- into a call sequence of the above form stored at DUMMYNAME. */
-
-#define FIX_CALL_DUMMY(dummyname, pc, fun, nargs, type) \
-{ \
- *(int *)((char *) dummyname+168) = (0x40000000|((fun-(pc+168))>>2)); \
- if (TYPE_CODE (type) == TYPE_CODE_STRUCT \
- || TYPE_CODE (type) == TYPE_CODE_UNION) \
- *(int *)((char *) dummyname+176) = (TYPE_LENGTH (type) & 0x1fff); \
-}
-
-
-/* Sparc has no reliable single step ptrace call */
-
-#define NO_SINGLE_STEP 1
-
-/* It does have a wait structure, and it might help things out . . . */
-
-#define HAVE_WAIT_STRUCT
-
-/* Handle a feature in the sun4 compiler ("call .stret4" at the end of
- functions returning structures). */
-
-#define SUN4_COMPILER_FEATURE
-
-/* We need two arguments (in general) to the "info frame" command.
- Note that the definition of this macro implies that there exists a
- function "setup_arbitrary_frame" in mach-dep.c */
-
-#define FRAME_SPECIFICATION_DYADIC
-
-/* KDB stuff flushed for now. */
-@
-
-
-1.2
-log
-@Don't stop the stack trace until the "next frame pointer" is zero.
-@
-text
-@d39 11
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d66 1
-a66 1
-#define STACK_END_ADDR 0xff000000
-d307 3
-d312 4
-@
diff --git a/gdb/RCS/m68k-pinsn.c,v b/gdb/RCS/m68k-pinsn.c,v
deleted file mode 100644
index d8c7f84..0000000
--- a/gdb/RCS/m68k-pinsn.c,v
+++ /dev/null
@@ -1,824 +0,0 @@
-head 1.2;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.2
-date 89.03.27.20.19.34; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.03.20.19.29.33; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.2
-log
-@Change HPUX_ASM to USG_SGS_ASM since it's really the Sys V
-"Software Generation System" that we are fighting here.
-@
-text
-@/* Print m68k instructions for GDB, the GNU debugger.
- Copyright (C) 1986, 1987 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#include <stdio.h>
-
-#include "defs.h"
-#include "param.h"
-#include "symtab.h"
-#include "opcode.h"
-
-/* 68k instructions are never longer than this many bytes. */
-#define MAXLEN 22
-
-/* Number of elements in the opcode table. */
-#define NOPCODES (sizeof m68k_opcodes / sizeof m68k_opcodes[0])
-
-extern char *reg_names[];
-char *fpcr_names[] = { "", "fpiar", "fpsr", "fpiar/fpsr", "fpcr",
- "fpiar/fpcr", "fpsr/fpcr", "fpiar-fpcr"};
-
-static unsigned char *print_insn_arg ();
-static unsigned char *print_indexed ();
-static void print_base ();
-static int fetch_arg ();
-
-#define NEXTBYTE(p) (p += 2, ((char *)p)[-1])
-
-#define NEXTWORD(p) \
- (p += 2, ((((char *)p)[-2]) << 8) + p[-1])
-
-#define NEXTLONG(p) \
- (p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])
-
-#define NEXTSINGLE(p) \
- (p += 4, *((float *)(p - 4)))
-
-#define NEXTDOUBLE(p) \
- (p += 8, *((double *)(p - 8)))
-
-#define NEXTEXTEND(p) \
- (p += 12, 0.0) /* Need a function to convert from extended to double
- precision... */
-
-#define NEXTPACKED(p) \
- (p += 12, 0.0) /* Need a function to convert from packed to double
- precision. Actually, it's easier to print a
- packed number than a double anyway, so maybe
- there should be a special case to handle this... */
-
-/* Print the m68k instruction at address MEMADDR in debugged memory,
- on STREAM. Returns length of the instruction, in bytes. */
-
-int
-print_insn (memaddr, stream)
- CORE_ADDR memaddr;
- FILE *stream;
-{
- unsigned char buffer[MAXLEN];
- register int i;
- register unsigned char *p;
- register char *d;
- register int bestmask;
- int best;
-
- read_memory (memaddr, buffer, MAXLEN);
-
- bestmask = 0;
- best = -1;
- for (i = 0; i < NOPCODES; i++)
- {
- register unsigned int opcode = m68k_opcodes[i].opcode;
- register unsigned int match = m68k_opcodes[i].match;
- if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24)))
- && ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16)))
- && ((0xff & buffer[2] & (match >> 8)) == (0xff & (opcode >> 8)))
- && ((0xff & buffer[3] & match) == (0xff & opcode)))
- {
- /* Don't use for printout the variants of divul and divsl
- that have the same register number in two places.
- The more general variants will match instead. */
- for (d = m68k_opcodes[i].args; *d; d += 2)
- if (d[1] == 'D')
- break;
-
- /* Don't use for printout the variants of most floating
- point coprocessor instructions which use the same
- register number in two places, as above. */
- if (*d == 0)
- for (d = m68k_opcodes[i].args; *d; d += 2)
- if (d[1] == 't')
- break;
-
- if (*d == 0 && match > bestmask)
- {
- best = i;
- bestmask = match;
- }
- }
- }
-
- /* Handle undefined instructions. */
- if (best < 0)
- {
- fprintf (stream, "0%o", (buffer[0] << 8) + buffer[1]);
- return 2;
- }
-
- fprintf (stream, "%s", m68k_opcodes[best].name);
-
- /* Point at first word of argument data,
- and at descriptor for first argument. */
- p = buffer + 2;
-
- /* Why do this this way? -MelloN */
- for (d = m68k_opcodes[best].args; *d; d += 2)
- {
- if (d[0] == '#')
- {
- if (d[1] == 'l' && p - buffer < 6)
- p = buffer + 6;
- else if (p - buffer < 4 && d[1] != 'C' && d[1] != '8' )
- p = buffer + 4;
- }
- if (d[1] >= '1' && d[1] <= '3' && p - buffer < 4)
- p = buffer + 4;
- if (d[1] >= '4' && d[1] <= '6' && p - buffer < 6)
- p = buffer + 6;
- }
-
- d = m68k_opcodes[best].args;
-
- if (*d)
- fputc (' ', stream);
-
- while (*d)
- {
- p = print_insn_arg (d, buffer, p, memaddr + p - buffer, stream);
- d += 2;
- if (*d && *(d - 2) != 'I' && *d != 'k')
- fprintf (stream, ",");
- }
- return p - buffer;
-}
-
-static unsigned char *
-print_insn_arg (d, buffer, p, addr, stream)
- char *d;
- unsigned char *buffer;
- register unsigned char *p;
- CORE_ADDR addr; /* PC for this arg to be relative to */
- FILE *stream;
-{
- register int val;
- register int place = d[1];
- int regno;
- register char *regname;
- register unsigned char *p1;
- register double flval;
- int flt_p;
-
- switch (*d)
- {
- case 'C':
- fprintf (stream, "ccr");
- break;
-
- case 'S':
- fprintf (stream, "sr");
- break;
-
- case 'U':
- fprintf (stream, "usp");
- break;
-
- case 'J':
- {
- static struct { char *name; int value; } names[]
- = {{"sfc", 0x000}, {"dfc", 0x001}, {"cacr", 0x002},
- {"usp", 0x800}, {"vbr", 0x801}, {"caar", 0x802},
- {"msp", 0x803}, {"isp", 0x804}};
-
- val = fetch_arg (buffer, place, 12);
- for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
- if (names[regno].value == val)
- {
- fprintf (stream, names[regno].name);
- break;
- }
- if (regno < 0)
- fprintf (stream, "%d", val);
- }
- break;
-
- case 'Q':
- val = fetch_arg (buffer, place, 3);
- if (val == 0) val = 8;
- fprintf (stream, "#%d", val);
- break;
-
- case 'M':
- val = fetch_arg (buffer, place, 8);
- if (val & 0x80)
- val = val - 0x100;
- fprintf (stream, "#%d", val);
- break;
-
- case 'T':
- val = fetch_arg (buffer, place, 4);
- fprintf (stream, "#%d", val);
- break;
-
- case 'D':
- fprintf (stream, "%s", reg_names[fetch_arg (buffer, place, 3)]);
- break;
-
- case 'A':
- fprintf (stream, "%s", reg_names[fetch_arg (buffer, place, 3) + 010]);
- break;
-
- case 'R':
- fprintf (stream, "%s", reg_names[fetch_arg (buffer, place, 4)]);
- break;
-
- case 'F':
- fprintf (stream, "fp%d", fetch_arg (buffer, place, 3));
- break;
-
- case 'O':
- val = fetch_arg (buffer, place, 6);
- if (val & 0x20)
- fprintf (stream, "%s", reg_names [val & 7]);
- else
- fprintf (stream, "%d", val);
- break;
-
- case '+':
- fprintf (stream, "(%s)+", reg_names[fetch_arg (buffer, place, 3) + 8]);
- break;
-
- case '-':
- fprintf (stream, "-(%s)", reg_names[fetch_arg (buffer, place, 3) + 8]);
- break;
-
- case 'k':
- if (place == 'k')
- fprintf (stream, "{%s}", reg_names[fetch_arg (buffer, place, 3)]);
- else if (place == 'C')
- {
- val = fetch_arg (buffer, place, 7);
- if ( val > 63 ) /* This is a signed constant. */
- val -= 128;
- fprintf (stream, "{#%d}", val);
- }
- else
- error ("Invalid arg format in opcode table: \"%c%c\".",
- *d, place);
- break;
-
- case '#':
- p1 = buffer + 2;
- if (place == 's')
- val = fetch_arg (buffer, place, 4);
- else if (place == 'C')
- val = fetch_arg (buffer, place, 7);
- else if (place == '8')
- val = fetch_arg (buffer, place, 3);
- else if (place == '3')
- val = fetch_arg (buffer, place, 8);
- else if (place == 'b')
- val = NEXTBYTE (p1);
- else if (place == 'w')
- val = NEXTWORD (p1);
- else if (place == 'l')
- val = NEXTLONG (p1);
- else
- error ("Invalid arg format in opcode table: \"%c%c\".",
- *d, place);
- fprintf (stream, "#%d", val);
- break;
-
- case '^':
- if (place == 's')
- val = fetch_arg (buffer, place, 4);
- else if (place == 'C')
- val = fetch_arg (buffer, place, 7);
- else if (place == '8')
- val = fetch_arg (buffer, place, 3);
- else if (place == 'b')
- val = NEXTBYTE (p);
- else if (place == 'w')
- val = NEXTWORD (p);
- else if (place == 'l')
- val = NEXTLONG (p);
- else
- error ("Invalid arg format in opcode table: \"%c%c\".",
- *d, place);
- fprintf (stream, "#%d", val);
- break;
-
- case 'B':
- if (place == 'b')
- val = NEXTBYTE (p);
- else if (place == 'w')
- val = NEXTWORD (p);
- else if (place == 'l')
- val = NEXTLONG (p);
- else if (place == 'g')
- {
- val = ((char *)buffer)[1];
- if (val == 0)
- val = NEXTWORD (p);
- else if (val == -1)
- val = NEXTLONG (p);
- }
- else if (place == 'c')
- {
- if (buffer[1] & 0x40) /* If bit six is one, long offset */
- val = NEXTLONG (p);
- else
- val = NEXTWORD (p);
- }
- else
- error ("Invalid arg format in opcode table: \"%c%c\".",
- *d, place);
-
- print_address (addr + val, stream);
- break;
-
- case 'd':
- val = NEXTWORD (p);
- fprintf (stream, "%d(%s)", val, reg_names[fetch_arg (buffer, place, 3)]);
- break;
-
- case 's':
- fprintf (stream, "%s", fpcr_names[fetch_arg (buffer, place, 3)]);
- break;
-
- case 'I':
- val = fetch_arg (buffer, 'd', 3); /* Get coprocessor ID... */
- if (val != 1) /* Unusual coprocessor ID? */
- fprintf (stream, "(cpid=%d) ", val);
- if (place == 'i')
- p += 2; /* Skip coprocessor extended operands */
- break;
-
- case '*':
- case '~':
- case '%':
- case ';':
- case '@@':
- case '!':
- case '$':
- case '?':
- case '/':
- case '&':
-
- if (place == 'd')
- {
- val = fetch_arg (buffer, 'x', 6);
- val = ((val & 7) << 3) + ((val >> 3) & 7);
- }
- else
- val = fetch_arg (buffer, 's', 6);
-
- /* Get register number assuming address register. */
- regno = (val & 7) + 8;
- regname = reg_names[regno];
- switch (val >> 3)
- {
- case 0:
- fprintf (stream, "%s", reg_names[val]);
- break;
-
- case 1:
- fprintf (stream, "%s", regname);
- break;
-
- case 2:
- fprintf (stream, "(%s)", regname);
- break;
-
- case 3:
- fprintf (stream, "(%s)+", regname);
- break;
-
- case 4:
- fprintf (stream, "-(%s)", regname);
- break;
-
- case 5:
- val = NEXTWORD (p);
- fprintf (stream, "%d(%s)", val, regname);
- break;
-
- case 6:
- p = print_indexed (regno, p, addr, stream);
- break;
-
- case 7:
- switch (val & 7)
- {
- case 0:
- val = NEXTWORD (p);
- fprintf (stream, "@@#");
- print_address (val, stream);
- break;
-
- case 1:
- val = NEXTLONG (p);
- fprintf (stream, "@@#");
- print_address (val, stream);
- break;
-
- case 2:
- val = NEXTWORD (p);
- print_address (addr + val, stream);
- break;
-
- case 3:
- p = print_indexed (-1, p, addr, stream);
- break;
-
- case 4:
- flt_p = 1; /* Assume it's a float... */
- switch( place )
- {
- case 'b':
- val = NEXTBYTE (p);
- flt_p = 0;
- break;
-
- case 'w':
- val = NEXTWORD (p);
- flt_p = 0;
- break;
-
- case 'l':
- val = NEXTLONG (p);
- flt_p = 0;
- break;
-
- case 'f':
- flval = NEXTSINGLE(p);
- break;
-
- case 'F':
- flval = NEXTDOUBLE(p);
- break;
-
- case 'x':
- flval = NEXTEXTEND(p);
- break;
-
- case 'p':
- flval = NEXTPACKED(p);
- break;
-
- default:
- error ("Invalid arg format in opcode table: \"%c%c\".",
- *d, place);
- }
- if ( flt_p ) /* Print a float? */
- fprintf (stream, "#%g", flval);
- else
- fprintf (stream, "#%d", val);
- break;
-
- default:
- fprintf (stream, "<invalid address mode 0%o>", val);
- }
- }
- break;
-
- default:
- error ("Invalid arg format in opcode table: \"%c\".", *d);
- }
-
- return (unsigned char *) p;
-}
-
-/* Fetch BITS bits from a position in the instruction specified by CODE.
- CODE is a "place to put an argument", or 'x' for a destination
- that is a general address (mode and register).
- BUFFER contains the instruction. */
-
-static int
-fetch_arg (buffer, code, bits)
- unsigned char *buffer;
- char code;
- int bits;
-{
- register int val;
- switch (code)
- {
- case 's':
- val = buffer[1];
- break;
-
- case 'd': /* Destination, for register or quick. */
- val = (buffer[0] << 8) + buffer[1];
- val >>= 9;
- break;
-
- case 'x': /* Destination, for general arg */
- val = (buffer[0] << 8) + buffer[1];
- val >>= 6;
- break;
-
- case 'k':
- val = (buffer[3] >> 4);
- break;
-
- case 'C':
- val = buffer[3];
- break;
-
- case '1':
- val = (buffer[2] << 8) + buffer[3];
- val >>= 12;
- break;
-
- case '2':
- val = (buffer[2] << 8) + buffer[3];
- val >>= 6;
- break;
-
- case '3':
- case 'j':
- val = (buffer[2] << 8) + buffer[3];
- break;
-
- case '4':
- val = (buffer[4] << 8) + buffer[5];
- val >>= 12;
- break;
-
- case '5':
- val = (buffer[4] << 8) + buffer[5];
- val >>= 6;
- break;
-
- case '6':
- val = (buffer[4] << 8) + buffer[5];
- break;
-
- case '7':
- val = (buffer[2] << 8) + buffer[3];
- val >>= 7;
- break;
-
- case '8':
- val = (buffer[2] << 8) + buffer[3];
- val >>= 10;
- break;
-
- default:
- abort ();
- }
-
- switch (bits)
- {
- case 3:
- return val & 7;
- case 4:
- return val & 017;
- case 5:
- return val & 037;
- case 6:
- return val & 077;
- case 7:
- return val & 0177;
- case 8:
- return val & 0377;
- case 12:
- return val & 07777;
- default:
- abort ();
- }
-}
-
-/* Print an indexed argument. The base register is BASEREG (-1 for pc).
- P points to extension word, in buffer.
- ADDR is the nominal core address of that extension word. */
-
-static unsigned char *
-print_indexed (basereg, p, addr, stream)
- int basereg;
- unsigned char *p;
- FILE *stream;
- CORE_ADDR addr;
-{
- register int word;
- static char *scales[] = {"", "*2", "*4", "*8"};
- register int base_disp;
- register int outer_disp;
- char buf[40];
-
- word = NEXTWORD (p);
-
- /* Generate the text for the index register.
- Where this will be output is not yet determined. */
- sprintf (buf, "[%s.%c%s]",
- reg_names[(word >> 12) & 0xf],
- (word & 0x800) ? 'l' : 'w',
- scales[(word >> 9) & 3]);
-
- /* Handle the 68000 style of indexing. */
-
- if ((word & 0x100) == 0)
- {
- print_base (basereg,
- ((word & 0x80) ? word | 0xff00 : word & 0xff)
- + ((basereg == -1) ? addr : 0),
- stream);
- fprintf (stream, "%s", buf);
- return p;
- }
-
- /* Handle the generalized kind. */
- /* First, compute the displacement to add to the base register. */
-
- if (word & 0200)
- basereg = -2;
- if (word & 0100)
- buf[0] = 0;
- base_disp = 0;
- switch ((word >> 4) & 3)
- {
- case 2:
- base_disp = NEXTWORD (p);
- break;
- case 3:
- base_disp = NEXTLONG (p);
- }
- if (basereg == -1)
- base_disp += addr;
-
- /* Handle single-level case (not indirect) */
-
- if ((word & 7) == 0)
- {
- print_base (basereg, base_disp, stream);
- fprintf (stream, "%s", buf);
- return p;
- }
-
- /* Two level. Compute displacement to add after indirection. */
-
- outer_disp = 0;
- switch (word & 3)
- {
- case 2:
- outer_disp = NEXTWORD (p);
- break;
- case 3:
- outer_disp = NEXTLONG (p);
- }
-
- fprintf (stream, "%d(", outer_disp);
- print_base (basereg, base_disp, stream);
-
- /* If postindexed, print the closeparen before the index. */
- if (word & 4)
- fprintf (stream, ")%s", buf);
- /* If preindexed, print the closeparen after the index. */
- else
- fprintf (stream, "%s)", buf);
-
- return p;
-}
-
-/* Print a base register REGNO and displacement DISP, on STREAM.
- REGNO = -1 for pc, -2 for none (suppressed). */
-
-static void
-print_base (regno, disp, stream)
- int regno;
- int disp;
- FILE *stream;
-{
- if (regno == -2)
- fprintf (stream, "%d", disp);
- else if (regno == -1)
- fprintf (stream, "0x%x", disp);
- else
- fprintf (stream, "%d(%s)", disp, reg_names[regno]);
-}
-
-/* This is not part of insn printing, but it is machine-specific,
- so this is a convenient place to put it.
-
- Convert a 68881 extended float to a double.
- FROM is the address of the extended float.
- Store the double in *TO. */
-
-convert_from_68881 (from, to)
- char *from;
- double *to;
-{
-#ifdef USG_SGS_ASM
- asm ("mov.l 8(%a6),%a0");
- asm ("mov.l 12(%a6),%a1");
- asm ("fmove.x (%a0),%fp0");
- asm ("fmove.d %fp0,(%a1)");
-#else /* not USG_SGS_ASM */
-#if 0
- asm ("movl a6@@(8),a0");
- asm ("movl a6@@(12),a1");
- asm ("fmovex a0@@,fp0");
- asm ("fmoved fp0,a1@@");
-#else
- /* Hand-assemble those insns since some assemblers lose
- and some have different syntax. */
- asm (".word 020156");
- asm (".word 8");
- asm (".word 021156");
- asm (".word 12");
- asm (".long 0xf2104800");
- asm (".long 0xf2117400");
-#endif
-#endif /* not USG_SGS_ASM */
-}
-
-/* The converse: convert the double *FROM to an extended float
- and store where TO points. */
-
-convert_to_68881 (from, to)
- double *from;
- char *to;
-{
-#ifdef USG_SGS_ASM
- asm ("mov.l 8(%a6),%a0");
- asm ("mov.l 12(%a6),%a1");
- asm ("fmove.d (%a0),%fp0");
- asm ("fmove.x %fp0,(%a1)");
-#else /* not USG_SGS_ASM */
-#if 0
- asm ("movl a6@@(8),a0");
- asm ("movl a6@@(12),a1");
- asm ("fmoved a0@@,fp0");
- asm ("fmovex fp0,a1@@");
-#else
- /* Hand-assemble those insns since some assemblers lose. */
- asm (".word 020156");
- asm (".word 8");
- asm (".word 021156");
- asm (".word 12");
- asm (".long 0xf2105400");
- asm (".long 0xf2116800");
-#endif
-#endif /* not USG_SGS_ASM */
-}
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d717 1
-a717 1
-#ifdef HPUX_ASM
-d722 1
-a722 1
-#else /* not HPUX_ASM */
-d738 1
-a738 1
-#endif /* not HPUX_ASM */
-d748 1
-a748 1
-#ifdef HPUX_ASM
-d753 1
-a753 1
-#else /* not HPUX_ASM */
-d768 1
-a768 1
-#endif /* not HPUX_ASM */
-@
diff --git a/gdb/RCS/main.c,v b/gdb/RCS/main.c,v
deleted file mode 100644
index 1e6fafa..0000000
--- a/gdb/RCS/main.c,v
+++ /dev/null
@@ -1,1348 +0,0 @@
-head 1.2;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.2
-date 89.03.27.21.15.02; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.03.27.21.11.51; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.2
-log
-@Fix up "munch" so it generates a name that doesn't match its own
-"grep" conventions. Change main so that it calls the new name,
-and also doesn't use the conventions for functions that should NOT
-be called by init.c.
-@
-text
-@/* Top level for GDB, the GNU debugger.
- Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-#include "defs.h"
-#include "command.h"
-#include "param.h"
-
-#ifdef USG
-#include <sys/types.h>
-#include <unistd.h>
-#endif
-
-#include <sys/file.h>
-#include <stdio.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <sys/param.h>
-
-#ifdef SET_STACK_LIMIT_HUGE
-#include <sys/time.h>
-#include <sys/resource.h>
-
-int original_stack_limit;
-#endif
-
-/* Version number of GDB, as a string. */
-
-extern char *version;
-
-/*
- * Declare all cmd_list_element's
- */
-
-/* Chain containing all defined commands. */
-
-struct cmd_list_element *cmdlist;
-
-/* Chain containing all defined info subcommands. */
-
-struct cmd_list_element *infolist;
-
-/* Chain containing all defined enable subcommands. */
-
-struct cmd_list_element *enablelist;
-
-/* Chain containing all defined disable subcommands. */
-
-struct cmd_list_element *disablelist;
-
-/* Chain containing all defined delete subcommands. */
-
-struct cmd_list_element *deletelist;
-
-/* Chain containing all defined "enable breakpoint" subcommands. */
-
-struct cmd_list_element *enablebreaklist;
-
-/* Chain containing all defined set subcommands */
-
-struct cmd_list_element *setlist;
-
-/* stdio stream that command input is being read from. */
-
-FILE *instream;
-
-/* Current working directory. */
-
-char *current_directory;
-
-/* The directory name is actually stored here (usually). */
-static char dirbuf[MAXPATHLEN];
-
-/* Nonzero if we should refrain from using an X window. */
-
-int inhibit_windows = 0;
-
-/* Function to call before reading a command, if nonzero.
- The function receives two args: an input stream,
- and a prompt string. */
-
-void (*window_hook) ();
-
-extern int frame_file_full_name;
-
-void free_command_lines ();
-char *gdb_read_line ();
-static void init_main ();
-static void init_cmd_lists ();
-void command_loop ();
-static void source_command ();
-static void print_gdb_version ();
-
-/* gdb prints this when reading a command interactively */
-static char *prompt;
-
-/* Buffer used for reading command lines, and the size
- allocated for it so far. */
-
-char *line;
-int linesize;
-
-/* This is how `error' returns to command level. */
-
-jmp_buf to_top_level;
-
-void
-return_to_top_level ()
-{
- quit_flag = 0;
- immediate_quit = 0;
- clear_breakpoint_commands ();
- clear_momentary_breakpoints ();
- delete_current_display ();
- do_cleanups (0);
- longjmp (to_top_level, 1);
-}
-
-/* Call FUNC with arg ARG, catching any errors.
- If there is no error, return the value returned by FUNC.
- If there is an error, return zero after printing ERRSTRING
- (which is in addition to the specific error message already printed). */
-
-int
-catch_errors (func, arg, errstring)
- int (*func) ();
- int arg;
- char *errstring;
-{
- jmp_buf saved;
- int val;
- struct cleanup *saved_cleanup_chain;
-
- saved_cleanup_chain = save_cleanups ();
-
- bcopy (to_top_level, saved, sizeof (jmp_buf));
-
- if (setjmp (to_top_level) == 0)
- val = (*func) (arg);
- else
- {
- fprintf (stderr, "%s\n", errstring);
- val = 0;
- }
-
- restore_cleanups (saved_cleanup_chain);
-
- bcopy (saved, to_top_level, sizeof (jmp_buf));
- return val;
-}
-
-/* Handler for SIGHUP. */
-
-static void
-disconnect ()
-{
- kill_inferior_fast ();
- signal (SIGHUP, SIG_DFL);
- kill (getpid (), SIGHUP);
-}
-
-/* Clean up on error during a "source" command (or execution of a
- user-defined command).
- Close the file opened by the command
- and restore the previous input stream. */
-
-static void
-source_cleanup (stream)
- FILE *stream;
-{
- /* Instream may be 0; set to it when executing user-defined command. */
- if (instream)
- fclose (instream);
- instream = stream;
-}
-
-
-int
-main (argc, argv, envp)
- int argc;
- char **argv;
- char **envp;
-{
- extern void request_quit ();
- int count;
- int inhibit_gdbinit = 0;
- int quiet = 0;
- int batch = 0;
- register int i;
-
- quit_flag = 0;
- linesize = 100;
- line = (char *) xmalloc (linesize);
- instream = stdin;
-
- getwd (dirbuf);
- current_directory = dirbuf;
-
-#ifdef SET_STACK_LIMIT_HUGE
- {
- struct rlimit rlim;
-
- /* Set the stack limit huge so that alloca (particularly stringtab
- * in dbxread.c) does not fail. */
- getrlimit (RLIMIT_STACK, &rlim);
- original_stack_limit = rlim.rlim_cur;
- rlim.rlim_cur = rlim.rlim_max;
- setrlimit (RLIMIT_STACK, &rlim);
- }
-#endif /* SET_STACK_LIMIT_HUGE */
-
- /* Look for flag arguments. */
-
- for (i = 1; i < argc; i++)
- {
- if (!strcmp (argv[i], "-q") || !strcmp (argv[i], "-quiet"))
- quiet = 1;
- else if (!strcmp (argv[i], "-nx"))
- inhibit_gdbinit = 1;
- else if (!strcmp (argv[i], "-nw"))
- inhibit_windows = 1;
- else if (!strcmp (argv[i], "-batch"))
- batch = 1, quiet = 1;
- else if (!strcmp (argv[i], "-fullname"))
- frame_file_full_name = 1;
- else if (argv[i][0] == '-')
- i++;
- }
-
- /* Run the init function of each source file */
-
- init_cmd_lists (); /* This needs to be done first */
- init_all_files ();
- init_main (); /* But that omits this file! Do it now */
-
- signal (SIGINT, request_quit);
- signal (SIGQUIT, SIG_IGN);
- if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
- signal (SIGHUP, disconnect);
-
- if (!quiet)
- print_gdb_version ();
-
- /* Process the command line arguments. */
-
- count = 0;
- for (i = 1; i < argc; i++)
- {
- register char *arg = argv[i];
- /* Args starting with - say what to do with the following arg
- as a filename. */
- if (arg[0] == '-')
- {
- extern void exec_file_command (), symbol_file_command ();
- extern void core_file_command (), directory_command ();
- extern void tty_command ();
-
- if (!strcmp (arg, "-q") || !strcmp (arg, "-nx")
- || !strcmp (arg, "-quiet") || !strcmp (arg, "-batch")
- || !strcmp (arg, "-fullname"))
- /* Already processed above */
- continue;
-
- if (++i == argc)
- fprintf (stderr, "No argument follows \"%s\".\n", arg);
- if (!setjmp (to_top_level))
- {
- /* -s foo: get syms from foo. -e foo: execute foo.
- -se foo: do both with foo. -c foo: use foo as core dump. */
- if (!strcmp (arg, "-se"))
- {
- exec_file_command (argv[i], !batch);
- symbol_file_command (argv[i], !batch);
- }
- else if (!strcmp (arg, "-s") || !strcmp (arg, "-symbols"))
- symbol_file_command (argv[i], !batch);
- else if (!strcmp (arg, "-e") || !strcmp (arg, "-exec"))
- exec_file_command (argv[i], !batch);
- else if (!strcmp (arg, "-c") || !strcmp (arg, "-core"))
- core_file_command (argv[i], !batch);
- /* -x foo: execute commands from foo. */
- else if (!strcmp (arg, "-x") || !strcmp (arg, "-command")
- || !strcmp (arg, "-commands"))
- source_command (argv[i]);
- /* -d foo: add directory `foo' to source-file directory
- search-list */
- else if (!strcmp (arg, "-d") || !strcmp (arg, "-dir")
- || !strcmp (arg, "-directory"))
- directory_command (argv[i], 0);
- /* -cd FOO: specify current directory as FOO.
- GDB remembers the precise string FOO as the dirname. */
- else if (!strcmp (arg, "-cd"))
- {
- int len = strlen (argv[i]);
- current_directory = argv[i];
- if (len > 1 && current_directory[len - 1] == '/')
- current_directory = savestring (current_directory, len-1);
- chdir (current_directory);
- init_source_path ();
- }
- /* -t /def/ttyp1: use /dev/ttyp1 for inferior I/O. */
- else if (!strcmp (arg, "-t") || !strcmp (arg, "-tty"))
- tty_command (argv[i], 0);
- else
- error ("Unknown command-line switch: \"%s\"\n", arg);
- }
- }
- else
- {
- /* Args not thus accounted for
- are treated as, first, the symbol/executable file
- and, second, the core dump file. */
- count++;
- if (!setjmp (to_top_level))
- switch (count)
- {
- case 1:
- exec_file_command (arg, !batch);
- symbol_file_command (arg, !batch);
- break;
-
- case 2:
- core_file_command (arg, !batch);
- break;
-
- case 3:
- fprintf (stderr, "Excess command line args ignored. (%s%s)\n",
- arg, (i == argc - 1) ? "" : " ...");
- }
- }
- }
-
- /* Read init file, if it exists in home directory */
- if (getenv ("HOME"))
- {
- char *s;
- s = (char *) xmalloc (strlen (getenv ("HOME")) + 10);
- strcpy (s, getenv ("HOME"));
- strcat (s, "/.gdbinit");
- if (!inhibit_gdbinit && access (s, R_OK) == 0)
- if (!setjmp (to_top_level))
- source_command (s);
- }
-
- /* Read init file, if it exists in current directory. */
- if (!inhibit_gdbinit && access (".gdbinit", R_OK) == 0)
- if (!setjmp (to_top_level))
- source_command (".gdbinit");
-
- if (batch)
- fatal ("Attempt to read commands from stdin in batch mode.");
-
- if (!quiet)
- printf ("Type \"help\" for a list of commands.\n");
-
- /* The command loop. */
-
- while (1)
- {
- if (!setjmp (to_top_level))
- command_loop ();
- clearerr (stdin); /* Don't get hung if C-d is typed. */
- }
-}
-
-/* Execute the line P as a command.
- Pass FROM_TTY as second argument to the defining function. */
-
-void
-execute_command (p, from_tty)
- char *p;
- int from_tty;
-{
- register struct cmd_list_element *c;
- register struct command_line *cmdlines;
-
- free_all_values ();
- while (*p == ' ' || *p == '\t') p++;
- if (*p)
- {
- c = lookup_cmd (&p, cmdlist, "", 0);
- if (c->function == 0)
- error ("That is not a command, just a help topic.");
- else if (c->class == (int) class_user)
- {
- struct cleanup *old_chain;
-
- if (*p)
- error ("User-defined commands cannot take arguments.");
- cmdlines = (struct command_line *) c->function;
- if (cmdlines == (struct command_line *) 0)
- /* Null command */
- return;
-
- /* Set the instream to 0, indicating execution of a
- user-defined function. */
- old_chain = make_cleanup (source_cleanup, instream);
- instream = (FILE *) 0;
- while (cmdlines)
- {
- execute_command (cmdlines->line, 0);
- cmdlines = cmdlines->next;
- }
- do_cleanups (old_chain);
- }
- else
- /* Pass null arg rather than an empty one. */
- (*c->function) (*p ? p : 0, from_tty);
- }
-}
-
-static void
-do_nothing ()
-{
-}
-
-/* Read commands from `instream' and execute them
- until end of file. */
-void
-command_loop ()
-{
- struct cleanup *old_chain;
- while (!feof (instream))
- {
- if (window_hook && instream == stdin)
- (*window_hook) (instream, prompt);
-
- quit_flag = 0;
- old_chain = make_cleanup (do_nothing, 0);
- execute_command (gdb_read_line (instream == stdin ? prompt : 0,
- instream == stdin),
- instream == stdin);
- /* Do any commands attached to breakpoint we stopped at. */
- do_breakpoint_commands ();
- do_cleanups (old_chain);
- }
-}
-
-#ifdef SIGTSTP
-static void
-stop_sig ()
-{
- signal (SIGTSTP, SIG_DFL);
- sigsetmask (0);
- kill (getpid (), SIGTSTP);
- signal (SIGTSTP, stop_sig);
- printf ("%s", prompt);
- fflush (stdout);
-
- /* Forget about any previous command -- null line now will do nothing. */
- *line = 0;
-}
-#endif /* SIGTSTP */
-
-/* Commands call this if they do not want to be repeated by null lines. */
-
-void
-dont_repeat ()
-{
- *line = 0;
-}
-
-/* Read one line from the command input stream `instream'
- into the buffer `line' (whose current length is `linesize').
- The buffer is made bigger as necessary.
- Returns the address of the start of the line. */
-
-char *
-gdb_read_line (prompt, repeat)
- char *prompt;
- int repeat;
-{
- register char *p = line;
- register char *p1;
- register int c;
- char *nline;
-
- /* Control-C quits instantly if typed while in this loop
- since it should not wait until the user types a newline. */
- immediate_quit++;
-#ifdef SIGTSTP
- signal (SIGTSTP, stop_sig);
-#endif
-
- if (prompt)
- {
- printf (prompt);
- fflush (stdout);
- }
-
- while (1)
- {
- c = fgetc (instream);
- if (c == -1 || c == '\n')
- break;
- /* Ignore backslash-newline; keep adding to the same line. */
- else if (c == '\\')
- {
- int c1 = fgetc (instream);
- if (c1 == '\n')
- continue;
- else
- ungetc (c1, instream);
- }
-
- if (p - line == linesize - 1)
- {
- linesize *= 2;
- nline = (char *) xrealloc (line, linesize);
- p += nline - line;
- line = nline;
- }
- *p++ = c;
- }
-
-#ifdef SIGTSTP
- signal (SIGTSTP, SIG_DFL);
-#endif
- immediate_quit--;
-
- /* If we just got an empty line, and that is supposed
- to repeat the previous command, leave the last input unchanged. */
- if (p == line && repeat)
- return line;
-
- /* If line is a comment, clear it out. */
- p1 = line;
- while ((c = *p1) == ' ' || c == '\t') p1++;
- if (c == '#')
- p = line;
-
- *p = 0;
-
- return line;
-}
-
-/* Read lines from the input stream
- and accumulate them in a chain of struct command_line's
- which is then returned. */
-
-struct command_line *
-read_command_lines ()
-{
- struct command_line *first = 0;
- register struct command_line *next, *tail = 0;
- register char *p, *p1;
- struct cleanup *old_chain = 0;
-
- while (1)
- {
- dont_repeat ();
- p = gdb_read_line (0, 1);
- /* Remove leading and trailing blanks. */
- while (*p == ' ' || *p == '\t') p++;
- p1 = p + strlen (p);
- while (p1 != p && (p1[-1] == ' ' || p1[-1] == '\t')) p1--;
-
- /* Is this "end"? */
- if (p1 - p == 3 && !strncmp (p, "end", 3))
- break;
-
- /* No => add this line to the chain of command lines. */
- next = (struct command_line *) xmalloc (sizeof (struct command_line));
- next->line = savestring (p, p1 - p);
- next->next = 0;
- if (tail)
- {
- tail->next = next;
- }
- else
- {
- /* We just read the first line.
- From now on, arrange to throw away the lines we have
- if we quit or get an error while inside this function. */
- first = next;
- old_chain = make_cleanup (free_command_lines, &first);
- }
- tail = next;
- }
-
- dont_repeat ();
-
- /* Now we are about to return the chain to our caller,
- so freeing it becomes his responsibility. */
- if (first)
- discard_cleanups (old_chain);
- return first;
-}
-
-/* Free a chain of struct command_line's. */
-
-void
-free_command_lines (lptr)
- struct command_line **lptr;
-{
- register struct command_line *l = *lptr;
- register struct command_line *next;
-
- while (l)
- {
- next = l->next;
- free (l->line);
- free (l);
- l = next;
- }
-}
-
-/* Add an element to the list of info subcommands. */
-
-void
-add_info (name, fun, doc)
- char *name;
- void (*fun) ();
- char *doc;
-{
- add_cmd (name, no_class, fun, doc, &infolist);
-}
-
-/* Add an alias to the list of info subcommands. */
-
-void
-add_info_alias (name, oldname, abbrev_flag)
- char *name;
- char *oldname;
- int abbrev_flag;
-{
- add_alias_cmd (name, oldname, 0, abbrev_flag, &infolist);
-}
-
-/* The "info" command is defined as a prefix, with allow_unknown = 0.
- Therefore, its own definition is called only for "info" with no args. */
-
-static void
-info_command ()
-{
- printf ("\"info\" must be followed by the name of an info command.\n");
- help_list (infolist, "info ", -1, stdout);
-}
-
-/* Add an element to the list of commands. */
-
-void
-add_com (name, class, fun, doc)
- char *name;
- int class;
- void (*fun) ();
- char *doc;
-{
- add_cmd (name, class, fun, doc, &cmdlist);
-}
-
-/* Add an alias or abbreviation command to the list of commands. */
-
-void
-add_com_alias (name, oldname, class, abbrev_flag)
- char *name;
- char *oldname;
- int class;
- int abbrev_flag;
-{
- add_alias_cmd (name, oldname, class, abbrev_flag, &cmdlist);
-}
-
-void
-error_no_arg (why)
- char *why;
-{
- error ("Argument required (%s).", why);
-}
-
-static void
-help_command (command, from_tty)
- char *command;
- int from_tty; /* Ignored */
-{
- help_cmd (command, stdout);
-}
-
-static void
-validate_comname (comname)
- char *comname;
-{
- register char *p;
-
- if (comname == 0)
- error_no_arg ("name of command to define");
-
- p = comname;
- while (*p)
- {
- if (!(*p >= 'A' && *p <= 'Z')
- && !(*p >= 'a' && *p <= 'z')
- && !(*p >= '0' && *p <= '9')
- && *p != '-')
- error ("Junk in argument list: \"%s\"", p);
- p++;
- }
-}
-
-static void
-define_command (comname, from_tty)
- char *comname;
- int from_tty;
-{
- register struct command_line *cmds;
- register struct cmd_list_element *c;
- char *tem = comname;
-
- validate_comname (comname);
-
- c = lookup_cmd (&tem, cmdlist, "", -1);
- if (c)
- {
- if (c->class == (int) class_user || c->class == (int) class_alias)
- tem = "Redefine command \"%s\"? ";
- else
- tem = "Really redefine built-in command \"%s\"? ";
- if (!query (tem, comname))
- error ("Command \"%s\" not redefined.", comname);
- }
-
- if (from_tty)
- {
- printf ("Type commands for definition of \"%s\".\n\
-End with a line saying just \"end\".\n", comname);
- fflush (stdout);
- }
- comname = savestring (comname, strlen (comname));
-
- cmds = read_command_lines ();
-
- if (c && c->class == (int) class_user)
- free_command_lines (&c->function);
-
- add_com (comname, class_user, cmds,
- (c && c->class == (int) class_user)
- ? c->doc : savestring ("User-defined.", 13));
-}
-
-static void
-document_command (comname, from_tty)
- char *comname;
- int from_tty;
-{
- struct command_line *doclines;
- register struct cmd_list_element *c;
- char *tem = comname;
-
- validate_comname (comname);
-
- c = lookup_cmd (&tem, cmdlist, "", 0);
-
- if (c->class != (int) class_user)
- error ("Command \"%s\" is built-in.", comname);
-
- if (from_tty)
- printf ("Type documentation for \"%s\".\n\
-End with a line saying just \"end\".\n", comname);
-
- doclines = read_command_lines ();
-
- if (c->doc) free (c->doc);
-
- {
- register struct command_line *cl1;
- register int len = 0;
-
- for (cl1 = doclines; cl1; cl1 = cl1->next)
- len += strlen (cl1->line) + 1;
-
- c->doc = (char *) xmalloc (len + 1);
- *c->doc = 0;
-
- for (cl1 = doclines; cl1; cl1 = cl1->next)
- {
- strcat (c->doc, cl1->line);
- if (cl1->next)
- strcat (c->doc, "\n");
- }
- }
-
- free_command_lines (&doclines);
-}
-
-static void
-copying_info ()
-{
- immediate_quit++;
- printf (" GDB GENERAL PUBLIC LICENSE\n\
- (Clarified 11 Feb 1988)\n\
-\n\
- Copyright (C) 1988 Richard M. Stallman\n\
- Everyone is permitted to copy and distribute verbatim copies\n\
- of this license, but changing it is not allowed.\n\
- You can also use this wording to make the terms for other programs.\n\
-\n\
- The license agreements of most software companies keep you at the\n\
-mercy of those companies. By contrast, our general public license is\n\
-intended to give everyone the right to share GDB. To make sure that\n\
-you get the rights we want you to have, we need to make restrictions\n\
-that forbid anyone to deny you these rights or to ask you to surrender\n\
-the rights. Hence this license agreement.\n\
-\n\
- Specifically, we want to make sure that you have the right to give\n\
-away copies of GDB, that you receive source code or else can get it\n\
-if you want it, that you can change GDB or use pieces of it in new\n\
-free programs, and that you know you can do these things.\n\
---Type Return to print more--");
- fflush (stdout);
- gdb_read_line (0, 0);
-
- printf ("\
- To make sure that everyone has such rights, we have to forbid you to\n\
-deprive anyone else of these rights. For example, if you distribute\n\
-copies of GDB, you must give the recipients all the rights that you\n\
-have. You must make sure that they, too, receive or can get the\n\
-source code. And you must tell them their rights.\n\
-\n\
- Also, for our own protection, we must make certain that everyone\n\
-finds out that there is no warranty for GDB. If GDB is modified by\n\
-someone else and passed on, we want its recipients to know that what\n\
-they have is not what we distributed, so that any problems introduced\n\
-by others will not reflect on our reputation.\n\
-\n\
- Therefore we (Richard Stallman and the Free Software Foundation,\n\
-Inc.) make the following terms which say what you must do to be\n\
-allowed to distribute or change GDB.\n\
---Type Return to print more--");
- fflush (stdout);
- gdb_read_line (0, 0);
-
- printf ("\
- COPYING POLICIES\n\
-\n\
- 1. You may copy and distribute verbatim copies of GDB source code as\n\
-you receive it, in any medium, provided that you conspicuously and\n\
-appropriately publish on each copy a valid copyright notice \"Copyright\n\
-\(C) 1988 Free Software Foundation, Inc.\" (or with whatever year is\n\
-appropriate); keep intact the notices on all files that refer\n\
-to this License Agreement and to the absence of any warranty; and give\n\
-any other recipients of the GDB program a copy of this License\n\
-Agreement along with the program. You may charge a distribution fee\n\
-for the physical act of transferring a copy.\n\
-\n\
- 2. You may modify your copy or copies of GDB or any portion of it,\n\
-and copy and distribute such modifications under the terms of\n\
-Paragraph 1 above, provided that you also do the following:\n\
-\n\
- a) cause the modified files to carry prominent notices stating\n\
- that you changed the files and the date of any change; and\n\
---Type Return to print more--");
- fflush (stdout);
- gdb_read_line (0, 0);
-
- printf ("\
- b) cause the whole of any work that you distribute or publish,\n\
- that in whole or in part contains or is a derivative of GDB\n\
- or any part thereof, to be licensed to all third parties on terms\n\
- identical to those contained in this License Agreement (except that\n\
- you may choose to grant more extensive warranty protection to some\n\
- or all third parties, at your option).\n\
-\n");
- printf ("\
- c) if the modified program serves as a debugger, cause it\n\
- when started running in the simplest and usual way, to print\n\
- an announcement including a valid copyright notice\n\
- \"Copyright (C) 1988 Free Software Foundation, Inc.\" (or with\n\
- the year that is appropriate), saying that there is no warranty\n\
- (or else, saying that you provide a warranty) and that users may\n\
- redistribute the program under these conditions, and telling the user\n\
- how to view a copy of this License Agreement.\n\
-\n\
- d) You may charge a distribution fee for the physical act of\n\
- transferring a copy, and you may at your option offer warranty\n\
- protection in exchange for a fee.\n\
-\n\
-Mere aggregation of another unrelated program with this program (or its\n\
-derivative) on a volume of a storage or distribution medium does not bring\n\
-the other program under the scope of these terms.\n\
---Type Return to print more--");
- fflush (stdout);
- gdb_read_line (0, 0);
-
- printf ("\
- 3. You may copy and distribute GDB (or a portion or derivative of it,\n\
-under Paragraph 2) in object code or executable form under the terms of\n\
-Paragraphs 1 and 2 above provided that you also do one of the following:\n\
-\n\
- a) accompany it with the complete corresponding machine-readable\n\
- source code, which must be distributed under the terms of\n\
- Paragraphs 1 and 2 above; or,\n\
-\n\
- b) accompany it with a written offer, valid for at least three\n\
- years, to give any third party free (except for a nominal\n\
- shipping charge) a complete machine-readable copy of the\n\
- corresponding source code, to be distributed under the terms of\n\
- Paragraphs 1 and 2 above; or,\n\n");
-
- printf ("\
- c) accompany it with the information you received as to where the\n\
- corresponding source code may be obtained. (This alternative is\n\
- allowed only for noncommercial distribution and only if you\n\
- received the program in object code or executable form alone.)\n\
-\n\
-For an executable file, complete source code means all the source code for\n\
-all modules it contains; but, as a special exception, it need not include\n\
-source code for modules which are standard libraries that accompany the\n\
-operating system on which the executable file runs.\n\
---Type Return to print more--");
- fflush (stdout);
- gdb_read_line (0, 0);
-
- printf ("\
- 4. You may not copy, sublicense, distribute or transfer GDB\n\
-except as expressly provided under this License Agreement. Any attempt\n\
-otherwise to copy, sublicense, distribute or transfer GDB is void and\n\
-your rights to use the program under this License agreement shall be\n\
-automatically terminated. However, parties who have received computer\n\
-software programs from you with this License Agreement will not have\n\
-their licenses terminated so long as such parties remain in full compliance.\n\
-\n\
-");
- printf ("\
- 5. If you wish to incorporate parts of GDB into other free\n\
-programs whose distribution conditions are different, write to the Free\n\
-Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet\n\
-worked out a simple rule that can be stated here, but we will often permit\n\
-this. We will be guided by the two goals of preserving the free status of\n\
-all derivatives of our free software and of promoting the sharing and reuse\n\
-of software.\n\
-\n\
-In other words, go ahead and share GDB, but don't try to stop\n\
-anyone else from sharing it farther. Help stamp out software hoarding!\n\
-");
- immediate_quit--;
-}
-
-static void
-warranty_info ()
-{
- immediate_quit++;
- printf (" NO WARRANTY\n\
-\n\
- BECAUSE GDB IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY NO\n\
-WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT\n\
-WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,\n\
-RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE GDB \"AS IS\" WITHOUT\n\
-WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT\n\
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n\
-A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND\n\
-PERFORMANCE OF GDB IS WITH YOU. SHOULD GDB PROVE DEFECTIVE, YOU\n\
-ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n");
-
- printf ("\
- IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.\n\
-STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY\n\
-WHO MAY MODIFY AND REDISTRIBUTE GDB, BE LIABLE TO\n\
-YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER\n\
-SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR\n\
-INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA\n\
-BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A\n\
-FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GDB, EVEN\n\
-IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR\n\
-ANY CLAIM BY ANY OTHER PARTY.\n");
- immediate_quit--;
-}
-
-static void
-print_gdb_version ()
-{
- printf ("GDB %s, Copyright (C) 1988 Free Software Foundation, Inc.\n\
-There is ABSOLUTELY NO WARRANTY for GDB; type \"info warranty\" for details.\n\
-GDB is free software and you are welcome to distribute copies of it\n\
- under certain conditions; type \"info copying\" to see the conditions.\n",
- version);
-}
-
-static void
-version_info ()
-{
- immediate_quit++;
- print_gdb_version ();
- immediate_quit--;
-}
-
-/* xgdb calls this to reprint the usual GDB prompt. */
-
-void
-print_prompt ()
-{
- printf ("%s", prompt);
- fflush (stdout);
-}
-
-/* Command to specify a prompt string instead of "(gdb) ". */
-
-static void
-set_prompt_command (text)
- char *text;
-{
- char *p, *q;
- register int c;
- char *new;
-
- if (text == 0)
- error_no_arg ("string to which to set prompt");
-
- new = (char *) xmalloc (strlen (text) + 2);
- p = text; q = new;
- while (c = *p++)
- {
- if (c == '\\')
- {
- /* \ at end of argument is used after spaces
- so they won't be lost. */
- if (*p == 0)
- break;
- c = parse_escape (&p);
- if (c == 0)
- break; /* C loses */
- else if (c > 0)
- *q++ = c;
- }
- else
- *q++ = c;
- }
- if (*(p - 1) != '\\')
- *q++ = ' ';
- *q++ = '\0';
- new = (char *) xrealloc (new, q - new);
- free (prompt);
- prompt = new;
-}
-
-static void
-quit_command ()
-{
- if (have_inferior_p ())
- {
- if (query ("The program is running. Quit anyway? "))
- {
- /* Prevent any warning message from reopen_exec_file, in case
- we have a core file that's inconsistent with the exec file. */
- exec_file_command (0, 0);
- kill_inferior ();
- }
- else
- error ("Not confirmed.");
- }
- exit (0);
-}
-
-int
-input_from_terminal_p ()
-{
- return instream == stdin;
-}
-
-static void
-pwd_command (arg, from_tty)
- char *arg;
- int from_tty;
-{
- if (arg) error ("The \"pwd\" command does not take an argument: %s", arg);
- getwd (dirbuf);
-
- if (strcmp (dirbuf, current_directory))
- printf ("Working directory %s\n (canonically %s).\n",
- current_directory, dirbuf);
- else
- printf ("Working directory %s.\n", current_directory);
-}
-
-static void
-cd_command (dir, from_tty)
- char *dir;
- int from_tty;
-{
- int len;
- int change;
-
- if (dir == 0)
- error_no_arg ("new working directory");
-
- len = strlen (dir);
- dir = savestring (dir, len - (len > 1 && dir[len-1] == '/'));
- if (dir[0] == '/')
- current_directory = dir;
- else
- {
- current_directory = concat (current_directory, "/", dir);
- free (dir);
- }
-
- /* Now simplify any occurrences of `.' and `..' in the pathname. */
-
- change = 1;
- while (change)
- {
- char *p;
- change = 0;
-
- for (p = current_directory; *p;)
- {
- if (!strncmp (p, "/./", 2)
- && (p[2] == 0 || p[2] == '/'))
- strcpy (p, p + 2);
- else if (!strncmp (p, "/..", 3)
- && (p[3] == 0 || p[3] == '/')
- && p != current_directory)
- {
- char *q = p;
- while (q != current_directory && q[-1] != '/') q--;
- if (q != current_directory)
- {
- strcpy (q-1, p+3);
- p = q-1;
- }
- }
- else p++;
- }
- }
-
- if (chdir (dir) < 0)
- perror_with_name (dir);
-
- if (from_tty)
- pwd_command ((char *) 0, 1);
-}
-
-static void
-source_command (file)
- char *file;
-{
- FILE *stream;
- struct cleanup *cleanups;
-
- if (file == 0)
- error_no_arg ("file to read commands from");
-
- stream = fopen (file, "r");
- if (stream == 0)
- perror_with_name (file);
-
- cleanups = make_cleanup (source_cleanup, instream);
-
- instream = stream;
-
- command_loop ();
-
- do_cleanups (cleanups);
-}
-
-static void
-echo_command (text)
- char *text;
-{
- char *p = text;
- register int c;
-
- if (text)
- while (c = *p++)
- {
- if (c == '\\')
- {
- /* \ at end of argument is used after spaces
- so they won't be lost. */
- if (*p == 0)
- return;
-
- c = parse_escape (&p);
- if (c >= 0)
- fputc (c, stdout);
- }
- else
- fputc (c, stdout);
- }
-}
-
-static void
-dump_me_command ()
-{
- if (query ("Should GDB dump core? "))
- {
- signal (SIGQUIT, SIG_DFL);
- kill (getpid (), SIGQUIT);
- }
-}
-
-static void
-init_cmd_lists ()
-{
- cmdlist = (struct cmd_list_element *) 0;
- infolist = (struct cmd_list_element *) 0;
- enablelist = (struct cmd_list_element *) 0;
- disablelist = (struct cmd_list_element *) 0;
- deletelist = (struct cmd_list_element *) 0;
- enablebreaklist = (struct cmd_list_element *) 0;
- setlist = (struct cmd_list_element *) 0;
-}
-
-static void
-init_main ()
-{
- prompt = savestring ("(gdb) ", 6);
-
- /* Define the classes of commands.
- They will appear in the help list in the reverse of this order. */
-
- add_cmd ("obscure", class_obscure, 0, "Obscure features.", &cmdlist);
- add_cmd ("alias", class_alias, 0, "Aliases of other commands.", &cmdlist);
- add_cmd ("user", class_user, 0, "User-defined commands.\n\
-The commands in this class are those defined by the user.\n\
-Use the \"define\" command to define a command.", &cmdlist);
- add_cmd ("support", class_support, 0, "Support facilities.", &cmdlist);
- add_cmd ("status", class_info, 0, "Status inquiries.", &cmdlist);
- add_cmd ("files", class_files, 0, "Specifying and examining files.", &cmdlist);
- add_cmd ("breakpoints", class_breakpoint, 0, "Making program stop at certain points.", &cmdlist);
- add_cmd ("data", class_vars, 0, "Examining data.", &cmdlist);
- add_cmd ("stack", class_stack, 0, "Examining the stack.\n\
-The stack is made up of stack frames. Gdb assigns numbers to stack frames\n\
-counting from zero for the innermost (currently executing) frame.\n\n\
-At any time gdb identifies one frame as the \"selected\" frame.\n\
-Variable lookups are done with respect to the selected frame.\n\
-When the program being debugged stops, gdb selects the innermost frame.\n\
-The commands below can be used to select other frames by number or address.",
- &cmdlist);
- add_cmd ("running", class_run, 0, "Running the program.", &cmdlist);
-
- add_com ("pwd", class_files, pwd_command,
- "Print working directory. This is used for your program as well.");
- add_com ("cd", class_files, cd_command,
- "Set working directory to DIR for debugger and program being debugged.\n\
-The change does not take effect for the program being debugged\n\
-until the next time it is started.");
-
- add_cmd ("prompt", class_support, set_prompt_command,
- "Change gdb's prompt from the default of \"(gdb)\"",
- &setlist);
- add_com ("echo", class_support, echo_command,
- "Print a constant string. Give string as argument.\n\
-C escape sequences may be used in the argument.\n\
-No newline is added at the end of the argument;\n\
-use \"\\n\" if you want a newline to be printed.\n\
-Since leading and trailing whitespace are ignored in command arguments,\n\
-if you want to print some you must use \"\\\" before leading whitespace\n\
-to be printed or after trailing whitespace.");
- add_com ("document", class_support, document_command,
- "Document a user-defined command.\n\
-Give command name as argument. Give documentation on following lines.\n\
-End with a line of just \"end\".");
- add_com ("define", class_support, define_command,
- "Define a new command name. Command name is argument.\n\
-Definition appears on following lines, one command per line.\n\
-End with a line of just \"end\".\n\
-Use the \"document\" command to give documentation for the new command.\n\
-Commands defined in this way do not take arguments.");
-
- add_com ("source", class_support, source_command,
- "Read commands from a file named FILE.\n\
-Note that the file \".gdbinit\" is read automatically in this way\n\
-when gdb is started.");
- add_com ("quit", class_support, quit_command, "Exit gdb.");
- add_com ("help", class_support, help_command, "Print list of commands.");
- add_com_alias ("q", "quit", class_support, 1);
- add_com_alias ("h", "help", class_support, 1);
-
- add_com ("dump-me", class_obscure, dump_me_command,
- "Get fatal error; make debugger dump its core.");
-
- add_prefix_cmd ("info", class_info, info_command,
- "Generic command for printing status.",
- &infolist, "info ", 0, &cmdlist);
- add_com_alias ("i", "info", class_info, 1);
-
- add_info ("copying", copying_info, "Conditions for redistributing copies of GDB.");
- add_info ("warranty", warranty_info, "Various kinds of warranty you do not have.");
- add_info ("version", version_info, "Report what version of GDB this is.");
-}
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d103 2
-a104 2
-static void initialize_main ();
-static void initialize_cmd_lists ();
-d247 3
-a249 3
- initialize_cmd_lists (); /* This needs to be done first */
- initialize_all_files ();
- initialize_main (); /* But that omits this file! Do it now */
-d1206 1
-a1206 1
-initialize_cmd_lists ()
-d1218 1
-a1218 1
-initialize_main ()
-@
diff --git a/gdb/RCS/munch,v b/gdb/RCS/munch,v
deleted file mode 100755
index bac6946..0000000
--- a/gdb/RCS/munch,v
+++ /dev/null
@@ -1,75 +0,0 @@
-head 1.3;
-access ;
-symbols ;
-locks ; strict;
-comment @# @;
-
-
-1.3
-date 89.03.27.21.15.45; author gnu; state Exp;
-branches ;
-next 1.2;
-
-1.2
-date 89.03.27.20.18.28; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.03.20.18.58.17; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.3
-log
-@Fix up "munch" so it generates a name that doesn't match its own
-"grep" conventions. Change main so that it calls the new name,
-and also doesn't use the conventions for functions that should NOT
-be called by init.c.
-@
-text
-@#! /bin/sh
-
-# create an initialization procedure from a list of .o files
-# Look in object files, find symbols including the string _initialize_,
-# and call each one as a function.
-
-echo '/* Do not modify this file. It is created automatically by "munch". */'
-echo 'void init_all_files () {'
-
-nm $* | egrep '_initialize_' | \
- sed -e 's/^.*\(initialize_[a-zA-Z_0-9]*\).*$/ _\1 ();/' | \
- sort -u
-
-echo '}'
-@
-
-
-1.2
-log
-@Generic change: make it not care much about the output format of "nm".
-Now as long as _initialize_foo is not touching any other
-symbol or alphanumeric, we'll find it and use it.
-@
-text
-@d8 1
-a8 1
-echo 'void initialize_all_files () {'
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d4 2
-d10 3
-a12 1
-nm -p $* | egrep 'T *__?initialize_' | sed -e 's/^.*T *_*\(.*\)/ _\1 ();/'
-@
diff --git a/gdb/RCS/printcmd.c,v b/gdb/RCS/printcmd.c,v
deleted file mode 100644
index 2ab3acc..0000000
--- a/gdb/RCS/printcmd.c,v
+++ /dev/null
@@ -1,1707 +0,0 @@
-head 1.2;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.2
-date 89.04.26.00.54.22; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.04.25.15.38.49; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.2
-log
-@(1) Depend on XXX_BIG_ENDIAN rather than testing gdb's object code.
-(2) Print to the STREAM parameter, not to stdout.
-(3) Use is_nan with new arguments.
-(4) Use unpack_double with new args, and deal with invalid results.
-(5) Don't print history numbers in the "print" command for things
-that weren't recorded in history (because they were invalid values).
-@
-text
-@/* Print values for GNU debugger GDB.
- Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#include <stdio.h>
-#include "defs.h"
-#include "param.h"
-#include "frame.h"
-#include "symtab.h"
-#include "value.h"
-#include "expression.h"
-
-struct format_data
-{
- int count;
- char format;
- char size;
-};
-
-/* Last specified output format. */
-
-static char last_format = 'x';
-
-/* Last specified examination size. 'b', 'h', 'w' or `q'. */
-
-static char last_size = 'w';
-
-/* Default address to examine next. */
-
-static CORE_ADDR next_address;
-
-/* Last address examined. */
-
-static CORE_ADDR last_examine_address;
-
-/* Contents of last address examined.
- This is not valid past the end of the `x' command! */
-
-static value last_examine_value;
-
-/* Number of auto-display expression currently being displayed.
- So that we can deleted it if we get an error or a signal within it.
- -1 when not doing one. */
-
-int current_display_number;
-
-static void do_one_display ();
-
-void do_displays ();
-void print_address ();
-void print_scalar_formatted ();
-
-
-/* Decode a format specification. *STRING_PTR should point to it.
- OFORMAT and OSIZE are used as defaults for the format and size
- if none are given in the format specification.
- The structure returned describes all the data
- found in the specification. In addition, *STRING_PTR is advanced
- past the specification and past all whitespace following it. */
-
-struct format_data
-decode_format (string_ptr, oformat, osize)
- char **string_ptr;
- char oformat;
- char osize;
-{
- struct format_data val;
- register char *p = *string_ptr;
-
- val.format = oformat;
- val.size = osize;
- val.count = 1;
-
- if (*p >= '0' && *p <= '9')
- val.count = atoi (p);
- while (*p >= '0' && *p <= '9') p++;
-
- /* Now process size or format letters that follow. */
-
- while (1)
- {
- if (*p == 'b' || *p == 'h' || *p == 'w' || *p == 'g')
- val.size = *p++;
-#ifdef LONG_LONG
- else if (*p == 'l')
- {
- val.size = 'g';
- p++;
- }
-#endif
- else if (*p >= 'a' && *p <= 'z')
- val.format = *p++;
- else
- break;
- }
-
-#ifndef LONG_LONG
- /* Make sure 'g' size is not used on integer types.
- Well, actually, we can handle hex. */
- if (val.size == 'g' && val.format != 'f' && val.format != 'x')
- val.size = 'w';
-#endif
-
- while (*p == ' ' || *p == '\t') p++;
- *string_ptr = p;
-
- return val;
-}
-
-/* Print value VAL on stdout according to FORMAT, a letter or 0.
- Do not end with a newline.
- 0 means print VAL according to its own type.
- SIZE is the letter for the size of datum being printed.
- This is used to pad hex numbers so they line up. */
-
-static void
-print_formatted (val, format, size)
- register value val;
- register char format;
- char size;
-{
- int len = TYPE_LENGTH (VALUE_TYPE (val));
-
- if (VALUE_LVAL (val) == lval_memory)
- next_address = VALUE_ADDRESS (val) + len;
-
- switch (format)
- {
- case 's':
- next_address = VALUE_ADDRESS (val)
- + value_print (value_addr (val), stdout, 0);
- break;
-
- case 'i':
- next_address = VALUE_ADDRESS (val)
- + print_insn (VALUE_ADDRESS (val), stdout);
- break;
-
- default:
- if (format == 0
- || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_ARRAY
- || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_STRUCT
- || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_UNION
- || VALUE_REPEATED (val))
- value_print (val, stdout, format);
- else
- print_scalar_formatted (VALUE_CONTENTS (val), VALUE_TYPE (val),
- format, size, stdout);
- }
-}
-
-/* Print a scalar of data of type TYPE, pointed to in GDB by VALADDR,
- according to letters FORMAT and SIZE on STREAM.
- FORMAT may not be zero. Formats s and i are not supported at this level.
-
- This is how the elements of an array or structure are printed
- with a format. */
-
-void
-print_scalar_formatted (valaddr, type, format, size, stream)
- char *valaddr;
- struct type *type;
- char format;
- int size;
- FILE *stream;
-{
- LONGEST val_long;
- int len = TYPE_LENGTH (type);
-
- if (size == 'g' && sizeof (LONGEST) < 8
- && format == 'x')
- {
- /* ok, we're going to have to get fancy here. Assumption: a
- long is four bytes. */
- unsigned long v1, v2, tmp;
-
- v1 = unpack_long (builtin_type_long, valaddr);
- v2 = unpack_long (builtin_type_long, valaddr + 4);
-
-#ifdef BYTES_BIG_ENDIAN
-#else
- /* Little endian -- swap the two for printing */
- tmp = v1;
- v1 = v2;
- v2 = tmp;
-#endif
-
- switch (format)
- {
- case 'x':
- fprintf (stream, "0x%08x%08x", v1, v2);
- break;
- default:
- error ("Output size \"g\" unimplemented for format \"%c\".",
- format);
- }
- return;
- }
-
- val_long = unpack_long (type, valaddr);
-
- /* If value is unsigned, truncate it in case negative. */
- if (format != 'd')
- {
- if (len == sizeof (char))
- val_long &= (1 << 8 * sizeof(char)) - 1;
- else if (len == sizeof (short))
- val_long &= (1 << 8 * sizeof(short)) - 1;
- else if (len == sizeof (long))
- val_long &= (unsigned long) - 1;
- }
-
- switch (format)
- {
- case 'x':
-#ifdef LONG_LONG
- if (!size)
- size = (len < sizeof (long long) ? 'w' : 'g');
- switch (size)
- {
- case 'b':
- fprintf (stream, "0x%02llx", val_long);
- break;
- case 'h':
- fprintf (stream, "0x%04llx", val_long);
- break;
- case 0: /* no size specified, like in print */
- case 'w':
- fprintf (stream, "0x%08llx", val_long);
- break;
- case 'g':
- fprintf (stream, "0x%16llx", val_long);
- break;
- default:
- error ("Undefined output size \"%c\".", size);
- }
-#else
- switch (size)
- {
- case 'b':
- fprintf (stream, "0x%02x", val_long);
- break;
- case 'h':
- fprintf (stream, "0x%04x", val_long);
- break;
- case 0: /* no size specified, like in print */
- case 'w':
- fprintf (stream, "0x%08x", val_long);
- break;
- case 'g':
- fprintf (stream, "0x%16x", val_long);
- break;
- default:
- error ("Undefined output size \"%c\".", size);
- }
-#endif /* not LONG_LONG */
- break;
-
- case 'd':
-#ifdef LONG_LONG
- fprintf (stream, "%lld", val_long);
-#else
- fprintf (stream, "%d", val_long);
-#endif
- break;
-
- case 'u':
-#ifdef LONG_LONG
- fprintf (stream, "%llu", val_long);
-#else
- fprintf (stream, "%u", val_long);
-#endif
- break;
-
- case 'o':
- if (val_long)
-#ifdef LONG_LONG
- fprintf (stream, "0%llo", val_long);
-#else
- fprintf (stream, "0%o", val_long);
-#endif
- else
- fprintf (stream, "0");
- break;
-
- case 'a':
- print_address ((CORE_ADDR) val_long, stream);
- break;
-
- case 'c':
- value_print (value_from_long (builtin_type_char, val_long), stream, 0);
- break;
-
- case 'f':
- if (len == sizeof (float))
- type = builtin_type_float;
- else if (len == sizeof (double))
- type = builtin_type_double;
- else abort();
-
-#ifdef IEEE_FLOAT
- if (is_nan (valaddr, len))
- {
- fprintf (stream, "NaN");
- break;
- }
-#endif
- {
- double doub;
- int inv;
-
- doub = unpack_double (type, valaddr, &inv);
- if (inv)
- fprintf (stream, "Invalid float value");
- else
- fprintf (stream, len > 4? "%.16g": "%.6g", doub);
- }
- break;
-
- case 0:
- abort ();
-
- default:
- error ("Undefined output format \"%c\".", format);
- }
-}
-
-/* Specify default address for `x' command.
- `info lines' uses this. */
-
-void
-set_next_address (addr)
- CORE_ADDR addr;
-{
- next_address = addr;
-
- /* Make address available to the user as $_. */
- set_internalvar (lookup_internalvar ("_"),
- value_from_long (builtin_type_int, (LONGEST) addr));
-}
-
-/* Print address ADDR symbolically on STREAM.
- First print it as a number. Then perhaps print
- <SYMBOL + OFFSET> after the number. */
-
-void
-print_address (addr, stream)
- CORE_ADDR addr;
- FILE *stream;
-{
- register int i;
- struct symbol *fs;
- char *name;
- int name_location;
-
- fprintf (stream, "0x%x", addr);
-
- fs = find_pc_function (addr);
-
- if (!fs)
- {
- i = find_pc_misc_function (addr);
-
- if (i < 0) return; /* If nothing comes through, don't
- print anything symbolic */
-
- name = misc_function_vector[i].name;
- name_location = misc_function_vector[i].address;
- }
- else
- {
- name = fs->name;
- name_location = BLOCK_START (SYMBOL_BLOCK_VALUE (fs));
- }
-
- if (addr - name_location)
- fprintf (stream, " <%s+%d>",
- name,
- addr - name_location);
- else
- fprintf (stream, " <%s>", name);
-}
-
-/* Examine data at address ADDR in format FMT.
- Fetch it from memory and print on stdout. */
-
-static void
-do_examine (fmt, addr)
- struct format_data fmt;
- CORE_ADDR addr;
-{
- register char format = 0;
- register char size;
- register int count = 1;
- struct type *val_type;
- register int i;
- register int maxelts;
-
- format = fmt.format;
- size = fmt.size;
- count = fmt.count;
- next_address = addr;
-
- /* String or instruction format implies fetch single bytes
- regardless of the specified size. */
- if (format == 's' || format == 'i')
- size = 'b';
-
- if (size == 'b')
- val_type = builtin_type_char;
- else if (size == 'h')
- val_type = builtin_type_short;
- else if (size == 'w')
- val_type = builtin_type_long;
- else if (size == 'g')
-#ifndef LONG_LONG
- val_type = builtin_type_double;
-#else
- val_type = builtin_type_long_long;
-#endif
-
- maxelts = 8;
- if (size == 'w')
- maxelts = 4;
- if (size == 'g')
- maxelts = 2;
- if (format == 's' || format == 'i')
- maxelts = 1;
-
- /* Print as many objects as specified in COUNT, at most maxelts per line,
- with the address of the next one at the start of each line. */
-
- while (count > 0)
- {
- print_address (next_address, stdout);
- fputc (':', stdout);
- for (i = maxelts;
- i > 0 && count > 0;
- i--, count--)
- {
- fputc ('\t', stdout);
- /* Note that print_formatted sets next_address for the next
- object. */
- last_examine_address = next_address;
- last_examine_value = value_at (val_type, next_address);
- print_formatted (last_examine_value, format, size);
- }
- fputc ('\n', stdout);
- fflush (stdout);
- }
-}
-
-static void
-validate_format (fmt, cmdname)
- struct format_data fmt;
- char *cmdname;
-{
- if (fmt.size != 0)
- error ("Size letters are meaningless in \"%s\" command.", cmdname);
- if (fmt.count != 1)
- error ("Item count other than 1 is meaningless in \"%s\" command.",
- cmdname);
- if (fmt.format == 'i' || fmt.format == 's')
- error ("Format letter \"%c\" is meaningless in \"%s\" command.",
- fmt.format, cmdname);
-}
-
-static void
-print_command (exp)
- char *exp;
-{
- struct expression *expr;
- register struct cleanup *old_chain = 0;
- register char format = 0;
- register value val;
- struct format_data fmt;
- int histindex;
- int cleanup = 0;
-
- if (exp && *exp == '/')
- {
- exp++;
- fmt = decode_format (&exp, last_format, 0);
- validate_format (fmt, "print");
- last_format = format = fmt.format;
- }
-
- if (exp && *exp)
- {
- expr = parse_c_expression (exp);
- old_chain = make_cleanup (free_current_contents, &expr);
- cleanup = 1;
- val = evaluate_expression (expr);
- }
- else
- val = access_value_history (0);
-
- histindex = record_latest_value (val);
- if (histindex >= 0) printf ("$%d = ", histindex);
-
- print_formatted (val, format, fmt.size);
- printf ("\n");
-
- if (cleanup)
- do_cleanups (old_chain);
-}
-
-static void
-output_command (exp)
- char *exp;
-{
- struct expression *expr;
- register struct cleanup *old_chain;
- register char format = 0;
- register value val;
- struct format_data fmt;
-
- if (exp && *exp == '/')
- {
- exp++;
- fmt = decode_format (&exp, 0, 0);
- validate_format (fmt, "print");
- format = fmt.format;
- }
-
- expr = parse_c_expression (exp);
- old_chain = make_cleanup (free_current_contents, &expr);
-
- val = evaluate_expression (expr);
-
- print_formatted (val, format, fmt.size);
-
- do_cleanups (old_chain);
-}
-
-static void
-set_command (exp)
- char *exp;
-{
- struct expression *expr = parse_c_expression (exp);
- register struct cleanup *old_chain
- = make_cleanup (free_current_contents, &expr);
- evaluate_expression (expr);
- do_cleanups (old_chain);
-}
-
-static void
-address_info (exp)
- char *exp;
-{
- register struct symbol *sym;
- register CORE_ADDR val;
- int is_a_field_of_this; /* C++: lookup_symbol sets this to nonzero
- if exp is a field of `this'. */
-
- if (exp == 0)
- error ("Argument required.");
-
- sym = lookup_symbol (exp, get_selected_block (), VAR_NAMESPACE,
- &is_a_field_of_this);
- if (sym == 0)
- {
- register int i;
-
- if (is_a_field_of_this)
- {
- printf("Symbol \"%s\" is a field of the local class variable `this'\n", exp);
- return;
- }
-
- for (i = 0; i < misc_function_count; i++)
- if (!strcmp (misc_function_vector[i].name, exp))
- break;
-
- if (i < misc_function_count)
- printf ("Symbol \"%s\" is at 0x%x in a file compiled without -g.\n",
- exp, misc_function_vector[i].address);
- else
- error ("No symbol \"%s\" in current context.", exp);
- return;
- }
-
- printf ("Symbol \"%s\" is ", SYMBOL_NAME (sym));
- val = SYMBOL_VALUE (sym);
-
- switch (SYMBOL_CLASS (sym))
- {
- case LOC_CONST:
- case LOC_CONST_BYTES:
- printf ("constant");
- break;
-
- case LOC_LABEL:
- printf ("a label at address 0x%x", val);
- break;
-
- case LOC_REGISTER:
- printf ("a variable in register %s", reg_names[val]);
- break;
-
- case LOC_STATIC:
- printf ("static at address 0x%x", val);
- break;
-
- case LOC_REGPARM:
- printf ("an argument in register %s", reg_names[val]);
- break;
-
- case LOC_ARG:
- printf ("an argument at offset %d", val);
- break;
-
- case LOC_LOCAL:
- printf ("a local variable at frame offset %d", val);
- break;
-
- case LOC_TYPEDEF:
- printf ("a typedef");
- break;
-
- case LOC_BLOCK:
- printf ("a function at address 0x%x",
- BLOCK_START (SYMBOL_BLOCK_VALUE (sym)));
- break;
- }
- printf (".\n");
-}
-
-static void
-x_command (exp, from_tty)
- char *exp;
- int from_tty;
-{
- struct expression *expr;
- struct format_data fmt;
- struct cleanup *old_chain;
-
- fmt.format = last_format;
- fmt.size = last_size;
- fmt.count = 1;
-
- if (exp && *exp == '/')
- {
- exp++;
- fmt = decode_format (&exp, last_format, last_size);
- last_size = fmt.size;
- last_format = fmt.format;
- }
-
- /* If we have an expression, evaluate it and use it as the address. */
-
- if (exp != 0 && *exp != 0)
- {
- expr = parse_c_expression (exp);
- /* Cause expression not to be there any more
- if this command is repeated with Newline.
- But don't clobber a user-defined command's definition. */
- if (from_tty)
- *exp = 0;
- old_chain = make_cleanup (free_current_contents, &expr);
- next_address = (CORE_ADDR) value_as_long (evaluate_expression (expr));
- do_cleanups (old_chain);
- }
-
- do_examine (fmt, next_address);
-
- /* Set a couple of internal variables if appropriate. */
- if (last_examine_value)
- {
- /* Make last address examined available to the user as $_. */
- set_internalvar (lookup_internalvar ("_"),
- value_from_long (builtin_type_int,
- (LONGEST) last_examine_address));
-
- /* Make contents of last address examined available to the user as $__.*/
- set_internalvar (lookup_internalvar ("__"), last_examine_value);
- }
-}
-
-/* Commands for printing types of things. */
-
-static void
-whatis_command (exp)
- char *exp;
-{
- struct expression *expr;
- register value val;
- register struct cleanup *old_chain;
-
- if (exp)
- {
- expr = parse_c_expression (exp);
- old_chain = make_cleanup (free_current_contents, &expr);
- val = evaluate_type (expr);
- }
- else
- val = access_value_history (0);
-
- printf ("type = ");
- type_print (VALUE_TYPE (val), "", stdout, 1);
- printf ("\n");
-
- if (exp)
- do_cleanups (old_chain);
-}
-
-static void
-ptype_command (typename)
- char *typename;
-{
- register char *p = typename;
- register int len;
- extern struct block *get_current_block ();
- register struct block *b
- = (have_inferior_p () || have_core_file_p ()) ? get_current_block () : 0;
- register struct type *type;
-
- if (typename == 0)
- error_no_arg ("type name");
-
- while (*p && *p != ' ' && *p != '\t') p++;
- len = p - typename;
- while (*p == ' ' || *p == '\t') p++;
-
- if (len == 6 && !strncmp (typename, "struct", 6))
- type = lookup_struct (p, b);
- else if (len == 5 && !strncmp (typename, "union", 5))
- type = lookup_union (p, b);
- else if (len == 4 && !strncmp (typename, "enum", 4))
- type = lookup_enum (p, b);
- else
- {
- type = lookup_typename (typename, b, 1);
- if (type == 0)
- {
- register struct symbol *sym
- = lookup_symbol (typename, b, STRUCT_NAMESPACE, 0);
- if (sym == 0)
- error ("No type named %s.", typename);
- printf ("No type named %s, but there is a ",
- typename);
- switch (TYPE_CODE (SYMBOL_TYPE (sym)))
- {
- case TYPE_CODE_STRUCT:
- printf ("struct");
- break;
-
- case TYPE_CODE_UNION:
- printf ("union");
- break;
-
- case TYPE_CODE_ENUM:
- printf ("enum");
- }
- printf (" %s. Type \"help ptype\".\n", typename);
- type = SYMBOL_TYPE (sym);
- }
- }
-
- type_print (type, "", stdout, 1);
- printf ("\n");
-}
-
-enum display_status {disabled, enabled};
-
-struct display
-{
- /* Chain link to next auto-display item. */
- struct display *next;
- /* Expression to be evaluated and displayed. */
- struct expression *exp;
- /* Item number of this auto-display item. */
- int number;
- /* Display format specified. */
- struct format_data format;
- /* Innermost block required by this expression when evaluated */
- struct block *block;
- /* Status of this display (enabled or disabled) */
- enum display_status status;
-};
-
-/* Chain of expressions whose values should be displayed
- automatically each time the program stops. */
-
-static struct display *display_chain;
-
-static int display_number;
-
-/* Add an expression to the auto-display chain.
- Specify the expression. */
-
-static void
-display_command (exp, from_tty)
- char *exp;
- int from_tty;
-{
- struct format_data fmt;
- register struct expression *expr;
- register struct display *new;
- extern struct block *innermost_block;
-
- if (exp == 0)
- {
- do_displays ();
- return;
- }
-
- if (*exp == '/')
- {
- exp++;
- fmt = decode_format (&exp, 0, 0);
- if (fmt.size && fmt.format == 0)
- fmt.format = 'x';
- if (fmt.format == 'i' || fmt.format == 's')
- fmt.size = 'b';
- }
- else
- {
- fmt.format = 0;
- fmt.size = 0;
- fmt.count = 0;
- }
-
- innermost_block = 0;
- expr = parse_c_expression (exp);
-
- new = (struct display *) xmalloc (sizeof (struct display));
-
- new->exp = expr;
- new->block = innermost_block;
- new->next = display_chain;
- new->number = ++display_number;
- new->format = fmt;
- new->status = enabled;
- display_chain = new;
-
- if (from_tty && have_inferior_p ())
- do_one_display (new);
-
- dont_repeat ();
-}
-
-static void
-free_display (d)
- struct display *d;
-{
- free (d->exp);
- free (d);
-}
-
-/* Clear out the display_chain.
- Done when new symtabs are loaded, since this invalidates
- the types stored in many expressions. */
-
-void
-clear_displays ()
-{
- register struct display *d;
-
- while (d = display_chain)
- {
- free (d->exp);
- display_chain = d->next;
- free (d);
- }
-}
-
-/* Delete the auto-display number NUM. */
-
-void
-delete_display (num)
- int num;
-{
- register struct display *d1, *d;
-
- if (!display_chain)
- error ("No display number %d.", num);
-
- if (display_chain->number == num)
- {
- d1 = display_chain;
- display_chain = d1->next;
- free_display (d1);
- }
- else
- for (d = display_chain; ; d = d->next)
- {
- if (d->next == 0)
- error ("No display number %d.", num);
- if (d->next->number == num)
- {
- d1 = d->next;
- d->next = d1->next;
- free_display (d1);
- break;
- }
- }
-}
-
-/* Delete some values from the auto-display chain.
- Specify the element numbers. */
-
-static void
-undisplay_command (args)
- char *args;
-{
- register char *p = args;
- register char *p1;
- register int num;
- register struct display *d, *d1;
-
- if (args == 0)
- {
- if (query ("Delete all auto-display expressions? "))
- clear_displays ();
- dont_repeat ();
- return;
- }
-
- while (*p)
- {
- p1 = p;
- while (*p1 >= '0' && *p1 <= '9') p1++;
- if (*p1 && *p1 != ' ' && *p1 != '\t')
- error ("Arguments must be display numbers.");
-
- num = atoi (p);
-
- delete_display (num);
-
- p = p1;
- while (*p == ' ' || *p == '\t') p++;
- }
- dont_repeat ();
-}
-
-/* Display a single auto-display.
- Do nothing if the display cannot be printed in the current context,
- or if the display is disabled. */
-
-static void
-do_one_display (d)
- struct display *d;
-{
- int within_current_scope;
-
- if (d->status == disabled)
- return;
-
- if (d->block)
- within_current_scope = contained_in (get_selected_block (), d->block);
- else
- within_current_scope = 1;
- if (!within_current_scope)
- return;
-
- current_display_number = d->number;
-
- printf ("%d: ", d->number);
- if (d->format.size)
- {
- printf ("x/");
- if (d->format.count != 1)
- printf ("%d", d->format.count);
- printf ("%c", d->format.format);
- if (d->format.format != 'i' && d->format.format != 's')
- printf ("%c", d->format.size);
- printf (" ");
- print_expression (d->exp, stdout);
- if (d->format.count != 1)
- printf ("\n");
- else
- printf (" ");
- do_examine (d->format,
- (CORE_ADDR) value_as_long (evaluate_expression (d->exp)));
-
- }
- else
- {
- if (d->format.format)
- printf ("/%c ", d->format.format);
- print_expression (d->exp, stdout);
- printf (" = ");
- print_formatted (evaluate_expression (d->exp),
- d->format.format, d->format.size);
- printf ("\n");
- }
-
- fflush (stdout);
- current_display_number = -1;
-}
-
-/* Display all of the values on the auto-display chain which can be
- evaluated in the current scope. */
-
-void
-do_displays ()
-{
- register struct display *d;
-
- for (d = display_chain; d; d = d->next)
- do_one_display (d);
-}
-
-/* Delete the auto-display which we were in the process of displaying.
- This is done when there is an error or a signal. */
-
-void
-delete_current_display ()
-{
- if (current_display_number >= 0)
- {
- delete_display (current_display_number);
- fprintf (stderr, "Deleting display %d to avoid infinite recursion.\n",
- current_display_number);
- }
- current_display_number = -1;
-}
-
-static void
-display_info ()
-{
- register struct display *d;
-
- if (!display_chain)
- printf ("There are no auto-display expressions now.\n");
- else
- printf ("Auto-display expressions now in effect:\n\
-Num Enb Expression\n");
-
- for (d = display_chain; d; d = d->next)
- {
- printf ("%d: %c ", d->number, "ny"[(int)d->status]);
- if (d->format.size)
- printf ("/%d%c%c ", d->format.count, d->format.size,
- d->format.format);
- else if (d->format.format)
- printf ("/%c ", d->format.format);
- print_expression (d->exp, stdout);
- if (d->block && !contained_in (get_selected_block (), d->block))
- printf (" (cannot be evaluated in the current context)");
- printf ("\n");
- fflush (stdout);
- }
-}
-
-void
-enable_display (args)
- char *args;
-{
- register char *p = args;
- register char *p1;
- register int num;
- register struct display *d;
-
- if (p == 0)
- {
- for (d = display_chain; d; d->next)
- d->status = enabled;
- }
- else
- while (*p)
- {
- p1 = p;
- while (*p1 >= '0' && *p1 <= '9')
- p1++;
- if (*p1 && *p1 != ' ' && *p1 != '\t')
- error ("Arguments must be display numbers.");
-
- num = atoi (p);
-
- for (d = display_chain; d; d = d->next)
- if (d->number == num)
- {
- d->status = enabled;
- goto win;
- }
- printf ("No display number %d.\n", num);
- win:
- p = p1;
- while (*p == ' ' || *p == '\t')
- p++;
- }
-}
-
-void
-disable_display (args)
- char *args;
-{
- register char *p = args;
- register char *p1;
- register int num;
- register struct display *d;
-
- if (p == 0)
- {
- for (d = display_chain; d; d->next)
- d->status = disabled;
- }
- else
- while (*p)
- {
- p1 = p;
- while (*p1 >= '0' && *p1 <= '9')
- p1++;
- if (*p1 && *p1 != ' ' && *p1 != '\t')
- error ("Arguments must be display numbers.");
-
- num = atoi (p);
-
- for (d = display_chain; d; d = d->next)
- if (d->number == num)
- {
- d->status = disabled;
- goto win;
- }
- printf ("No display number %d.\n", num);
- win:
- p = p1;
- while (*p == ' ' || *p == '\t')
- p++;
- }
-}
-
-
-/* Print the value in stack frame FRAME of a variable
- specified by a struct symbol. */
-
-void
-print_variable_value (var, frame, stream)
- struct symbol *var;
- CORE_ADDR frame;
- FILE *stream;
-{
- value val = read_var_value (var, frame);
- value_print (val, stream, 0);
-}
-
-/* Print the arguments of a stack frame, given the function FUNC
- running in that frame (as a symbol), the info on the frame,
- and the number of args according to the stack frame (or -1 if unknown). */
-
-static void print_frame_nameless_args ();
-
-void
-print_frame_args (func, fi, num, stream)
- struct symbol *func;
- struct frame_info *fi;
- int num;
- FILE *stream;
-{
- struct block *b;
- int nsyms = 0;
- int first = 1;
- register int i;
- register int last_offset = FRAME_ARGS_SKIP;
- register int last_regparm = 0;
- register struct symbol *lastsym, *sym, *nextsym;
- register value val;
- register CORE_ADDR addr = FRAME_ARGS_ADDRESS (fi);
-
- if (func)
- {
- b = SYMBOL_BLOCK_VALUE (func);
- nsyms = BLOCK_NSYMS (b);
- }
-
- lastsym = 0;
- while (1)
- {
- /* Find first arg that is not before LAST_OFFSET. */
- nextsym = 0;
- for (i = 0; i < nsyms; i++)
- {
- QUIT;
- sym = BLOCK_SYM (b, i);
- if (SYMBOL_CLASS (sym) == LOC_ARG)
- {
- if (SYMBOL_VALUE (sym) >= last_offset
- && (nextsym == 0
- || SYMBOL_VALUE (sym) < SYMBOL_VALUE (nextsym)))
- nextsym = sym;
- }
- else if (SYMBOL_CLASS (sym) == LOC_REGPARM)
- {
- /* This shouldn't be sorted by number. Since we can't
- find nameless args with register parameters, print
- this out in order by .stabs. */
- if (sym > lastsym && nextsym == 0)
- nextsym = sym;
- }
- }
- if (nextsym == 0)
- break;
- sym = nextsym;
- /* Print any nameless args between the last arg printed
- and the next arg. */
- if (SYMBOL_CLASS (sym) == LOC_ARG
- && last_offset != (SYMBOL_VALUE (sym) / sizeof (int)) * sizeof (int))
- {
- print_frame_nameless_args (addr, last_offset, SYMBOL_VALUE (sym),
- stream);
- first = 0;
- }
- /* Print the next arg. */
- if (SYMBOL_CLASS (sym) == LOC_REGPARM)
- val = value_from_register (SYMBOL_TYPE (sym),
- SYMBOL_VALUE (sym),
- FRAME_INFO_ID (fi));
- else
- val = value_at (SYMBOL_TYPE (sym), addr + SYMBOL_VALUE (sym));
-
- if (! first)
- fprintf (stream, ", ");
- fprintf (stream, "%s=", SYMBOL_NAME (sym));
- value_print (val, stream, 0);
- first = 0;
- if (SYMBOL_CLASS (sym) == LOC_ARG)
- last_offset = SYMBOL_VALUE (sym) + TYPE_LENGTH (SYMBOL_TYPE (sym));
- else
- {
- last_regparm = SYMBOL_VALUE (sym) + 1;
- last_offset += TYPE_LENGTH (SYMBOL_TYPE (sym));
- }
-
- /* Round up address of next arg to multiple of size of int. */
- last_offset
- = ((last_offset + sizeof (int) - 1) / sizeof (int)) * sizeof (int);
- lastsym = sym;
- }
- if (num >= 0 && num * sizeof (int) + FRAME_ARGS_SKIP > last_offset)
- print_frame_nameless_args (addr, last_offset,
- num * sizeof (int) + FRAME_ARGS_SKIP, stream);
-}
-
-static void
-print_frame_nameless_args (argsaddr, start, end, stream)
- CORE_ADDR argsaddr;
- int start;
- int end;
- FILE *stream;
-{
- while (start < end)
- {
- QUIT;
- if (start != FRAME_ARGS_SKIP)
- fprintf (stream, ", ");
- fprintf (stream, "%d",
- read_memory_integer (argsaddr + start, sizeof (int)));
- start += sizeof (int);
- }
-}
-
-static void
-printf_command (arg)
- char *arg;
-{
- register char *f;
- register char *s = arg;
- char *string;
- value *val_args;
- int nargs = 0;
- int allocated_args = 20;
- char *arg_bytes;
- char *argclass;
- int i;
- int argindex;
- int nargs_wanted;
-
- val_args = (value *) xmalloc (allocated_args * sizeof (value));
-
- if (s == 0)
- error_no_arg ("format-control string and values to print");
-
- /* Skip white space before format string */
- while (*s == ' ' || *s == '\t') s++;
-
- /* A format string should follow, enveloped in double quotes */
- if (*s++ != '"')
- error ("Bad format string, missing '\"'.");
-
- /* Parse the format-control string and copy it into the string STRING,
- processing some kinds of escape sequence. */
-
- f = string = (char *) alloca (strlen (s) + 1);
- while (*s != '"')
- {
- int c = *s++;
- switch (c)
- {
- case '\0':
- error ("Bad format string, non-terminated '\"'.");
- /* doesn't return */
-
- case '\\':
- switch (c = *s++)
- {
- case '\\':
- *f++ = '\\';
- break;
- case 'n':
- *f++ = '\n';
- break;
- case 't':
- *f++ = '\t';
- break;
- case 'r':
- *f++ = '\r';
- break;
- case '"':
- *f++ = '"';
- break;
- default:
- /* ??? TODO: handle other escape sequences */
- error ("Unrecognized \\ escape character in format string.");
- }
- break;
-
- default:
- *f++ = c;
- }
- }
-
- /* Skip over " and following space and comma. */
- s++;
- *f++ = '\0';
- while (*s == ' ' || *s == '\t') s++;
-
- if (*s != ',' && *s != 0)
- error ("Invalid argument syntax");
-
- if (*s == ',') s++;
- while (*s == ' ' || *s == '\t') s++;
-
- /* Now scan the string for %-specs and see what kinds of args they want.
- argclass[I] is set to 1 if the Ith arg should be a string.
- It's set to 2 if the Ith arg should be floating point. */
-
- argclass = (char *) alloca (strlen (s));
- nargs_wanted = 0;
- f = string;
- while (*f)
- if (*f++ == '%')
- {
- while (index ("0123456789.hlL-+ #", *f)) f++;
- if (*f == 's')
- argclass[nargs_wanted++] = 1;
- else if (*f == 'e' || *f == 'f' || *f == 'g')
- argclass[nargs_wanted++] = 2;
- else if (*f != '%')
- argclass[nargs_wanted++] = 0;
- f++;
- }
-
- /* Now, parse all arguments and evaluate them.
- Store the VALUEs in VAL_ARGS. */
-
- while (*s != '\0')
- {
- char *s1;
- if (nargs == allocated_args)
- val_args = (value *) xrealloc (val_args,
- (allocated_args *= 2)
- * sizeof (value));
- s1 = s;
- val_args[nargs] = parse_to_comma_and_eval (&s1);
-
- /* If format string wants a float, unchecked-convert the value to
- floating point of the same size */
-
- if (argclass[nargs] == 2)
- {
- argclass[nargs] = 0;
- if (TYPE_LENGTH (VALUE_TYPE (val_args[nargs])) == sizeof (float))
- VALUE_TYPE (val_args[nargs]) = builtin_type_float;
- if (TYPE_LENGTH (VALUE_TYPE (val_args[nargs])) == sizeof (double))
- VALUE_TYPE (val_args[nargs]) = builtin_type_double;
- }
- nargs++;
- s = s1;
- if (*s == ',')
- s++;
- }
-
- if (nargs != nargs_wanted)
- error ("Wrong number of arguments for specified format-string");
-
- /* Now lay out an argument-list containing the arguments
- as doubles, integers and C pointers. */
-
- arg_bytes = (char *) alloca (sizeof (double) * nargs);
- argindex = 0;
- for (i = 0; i < nargs; i++)
- {
- if (argclass[i])
- {
- char *str;
- int tem, j;
- tem = value_as_long (val_args[i]);
-
- /* This is a %s argument. Find the length of the string. */
- for (j = 0; ; j++)
- {
- char c;
- QUIT;
- read_memory (tem + j, &c, 1);
- if (c == 0)
- break;
- }
-
- /* Copy the string contents into a string inside GDB. */
- str = (char *) alloca (j + 1);
- read_memory (tem, str, j);
- str[j] = 0;
-
- /* Pass address of internal copy as the arg to vprintf. */
- *((int *) &arg_bytes[argindex]) = (int) str;
- argindex += sizeof (int);
- }
- else if (VALUE_TYPE (val_args[i])->code == TYPE_CODE_FLT)
- {
- *((double *) &arg_bytes[argindex]) = value_as_double (val_args[i]);
- argindex += sizeof (double);
- }
- else
-#ifdef LONG_LONG
- if (TYPE_LENGTH (VALUE_TYPE (val_args[i])) == sizeof (long long))
- {
- *(long long *) &arg_bytes[argindex] = value_as_long (val_args[i]);
- argindex += sizeof (long long);
- }
- else
-#endif
- {
- *((int *) &arg_bytes[argindex]) = value_as_long (val_args[i]);
- argindex += sizeof (int);
- }
- }
-
- vprintf (string, arg_bytes);
-}
-
-extern struct cmd_list_element *enablelist, *disablelist, *deletelist;
-extern struct cmd_list_element *cmdlist, *setlist;
-
-void
-_initialize_printcmd ()
-{
- current_display_number = -1;
-
- add_info ("address", address_info,
- "Describe where variable VAR is stored.");
-
- add_com ("x", class_vars, x_command,
- "Examine memory: x/FMT ADDRESS.\n\
-ADDRESS is an expression for the memory address to examine.\n\
-FMT is a repeat count followed by a format letter and a size letter.\n\
-Format letters are o(octal), x(hex), d(decimal), u(unsigned decimal),\n\
- f(float), a(address), i(instruction), c(char) and s(string).\n\
-Size letters are b(byte), h(halfword), w(word), g(giant, 8 bytes).\n\
- g is meaningful only with f, for type double.\n\
-The specified number of objects of the specified size are printed\n\
-according to the format.\n\n\
-Defaults for format and size letters are those previously used.\n\
-Default count is 1. Default address is following last thing printed\n\
-with this command or \"print\".");
-
- add_com ("ptype", class_vars, ptype_command,
- "Print definition of type TYPE.\n\
-Argument may be a type name defined by typedef, or \"struct STRUCTNAME\"\n\
-or \"union UNIONNAME\" or \"enum ENUMNAME\".\n\
-The selected stack frame's lexical context is used to look up the name.");
-
- add_com ("whatis", class_vars, whatis_command,
- "Print data type of expression EXP.");
-
- add_info ("display", display_info,
- "Expressions to display when program stops, with code numbers.");
-
- add_abbrev_cmd ("undisplay", class_vars, undisplay_command,
- "Cancel some expressions to be displayed when program stops.\n\
-Arguments are the code numbers of the expressions to stop displaying.\n\
-No argument means cancel all automatic-display expressions.\n\
-\"delete display\" has the same effect as this command.\n\
-Do \"info display\" to see current list of code numbers.",
- &cmdlist);
-
- add_com ("display", class_vars, display_command,
- "Print value of expression EXP each time the program stops.\n\
-/FMT may be used before EXP as in the \"print\" command.\n\
-/FMT \"i\" or \"s\" or including a size-letter is allowed,\n\
-as in the \"x\" command, and then EXP is used to get the address to examine\n\
-and examining is done as in the \"x\" command.\n\n\
-With no argument, display all currently requested auto-display expressions.\n\
-Use \"undisplay\" to cancel display requests previously made.");
-
- add_cmd ("display", class_vars, enable_display,
- "Enable some expressions to be displayed when program stops.\n\
-Arguments are the code numbers of the expressions to resume displaying.\n\
-No argument means enable all automatic-display expressions.\n\
-Do \"info display\" to see current list of code numbers.", &enablelist);
-
- add_cmd ("display", class_vars, disable_display,
- "Disable some expressions to be displayed when program stops.\n\
-Arguments are the code numbers of the expressions to stop displaying.\n\
-No argument means disable all automatic-display expressions.\n\
-Do \"info display\" to see current list of code numbers.", &disablelist);
-
- add_cmd ("display", class_vars, undisplay_command,
- "Cancel some expressions to be displayed when program stops.\n\
-Arguments are the code numbers of the expressions to stop displaying.\n\
-No argument means cancel all automatic-display expressions.\n\
-Do \"info display\" to see current list of code numbers.", &deletelist);
-
- add_com ("printf", class_vars, printf_command,
- "printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\
-This is useful for formatted output in user-defined commands.");
- add_com ("output", class_vars, output_command,
- "Like \"print\" but don't put in value history and don't print newline.\n\
-This is useful in user-defined commands.");
-
- add_prefix_cmd ("set", class_vars, set_command,
-"Perform an assignment VAR = EXP.\n\
-You must type the \"=\". VAR may be a debugger \"convenience\" variable\n\
-(names starting with $), a register (a few standard names starting with $),\n\
-or an actual variable in the program being debugged. EXP is any expression.\n\
-Use \"set variable\" for variables with names identical to set subcommands.\n\
-\nWith a subcommand, this command modifies parts of the gdb environment",
- &setlist, "set ", 1, &cmdlist);
-
- add_cmd ("variable", class_vars, set_command,
- "Perform an assignment VAR = EXP.\n\
-You must type the \"=\". VAR may be a debugger \"convenience\" variable\n\
-(names starting with $), a register (a few standard names starting with $),\n\
-or an actual variable in the program being debugged. EXP is any expression.\n\
-This may usually be abbreviated to simply \"set\".",
- &setlist);
-
- add_com ("print", class_vars, print_command,
- concat ("Print value of expression EXP.\n\
-Variables accessible are those of the lexical environment of the selected\n\
-stack frame, plus all those whose scope is global or an entire file.\n\
-\n\
-$NUM gets previous value number NUM. $ and $$ are the last two values.\n\
-$$NUM refers to NUM'th value back from the last one.\n\
-Names starting with $ refer to registers (with the values they would have\n\
-if the program were to return to the stack frame now selected, restoring\n\
-all registers saved by frames farther in) or else to debugger\n\
-\"convenience\" variables (any such name not a known register).\n\
-Use assignment expressions to give values to convenience variables.\n",
- "\n\
-\{TYPE}ADREXP refers to a datum of data type TYPE, located at address ADREXP.\n\
-@@ is a binary operator for treating consecutive data objects\n\
-anywhere in memory as an array. FOO@@NUM gives an array whose first\n\
-element is FOO, whose second element is stored in the space following\n\
-where FOO is stored, etc. FOO must be an expression whose value\n\
-resides in memory.\n",
- "\n\
-EXP may be preceded with /FMT, where FMT is a format letter\n\
-but no count or size letter (see \"x\" command)."));
- add_com_alias ("p", "print", class_vars, 1);
-}
-
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@a191 1
- int bigendian = 0;
-d196 7
-a202 5
- {
- union {
- char a, b, c, d;
- long i;
- } x;
-a203 10
- x.i = 1;
- if (x.a)
- {
- /* Little endian */
- tmp = v1;
- v1 = v2;
- v2 = tmp;
- }
- }
-
-d207 1
-a207 1
- printf ("0x%08x%08x", v1, v2);
-d238 1
-a238 1
- printf ("0x%02llx", val_long);
-d241 1
-a241 1
- printf ("0x%04llx", val_long);
-d245 1
-a245 1
- printf ("0x%08llx", val_long);
-d248 1
-a248 1
- printf ("0x%16llx", val_long);
-d257 1
-a257 1
- printf ("0x%02x", val_long);
-d260 1
-a260 1
- printf ("0x%04x", val_long);
-d264 1
-a264 1
- printf ("0x%08x", val_long);
-d267 1
-a267 1
- printf ("0x%16x", val_long);
-d277 1
-a277 1
- printf ("%lld", val_long);
-d279 1
-a279 1
- printf ("%d", val_long);
-d285 1
-a285 1
- printf ("%llu", val_long);
-d287 1
-a287 1
- printf ("%u", val_long);
-d294 1
-a294 1
- printf ("0%llo", val_long);
-d296 1
-a296 1
- printf ("0%o", val_long);
-d299 1
-a299 1
- printf ("0");
-d313 1
-a313 1
- if (len == sizeof (double))
-d315 2
-d318 1
-a318 1
- if (is_nan (unpack_double (type, valaddr)))
-d320 1
-a320 1
- printf ("Nan");
-d324 10
-a333 4
- if (len > 4)
- printf ("%.16g", unpack_double (type, valaddr));
- else
- printf ("%.6g", unpack_double (type, valaddr));
-d515 1
-a515 1
- printf ("$%d = ", histindex);
-@
diff --git a/gdb/RCS/remote.c,v b/gdb/RCS/remote.c,v
deleted file mode 100644
index 213113d..0000000
--- a/gdb/RCS/remote.c,v
+++ /dev/null
@@ -1,662 +0,0 @@
-head 1.2;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.2
-date 89.03.27.20.21.22; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.03.20.18.45.46; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.2
-log
-@Avoid <sys/fcntl.h>.
-@
-text
-@/* Memory-access and commands for inferior process, for GDB.
- Copyright (C) 1988 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-/* Remote communication protocol.
- All values are encoded in ascii hex digits.
-
- Request Packet
-
- read registers g
- reply XX....X Each byte of register data
- is described by two hex digits.
- Registers are in the internal order
- for GDB, and the bytes in a register
- are in the same order the machine uses.
- or ENN for an error.
-
- write regs GXX..XX Each byte of register data
- is described by two hex digits.
- reply OK for success
- ENN for an error
-
- read mem mAA..AA,LLLL AA..AA is address, LLLL is length.
- reply XX..XX XX..XX is mem contents
- or ENN NN is errno
-
- write mem MAA..AA,LLLL:XX..XX
- AA..AA is address,
- LLLL is number of bytes,
- XX..XX is data
- reply OK for success
- ENN for an error
-
- cont cAA..AA AA..AA is address to resume
- If AA..AA is omitted,
- resume at same address.
-
- step sAA..AA AA..AA is address to resume
- If AA..AA is omitted,
- resume at same address.
-
- There is no immediate reply to step or cont.
- The reply comes when the machine stops.
- It is SAA AA is the "signal number"
-
- kill req k
-*/
-
-#include "defs.h"
-#include "param.h"
-#include "frame.h"
-#include "inferior.h"
-
-#include "wait.h"
-
-#ifdef USG
-#include <sys/types.h>
-#include <fcntl.h>
-#endif
-
-#include <stdio.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <sys/file.h>
-
-#ifdef HAVE_TERMIO
-#include <termio.h>
-#undef TIOCGETP
-#define TIOCGETP TCGETA
-#undef TIOCSETN
-#define TIOCSETN TCSETA
-#undef TIOCSETP
-#define TIOCSETP TCSETAF
-#define TERMINAL struct termio
-#else
-#include <sgtty.h>
-#define TERMINAL struct sgttyb
-#endif
-
-int kiodebug;
-
-int icache;
-
-/* Descriptor for I/O to remote machine. */
-int remote_desc;
-
-#define PBUFSIZ 400
-
-static void remote_send ();
-static void putpkt ();
-static void getpkt ();
-static void dcache_flush ();
-
-
-/* Open a connection to a remote debugger.
- NAME is the filename used for communication. */
-
-void
-remote_open (name, from_tty)
- char *name;
- int from_tty;
-{
- TERMINAL sg;
-
- remote_debugging = 0;
- dcache_init ();
-
- remote_desc = open (name, O_RDWR);
- if (remote_desc < 0)
- perror_with_name (name);
-
- ioctl (remote_desc, TIOCGETP, &sg);
-#ifdef HAVE_TERMIO
- sg.c_lflag &= ~ICANON;
-#else
- sg.sg_flags = RAW;
-#endif
- ioctl (remote_desc, TIOCSETP, &sg);
-
- if (from_tty)
- printf ("Remote debugging using %s\n", name);
- remote_debugging = 1;
-}
-
-/* Convert hex digit A to a number. */
-
-static int
-fromhex (a)
- int a;
-{
- if (a >= '0' && a <= '9')
- return a - '0';
- else if (a >= 'a' && a <= 'f')
- return a - 'a' + 10;
- else
- error ("Reply contains invalid hex digit");
-}
-
-/* Convert number NIB to a hex digit. */
-
-static int
-tohex (nib)
- int nib;
-{
- if (nib < 10)
- return '0'+nib;
- else
- return 'a'+nib-10;
-}
-
-/* Tell the remote machine to resume. */
-
-int
-remote_resume (step, signal)
- int step, signal;
-{
- char buf[PBUFSIZ];
-
- dcache_flush ();
-
- strcpy (buf, step ? "s": "c");
-
- putpkt (buf);
-}
-
-/* Wait until the remote machine stops, then return,
- storing status in STATUS just as `wait' would. */
-
-int
-remote_wait (status)
- WAITTYPE *status;
-{
- char buf[PBUFSIZ];
-
- WSETEXIT ((*status), 0);
- getpkt (buf);
- if (buf[0] == 'E')
- error ("Remote failure reply: %s", buf);
- if (buf[0] != 'S')
- error ("Invalid remote reply: %s", buf);
- WSETSTOP ((*status), (((fromhex (buf[1])) << 4) + (fromhex (buf[2]))));
-}
-
-/* Read the remote registers into the block REGS. */
-
-void
-remote_fetch_registers (regs)
- char *regs;
-{
- char buf[PBUFSIZ];
- int i;
- char *p;
-
- sprintf (buf, "g");
- remote_send (buf);
-
- /* Reply describes registers byte by byte,
- each byte encoded as two hex characters. */
-
- p = buf;
- for (i = 0; i < REGISTER_BYTES; i++)
- {
- if (p[0] == 0 || p[1] == 0)
- error ("Remote reply is too short: %s", buf);
- regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
- p += 2;
- }
-}
-
-/* Store the remote registers from the contents of the block REGS. */
-
-void
-remote_store_registers (regs)
- char *regs;
-{
- char buf[PBUFSIZ];
- int i;
- char *p;
-
- buf[0] = 'G';
-
- /* Command describes registers byte by byte,
- each byte encoded as two hex characters. */
-
- p = buf + 1;
- for (i = 0; i < REGISTER_BYTES; i++)
- {
- *p++ = tohex ((regs[i] >> 4) & 0xf);
- *p++ = tohex (regs[i] & 0xf);
- }
-
- remote_send (buf);
-}
-
-/* Read a word from remote address ADDR and return it.
- This goes through the data cache. */
-
-int
-remote_fetch_word (addr)
- CORE_ADDR addr;
-{
- if (icache)
- {
- extern CORE_ADDR text_start, text_end;
-
- if (addr >= text_start && addr < text_end)
- {
- int buffer;
- xfer_core_file (addr, &buffer, sizeof (int));
- return buffer;
- }
- }
- return dcache_fetch (addr);
-}
-
-/* Write a word WORD into remote address ADDR.
- This goes through the data cache. */
-
-void
-remote_store_word (addr, word)
- CORE_ADDR addr;
- int word;
-{
- dcache_poke (addr, word);
-}
-
-/* Write memory data directly to the remote machine.
- This does not inform the data cache; the data cache uses this.
- MEMADDR is the address in the remote memory space.
- MYADDR is the address of the buffer in our space.
- LEN is the number of bytes. */
-
-void
-remote_write_bytes (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
-{
- char buf[PBUFSIZ];
- int i;
- char *p;
-
- if (len > PBUFSIZ / 2 - 20)
- abort ();
-
- sprintf (buf, "M%x,%x:", memaddr, len);
-
- /* Command describes registers byte by byte,
- each byte encoded as two hex characters. */
-
- p = buf + strlen (buf);
- for (i = 0; i < len; i++)
- {
- *p++ = tohex ((myaddr[i] >> 4) & 0xf);
- *p++ = tohex (myaddr[i] & 0xf);
- }
-
- remote_send (buf);
-}
-
-/* Read memory data directly from the remote machine.
- This does not use the data cache; the data cache uses this.
- MEMADDR is the address in the remote memory space.
- MYADDR is the address of the buffer in our space.
- LEN is the number of bytes. */
-
-void
-remote_read_bytes (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
-{
- char buf[PBUFSIZ];
- int i;
- char *p;
-
- if (len > PBUFSIZ / 2 - 1)
- abort ();
-
- sprintf (buf, "m%x,%x", memaddr, len);
- remote_send (buf);
-
- /* Reply describes registers byte by byte,
- each byte encoded as two hex characters. */
-
- p = buf;
- for (i = 0; i < len; i++)
- {
- if (p[0] == 0 || p[1] == 0)
- error ("Remote reply is too short: %s", buf);
- myaddr[i] = fromhex (p[0]) * 16 + fromhex (p[1]);
- p += 2;
- }
-}
-
-/*
-
-A debug packet whose contents are <data>
-is encapsulated for transmission in the form:
-
- $ <data> # CSUM1 CSUM2
-
- <data> must be ASCII alphanumeric and cannot include characters
- '$' or '#'
-
- CSUM1 and CSUM2 are ascii hex representation of an 8-bit
- checksum of <data>, the most significant nibble is sent first.
- the hex digits 0-9,a-f are used.
-
-Receiver responds with:
-
- + - if CSUM is correct and ready for next packet
- - - if CSUM is incorrect
-
-*/
-
-/* Send the command in BUF to the remote machine,
- and read the reply into BUF.
- Report an error if we get an error reply. */
-
-static void
-remote_send (buf)
- char *buf;
-{
- int i;
- putpkt (buf);
- getpkt (buf);
-
- if (buf[0] == 'E')
- error ("Remote failure reply: %s", buf);
-}
-
-/* Send a packet to the remote machine, with error checking.
- The data of the packet is in BUF. */
-
-static void
-putpkt (buf)
- char *buf;
-{
- int i;
- char csum = 0;
- char buf2[500];
- char buf3[1];
- int cnt = strlen (buf);
- char *p;
-
- if (kiodebug)
- fprintf (stderr, "Sending packet: %s\n", buf);
-
- /* Copy the packet into buffer BUF2, encapsulating it
- and giving it a checksum. */
-
- p = buf2;
- *p++ = '$';
-
- for (i = 0; i < cnt; i++)
- {
- csum += buf[i];
- *p++ = buf[i];
- }
- *p++ = '#';
- *p++ = tohex ((csum >> 4) & 0xf);
- *p++ = tohex (csum & 0xf);
-
- /* Send it over and over until we get a positive ack. */
-
- do {
- write (remote_desc, buf2, p - buf2);
- read (remote_desc, buf3, 1);
- } while (buf3[0] != '+');
-}
-
-static int
-readchar ()
-{
- char buf[1];
- while (read (remote_desc, buf, 1) != 1) ;
- return buf[0] & 0x7f;
-}
-
-/* Read a packet from the remote machine, with error checking,
- and store it in BUF. */
-
-static void
-getpkt (buf)
- char *buf;
-{
- char *bp;
- unsigned char csum;
- unsigned int c, c1, c2;
- extern kiodebug;
-
- while (1)
- {
- /* Force csum to be zero here because of possible error retry. */
- csum = 0;
-
- while ((c = readchar()) != '$');
-
- bp = buf;
- while (1)
- {
- c = readchar ();
- if (c == '#')
- break;
- *bp++ = c;
- csum += c;
- }
- *bp = 0;
-
- c1 = fromhex (readchar ());
- c2 = fromhex (readchar ());
- if (csum == (c1 << 4) + c2)
- break;
- printf ("Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n",
- (c1 << 4) + c2, csum, buf);
- write (remote_desc, "-", 1);
- }
-
- write (remote_desc, "+", 1);
-
- if (kiodebug)
- fprintf (stderr,"Packet received :%s\n", buf);
-}
-
-/* The data cache records all the data read from the remote machine
- since the last time it stopped.
-
- Each cache block holds 16 bytes of data
- starting at a multiple-of-16 address. */
-
-#define DCACHE_SIZE 64 /* Number of cache blocks */
-
-struct dcache_block {
- struct dcache_block *next, *last;
- unsigned int addr; /* Address for which data is recorded. */
- int data[4];
-};
-
-struct dcache_block dcache_free, dcache_valid;
-
-/* Free all the data cache blocks, thus discarding all cached data. */
-
-static void
-dcache_flush ()
-{
- register struct dcache_block *db;
-
- while ((db = dcache_valid.next) != &dcache_valid)
- {
- remque (db);
- insque (db, &dcache_free);
- }
-}
-
-/*
- * If addr is present in the dcache, return the address of the block
- * containing it.
- */
-
-struct dcache_block *
-dcache_hit (addr)
-{
- register struct dcache_block *db;
-
- if (addr & 3)
- abort ();
-
- /* Search all cache blocks for one that is at this address. */
- db = dcache_valid.next;
- while (db != &dcache_valid)
- {
- if ((addr & 0xfffffff0) == db->addr)
- return db;
- db = db->next;
- }
- return NULL;
-}
-
-/* Return the int data at address ADDR in dcache block DC. */
-
-int
-dcache_value (db, addr)
- struct dcache_block *db;
- unsigned int addr;
-{
- if (addr & 3)
- abort ();
- return (db->data[(addr>>2)&3]);
-}
-
-/* Get a free cache block, put it on the valid list,
- and return its address. The caller should store into the block
- the address and data that it describes. */
-
-struct dcache_block *
-dcache_alloc ()
-{
- register struct dcache_block *db;
-
- if ((db = dcache_free.next) == &dcache_free)
- /* If we can't get one from the free list, take last valid */
- db = dcache_valid.last;
-
- remque (db);
- insque (db, &dcache_valid);
- return (db);
-}
-
-/* Return the contents of the word at address ADDR in the remote machine,
- using the data cache. */
-
-int
-dcache_fetch (addr)
- CORE_ADDR addr;
-{
- register struct dcache_block *db;
-
- db = dcache_hit (addr);
- if (db == 0)
- {
- db = dcache_alloc ();
- remote_read_bytes (addr & ~0xf, db->data, 16);
- db->addr = addr & ~0xf;
- }
- return (dcache_value (db, addr));
-}
-
-/* Write the word at ADDR both in the data cache and in the remote machine. */
-
-dcache_poke (addr, data)
- CORE_ADDR addr;
- int data;
-{
- register struct dcache_block *db;
-
- /* First make sure the word is IN the cache. DB is its cache block. */
- db = dcache_hit (addr);
- if (db == 0)
- {
- db = dcache_alloc ();
- remote_read_bytes (addr & ~0xf, db->data, 16);
- db->addr = addr & ~0xf;
- }
-
- /* Modify the word in the cache. */
- db->data[(addr>>2)&3] = data;
-
- /* Send the changed word. */
- remote_write_bytes (addr, &data, 4);
-}
-
-/* Initialize the data cache. */
-
-dcache_init ()
-{
- register i;
- register struct dcache_block *db;
-
- db = (struct dcache_block *) xmalloc (sizeof (struct dcache_block) *
- DCACHE_SIZE);
- dcache_free.next = dcache_free.last = &dcache_free;
- dcache_valid.next = dcache_valid.last = &dcache_valid;
- for (i=0;i<DCACHE_SIZE;i++,db++)
- insque (db, &dcache_free);
-}
-
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d74 1
-a74 1
-#include <sys/fcntl.h>
-@
diff --git a/gdb/RCS/source.c,v b/gdb/RCS/source.c,v
deleted file mode 100644
index f19ff1d..0000000
--- a/gdb/RCS/source.c,v
+++ /dev/null
@@ -1,990 +0,0 @@
-head 1.2;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.2
-date 89.03.27.20.21.45; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.03.20.18.45.48; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.2
-log
-@Avoid <sys/fcntl.h>.
-@
-text
-@/* List lines of source files for GDB, the GNU debugger.
- Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#include "defs.h"
-#include "symtab.h"
-#include "param.h"
-
-#ifdef USG
-#include <sys/types.h>
-#include <fcntl.h>
-#endif
-
-#include <stdio.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-#include <sys/file.h>
-
-/* Path of directories to search for source files.
- Same format as the PATH environment variable's value. */
-
-static char *source_path;
-
-/* Symtab of default file for listing lines of. */
-
-struct symtab *current_source_symtab;
-
-/* Default next line to list. */
-
-int current_source_line;
-
-/* Line number of last line printed. Default for various commands.
- current_source_line is usually, but not always, the same as this. */
-
-static int last_line_listed;
-
-/* First line number listed by last listing command. */
-
-static int first_line_listed;
-
-
-struct symtab *psymtab_to_symtab ();
-
-/* Set the source file default for the "list" command,
- specifying a symtab. */
-
-void
-select_source_symtab (s)
- register struct symtab *s;
-{
- struct symtabs_and_lines sals;
- struct symtab_and_line sal;
- struct partial_symtab *ps, *cs_pst;
-
- /* Make the default place to list be the function `main'
- if one exists. */
- if (lookup_symbol ("main", 0, VAR_NAMESPACE, 0))
- {
- sals = decode_line_spec ("main", 1);
- sal = sals.sals[0];
- free (sals.sals);
- current_source_symtab = sal.symtab;
- current_source_line = sal.line - 9;
- return;
- }
-
- /* If there is no `main', use the last symtab in the list,
- which is actually the first found in the file's symbol table.
- But ignore .h files. */
- if (s)
- {
- do
- {
- char *name = s->filename;
- int len = strlen (name);
- if (! (len > 2 && !strcmp (&name[len - 2], ".h")))
- current_source_symtab = s;
- s = s->next;
- }
- while (s);
- current_source_line = 1;
- }
- else
- {
- ps = partial_symtab_list;
- while (ps)
- {
- char *name = ps->filename;
- int len = strlen (name);
- if (! (len > 2 && !strcmp (&name[len - 2], ".h")))
- cs_pst = ps;
- ps = ps->next;
- }
- if (cs_pst)
- current_source_symtab = psymtab_to_symtab (cs_pst);
- else
- current_source_symtab = 0;
- current_source_line = 1;
- }
-}
-
-static void
-directories_info ()
-{
- printf ("Source directories searched: %s\n", source_path);
-}
-
-void
-init_source_path ()
-{
- register struct symtab *s;
-
- source_path = savestring (current_directory, strlen (current_directory));
-
- /* Forget what we learned about line positions in source files;
- must check again now since files may be found in
- a different directory now. */
- for (s = symtab_list; s; s = s->next)
- if (s->line_charpos != 0)
- {
- free (s->line_charpos);
- s->line_charpos = 0;
- }
-}
-
-void
-directory_command (dirname, from_tty)
- char *dirname;
- int from_tty;
-{
- char *old = source_path;
-
- if (dirname == 0)
- {
- if (query ("Reinitialize source path to %s? ", current_directory))
- {
- init_source_path ();
- free (old);
- }
- }
- else
- {
- struct stat st;
- register int len = strlen (dirname);
- register char *tem;
- extern char *index ();
-
- if (index (dirname, ':'))
- error ("Please add one directory at a time to the source path.");
- if (dirname[len - 1] == '/')
- /* Sigh. "foo/" => "foo" */
- dirname[--len] == '\0';
-
- while (dirname[len - 1] == '.')
- {
- if (len == 1)
- {
- /* "." => getwd () */
- dirname = current_directory;
- goto append;
- }
- else if (dirname[len - 2] == '/')
- {
- if (len == 2)
- {
- /* "/." => "/" */
- dirname[--len] = '\0';
- goto append;
- }
- else
- {
- /* "...foo/." => "...foo" */
- dirname[len -= 2] = '\0';
- continue;
- }
- }
- break;
- }
-
- if (dirname[0] != '/')
- dirname = concat (current_directory, "/", dirname);
- else
- dirname = savestring (dirname, len);
- make_cleanup (free, dirname);
-
- if (stat (dirname, &st) < 0)
- perror_with_name (dirname);
- if ((st.st_mode & S_IFMT) != S_IFDIR)
- error ("%s is not a directory.", dirname);
-
- append:
- len = strlen (dirname);
- tem = source_path;
- while (1)
- {
- if (!strncmp (tem, dirname, len)
- && (tem[len] == '\0' || tem[len] == ':'))
- {
- printf ("\"%s\" is already in the source path.\n",
- dirname);
- break;
- }
- tem = index (tem, ':');
- if (tem)
- tem++;
- else
- {
- source_path = concat (old, ":", dirname);
- free (old);
- break;
- }
- }
- if (from_tty)
- directories_info ();
- }
-}
-
-/* Open a file named STRING, searching path PATH (dir names sep by colons)
- using mode MODE and protection bits PROT in the calls to open.
- If TRY_CWD_FIRST, try to open ./STRING before searching PATH.
- (ie pretend the first element of PATH is ".")
- If FILENAMED_OPENED is non-null, set it to a newly allocated string naming
- the actual file opened (this string will always start with a "/"
-
- If a file is found, return the descriptor.
- Otherwise, return -1, with errno set for the last name we tried to open. */
-
-/* >>>> This should only allow files of certain types,
- >>>> eg executable, non-directory */
-int
-openp (path, try_cwd_first, string, mode, prot, filename_opened)
- char *path;
- int try_cwd_first;
- char *string;
- int mode;
- int prot;
- char **filename_opened;
-{
- register int fd;
- register char *filename;
- register char *p, *p1;
- register int len;
-
- /* ./foo => foo */
- while (string[0] == '.' && string[1] == '/')
- string += 2;
-
- if (try_cwd_first || string[0] == '/')
- {
- filename = string;
- fd = open (filename, mode, prot);
- if (fd >= 0 || string[0] == '/')
- goto done;
- }
-
- filename = (char *) alloca (strlen (path) + strlen (string) + 2);
- fd = -1;
- for (p = path; p; p = p1 ? p1 + 1 : 0)
- {
- p1 = (char *) index (p, ':');
- if (p1)
- len = p1 - p;
- else
- len = strlen (p);
-
- strncpy (filename, p, len);
- filename[len] = 0;
- strcat (filename, "/");
- strcat (filename, string);
-
- fd = open (filename, mode, prot);
- if (fd >= 0) break;
- }
-
- done:
- if (filename_opened)
- if (fd < 0)
- *filename_opened = (char *) 0;
- else if (filename[0] == '/')
- *filename_opened = savestring (filename, strlen (filename));
- else
- {
- *filename_opened = concat (current_directory, "/", filename);
- }
-
- return fd;
-}
-
-/* Create and initialize the table S->line_charpos that records
- the positions of the lines in the source file, which is assumed
- to be open on descriptor DESC.
- All set S->nlines to the number of such lines. */
-
-static void
-find_source_lines (s, desc)
- struct symtab *s;
- int desc;
-{
- struct stat st;
- register char *data, *p, *end;
- int nlines = 0;
- int lines_allocated = 1000;
- int *line_charpos = (int *) xmalloc (lines_allocated * sizeof (int));
- extern int exec_mtime;
-
- fstat (desc, &st);
- if (get_exec_file (0) != 0 && exec_mtime < st.st_mtime)
- printf ("Source file is more recent than executable.\n");
-
- data = (char *) alloca (st.st_size);
- myread (desc, data, st.st_size);
- end = data + st.st_size;
- p = data;
- line_charpos[0] = 0;
- nlines = 1;
- while (p != end)
- {
- if (*p++ == '\n'
- /* A newline at the end does not start a new line. */
- && p != end)
- {
- if (nlines == lines_allocated)
- {
- lines_allocated *= 2;
- line_charpos = (int *) xrealloc (line_charpos,
- sizeof (int) * lines_allocated);
- }
- line_charpos[nlines++] = p - data;
- }
- }
- s->nlines = nlines;
- s->line_charpos = (int *) xrealloc (line_charpos, nlines * sizeof (int));
-}
-
-/* Return the character position of a line LINE in symtab S.
- Return 0 if anything is invalid. */
-
-int
-source_line_charpos (s, line)
- struct symtab *s;
- int line;
-{
- if (!s) return 0;
- if (!s->line_charpos || line <= 0) return 0;
- if (line > s->nlines)
- line = s->nlines;
- return s->line_charpos[line - 1];
-}
-
-/* Return the line number of character position POS in symtab S. */
-
-int
-source_charpos_line (s, chr)
- register struct symtab *s;
- register int chr;
-{
- register int line = 0;
- register int *lnp;
-
- if (s == 0 || s->line_charpos == 0) return 0;
- lnp = s->line_charpos;
- /* Files are usually short, so sequential search is Ok */
- while (line < s->nlines && *lnp <= chr)
- {
- line++;
- lnp++;
- }
- if (line >= s->nlines)
- line = s->nlines;
- return line;
-}
-
-/* Get full pathname and line number positions for a symtab.
- Return nonzero if line numbers may have changed.
- Set *FULLNAME to actual name of the file as found by `openp',
- or to 0 if the file is not found. */
-
-int
-get_filename_and_charpos (s, line, fullname)
- struct symtab *s;
- int line;
- char **fullname;
-{
- register int desc, linenums_changed = 0;
-
- desc = openp (source_path, 0, s->filename, O_RDONLY, 0, &s->fullname);
- if (desc < 0)
- {
- if (fullname)
- *fullname = NULL;
- return 0;
- }
- if (fullname)
- *fullname = s->fullname;
- if (s->line_charpos == 0) linenums_changed = 1;
- if (linenums_changed) find_source_lines (s, desc);
- close (desc);
- return linenums_changed;
-}
-
-/* Print text describing the full name of the source file S
- and the line number LINE and its corresponding character position.
- The text starts with two Ctrl-z so that the Emacs-GDB interface
- can easily find it.
-
- MID_STATEMENT is nonzero if the PC is not at the beginning of that line.
-
- Return 1 if successful, 0 if could not find the file. */
-
-int
-identify_source_line (s, line, mid_statement)
- struct symtab *s;
- int line;
- int mid_statement;
-{
- if (s->line_charpos == 0)
- get_filename_and_charpos (s, line, 0);
- if (s->fullname == 0)
- return 0;
- printf ("\032\032%s:%d:%d:%s\n", s->fullname,
- line, s->line_charpos[line - 1],
- mid_statement ? "middle" : "beg");
- current_source_line = line;
- first_line_listed = line;
- last_line_listed = line;
- current_source_symtab = s;
- return 1;
-}
-
-/* Print source lines from the file of symtab S,
- starting with line number LINE and stopping before line number STOPLINE. */
-
-void
-print_source_lines (s, line, stopline, noerror)
- struct symtab *s;
- int line, stopline;
- int noerror;
-{
- register int c;
- register int desc;
- register FILE *stream;
- int nlines = stopline - line;
-
- desc = openp (source_path, 0, s->filename, O_RDONLY, 0, &s->fullname);
- if (desc < 0)
- {
- extern int errno;
- if (! noerror)
- perror_with_name (s->filename);
- print_sys_errmsg (s->filename, errno);
- return;
- }
-
- if (s->line_charpos == 0)
- find_source_lines (s, desc);
-
- if (line < 1 || line > s->nlines)
- {
- close (desc);
- error ("Line number out of range; %s has %d lines.",
- s->filename, s->nlines);
- }
-
- if (lseek (desc, s->line_charpos[line - 1], 0) < 0)
- {
- close (desc);
- perror_with_name (s->filename);
- }
-
- current_source_symtab = s;
- current_source_line = line;
- first_line_listed = line;
-
- stream = fdopen (desc, "r");
- clearerr (stream);
-
- while (nlines-- > 0)
- {
- c = fgetc (stream);
- if (c == EOF) break;
- last_line_listed = current_source_line;
- printf ("%d\t", current_source_line++);
- do
- {
- if (c < 040 && c != '\t' && c != '\n')
- {
- fputc ('^', stdout);
- fputc (c + 0100, stdout);
- }
- else if (c == 0177)
- printf ("^?");
- else
- fputc (c, stdout);
- } while (c != '\n' && (c = fgetc (stream)) >= 0);
- }
-
- fclose (stream);
-}
-
-
-
-/*
- C++
- Print a list of files and line numbers which a user may choose from
- in order to list a function which was specified ambiguously
- (as with `list classname::overloadedfuncname', for example).
- The vector in SALS provides the filenames and line numbers.
- */
-static void
-ambiguous_line_spec (sals)
- struct symtabs_and_lines *sals;
-{
- int i;
-
- for (i = 0; i < sals->nelts; ++i)
- printf("file: \"%s\", line number: %d\n",
- sals->sals[i].symtab->filename, sals->sals[i].line);
-}
-
-
-static void
-list_command (arg, from_tty)
- char *arg;
- int from_tty;
-{
- struct symtabs_and_lines sals, sals_end;
- struct symtab_and_line sal, sal_end;
- struct symbol *sym;
- char *arg1;
- int no_end = 1;
- int dummy_end = 0;
- int dummy_beg = 0;
- int linenum_beg = 0;
- char *p;
-
- if (symtab_list == 0 && partial_symtab_list == 0)
- error ("Listing source lines requires symbols.");
-
- /* Pull in a current source symtab if necessary */
- if (current_source_symtab == 0 &&
- (arg == 0 || arg[0] == '+' || arg[0] == '-'))
- select_source_symtab (symtab_list);
-
- /* "l" or "l +" lists next ten lines. */
-
- if (arg == 0 || !strcmp (arg, "+"))
- {
- if (current_source_symtab == 0)
- error ("No default source file yet. Do \"help list\".");
- print_source_lines (current_source_symtab, current_source_line,
- current_source_line + 10, 0);
- return;
- }
-
- /* "l -" lists previous ten lines, the ones before the ten just listed. */
- if (!strcmp (arg, "-"))
- {
- if (current_source_symtab == 0)
- error ("No default source file yet. Do \"help list\".");
- print_source_lines (current_source_symtab,
- max (first_line_listed - 10, 1),
- first_line_listed, 0);
- return;
- }
-
- /* Now if there is only one argument, decode it in SAL
- and set NO_END.
- If there are two arguments, decode them in SAL and SAL_END
- and clear NO_END; however, if one of the arguments is blank,
- set DUMMY_BEG or DUMMY_END to record that fact. */
-
- arg1 = arg;
- if (*arg1 == ',')
- dummy_beg = 1;
- else
- {
- sals = decode_line_1 (&arg1, 0, 0, 0);
-
- if (! sals.nelts) return; /* C++ */
- if (sals.nelts > 1)
- {
- ambiguous_line_spec (&sals);
- free (sals.sals);
- return;
- }
-
- sal = sals.sals[0];
- free (sals.sals);
- }
-
- /* Record whether the BEG arg is all digits. */
-
- for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++);
- linenum_beg = (p == arg1);
-
- while (*arg1 == ' ' || *arg1 == '\t')
- arg1++;
- if (*arg1 == ',')
- {
- no_end = 0;
- arg1++;
- while (*arg1 == ' ' || *arg1 == '\t')
- arg1++;
- if (*arg1 == 0)
- dummy_end = 1;
- else
- {
- if (dummy_beg)
- sals_end = decode_line_1 (&arg1, 0, 0, 0);
- else
- sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line);
- if (sals_end.nelts == 0)
- return;
- if (sals_end.nelts > 1)
- {
- ambiguous_line_spec (&sals_end);
- free (sals_end.sals);
- return;
- }
- sal_end = sals_end.sals[0];
- free (sals_end.sals);
- }
- }
-
- if (*arg1)
- error ("Junk at end of line specification.");
-
- if (!no_end && !dummy_beg && !dummy_end
- && sal.symtab != sal_end.symtab)
- error ("Specified start and end are in different files.");
- if (dummy_beg && dummy_end)
- error ("Two empty args do not say what lines to list.");
-
- /* if line was specified by address,
- first print exactly which line, and which file.
- In this case, sal.symtab == 0 means address is outside
- of all known source files, not that user failed to give a filename. */
- if (*arg == '*')
- {
- if (sal.symtab == 0)
- error ("No source file for address 0x%x.", sal.pc);
- sym = find_pc_function (sal.pc);
- if (sym)
- printf ("0x%x is in %s (%s, line %d).\n",
- sal.pc, SYMBOL_NAME (sym), sal.symtab->filename, sal.line);
- else
- printf ("0x%x is in %s, line %d.\n",
- sal.pc, sal.symtab->filename, sal.line);
- }
-
- /* If line was not specified by just a line number,
- and it does not imply a symtab, it must be an undebuggable symbol
- which means no source code. */
-
- if (! linenum_beg && sal.symtab == 0)
- error ("No line number known for %s.", arg);
-
- /* If this command is repeated with RET,
- turn it into the no-arg variant. */
-
- if (from_tty)
- *arg = 0;
-
- if (dummy_beg && sal_end.symtab == 0)
- error ("No default source file yet. Do \"help list\".");
- if (dummy_beg)
- print_source_lines (sal_end.symtab, max (sal_end.line - 9, 1),
- sal_end.line + 1, 0);
- else if (sal.symtab == 0)
- error ("No default source file yet. Do \"help list\".");
- else if (no_end)
- print_source_lines (sal.symtab, max (sal.line - 5, 1), sal.line + 5, 0);
- else
- print_source_lines (sal.symtab, sal.line,
- dummy_end ? sal.line + 10 : sal_end.line + 1,
- 0);
-}
-
-/* Print info on range of pc's in a specified line. */
-
-static void
-line_info (arg, from_tty)
- char *arg;
- int from_tty;
-{
- struct symtabs_and_lines sals;
- struct symtab_and_line sal;
- int start_pc, end_pc;
- int i;
-
- if (arg == 0)
- {
- sal.symtab = current_source_symtab;
- sal.line = last_line_listed;
- sals.nelts = 1;
- sals.sals = (struct symtab_and_line *)
- xmalloc (sizeof (struct symtab_and_line));
- sals.sals[0] = sal;
- }
- else
- {
- sals = decode_line_spec_1 (arg, 0);
-
- /* If this command is repeated with RET,
- turn it into the no-arg variant. */
- if (from_tty)
- *arg = 0;
- }
-
- /* C++ More than one line may have been specified, as when the user
- specifies an overloaded function name. Print info on them all. */
- for (i = 0; i < sals.nelts; i++)
- {
- sal = sals.sals[i];
-
- if (sal.symtab == 0)
- error ("No source file specified.");
-
- if (sal.line > 0
- && find_line_pc_range (sal.symtab, sal.line, &start_pc, &end_pc))
- {
- if (start_pc == end_pc)
- printf ("Line %d of \"%s\" is at pc 0x%x but contains no code.\n",
- sal.line, sal.symtab->filename, start_pc);
- else
- printf ("Line %d of \"%s\" starts at pc 0x%x and ends at 0x%x.\n",
- sal.line, sal.symtab->filename, start_pc, end_pc);
- /* x/i should display this line's code. */
- set_next_address (start_pc);
- /* Repeating "info line" should do the following line. */
- last_line_listed = sal.line + 1;
- }
- else
- printf ("Line number %d is out of range for \"%s\".\n",
- sal.line, sal.symtab->filename);
- }
-}
-
-/* Commands to search the source file for a regexp. */
-
-static void
-forward_search_command (regex, from_tty)
- char *regex;
-{
- register int c;
- register int desc;
- register FILE *stream;
- int line = last_line_listed + 1;
- char *msg;
-
- msg = (char *) re_comp (regex);
- if (msg)
- error (msg);
-
- if (current_source_symtab == 0)
- error ("No default source file yet. Do \"help list\".");
-
- /* Search from last_line_listed+1 in current_source_symtab */
-
- desc = openp (source_path, 0, current_source_symtab->filename,
- O_RDONLY, 0, &current_source_symtab->fullname);
- if (desc < 0)
- perror_with_name (current_source_symtab->filename);
-
- if (current_source_symtab->line_charpos == 0)
- find_source_lines (current_source_symtab, desc);
-
- if (line < 1 || line > current_source_symtab->nlines)
- {
- close (desc);
- error ("Expression not found");
- }
-
- if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
- {
- close (desc);
- perror_with_name (current_source_symtab->filename);
- }
-
- stream = fdopen (desc, "r");
- clearerr (stream);
- while (1) {
- char buf[4096]; /* Should be reasonable??? */
- register char *p = buf;
-
- c = fgetc (stream);
- if (c == EOF)
- break;
- do {
- *p++ = c;
- } while (c != '\n' && (c = fgetc (stream)) >= 0);
-
- /* we now have a source line in buf, null terminate and match */
- *p = 0;
- if (re_exec (buf) > 0)
- {
- /* Match! */
- fclose (stream);
- print_source_lines (current_source_symtab,
- line, line+1, 0);
- current_source_line = max (line - 5, 1);
- return;
- }
- line++;
- }
-
- printf ("Expression not found\n");
- fclose (stream);
-}
-
-static void
-reverse_search_command (regex, from_tty)
- char *regex;
-{
- register int c;
- register int desc;
- register FILE *stream;
- int line = last_line_listed - 1;
- char *msg;
-
- msg = (char *) re_comp (regex);
- if (msg)
- error (msg);
-
- if (current_source_symtab == 0)
- error ("No default source file yet. Do \"help list\".");
-
- /* Search from last_line_listed-1 in current_source_symtab */
-
- desc = openp (source_path, 0, current_source_symtab->filename,
- O_RDONLY, 0, &current_source_symtab->fullname);
- if (desc < 0)
- perror_with_name (current_source_symtab->filename);
-
- if (current_source_symtab->line_charpos == 0)
- find_source_lines (current_source_symtab, desc);
-
- if (line < 1 || line > current_source_symtab->nlines)
- {
- close (desc);
- error ("Expression not found");
- }
-
- if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0)
- {
- close (desc);
- perror_with_name (current_source_symtab->filename);
- }
-
- stream = fdopen (desc, "r");
- clearerr (stream);
- while (1)
- {
- char buf[4096]; /* Should be reasonable??? */
- register char *p = buf;
-
- c = fgetc (stream);
- if (c == EOF)
- break;
- do {
- *p++ = c;
- } while (c != '\n' && (c = fgetc (stream)) >= 0);
-
- /* We now have a source line in buf; null terminate and match. */
- *p = 0;
- if (re_exec (buf) > 0)
- {
- /* Match! */
- fclose (stream);
- print_source_lines (current_source_symtab,
- line, line+1, 0);
- current_source_line = max (line - 5, 1);
- return;
- }
- line--;
- if (fseek (stream, current_source_symtab->line_charpos[line - 1], 0) < 0)
- {
- fclose (stream);
- perror_with_name (current_source_symtab->filename);
- }
- }
-
- printf ("Expression not found\n");
- fclose (stream);
- return;
-}
-
-void
-_initialize_source ()
-{
- current_source_symtab = 0;
- init_source_path ();
-
- add_com ("directory", class_files, directory_command,
- "Add directory DIR to end of search path for source files.\n\
-With no argument, reset the search path to just the working directory\n\
-and forget cached info on line positions in source files.");
-
- add_info ("directories", directories_info,
- "Current search path for finding source files.");
-
- add_info ("line", line_info,
- "Core addresses of the code for a source line.\n\
-Line can be specified as\n\
- LINENUM, to list around that line in current file,\n\
- FILE:LINENUM, to list around that line in that file,\n\
- FUNCTION, to list around beginning of that function,\n\
- FILE:FUNCTION, to distinguish among like-named static functions.\n\
-Default is to describe the last source line that was listed.\n\n\
-This sets the default address for \"x\" to the line's first instruction\n\
-so that \"x/i\" suffices to start examining the machine code.\n\
-The address is also stored as the value of \"$_\".");
-
- add_com ("forward-search", class_files, forward_search_command,
- "Search for regular expression (see regex(3)) from last line listed.");
- add_com_alias ("search", "forward-search", class_files, 0);
-
- add_com ("reverse-search", class_files, reverse_search_command,
- "Search backward for regular expression (see regex(3)) from last line listed.");
-
- add_com ("list", class_files, list_command,
- "List specified function or line.\n\
-With no argument, lists ten more lines after or around previous listing.\n\
-\"list -\" lists the ten lines before a previous ten-line listing.\n\
-One argument specifies a line, and ten lines are listed around that line.\n\
-Two arguments with comma between specify starting and ending lines to list.\n\
-Lines can be specified in these ways:\n\
- LINENUM, to list around that line in current file,\n\
- FILE:LINENUM, to list around that line in that file,\n\
- FUNCTION, to list around beginning of that function,\n\
- FILE:FUNCTION, to distinguish among like-named static functions.\n\
- *ADDRESS, to list around the line containing that address.\n\
-With two args if one is empty it stands for ten lines away from the other arg.");
-}
-
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d27 1
-a27 1
-#include <sys/fcntl.h>
-@
diff --git a/gdb/RCS/sparc-dep.c,v b/gdb/RCS/sparc-dep.c,v
deleted file mode 100644
index 8178e00..0000000
--- a/gdb/RCS/sparc-dep.c,v
+++ /dev/null
@@ -1,1091 +0,0 @@
-head 1.3;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.3
-date 89.04.04.21.31.02; author gnu; state Exp;
-branches ;
-next 1.2;
-
-1.2
-date 89.02.10.01.47.27; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.02.10.01.46.36; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.3
-log
-@Fix handling of annulled branches in single step. "b foo; bcc,a bar"
-annuls the instruction at foo, not just after the bcc,a. Also,
-handle CBcc (coprocessor) annulled branch, and improve doc.
-@
-text
-@/* Machine-dependent code which would otherwise be in inflow.c and core.c,
- for GDB, the GNU debugger.
- Copyright (C) 1986, 1987 Free Software Foundation, Inc.
- This code is for the sparc cpu.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#include "defs.h"
-#include "param.h"
-#include "frame.h"
-#include "inferior.h"
-#include "obstack.h"
-#include "sparc-opcode.h"
-#include "gdbcore.h"
-
-#include <stdio.h>
-#include <sys/param.h>
-#include <sys/dir.h>
-#include <sys/user.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <fcntl.h>
-
-#include <sys/ptrace.h>
-#include <machine/reg.h>
-
-#include <a.out.h>
-#include <sys/file.h>
-#include <sys/stat.h>
-#include <sys/core.h>
-
-extern int errno;
-extern int attach_flag;
-
-/* This function simply calls ptrace with the given arguments.
- It exists so that all calls to ptrace are isolated in this
- machine-dependent file. */
-int
-call_ptrace (request, pid, arg3, arg4)
- int request, pid, arg3, arg4;
-{
- return ptrace (request, pid, arg3, arg4);
-}
-
-void
-kill_inferior ()
-{
- if (remote_debugging)
- return;
- if (inferior_pid == 0)
- return;
- ptrace (8, inferior_pid, 0, 0);
- wait (0);
- inferior_died ();
-}
-
-/* This is used when GDB is exiting. It gives less chance of error.*/
-
-void
-kill_inferior_fast ()
-{
- if (remote_debugging)
- return;
- if (inferior_pid == 0)
- return;
- ptrace (8, inferior_pid, 0, 0);
- wait (0);
-}
-
-/* Simulate single-step ptrace call for sun4. Code written by Gary
- Beihl (beihl@@mcc.com). */
-
-/*
- * Duplicated from breakpoint.c because (at least for now) this is a
- * machine dependent routine.
- */
-static char break_insn[] = BREAKPOINT;
-
-/* From infrun.c */
-extern int stop_after_trap, stop_after_attach;
-
-static CORE_ADDR next_pc, npc4, target;
-static int brknpc4, brktrg;
-typedef char binsn_quantum[sizeof break_insn];
-static binsn_quantum break_mem[3];
-
-/* Non-zero if we just simulated a single-step ptrace call. This is
- needed because we cannot remove the breakpoints in the inferior
- process until after the `wait' in `wait_for_inferior'. Used for
- sun4. */
-
-int one_stepped;
-
-void
-single_step (signal)
- int signal;
-{
- branch_type br, isannulled();
- CORE_ADDR pc;
-
- next_pc = read_register (NPC_REGNUM);
- npc4 = next_pc + 4; /* branch not taken */
-
- if (!one_stepped)
- {
- /* Always set breakpoint for NPC. */
- read_memory (next_pc, break_mem[0], sizeof break_insn);
- write_memory (next_pc, break_insn, sizeof break_insn);
- /* printf ("set break at %x\n",next_pc); */
-
- pc = read_register (PC_REGNUM);
- br = isannulled (pc, &target);
- brknpc4 = brktrg = 0;
-
- if (br == bicca)
- {
- /* Conditional annulled branch will either end up at
- npc (if taken) or at npc+4 (if not taken). Trap npc+4. */
- brknpc4 = 1;
- read_memory (npc4, break_mem[1], sizeof break_insn);
- write_memory (npc4, break_insn, sizeof break_insn);
- }
- else if (br == baa && target != next_pc)
- {
- /* Unconditional annulled branch will always end up at
- the target. */
- brktrg = 1;
- read_memory (target, break_mem[2], sizeof break_insn);
- write_memory (target, break_insn, sizeof break_insn);
- }
-
- /* Let it go */
- ptrace (7, inferior_pid, 1, signal);
- one_stepped = 1;
- return;
- }
- else
- {
- /* Remove breakpoints */
- write_memory (next_pc, break_mem[0], sizeof break_insn);
-
- if (brknpc4)
- {
- write_memory (npc4, break_mem[1], sizeof break_insn);
- }
- if (brktrg)
- {
- write_memory (target, break_mem[2], sizeof break_insn);
- }
- one_stepped = 0;
- }
-}
-
-/* Resume execution of the inferior process.
- If STEP is nonzero, single-step it.
- If SIGNAL is nonzero, give it that signal. */
-
-void
-resume (step, signal)
- int step;
- int signal;
-{
- errno = 0;
- if (remote_debugging)
- remote_resume (step, signal);
- else
- {
- /* Sparc doesn't have single step on ptrace */
- if (step)
- single_step (signal);
- else
- ptrace (7, inferior_pid, 1, signal);
- if (errno)
- perror_with_name ("ptrace");
- }
-}
-
-#ifdef ATTACH_DETACH
-
-/* Start debugging the process whose number is PID. */
-
-int
-attach (pid)
- int pid;
-{
- errno = 0;
- ptrace (PTRACE_ATTACH, pid, 0, 0);
- if (errno)
- perror_with_name ("ptrace");
- attach_flag = 1;
- return pid;
-}
-
-/* Stop debugging the process whose number is PID
- and continue it with signal number SIGNAL.
- SIGNAL = 0 means just continue it. */
-
-void
-detach (signal)
- int signal;
-{
- errno = 0;
- ptrace (PTRACE_DETACH, inferior_pid, 1, signal);
- if (errno)
- perror_with_name ("ptrace");
- attach_flag = 0;
-}
-#endif /* ATTACH_DETACH */
-
-void
-fetch_inferior_registers ()
-{
- struct regs inferior_registers;
- struct fp_status inferior_fp_registers;
- extern char registers[];
- int cwp;
- struct rwindow local_and_ins;
-
- if (remote_debugging)
- remote_fetch_registers (registers);
- else
- {
- ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers);
- ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers);
-
- registers[REGISTER_BYTE (0)] = 0;
- bcopy (&inferior_registers.r_g1, &registers[REGISTER_BYTE (1)], 15 * 4);
- bcopy (&inferior_fp_registers, &registers[REGISTER_BYTE (FP0_REGNUM)],
- sizeof inferior_fp_registers.fpu_fr);
- *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps;
- *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc;
- *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)] = inferior_registers.r_npc;
- *(int *)&registers[REGISTER_BYTE (Y_REGNUM)] = inferior_registers.r_y;
-/* *(int *)&registers[REGISTER_BYTE (RP_REGNUM)] =
- inferior_registers.r_o7 + 8;
- bcopy (&inferior_fp_registers.Fpu_fsr,
- &registers[REGISTER_BYTE (FPS_REGNUM)],
- sizeof (FPU_FSR_TYPE)); */
-
- read_inferior_memory (inferior_registers.r_sp,
- &registers[REGISTER_BYTE (16)],
- 16*4);
- }
-}
-
-/* Store our register values back into the inferior.
- If REGNO is -1, do this for all registers.
- Otherwise, REGNO specifies which register (so we can save time). */
-
-void
-store_inferior_registers (regno)
- int regno;
-{
- struct regs inferior_registers;
- struct fp_status inferior_fp_registers;
- extern char registers[];
-
- if (remote_debugging)
- remote_store_registers (registers);
- else
- {
- int in_regs = 1, in_fpregs = 1, in_fparegs, in_cpregs = 1;
-
- if (regno >= 0)
- if (FP0_REGNUM <= regno && regno <= FP0_REGNUM + 32)
- in_regs = 0;
- else
- in_fpregs = 0;
-
- if (in_regs)
- {
- bcopy (&registers[REGISTER_BYTE (1)],
- &inferior_registers.r_g1, 15 * 4);
-
- inferior_registers.r_ps =
- *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
- inferior_registers.r_pc =
- *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
- inferior_registers.r_npc =
- *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)];
- inferior_registers.r_y =
- *(int *)&registers[REGISTER_BYTE (Y_REGNUM)];
-
- write_inferior_memory (*(int *)&registers[REGISTER_BYTE (SP_REGNUM)],
- &registers[REGISTER_BYTE (16)],
- 16*4);
- }
- if (in_fpregs)
- {
- bcopy (&registers[REGISTER_BYTE (FP0_REGNUM)],
- &inferior_fp_registers,
- sizeof inferior_fp_registers.fpu_fr);
-
- /* bcopy (&registers[REGISTER_BYTE (FPS_REGNUM)],
- &inferior_fp_registers.Fpu_fsr,
- sizeof (FPU_FSR_TYPE));
- ****/
- }
-
- if (in_regs)
- ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers);
- if (in_fpregs)
- ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers);
- }
-}
-
-/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory
- in the NEW_SUN_PTRACE case.
- It ought to be straightforward. But it appears that writing did
- not write the data that I specified. I cannot understand where
- it got the data that it actually did write. */
-
-/* Copy LEN bytes from inferior's memory starting at MEMADDR
- to debugger memory starting at MYADDR.
- On failure (cannot read from inferior, usually because address is out
- of bounds) returns the value of errno. */
-
-int
-read_inferior_memory (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
-{
- register int i;
- /* Round starting address down to longword boundary. */
- register CORE_ADDR addr = memaddr & - sizeof (int);
- /* Round ending address up; get number of longwords that makes. */
- register int count
- = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
- /* Allocate buffer of that many longwords. */
- register int *buffer = (int *) alloca (count * sizeof (int));
- extern int errno;
-
- /* Read all the longwords */
- for (i = 0; i < count; i++, addr += sizeof (int))
- {
- errno = 0;
- if (remote_debugging)
- buffer[i] = remote_fetch_word (addr);
- else
- buffer[i] = ptrace (1, inferior_pid, addr, 0);
- if (errno)
- return errno;
- }
-
- /* Copy appropriate bytes out of the buffer. */
- bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len);
- return 0;
-}
-
-/* Copy LEN bytes of data from debugger memory at MYADDR
- to inferior's memory at MEMADDR.
- On failure (cannot write the inferior)
- returns the value of errno. */
-
-int
-write_inferior_memory (memaddr, myaddr, len)
- CORE_ADDR memaddr;
- char *myaddr;
- int len;
-{
- register int i;
- /* Round starting address down to longword boundary. */
- register CORE_ADDR addr = memaddr & - sizeof (int);
- /* Round ending address up; get number of longwords that makes. */
- register int count
- = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int);
- /* Allocate buffer of that many longwords. */
- register int *buffer = (int *) alloca (count * sizeof (int));
- extern int errno;
-
- /* Fill start and end extra bytes of buffer with existing memory data. */
-
- if (remote_debugging)
- buffer[0] = remote_fetch_word (addr);
- else
- buffer[0] = ptrace (1, inferior_pid, addr, 0);
-
- if (count > 1)
- {
- if (remote_debugging)
- buffer[count - 1]
- = remote_fetch_word (addr + (count - 1) * sizeof (int));
- else
- buffer[count - 1]
- = ptrace (1, inferior_pid,
- addr + (count - 1) * sizeof (int), 0);
- }
-
- /* Copy data to be written over corresponding part of buffer */
-
- bcopy (myaddr, (char *) buffer + (memaddr & (sizeof (int) - 1)), len);
-
- /* Write the entire buffer. */
-
- for (i = 0; i < count; i++, addr += sizeof (int))
- {
- errno = 0;
- if (remote_debugging)
- remote_store_word (addr, buffer[i]);
- else
- ptrace (4, inferior_pid, addr, buffer[i]);
- if (errno)
- return errno;
- }
-
- return 0;
-}
-
-
-/* Machine-dependent code which would otherwise be in core.c */
-/* Work with core dump and executable files, for GDB. */
-
-/* Recognize COFF format systems because a.out.h defines AOUTHDR. */
-#ifdef AOUTHDR
-#define COFF_FORMAT
-#endif
-
-#ifndef N_TXTADDR
-#define N_TXTADDR(hdr) 0
-#endif /* no N_TXTADDR */
-
-#ifndef N_DATADDR
-#define N_DATADDR(hdr) hdr.a_text
-#endif /* no N_DATADDR */
-
-/* Make COFF and non-COFF names for things a little more compatible
- to reduce conditionals later. */
-
-#ifdef COFF_FORMAT
-#define a_magic magic
-#endif
-
-#ifndef COFF_FORMAT
-#define AOUTHDR struct exec
-#endif
-
-extern char *sys_siglist[];
-
-/* Hook for `exec_file_command' command to call. */
-
-extern void (*exec_file_display_hook) ();
-
-#ifdef COFF_FORMAT
-/* various coff data structures */
-
-extern FILHDR file_hdr;
-extern SCNHDR text_hdr;
-extern SCNHDR data_hdr;
-
-#endif /* not COFF_FORMAT */
-
-/* a.out header saved in core file. */
-
-extern AOUTHDR core_aouthdr;
-
-/* a.out header of exec file. */
-
-extern AOUTHDR exec_aouthdr;
-
-extern void validate_files ();
-
-void
-core_file_command (filename, from_tty)
- char *filename;
- int from_tty;
-{
- int val;
- extern char registers[];
-
- /* Discard all vestiges of any previous core file
- and mark data and stack spaces as empty. */
-
- if (corefile)
- free (corefile);
- corefile = 0;
-
- if (corechan >= 0)
- close (corechan);
- corechan = -1;
-
- data_start = 0;
- data_end = 0;
- stack_start = STACK_END_ADDR;
- stack_end = STACK_END_ADDR;
-
- /* Now, if a new core file was specified, open it and digest it. */
-
- if (filename)
- {
- if (have_inferior_p ())
- error ("To look at a core file, you must kill the inferior with \"kill\".");
- corechan = open (filename, O_RDONLY, 0);
- if (corechan < 0)
- perror_with_name (filename);
-
- {
- struct core corestr;
-
- val = myread (corechan, &corestr, sizeof corestr);
- if (val < 0)
- perror_with_name (filename);
- if (corestr.c_magic != CORE_MAGIC)
- error ("\"%s\" does not appear to be a core dump file (magic 0x%x, expected 0x%x)",
- filename, corestr.c_magic, (int) CORE_MAGIC);
- else if (sizeof (struct core) != corestr.c_len)
- error ("\"%s\" has an invalid struct core length (%d, expected %d)",
- filename, corestr.c_len, (int) sizeof (struct core));
-
- /* Note that data_start and data_end don't depend on the exec file */
- data_start = N_DATADDR (corestr.c_aouthdr);
- data_end = data_start + corestr.c_dsize;
- stack_start = stack_end - corestr.c_ssize;
- data_offset = sizeof corestr;
- stack_offset = sizeof corestr + corestr.c_dsize;
-
- /* G0 *always* holds 0. */
- *(int *)&registers[REGISTER_BYTE (0)] = 0;
- /* The globals and output registers. */
-
- bcopy (&corestr.c_regs.r_g1, ((int *) registers) + 1, 15 * 4);
- *(int *)&registers[REGISTER_BYTE (PS_REGNUM)] = corestr.c_regs.r_ps;
- *(int *)&registers[REGISTER_BYTE (PC_REGNUM)] = corestr.c_regs.r_pc;
- *(int *)&registers[REGISTER_BYTE (NPC_REGNUM)] = corestr.c_regs.r_npc;
- *(int *)&registers[REGISTER_BYTE (Y_REGNUM)] = corestr.c_regs.r_y;
-
- /* My best guess at where to get the locals and input
- registers is exactly where they usually are, right above
- the stack pointer. If the core dump was caused by a bus
- writing off the stack pointer (as is possible) then this
- won't work, but it's worth the try. */
- {
- int sp;
-
- sp = *(int *)&registers[REGISTER_BYTE (SP_REGNUM)];
- lseek (corechan, sp - stack_start + stack_offset, L_SET);
- if (16 * 4 != myread (corechan,
- &registers[REGISTER_BYTE (16)],
- 16 * 4))
- /* fprintf so user can still use gdb */
- fprintf (stderr, "Couldn't read input and local registers from core file\n");
- }
-
- bcopy (corestr.c_fpu.fpu_regs,
- &registers[REGISTER_BYTE (FP0_REGNUM)],
- sizeof corestr.c_fpu.fpu_regs);
-#ifdef FPU
- bcopy (&corestr.c_fpu.fpu_fsr,
- &registers[REGISTER_BYTE (FPS_REGNUM)],
- sizeof (FPU_FSR_TYPE));
-#endif
-
- bcopy (&corestr.c_aouthdr, &core_aouthdr, sizeof (struct exec));
-
- printf ("Core file is from \"%s\".\n", corestr.c_cmdname);
- if (corestr.c_signo > 0)
- printf ("Program terminated with signal %d, %s.\n",
- corestr.c_signo,
- corestr.c_signo < NSIG
- ? sys_siglist[corestr.c_signo]
- : "(undocumented)");
- }
- if (filename[0] == '/')
- corefile = savestring (filename, strlen (filename));
- else
- {
- corefile = concat (current_directory, "/", filename);
- }
-
- set_current_frame ( create_new_frame (read_register (FP_REGNUM),
- read_pc ()));
- select_frame (get_current_frame (), 0);
- validate_files ();
- }
- else if (from_tty)
- printf ("No core file now.\n");
-}
-
-void
-exec_file_command (filename, from_tty)
- char *filename;
- int from_tty;
-{
- int val;
-
- /* Eliminate all traces of old exec file.
- Mark text segment as empty. */
-
- if (execfile)
- free (execfile);
- execfile = 0;
- text_start = 0;
- text_end = 0;
- exec_data_start = 0;
- exec_data_end = 0;
- if (execchan >= 0)
- close (execchan);
- execchan = -1;
-
- /* Now open and digest the file the user requested, if any. */
-
- if (filename)
- {
- execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
- &execfile);
- if (execchan < 0)
- perror_with_name (filename);
-
-#ifdef COFF_FORMAT
- {
- int aout_hdrsize;
- int num_sections;
-
- if (read_file_hdr (execchan, &file_hdr) < 0)
- error ("\"%s\": not in executable format.", execfile);
-
- aout_hdrsize = file_hdr.f_opthdr;
- num_sections = file_hdr.f_nscns;
-
- if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0)
- error ("\"%s\": can't read optional aouthdr", execfile);
-
- if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections) < 0)
- error ("\"%s\": can't read text section header", execfile);
-
- if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
- error ("\"%s\": can't read data section header", execfile);
-
- text_start = exec_aouthdr.text_start;
- text_end = text_start + exec_aouthdr.tsize;
- text_offset = text_hdr.s_scnptr;
- exec_data_start = exec_aouthdr.data_start;
- exec_data_end = exec_data_start + exec_aouthdr.dsize;
- exec_data_offset = data_hdr.s_scnptr;
- exec_mtime = file_hdr.f_timdat;
- }
-#else /* not COFF_FORMAT */
- {
- struct stat st_exec;
- val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR));
-
- if (val < 0)
- perror_with_name (filename);
-
- text_start = N_TXTADDR (exec_aouthdr);
- exec_data_start = N_DATADDR (exec_aouthdr);
- text_offset = N_TXTOFF (exec_aouthdr);
- exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
-
- text_end = text_start + exec_aouthdr.a_text;
- exec_data_end = exec_data_start + exec_aouthdr.a_data;
-
- fstat (execchan, &st_exec);
- exec_mtime = st_exec.st_mtime;
- }
-#endif /* not COFF_FORMAT */
-
- validate_files ();
- }
- else if (from_tty)
- printf ("No exec file now.\n");
-
- /* Tell display code (if any) about the changed file name. */
- if (exec_file_display_hook)
- (*exec_file_display_hook) (filename);
-}
-
-/*
- * Find the pc saved in frame FRAME.
- */
-CORE_ADDR
-frame_saved_pc (frame)
- FRAME frame;
-{
- CORE_ADDR prev_pc;
-
- /* If it's at the bottom, the return value's stored in i7/rp */
- if (get_current_frame () == frame)
- prev_pc = GET_RWINDOW_REG (read_register (SP_REGNUM), rw_in[7]);
- else
- /* Wouldn't this always work? This would allow this routine to
- be completely a macro. */
- prev_pc = GET_RWINDOW_REG (frame->bottom, rw_in[7]);
-
- return PC_ADJUST (prev_pc);
-}
-
-/*
- * Since an individual frame in the frame cache is defined by two
- * arguments (a frame pointer and a stack pointer), we need two
- * arguments to get info for an arbitrary stack frame. This routine
- * takes two arguments and makes the cached frames look as if these
- * two arguments defined a frame on the cache. This allows the rest
- * of info frame to extract the important arguments without
- * difficulty.
- */
-FRAME
-setup_arbitrary_frame (frame, stack)
- FRAME_ADDR frame, stack;
-{
- struct frame_info *fci;
- FRAME fid = create_new_frame (frame, 0);
-
- if (!fid)
- fatal ("internal: create_new_frame returned invalid frame id");
-
- fid->bottom = stack;
-
- return fid;
-}
-
-/* This code was written by Gary Beihl (beihl@@mcc.com).
- It was modified by Michael Tiemann (tiemann@@corto.inria.fr). */
-
-struct command_line *get_breakpoint_commands ();
-
-/*
- * This routine appears to be passed a size by which to increase the
- * stack. It then executes a save instruction in the inferior to
- * increase the stack by this amount. Only the register window system
- * should be affected by this; the program counter & etc. will not be.
- *
- * This instructions used for this purpose are:
- *
- * sethi %hi(0x0),g1 *
- * add g1,0x1ee0,g1 *
- * save sp,g1,sp
- * sethi %hi(0x0),g1 *
- * add g1,0x1ee0,g1 *
- * t g0,0x1,o0
- * sethi %hi(0x0),g0 (nop)
- *
- * I presume that these set g1 to be the negative of the size, do a
- * save (putting the stack pointer at sp - size) and restore the
- * original contents of g1. A * indicates that the actual value of
- * the instruction is modified below.
- */
-static int save_insn_opcodes[] = {
- 0x03000000, 0x82007ee0, 0x9de38001, 0x03000000,
- 0x82007ee0, 0x91d02001, 0x01000000 };
-
-/* Neither do_save_insn or do_restore_insn save stack configuration
- (since the stack is in an indeterminate state through the call to
- each of them); that responsibility of the routine which calls them. */
-
-void
-do_save_insn (size)
- int size;
-{
- int g1 = read_register (1);
- CORE_ADDR sp = read_register (SP_REGNUM);
- CORE_ADDR pc = read_register (PC_REGNUM);
- CORE_ADDR npc = read_register (NPC_REGNUM);
- CORE_ADDR fake_pc = sp - sizeof (save_insn_opcodes);
- struct inferior_status inf_status;
-
- save_inferior_status (&inf_status, 0); /* Don't restore stack info */
- /*
- * See above.
- */
- save_insn_opcodes[0] = 0x03000000 | ((-size >> 10) & 0x3fffff);
- save_insn_opcodes[1] = 0x82006000 | (-size & 0x3ff);
- save_insn_opcodes[3] = 0x03000000 | ((g1 >> 10) & 0x3fffff);
- save_insn_opcodes[4] = 0x82006000 | (g1 & 0x3ff);
- write_memory (fake_pc, save_insn_opcodes, sizeof (save_insn_opcodes));
-
- clear_proceed_status ();
- stop_after_trap = 1;
- proceed (fake_pc, 0, 0);
-
- write_register (PC_REGNUM, pc);
- write_register (NPC_REGNUM, npc);
- restore_inferior_status (&inf_status);
-}
-
-/*
- * This routine takes a program counter value. It restores the
- * register window system to the frame above the current one, and sets
- * the pc and npc to the correct values.
- */
-
-/* The following insns translate to:
-
- restore
- t g0,0x1,o0
- sethi %hi(0x0), g0 */
-
-static int restore_insn_opcodes[] = { 0x81e80000, 0x91d02001, 0x01000000 };
-
-void
-do_restore_insn (pc)
- CORE_ADDR pc;
-{
- CORE_ADDR sp = read_register (SP_REGNUM);
- CORE_ADDR npc = pc + 4;
- CORE_ADDR fake_pc = sp - sizeof (restore_insn_opcodes);
- struct inferior_status inf_status;
-
- save_inferior_status (&inf_status, 0); /* Don't restore stack info */
-
- if (!pc)
- abort();
-
- write_memory (fake_pc, restore_insn_opcodes, sizeof (restore_insn_opcodes));
-
- clear_proceed_status ();
- stop_after_trap = 1;
- proceed (fake_pc, 0, 0);
-
- write_register (PC_REGNUM, pc);
- write_register (NPC_REGNUM, npc);
- restore_inferior_status (&inf_status);
-}
-
-/*
- * This routine should be more specific in it's actions; making sure
- * that it uses the same register in the initial prologue section.
- */
-CORE_ADDR
-skip_prologue (pc)
- CORE_ADDR pc;
-{
- union
- {
- union insn_fmt insn;
- int i;
- } x;
- int dest = -1;
-
- x.i = read_memory_integer (pc, 4);
-
- /* Recognize sethi insn. Record destination. */
- if (x.insn.sethi.op == 0
- && x.insn.sethi.op2 == 4)
- {
- dest = x.insn.sethi.rd;
- pc += 4;
- x.i = read_memory_integer (pc, 4);
- }
-
- /* Recognizes an add immediate value to register to either %g1 or
- the destination register recorded above. Actually, this might
- well recognize several different arithmetic operations.*/
- if (x.insn.arith_imm.op == 2
- && x.insn.arith_imm.i == 1
- && (x.insn.arith_imm.rd == 1
- || x.insn.arith_imm.rd == dest))
- {
- pc += 4;
- x.i = read_memory_integer (pc, 4);
- }
-
- /* This recognizes any SAVE insn. But why do the XOR and then
- the compare? That's identical to comparing against 60 (as long
- as there isn't any sign extension). */
- if (x.insn.arith.op == 2
- && (x.insn.arith.op3 ^ 32) == 28)
- {
- pc += 4;
- x.i = read_memory_integer (pc, 4);
- }
-
- /* Now we need to recognize stores into the frame from the input
- registers. This recognizes all non alternate stores of input
- register, into a location offset from the frame pointer. */
- while (x.insn.arith_imm.op == 3
- && (x.insn.arith_imm.op3 & 0x3c) == 4 /* Store, non-alt */
- && (x.insn.arith_imm.rd & 0x18) == 0x18 /* Input register */
- && x.insn.arith_imm.i == 1 /* Immediate mode */
- && x.insn.arith_imm.rs1 == 30 /* Off of frame pointer */
- && x.insn.arith_imm.simm >= 0x44 /* Into reserved */
- && x.insn.arith_imm.simm < 0x5b) /* stack space. */
- {
- pc += 4;
- x.i = read_memory_integer (pc, 4);
- }
- return pc;
-}
-
-/*
- * Check instruction at "addr" to see if it is an annulled branch.
- * All other instructions will go to NPC or will trap.
- *
- * Set *target if we find a candidate branch; set to zero if not.
- */
-
-branch_type
-isannulled (addr, target)
- CORE_ADDR addr, *target;
-{
- union insn_fmt instr;
- branch_type val = not_branch;
- long offset; /* Must be signed for sign-extend */
-
- *target = 0;
- instr.intval = read_memory_integer (addr, 4);
- /* printf("intval = %x\n",instr.intval); */
- switch (instr.op1.op1)
- {
- case 0: /* Format 2 */
- switch(instr.op2.op2)
- {
- case 2: case 6: case 7: /* Bcc, FBcc, CBcc */
- if (instr.branch.cond == 8)
- val = instr.branch.a ? baa : ba;
- else
- val = instr.branch.a ? bicca : bicc;
- /* 22 bits, sign extended */
- offset = 4 * ((int) (instr.branch.disp << 10) >> 10);
- *target = addr + offset;
- break;
- }
- break;
- }
- /*printf("isannulled ret: %d\n",val); */
- return val;
-}
-@
-
-
-1.2
-log
-@ * Use gdbcore.h rather than a bunch of externs.
- * Avoid dependency on "exec file" when figuring out data_start and data_end
-of core file.
-@
-text
-@d97 2
-a98 2
-static CORE_ADDR next_pc, pc8, target;
-static int brkpc8, brktrg;
-d113 2
-a114 1
- branch_type br, isabranch();
-d117 1
-a117 1
- pc8 = read_register (PC_REGNUM) + 8; /* branch not taken */
-d124 1
-d126 3
-a128 3
- /* printf ("set break at %x\n",next_pc); */
- br = isabranch (pc8 - 8, &target);
- brkpc8 = brktrg = 0;
-d130 7
-a136 6
- if (br == bicca && pc8 != next_pc)
- {
- /* Handle branches with care */
- brkpc8 = 1;
- read_memory (pc8, break_mem[1], sizeof break_insn);
- write_memory (pc8, break_insn, sizeof break_insn);
-d140 2
-d157 1
-a157 1
- if (brkpc8)
-d159 1
-a159 1
- write_memory (pc8, break_mem[1], sizeof break_insn);
-d895 6
-a900 1
-/* Set *target if we find a branch. */
-d903 1
-a903 1
-isabranch (addr, target)
-d918 1
-a918 1
- case 2: case 6: /* BICC & FBCC */
-d930 1
-a930 1
- /*printf("isabranch ret: %d\n",val); */
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d29 1
-a453 49
-/* File names of core file and executable file. */
-
-extern char *corefile;
-extern char *execfile;
-
-/* Descriptors on which core file and executable file are open.
- Note that the execchan is closed when an inferior is created
- and reopened if the inferior dies or is killed. */
-
-extern int corechan;
-extern int execchan;
-
-/* Last modification time of executable file.
- Also used in source.c to compare against mtime of a source file. */
-
-extern int exec_mtime;
-
-/* Virtual addresses of bounds of the two areas of memory in the core file. */
-
-extern CORE_ADDR data_start;
-extern CORE_ADDR data_end;
-extern CORE_ADDR stack_start;
-extern CORE_ADDR stack_end;
-
-/* Virtual addresses of bounds of two areas of memory in the exec file.
- Note that the data area in the exec file is used only when there is no core file. */
-
-extern CORE_ADDR text_start;
-extern CORE_ADDR text_end;
-
-extern CORE_ADDR exec_data_start;
-extern CORE_ADDR exec_data_end;
-
-/* Address in executable file of start of text area data. */
-
-extern int text_offset;
-
-/* Address in executable file of start of data area data. */
-
-extern int exec_data_offset;
-
-/* Address in core file of start of data area data. */
-
-extern int data_offset;
-
-/* Address in core file of start of stack area data. */
-
-extern int stack_offset;
-
-d520 2
-a521 1
- data_start = exec_data_start;
-a601 2
- data_start = 0;
- data_end -= exec_data_start;
-a644 2
- data_start = exec_data_start;
- data_end += exec_data_start;
-a661 2
- data_start = exec_data_start;
- data_end += exec_data_start;
-@
diff --git a/gdb/RCS/stack.c,v b/gdb/RCS/stack.c,v
deleted file mode 100644
index fc755c2..0000000
--- a/gdb/RCS/stack.c,v
+++ /dev/null
@@ -1,882 +0,0 @@
-head 1.2;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.2
-date 89.02.09.23.53.05; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.02.09.15.03.51; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.2
-log
-@Avoid coredumps if stack commands are used when there is no stack.
-@
-text
-@/* Print and select stack frames for GDB, the GNU debugger.
- Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#include <stdio.h>
-
-#include "defs.h"
-#include "param.h"
-#include "symtab.h"
-#include "frame.h"
-#include "inferior.h"
-#include "gdbcore.h"
-
-
-/* Thie "selected" stack frame is used by default for local and arg access.
- May be zero, for no selected frame. */
-
-FRAME selected_frame;
-
-/* Level of the selected frame:
- 0 for innermost, 1 for its caller, ...
- or -1 for frame specified by address with no defined level. */
-
-int selected_frame_level;
-
-/* Error message when selected_frame is zero when it's needed */
-char no_sel_frame[] = "There is no current stack frame.";
-
-/* Nonzero means print the full filename and linenumber
- when a frame is printed, and do so in a format programs can parse. */
-
-int frame_file_full_name = 0;
-
-static void select_calling_frame ();
-
-void print_frame_info ();
-
-/* Print a stack frame briefly. FRAME should be the frame address
- and LEVEL should be its level in the stack (or -1 for level not defined).
- This prints the level, the function executing, the arguments,
- and the file name and line number.
- If the pc is not at the beginning of the source line,
- the actual pc is printed at the beginning.
-
- If SOURCE is 1, print the source line as well.
- If SOURCE is -1, print ONLY the source line. */
-
-/* FIXME, the argument "frame" is always "selected_frame". This is why
- we can say "No selected frame" if it == 0. Probably shouldn't be an
- argument anymore... */
-
-static void
-print_stack_frame (frame, level, source)
- FRAME frame;
- int level;
- int source;
-{
- struct frame_info *fi;
-
- if (frame == 0)
- error (no_sel_frame);
- fi = get_frame_info (frame);
-
- print_frame_info (fi, level, source, 1);
-}
-
-void
-print_frame_info (fi, level, source, args)
- struct frame_info *fi;
- register int level;
- int source;
- int args;
-{
- struct symtab_and_line sal;
- struct symbol *func;
- register char *funname = 0;
- int numargs;
-
- sal = find_pc_line (fi->pc, fi->next_frame);
- func = find_pc_function (fi->pc);
- if (func)
- funname = SYMBOL_NAME (func);
- else
- {
- register int misc_index = find_pc_misc_function (fi->pc);
- if (misc_index >= 0)
- funname = misc_function_vector[misc_index].name;
- }
-
- if (source >= 0 || !sal.symtab)
- {
- if (level >= 0)
- printf ("#%-2d ", level);
- if (fi->pc != sal.pc || !sal.symtab)
- printf ("0x%x in ", fi->pc);
- printf ("%s (", funname ? funname : "??");
- if (args)
- {
- FRAME_NUM_ARGS (numargs, fi);
- print_frame_args (func, fi, numargs, stdout);
- }
- printf (")");
- if (sal.symtab)
- printf (" (%s line %d)", sal.symtab->filename, sal.line);
- printf ("\n");
- }
-
- if (source != 0 && sal.symtab)
- {
- int done = 0;
- int mid_statement = source < 0 && fi->pc != sal.pc;
- if (frame_file_full_name)
- done = identify_source_line (sal.symtab, sal.line, mid_statement);
- if (!done)
- {
- if (mid_statement)
- printf ("0x%x\t", fi->pc);
- print_source_lines (sal.symtab, sal.line, sal.line + 1, 1);
- }
- current_source_line = max (sal.line - 5, 1);
- }
- if (source != 0)
- set_default_breakpoint (1, fi->pc, sal.symtab, sal.line);
-
- fflush (stdout);
-}
-
-/* Call here to print info on selected frame, after a trap. */
-
-void
-print_sel_frame (just_source)
- int just_source;
-{
- print_stack_frame (selected_frame, -1, just_source ? -1 : 1);
-}
-
-/* Print info on the selected frame, including level number
- but not source. */
-
-void
-print_selected_frame ()
-{
- print_stack_frame (selected_frame, selected_frame_level, 0);
-}
-
-void flush_cached_frames (); /* FIXME, never called! */
-
-#ifdef FRAME_SPECIFICATION_DYADIC
-extern FRAME setup_arbitrary_frame ();
-#endif
-
-/*
- * Read a frame specification in whatever the appropriate format is.
- */
-static FRAME
-parse_frame_specification (frame_exp)
- char *frame_exp;
-{
- int numargs = 0;
- int arg1, arg2;
-
- if (frame_exp)
- {
- char *addr_string, *p;
- struct cleanup *tmp_cleanup;
- struct frame_info *fci;
-
- while (*frame_exp == ' ') frame_exp++;
- for (p = frame_exp; *p && *p != ' '; p++)
- ;
-
- if (*frame_exp)
- {
- numargs = 1;
- addr_string = savestring(frame_exp, p - frame_exp);
-
- {
- tmp_cleanup = make_cleanup (free, addr_string);
- arg1 = parse_and_eval_address (addr_string);
- do_cleanups (tmp_cleanup);
- }
-
- while (*p == ' ') p++;
-
- if (*p)
- {
- numargs = 2;
- arg2 = parse_and_eval_address (p);
- }
- }
- }
-
- switch (numargs)
- {
- case 0:
- if (selected_frame == 0)
- error (no_sel_frame);
- return selected_frame;
- /* NOTREACHED */
- case 1:
- {
- int level = arg1;
- FRAME fid = find_relative_frame (get_current_frame (), &level);
- FRAME tfid;
-
- if (level == 0)
- /* find_relative_frame was successful */
- return fid;
-
- /* If (s)he specifies the frame with an address, he deserves what
- (s)he gets. Still, give the highest one that matches. */
-
- for (fid = get_current_frame ();
- fid && FRAME_FP (fid) != arg1;
- fid = get_prev_frame (fid))
- ;
-
- if (fid)
- while ((tfid = get_prev_frame (fid)) &&
- (FRAME_FP (tfid) == arg1))
- fid = tfid;
-
-#ifdef FRAME_SPECIFICATION_DYADIC
- if (!fid)
- error ("Incorrect number of args in frame specification");
-
- return fid;
-#else
- return create_new_frame (arg1, 0);
-#endif
- }
- /* NOTREACHED */
- case 2:
- /* Must be addresses */
-#ifndef FRAME_SPECIFICATION_DYADIC
- error ("Incorrect number of args in frame specification");
-#else
- return setup_arbitrary_frame (arg1, arg2);
-#endif
- /* NOTREACHED */
- }
- fatal ("Internal: Error in parsing in parse_frame_specification");
- /* NOTREACHED */
-}
-
-/* Print verbosely the selected frame or the frame at address ADDR.
- This means absolutely all information in the frame is printed. */
-
-static void
-frame_info (addr_exp)
- char *addr_exp;
-{
- FRAME frame;
- struct frame_info *fi;
- struct frame_saved_regs fsr;
- struct symtab_and_line sal;
- struct symbol *func;
- FRAME calling_frame;
- int i, count;
- char *funname = 0;
- int numargs;
-
- frame = parse_frame_specification (addr_exp);
-
- fi = get_frame_info (frame);
- get_frame_saved_regs (fi, &fsr);
- sal = find_pc_line (fi->pc, fi->next_frame);
- func = get_frame_function (frame);
- if (func)
- funname = SYMBOL_NAME (func);
- else
- {
- register int misc_index = find_pc_misc_function (fi->pc);
- if (misc_index >= 0)
- funname = misc_function_vector[misc_index].name;
- }
- calling_frame = get_prev_frame (frame);
-
- if (!addr_exp && selected_frame_level >= 0)
- printf ("Stack level %d, frame at 0x%x:\n pc = 0x%x",
- selected_frame_level, FRAME_FP(frame), fi->pc);
- else
- printf ("Stack frame at 0x%x:\n pc = 0x%x",
- FRAME_FP(frame), fi->pc);
-
- if (funname)
- printf (" in %s", funname);
- if (sal.symtab)
- printf (" (%s line %d)", sal.symtab->filename, sal.line);
- printf ("; saved pc 0x%x\n", FRAME_SAVED_PC (frame));
- if (calling_frame)
- printf (" called by frame at 0x%x", FRAME_FP (calling_frame));
- if (fi->next_frame && calling_frame)
- printf (",");
- if (fi->next_frame)
- printf (" caller of frame at 0x%x", fi->next_frame);
- if (fi->next_frame || calling_frame)
- printf ("\n");
- printf (" Arglist at 0x%x,", FRAME_ARGS_ADDRESS (fi));
- FRAME_NUM_ARGS (i, fi);
- if (i < 0)
- printf (" args: ");
- else if (i == 0)
- printf (" no args.");
- else if (i == 1)
- printf (" 1 arg: ");
- else
- printf (" %d args: ", i);
-
- FRAME_NUM_ARGS (numargs, fi);
- print_frame_args (func, fi, numargs, stdout);
- printf ("\n");
- count = 0;
- for (i = 0; i < NUM_REGS; i++)
- if (fsr.regs[i])
- {
- if (count % 4 != 0)
- printf (", ");
- else
- {
- if (count == 0)
- printf (" Saved registers:");
- printf ("\n ");
- }
- printf ("%s at 0x%x", reg_names[i], fsr.regs[i]);
- count++;
- }
- if (count)
- printf ("\n");
-}
-
-#if 0
-/* Set a limit on the number of frames printed by default in a
- backtrace. */
-
-static int backtrace_limit;
-
-static void
-set_backtrace_limit_command (count_exp, from_tty)
- char *count_exp;
- int from_tty;
-{
- int count = parse_and_eval_address (count_exp);
-
- if (count < 0)
- error ("Negative argument not meaningful as backtrace limit.");
-
- backtrace_limit = count;
-}
-
-static void
-backtrace_limit_info (arg, from_tty)
- char *arg;
- int from_tty;
-{
- if (arg)
- error ("\"Info backtrace-limit\" takes no arguments.");
-
- printf ("Backtrace limit: %d.\n", backtrace_limit);
-}
-#endif
-
-/* Print briefly all stack frames or just the innermost COUNT frames. */
-
-static void
-backtrace_command (count_exp)
- char *count_exp;
-{
- struct frame_info *fi;
- register int count;
- register FRAME frame;
- register int i;
- register FRAME trailing;
- register int trailing_level;
-
- if (have_inferior_p () == 0 && corefile == 0)
- error ("There is no running program or core file.");
-
- /* The following code must do two things. First, it must
- set the variable TRAILING to the frame from which we should start
- printing. Second, it must set the variable count to the number
- of frames which we should print, or -1 if all of them. */
- trailing = get_current_frame ();
- trailing_level = 0;
- if (count_exp)
- {
- count = parse_and_eval_address (count_exp);
- if (count < 0)
- {
- FRAME current;
-
- count = -count;
-
- current = trailing;
- while (current && count--)
- current = get_prev_frame (current);
-
- /* Will stop when CURRENT reaches the top of the stack. TRAILING
- will be COUNT below it. */
- while (current)
- {
- trailing = get_prev_frame (trailing);
- current = get_prev_frame (current);
- trailing_level++;
- }
-
- count = -1;
- }
- }
- else
-#if 0
- count = backtrace_limit;
-#else
- count = -1;
-#endif
-
- for (i = 0, frame = trailing;
- frame && count--;
- i++, frame = get_prev_frame (frame))
- {
- QUIT;
- fi = get_frame_info (frame);
- print_frame_info (fi, trailing_level + i, 0, 1);
- }
-
- /* If we've stopped before the end, mention that. */
- if (frame)
- printf ("(More stack frames follow...)\n");
-}
-
-/* Print the local variables of a block B active in FRAME. */
-
-static void
-print_block_frame_locals (b, frame, stream)
- struct block *b;
- register FRAME frame;
- register FILE *stream;
-{
- int nsyms;
- register int i;
- register struct symbol *sym;
-
- nsyms = BLOCK_NSYMS (b);
-
- for (i = 0; i < nsyms; i++)
- {
- sym = BLOCK_SYM (b, i);
- if (SYMBOL_CLASS (sym) == LOC_LOCAL
- || SYMBOL_CLASS (sym) == LOC_REGISTER
- || SYMBOL_CLASS (sym) == LOC_STATIC)
- {
- fprintf (stream, "%s = ", SYMBOL_NAME (sym));
- print_variable_value (sym, frame, stream);
- fprintf (stream, "\n");
- fflush (stream);
- }
- }
-}
-
-/* Print on STREAM all the local variables in frame FRAME,
- including all the blocks active in that frame
- at its current pc.
-
- Returns 1 if the job was done,
- or 0 if nothing was printed because we have no info
- on the function running in FRAME. */
-
-static int
-print_frame_local_vars (frame, stream)
- register FRAME frame;
- register FILE *stream;
-{
- register struct block *block;
-
- block = get_frame_block (frame);
- if (block == 0)
- return 0;
- while (block != 0)
- {
- print_block_frame_locals (block, frame, stream);
- /* After handling the function's top-level block, stop.
- Don't continue to its superblock, the block of
- per-file symbols. */
- if (BLOCK_FUNCTION (block))
- break;
- block = BLOCK_SUPERBLOCK (block);
- }
- return 1;
-}
-
-static void
-locals_info ()
-{
- if (selected_frame == 0)
- error(no_sel_frame);
- print_frame_local_vars (selected_frame, stdout);
-}
-
-static int
-print_frame_arg_vars (frame, stream)
- register FRAME frame;
- register FILE *stream;
-{
- struct symbol *func;
- register struct block *b;
- int nsyms;
- register int i;
- register struct symbol *sym;
-
- func = get_frame_function (frame);
- if (func == 0)
- return 0;
-
- b = SYMBOL_BLOCK_VALUE (func);
- nsyms = BLOCK_NSYMS (b);
-
- for (i = 0; i < nsyms; i++)
- {
- sym = BLOCK_SYM (b, i);
- if (SYMBOL_CLASS (sym) == LOC_ARG || SYMBOL_CLASS (sym) == LOC_REGPARM)
- {
- fprintf (stream, "%s = ", SYMBOL_NAME (sym));
- print_variable_value (sym, frame, stream);
- fprintf (stream, "\n");
- fflush (stream);
- }
- }
-
- return 1;
-}
-
-static void
-args_info ()
-{
- if (selected_frame == 0)
- error(no_sel_frame);
- print_frame_arg_vars (selected_frame, stdout);
-}
-
-/* Select frame FRAME, and note that its stack level is LEVEL.
- LEVEL may be -1 if an actual level number is not known. */
-
-void
-select_frame (frame, level)
- FRAME frame;
- int level;
-{
- selected_frame = frame;
- selected_frame_level = level;
-}
-
-/* Store the selected frame and its level into *FRAMEP and *LEVELP. */
-
-void
-record_selected_frame (frameaddrp, levelp)
- FRAME_ADDR *frameaddrp;
- int *levelp;
-{
- *frameaddrp = FRAME_FP (selected_frame);
- *levelp = selected_frame_level;
-}
-
-/* Return the symbol-block in which the selected frame is executing.
- Can return zero under various legitimate circumstances. */
-
-struct block *
-get_selected_block ()
-{
- if (!have_inferior_p () && !have_core_file_p ())
- return 0;
-
- if (!selected_frame)
- return get_current_block ();
- return get_frame_block (selected_frame);
-}
-
-/* Find a frame a certain number of levels away from FRAME.
- LEVEL_OFFSET_PTR points to an int containing the number of levels.
- Positive means go to earlier frames (up); negative, the reverse.
- The int that contains the number of levels is counted toward
- zero as the frames for those levels are found.
- If the top or bottom frame is reached, that frame is returned,
- but the final value of *LEVEL_OFFSET_PTR is nonzero and indicates
- how much farther the original request asked to go. */
-
-FRAME
-find_relative_frame (frame, level_offset_ptr)
- register FRAME frame;
- register int* level_offset_ptr;
-{
- register FRAME prev;
- register FRAME frame1, frame2;
-
- if (frame == 0)
- error (no_sel_frame);
- /* Going up is simple: just do get_prev_frame enough times
- or until initial frame is reached. */
- while (*level_offset_ptr > 0)
- {
- prev = get_prev_frame (frame);
- if (prev == 0)
- break;
- (*level_offset_ptr)--;
- frame = prev;
- }
- /* Going down could be done by iterating get_frame_info to
- find the next frame, but that would be quadratic
- since get_frame_info must scan all the way from the current frame.
- The following algorithm is linear. */
- if (*level_offset_ptr < 0)
- {
- /* First put frame1 at innermost frame
- and frame2 N levels up from there. */
- frame1 = get_current_frame ();
- frame2 = frame1;
- while (*level_offset_ptr < 0 && frame2 != frame)
- {
- frame2 = get_prev_frame (frame2);
- (*level_offset_ptr) ++;
- }
- /* Then slide frame1 and frame2 up in synchrony
- and when frame2 reaches our starting point
- frame1 must be N levels down from there. */
- while (frame2 != frame)
- {
- frame1 = get_prev_frame (frame1);
- frame2 = get_prev_frame (frame2);
- }
- return frame1;
- }
- return frame;
-}
-
-/* The "frame" command. With no arg, print selected frame briefly.
- With arg LEVEL_EXP, select the frame at level LEVEL if it is a
- valid level. Otherwise, treat level_exp as an address expression
- and print it. See parse_frame_specification for more info on proper
- frame expressions. */
-
-static void
-frame_command (level_exp, from_tty)
- char *level_exp;
- int from_tty;
-{
- register FRAME frame, frame1;
- unsigned int level = 0;
-
- frame = parse_frame_specification (level_exp);
-
- for (frame1 = get_prev_frame (0);
- frame1 && frame1 != frame;
- frame1 = get_prev_frame (frame1))
- level++;
-
- if (!frame1)
- level = 0;
-
- select_frame (frame, level);
-
- if (!from_tty)
- return;
-
- print_stack_frame (selected_frame, selected_frame_level, 1);
-}
-
-/* Select the frame up one or COUNT stack levels
- from the previously selected frame, and print it briefly. */
-
-static void
-up_command (count_exp)
- char *count_exp;
-{
- register FRAME frame;
- int count = 1, count1;
- if (count_exp)
- count = parse_and_eval_address (count_exp);
- count1 = count;
-
- frame = find_relative_frame (selected_frame, &count1);
- if (count1 != 0 && count_exp == 0)
- error ("Initial frame selected; you cannot go up.");
- select_frame (frame, selected_frame_level + count - count1);
-
- print_stack_frame (selected_frame, selected_frame_level, 1);
-}
-
-/* Select the frame down one or COUNT stack levels
- from the previously selected frame, and print it briefly. */
-
-static void
-down_command (count_exp)
- char *count_exp;
-{
- register FRAME frame;
- int count = -1, count1;
- if (count_exp)
- count = - parse_and_eval_address (count_exp);
- count1 = count;
-
- frame = find_relative_frame (selected_frame, &count1);
- if (count1 != 0 && count_exp == 0)
- error ("Bottom (i.e., innermost) frame selected; you cannot go down.");
- select_frame (frame, selected_frame_level + count - count1);
-
- print_stack_frame (selected_frame, selected_frame_level, 1);
-}
-
-static void
-return_command (retval_exp, from_tty)
- char *retval_exp;
- int from_tty;
-{
- struct symbol *thisfun = get_frame_function (selected_frame);
-
- /* If interactive, require confirmation. */
-
- if (from_tty)
- {
- if (thisfun != 0)
- {
- if (!query ("Make %s return now? ", SYMBOL_NAME (thisfun)))
- error ("Not confirmed.");
- }
- else
- if (!query ("Make selected stack frame return now? "))
- error ("Not confirmed.");
- }
-
- /* Do the real work. Pop until the specified frame is current. */
-
- while (selected_frame != get_current_frame ())
- POP_FRAME;
-
- /* Then pop that frame. */
-
- POP_FRAME;
-
- /* Compute the return value (if any) and store in the place
- for return values. */
-
- if (retval_exp)
- set_return_value (parse_and_eval (retval_exp));
-
- /* If interactive, print the frame that is now current. */
-
- if (from_tty)
- frame_command ("0", 1);
-}
-
-extern struct cmd_list_element *setlist;
-
-void
-_initialize_stack ()
-{
-#if 0
- backtrace_limit = 30;
-#endif
-
- add_com ("return", class_stack, return_command,
- "Make selected stack frame return to its caller.\n\
-Control remains in the debugger, but when you continue\n\
-execution will resume in the frame above the one now selected.\n\
-If an argument is given, it is an expression for the value to return.");
-
- add_com ("up", class_stack, up_command,
- "Select and print stack frame that called this one.\n\
-An argument says how many frames up to go.");
-
- add_com ("down", class_stack, down_command,
- "Select and print stack frame called by this one.\n\
-An argument says how many frames down to go.");
- add_com_alias ("do", "down", class_stack, 1);
-
- add_com ("frame", class_stack, frame_command,
- "Select and print a stack frame.\n\
-With no argument, print the selected stack frame. (See also \"info frame\").\n\
-An argument specifies the frame to select.\n\
-It can be a stack frame number or the address of the frame.\n\
-With argument, nothing is printed if input is coming from\n\
-a command file or a user-defined command.");
-
- add_com_alias ("f", "frame", class_stack, 1);
-
- add_com ("backtrace", class_stack, backtrace_command,
- "Print backtrace of all stack frames, or innermost COUNT frames.\n\
-With a negative argument, print outermost -COUNT frames.");
- add_com_alias ("bt", "backtrace", class_stack, 0);
- add_com_alias ("where", "backtrace", class_alias, 0);
- add_info ("stack", backtrace_command,
- "Backtrace of the stack, or innermost COUNT frames.");
- add_info_alias ("s", "stack", 1);
- add_info ("frame", frame_info,
- "All about selected stack frame, or frame at ADDR.");
- add_info_alias ("f", "frame", 1);
- add_info ("locals", locals_info,
- "Local variables of current stack frame.");
- add_info ("args", args_info,
- "Argument variables of current stack frame.");
-
-#if 0
- add_cmd ("backtrace-limit", class_stack, set_backtrace_limit_command,
- "Specify maximum number of frames for \"backtrace\" to print by default.",
- &setlist);
- add_info ("backtrace-limit", backtrace_limit_info,
- "The maximum number of frames for \"backtrace\" to print by default.");
-#endif
-}
-
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d2 1
-a2 1
- Copyright (C) 1986, 1987 Free Software Foundation, Inc.
-d27 2
-d42 3
-d64 4
-d76 2
-d162 1
-a162 1
-void flush_cached_frames ();
-d212 2
-d392 3
-d489 3
-a491 1
- register struct block *block = get_frame_block (frame);
-d510 2
-d520 1
-a520 1
- struct symbol *func = get_frame_function (frame);
-d526 1
-d551 2
-d610 2
-@
diff --git a/gdb/RCS/utils.c,v b/gdb/RCS/utils.c,v
deleted file mode 100644
index 1d8000d..0000000
--- a/gdb/RCS/utils.c,v
+++ /dev/null
@@ -1,726 +0,0 @@
-head 1.2;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.2
-date 89.03.27.20.22.34; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.03.23.14.27.48; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.2
-log
-@Portability changes. If USG, we need to re-enable the SIGINT
-signal handler when it is called. Also, build the sys_siglist
-table at runtime, based on the actual values of the signal
-#define's. Too many USG systems added Berkeley signal names
-as various numbers.
-@
-text
-@/* General utility routines for GDB, the GNU debugger.
- Copyright (C) 1986 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#include <stdio.h>
-#include <signal.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include "defs.h"
-#include "param.h"
-#ifdef HAVE_TERMIO
-#include <termio.h>
-#endif
-
-void error ();
-void fatal ();
-
-/* Chain of cleanup actions established with make_cleanup,
- to be executed if an error happens. */
-
-static struct cleanup *cleanup_chain;
-
-/* Nonzero means a quit has been requested. */
-
-int quit_flag;
-
-/* Nonzero means quit immediately if Control-C is typed now,
- rather than waiting until QUIT is executed. */
-
-int immediate_quit;
-
-/* Add a new cleanup to the cleanup_chain,
- and return the previous chain pointer
- to be passed later to do_cleanups or discard_cleanups.
- Args are FUNCTION to clean up with, and ARG to pass to it. */
-
-struct cleanup *
-make_cleanup (function, arg)
- void (*function) ();
- int arg;
-{
- register struct cleanup *new
- = (struct cleanup *) xmalloc (sizeof (struct cleanup));
- register struct cleanup *old_chain = cleanup_chain;
-
- new->next = cleanup_chain;
- new->function = function;
- new->arg = arg;
- cleanup_chain = new;
-
- return old_chain;
-}
-
-/* Discard cleanups and do the actions they describe
- until we get back to the point OLD_CHAIN in the cleanup_chain. */
-
-void
-do_cleanups (old_chain)
- register struct cleanup *old_chain;
-{
- register struct cleanup *ptr;
- while ((ptr = cleanup_chain) != old_chain)
- {
- (*ptr->function) (ptr->arg);
- cleanup_chain = ptr->next;
- free (ptr);
- }
-}
-
-/* Discard cleanups, not doing the actions they describe,
- until we get back to the point OLD_CHAIN in the cleanup_chain. */
-
-void
-discard_cleanups (old_chain)
- register struct cleanup *old_chain;
-{
- register struct cleanup *ptr;
- while ((ptr = cleanup_chain) != old_chain)
- {
- cleanup_chain = ptr->next;
- free (ptr);
- }
-}
-
-/* Set the cleanup_chain to 0, and return the old cleanup chain. */
-struct cleanup *
-save_cleanups ()
-{
- struct cleanup *old_chain = cleanup_chain;
-
- cleanup_chain = 0;
- return old_chain;
-}
-
-/* Restore the cleanup chain from a previously saved chain. */
-void
-restore_cleanups (chain)
- struct cleanup *chain;
-{
- cleanup_chain = chain;
-}
-
-/* This function is useful for cleanups.
- Do
-
- foo = xmalloc (...);
- old_chain = make_cleanup (free_current_contents, &foo);
-
- to arrange to free the object thus allocated. */
-
-void
-free_current_contents (location)
- char **location;
-{
- free (*location);
-}
-
-/* Generally useful subroutines used throughout the program. */
-
-/* Like malloc but get error if no storage available. */
-
-char *
-xmalloc (size)
- long size;
-{
- register char *val = (char *) malloc (size);
- if (!val)
- fatal ("virtual memory exhausted.", 0);
- return val;
-}
-
-/* Like realloc but get error if no storage available. */
-
-char *
-xrealloc (ptr, size)
- char *ptr;
- long size;
-{
- register char *val = (char *) realloc (ptr, size);
- if (!val)
- fatal ("virtual memory exhausted.", 0);
- return val;
-}
-
-/* Print the system error message for errno, and also mention STRING
- as the file name for which the error was encountered.
- Then return to command level. */
-
-void
-perror_with_name (string)
- char *string;
-{
- extern int sys_nerr;
- extern char *sys_errlist[];
- extern int errno;
- char *err;
- char *combined;
-
- if (errno < sys_nerr)
- err = sys_errlist[errno];
- else
- err = "unknown error";
-
- combined = (char *) alloca (strlen (err) + strlen (string) + 3);
- strcpy (combined, string);
- strcat (combined, ": ");
- strcat (combined, err);
-
- error ("%s.", combined);
-}
-
-/* Print the system error message for ERRCODE, and also mention STRING
- as the file name for which the error was encountered. */
-
-void
-print_sys_errmsg (string, errcode)
- char *string;
- int errcode;
-{
- extern int sys_nerr;
- extern char *sys_errlist[];
- char *err;
- char *combined;
-
- if (errcode < sys_nerr)
- err = sys_errlist[errcode];
- else
- err = "unknown error";
-
- combined = (char *) alloca (strlen (err) + strlen (string) + 3);
- strcpy (combined, string);
- strcat (combined, ": ");
- strcat (combined, err);
-
- printf ("%s.\n", combined);
-}
-
-void
-quit ()
-{
- fflush (stdout);
-#ifdef HAVE_TERMIO
- ioctl (fileno (stdout), TCFLSH, 1);
-#else /* not HAVE_TERMIO */
- ioctl (fileno (stdout), TIOCFLUSH, 0);
-#endif /* not HAVE_TERMIO */
-
-#ifdef TIOCGPGRP
- error ("Quit");
-#else
- error ("Quit (expect signal %d when inferior is resumed)", SIGINT);
-#endif /* TIOCGPGRP */
-}
-
-/* Control C comes here */
-
-void
-request_quit ()
-{
- quit_flag = 1;
-
-#ifdef USG
- /* Restore the signal handler */
- signal(SIGINT, request_quit);
-#endif
-
- if (immediate_quit)
- quit ();
-}
-
-/* Print an error message and return to command level.
- STRING is the error message, used as a fprintf string,
- and ARG is passed as an argument to it. */
-
-void
-error (string, arg1, arg2, arg3)
- char *string;
- int arg1, arg2, arg3;
-{
- fflush (stdout);
- fprintf (stderr, string, arg1, arg2, arg3);
- fprintf (stderr, "\n");
- return_to_top_level ();
-}
-
-/* Print an error message and exit reporting failure.
- This is for a error that we cannot continue from.
- STRING and ARG are passed to fprintf. */
-
-void
-fatal (string, arg)
- char *string;
- int arg;
-{
- fprintf (stderr, "gdb: ");
- fprintf (stderr, string, arg);
- fprintf (stderr, "\n");
- exit (1);
-}
-
-/* Make a copy of the string at PTR with SIZE characters
- (and add a null character at the end in the copy).
- Uses malloc to get the space. Returns the address of the copy. */
-
-char *
-savestring (ptr, size)
- char *ptr;
- int size;
-{
- register char *p = (char *) xmalloc (size + 1);
- bcopy (ptr, p, size);
- p[size] = 0;
- return p;
-}
-
-char *
-concat (s1, s2, s3)
- char *s1, *s2, *s3;
-{
- register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1;
- register char *val = (char *) xmalloc (len);
- strcpy (val, s1);
- strcat (val, s2);
- strcat (val, s3);
- return val;
-}
-
-void
-print_spaces (n, file)
- register int n;
- register FILE *file;
-{
- while (n-- > 0)
- fputc (' ', file);
-}
-
-/* Ask user a y-or-n question and return 1 iff answer is yes.
- Takes three args which are given to printf to print the question.
- The first, a control string, should end in "? ".
- It should not say how to answer, because we do that. */
-
-int
-query (ctlstr, arg1, arg2)
- char *ctlstr;
-{
- register int answer;
-
- /* Automatically answer "yes" if input is not from a terminal. */
- if (!input_from_terminal_p ())
- return 1;
-
- while (1)
- {
- printf (ctlstr, arg1, arg2);
- printf ("(y or n) ");
- fflush (stdout);
- answer = fgetc (stdin);
- clearerr (stdin); /* in case of C-d */
- if (answer != '\n')
- while (fgetc (stdin) != '\n') clearerr (stdin);
- if (answer >= 'a')
- answer -= 040;
- if (answer == 'Y')
- return 1;
- if (answer == 'N')
- return 0;
- printf ("Please answer y or n.\n");
- }
-}
-
-/* Parse a C escape sequence. STRING_PTR points to a variable
- containing a pointer to the string to parse. That pointer
- is updated past the characters we use. The value of the
- escape sequence is returned.
-
- A negative value means the sequence \ newline was seen,
- which is supposed to be equivalent to nothing at all.
-
- If \ is followed by a null character, we return a negative
- value and leave the string pointer pointing at the null character.
-
- If \ is followed by 000, we return 0 and leave the string pointer
- after the zeros. A value of 0 does not mean end of string. */
-
-int
-parse_escape (string_ptr)
- char **string_ptr;
-{
- register int c = *(*string_ptr)++;
- switch (c)
- {
- case 'a':
- return '\a';
- case 'b':
- return '\b';
- case 'e':
- return 033;
- case 'f':
- return '\f';
- case 'n':
- return '\n';
- case 'r':
- return '\r';
- case 't':
- return '\t';
- case 'v':
- return '\v';
- case '\n':
- return -2;
- case 0:
- (*string_ptr)--;
- return 0;
- case '^':
- c = *(*string_ptr)++;
- if (c == '\\')
- c = parse_escape (string_ptr);
- if (c == '?')
- return 0177;
- return (c & 0200) | (c & 037);
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- {
- register int i = c - '0';
- register int count = 0;
- while (++count < 3)
- {
- if ((c = *(*string_ptr)++) >= '0' && c <= '7')
- {
- i *= 8;
- i += c - '0';
- }
- else
- {
- (*string_ptr)--;
- break;
- }
- }
- return i;
- }
- default:
- return c;
- }
-}
-
-/* Print the character CH on STREAM as part of the contents
- of a literal string whose delimiter is QUOTER. */
-
-void
-printchar (ch, stream, quoter)
- unsigned char ch;
- FILE *stream;
- int quoter;
-{
- register int c = ch;
- if (c < 040 || c >= 0177)
- {
- if (c == '\n')
- fprintf (stream, "\\n");
- else if (c == '\b')
- fprintf (stream, "\\b");
- else if (c == '\t')
- fprintf (stream, "\\t");
- else if (c == '\f')
- fprintf (stream, "\\f");
- else if (c == '\r')
- fprintf (stream, "\\r");
- else if (c == 033)
- fprintf (stream, "\\e");
- else if (c == '\a')
- fprintf (stream, "\\a");
- else
- fprintf (stream, "\\%03o", c);
- }
- else
- {
- if (c == '\\' || c == quoter)
- fputc ('\\', stream);
- fputc (c, stream);
- }
-}
-
-
-#ifdef USG
-bcopy (from, to, count)
-char *from, *to;
-{
- memcpy (to, from, count);
-}
-
-bcmp (from, to, count)
-{
- return (memcmp (to, from, count));
-}
-
-bzero (to, count)
-char *to;
-{
- while (count--)
- *to++ = 0;
-}
-
-getwd (buf)
-char *buf;
-{
- getcwd (buf, MAXPATHLEN);
-}
-
-char *
-index (s, c)
- char *s;
-{
- char *strchr ();
- return strchr (s, c);
-}
-
-char *
-rindex (s, c)
- char *s;
-{
- char *strrchr ();
- return strrchr (s, c);
-}
-
-/* Queue routines */
-
-struct queue {
- struct queue *forw;
- struct queue *back;
-};
-
-insque (item, after)
-struct queue *item;
-struct queue *after;
-{
- item->forw = after->forw;
- after->forw->back = item;
-
- item->back = after;
- after->forw = item;
-}
-
-remque (item)
-struct queue *item;
-{
- item->forw->back = item->back;
- item->back->forw = item->forw;
-}
-
-
-/*
- * There is too much variation in Sys V signal numbers and names, so
- * we must initialize them at runtime. If C provided a way to initialize
- * an array based on subscript and value, this would not be necessary.
- */
-static char undoc[] = "(undocumented)";
-
-char *sys_siglist[NSIG];
-
-_initialize_utils()
-{
- int i;
-
- for (i = 0; i < NSIG; i++)
- sys_siglist[i] = undoc;
-
-#ifdef SIGHUP
- sys_siglist[SIGHUP ] = "SIGHUP";
-#endif
-#ifdef SIGINT
- sys_siglist[SIGINT ] = "SIGINT";
-#endif
-#ifdef SIGQUIT
- sys_siglist[SIGQUIT ] = "SIGQUIT";
-#endif
-#ifdef SIGILL
- sys_siglist[SIGILL ] = "SIGILL";
-#endif
-#ifdef SIGTRAP
- sys_siglist[SIGTRAP ] = "SIGTRAP";
-#endif
-#ifdef SIGIOT
- sys_siglist[SIGIOT ] = "SIGIOT";
-#endif
-#ifdef SIGEMT
- sys_siglist[SIGEMT ] = "SIGEMT";
-#endif
-#ifdef SIGFPE
- sys_siglist[SIGFPE ] = "SIGFPE";
-#endif
-#ifdef SIGKILL
- sys_siglist[SIGKILL ] = "SIGKILL";
-#endif
-#ifdef SIGBUS
- sys_siglist[SIGBUS ] = "SIGBUS";
-#endif
-#ifdef SIGSEGV
- sys_siglist[SIGSEGV ] = "SIGSEGV";
-#endif
-#ifdef SIGSYS
- sys_siglist[SIGSYS ] = "SIGSYS";
-#endif
-#ifdef SIGPIPE
- sys_siglist[SIGPIPE ] = "SIGPIPE";
-#endif
-#ifdef SIGALRM
- sys_siglist[SIGALRM ] = "SIGALRM";
-#endif
-#ifdef SIGTERM
- sys_siglist[SIGTERM ] = "SIGTERM";
-#endif
-#ifdef SIGUSR1
- sys_siglist[SIGUSR1 ] = "SIGUSR1";
-#endif
-#ifdef SIGUSR2
- sys_siglist[SIGUSR2 ] = "SIGUSR2";
-#endif
-#ifdef SIGCLD
- sys_siglist[SIGCLD ] = "SIGCLD";
-#endif
-#ifdef SIGCHLD
- sys_siglist[SIGCHLD ] = "SIGCHLD";
-#endif
-#ifdef SIGPWR
- sys_siglist[SIGPWR ] = "SIGPWR";
-#endif
-#ifdef SIGTSTP
- sys_siglist[SIGTSTP ] = "SIGTSTP";
-#endif
-#ifdef SIGTTIN
- sys_siglist[SIGTTIN ] = "SIGTTIN";
-#endif
-#ifdef SIGTTOU
- sys_siglist[SIGTTOU ] = "SIGTTOU";
-#endif
-#ifdef SIGSTOP
- sys_siglist[SIGSTOP ] = "SIGSTOP";
-#endif
-#ifdef SIGXCPU
- sys_siglist[SIGXCPU ] = "SIGXCPU";
-#endif
-#ifdef SIGXFSZ
- sys_siglist[SIGXFSZ ] = "SIGXFSZ";
-#endif
-#ifdef SIGVTALRM
- sys_siglist[SIGVTALRM ] = "SIGVTALRM";
-#endif
-#ifdef SIGPROF
- sys_siglist[SIGPROF ] = "SIGPROF";
-#endif
-#ifdef SIGWINCH
- sys_siglist[SIGWINCH ] = "SIGWINCH";
-#endif
-#ifdef SIGCONT
- sys_siglist[SIGCONT ] = "SIGCONT";
-#endif
-#ifdef SIGURG
- sys_siglist[SIGURG ] = "SIGURG";
-#endif
-#ifdef SIGIO
- sys_siglist[SIGIO ] = "SIGIO";
-#endif
-#ifdef SIGWIND
- sys_siglist[SIGWIND ] = "SIGWIND";
-#endif
-#ifdef SIGPHONE
- sys_siglist[SIGPHONE ] = "SIGPHONE";
-#endif
-#ifdef SIGPOLL
- sys_siglist[SIGPOLL ] = "SIGPOLL";
-#endif
-}
-#endif /* USG */
-
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d223 1
-d237 6
-a506 26
-char *sys_siglist[32] = {
- "SIG0",
- "SIGHUP",
- "SIGINT",
- "SIGQUIT",
- "SIGILL",
- "SIGTRAP",
- "SIGIOT",
- "SIGEMT",
- "SIGFPE",
- "SIGKILL",
- "SIGBUS",
- "SIGSEGV",
- "SIGSYS",
- "SIGPIPE",
- "SIGALRM",
- "SIGTERM",
- "SIGUSR1",
- "SIGUSR2",
- "SIGCLD",
- "SIGPWR",
- "SIGWIND",
- "SIGPHONE",
- "SIGPOLL",
-};
-
-d530 124
-@
diff --git a/gdb/RCS/valprint.c,v b/gdb/RCS/valprint.c,v
deleted file mode 100644
index 52d89b0..0000000
--- a/gdb/RCS/valprint.c,v
+++ /dev/null
@@ -1,1117 +0,0 @@
-head 1.3;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.3
-date 89.04.26.01.49.11; author gnu; state Exp;
-branches ;
-next 1.2;
-
-1.2
-date 89.04.26.00.57.15; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.04.25.15.16.40; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.3
-log
-@Fix spelling Nan => NaN
-@
-text
-@/* Print values for GNU debugger gdb.
- Copyright (C) 1986, 1988 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#include <stdio.h>
-#include "defs.h"
-#include "param.h"
-#include "symtab.h"
-#include "value.h"
-
-/* Maximum number of chars to print for a string pointer value
- or vector contents. */
-
-static int print_max;
-
-static void type_print_varspec_suffix ();
-static void type_print_varspec_prefix ();
-static void type_print_base ();
-static void type_print_method_args ();
-
-
-char **unsigned_type_table;
-char **signed_type_table;
-char **float_type_table;
-
-/* Print the value VAL in C-ish syntax on stream STREAM.
- FORMAT is a format-letter, or 0 for print in natural format of data type.
- If the object printed is a string pointer, returns
- the number of string bytes printed. */
-
-int
-value_print (val, stream, format)
- value val;
- FILE *stream;
- char format;
-{
- register int i, n, typelen;
-
- /* A "repeated" value really contains several values in a row.
- They are made by the @@ operator.
- Print such values as if they were arrays. */
-
- if (VALUE_REPEATED (val))
- {
- n = VALUE_REPETITIONS (val);
- typelen = TYPE_LENGTH (VALUE_TYPE (val));
- fputc ('{', stream);
- /* Print arrays of characters using string syntax. */
- if (typelen == 1 && TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT
- && format == 0)
- {
- fputc ('"', stream);
- for (i = 0; i < n && i < print_max; i++)
- {
- QUIT;
- printchar (VALUE_CONTENTS (val)[i], stream, '"');
- }
- if (i < n)
- fprintf (stream, "...");
- fputc ('"', stream);
- }
- else
- {
- for (i = 0; i < n && i < print_max; i++)
- {
- if (i)
- fprintf (stream, ", ");
- val_print (VALUE_TYPE (val), VALUE_CONTENTS (val) + typelen * i,
- VALUE_ADDRESS (val) + typelen * i,
- stream, format, 1);
- }
- if (i < n)
- fprintf (stream, "...");
- }
- fputc ('}', stream);
- return n * typelen;
- }
- else
- {
- /* If it is a pointer, indicate what it points to.
-
- Print type also if it is a reference.
-
- C++: if it is a member pointer, we will take care
- of that when we print it. */
- if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_PTR
- || TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_REF)
- {
- fprintf (stream, "(");
- type_print (VALUE_TYPE (val), "", stream, -1);
- fprintf (stream, ") ");
- }
- return val_print (VALUE_TYPE (val), VALUE_CONTENTS (val),
- VALUE_ADDRESS (val), stream, format, 1);
- }
-}
-
-/* Print data of type TYPE located at VALADDR (within GDB),
- which came from the inferior at address ADDRESS,
- onto stdio stream STREAM according to FORMAT
- (a letter or 0 for natural format).
-
- If the data are a string pointer, returns the number of
- sting characters printed.
-
- if DEREF_REF is nonzero, then dereference references,
- otherwise just print them like pointers. */
-
-int
-val_print (type, valaddr, address, stream, format, deref_ref)
- struct type *type;
- char *valaddr;
- CORE_ADDR address;
- FILE *stream;
- char format;
- int deref_ref;
-{
- register int i;
- int len, n_baseclasses;
- struct type *elttype;
- int eltlen;
- LONGEST val;
- unsigned char c;
-
- QUIT;
-
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_ARRAY:
- if (TYPE_LENGTH (type) >= 0)
- {
- elttype = TYPE_TARGET_TYPE (type);
- eltlen = TYPE_LENGTH (elttype);
- len = TYPE_LENGTH (type) / eltlen;
- fprintf (stream, "{");
- /* For an array of chars, print with string syntax. */
- if (eltlen == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT
- && format == 0)
- {
- fputc ('"', stream);
- for (i = 0; i < len && i < print_max; i++)
- {
- QUIT;
- printchar (valaddr[i], stream, '"');
- }
- if (i < len)
- fprintf (stream, "...");
- fputc ('"', stream);
- }
- else
- {
- for (i = 0; i < len && i < print_max; i++)
- {
- if (i) fprintf (stream, ", ");
- val_print (elttype, valaddr + i * eltlen,
- 0, stream, format, deref_ref);
- }
- if (i < len)
- fprintf (stream, "...");
- }
- fprintf (stream, "}");
- break;
- }
- /* Array of unspecified length: treat like pointer. */
-
- case TYPE_CODE_PTR:
- if (format)
- {
- print_scalar_formatted (valaddr, type, format, 0, stream);
- break;
- }
- if (TYPE_CODE (TYPE_TARGET_TYPE (type)) == TYPE_CODE_MEMBER)
- {
- struct type *domain = TYPE_DOMAIN_TYPE (TYPE_TARGET_TYPE (type));
- struct type *target = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (type));
- struct fn_field *f;
- int j, len2;
- char *kind = "";
-
- val = unpack_long (builtin_type_int, valaddr);
- if (TYPE_CODE (target) == TYPE_CODE_FUNC)
- {
- if (val < 128)
- {
- len = TYPE_NFN_FIELDS (domain);
- for (i = 0; i < len; i++)
- {
- f = TYPE_FN_FIELDLIST1 (domain, i);
- len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
-
- for (j = 0; j < len2; j++)
- {
- QUIT;
- if (TYPE_FN_FIELD_VOFFSET (f, j) == val)
- {
- kind = "virtual";
- goto common;
- }
- }
- }
- }
- else
- {
- struct symbol *sym = find_pc_function ((CORE_ADDR) val);
- if (sym == 0)
- error ("invalid pointer to member function");
- len = TYPE_NFN_FIELDS (domain);
- for (i = 0; i < len; i++)
- {
- f = TYPE_FN_FIELDLIST1 (domain, i);
- len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i);
-
- for (j = 0; j < len2; j++)
- {
- QUIT;
- if (!strcmp (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j)))
- goto common;
- }
- }
- }
- common:
- if (i < len)
- {
- fputc ('&', stream);
- type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0);
- fprintf (stream, kind);
- if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
- && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$')
- type_print_method_args
- (TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
- TYPE_FN_FIELDLIST_NAME (domain, i), stream);
- else
- type_print_method_args
- (TYPE_FN_FIELD_ARGS (f, j), "",
- TYPE_FN_FIELDLIST_NAME (domain, i), stream);
- break;
- }
- }
- else
- {
- /* VAL is a byte offset into the structure type DOMAIN.
- Find the name of the field for that offset and
- print it. */
- int extra = 0;
- int bits = 0;
- len = TYPE_NFIELDS (domain);
- val <<= 3; /* @@@@ Make VAL into bit offset */
- for (i = 0; i < len; i++)
- {
- int bitpos = TYPE_FIELD_BITPOS (domain, i);
- QUIT;
- if (val == bitpos)
- break;
- if (val < bitpos && i > 0)
- {
- int ptrsize = (TYPE_LENGTH (builtin_type_char) * TYPE_LENGTH (target));
- /* Somehow pointing into a field. */
- i -= 1;
- extra = (val - TYPE_FIELD_BITPOS (domain, i));
- if (extra & 0x3)
- bits = 1;
- else
- extra >>= 3;
- break;
- }
- }
- if (i < len)
- {
- fputc ('&', stream);
- type_print_base (domain, stream, 0, 0);
- fprintf (stream, "::");
- fprintf (stream, "%s", TYPE_FIELD_NAME (domain, i));
- if (extra)
- fprintf (stream, " + %d bytes", extra);
- if (bits)
- fprintf (stream, " (offset in bits)");
- break;
- }
- }
- fputc ('(', stream);
- type_print (type, "", stream, -1);
- fprintf (stream, ") %d", val >> 3);
- }
- else
- {
- fprintf (stream, "0x%x", * (int *) valaddr);
- /* For a pointer to char or unsigned char,
- also print the string pointed to, unless pointer is null. */
-
- /* For an array of chars, print with string syntax. */
- elttype = TYPE_TARGET_TYPE (type);
- i = 0; /* Number of characters printed. */
- if (TYPE_LENGTH (elttype) == 1
- && TYPE_CODE (elttype) == TYPE_CODE_INT
- && format == 0
- /* Convex needs this typecast to a long */
- && (long) unpack_long (type, valaddr) != 0
- && print_max)
- {
- fputc (' ', stream);
-
- /* Get first character. */
- if (read_memory ( (CORE_ADDR) unpack_long (type, valaddr),
- &c, 1))
- {
- /* First address out of bounds. */
- fprintf (stream, "<Address 0x%x out of bounds>",
- (* (int *) valaddr));
- break;
- }
- else
- {
- /* A real string. */
- int out_of_bounds = 0;
-
- fputc ('"', stream);
- while (c)
- {
- QUIT;
- printchar (c, stream, '"');
- if (++i >= print_max)
- break;
- if (read_memory ((CORE_ADDR) unpack_long (type, valaddr)
- + i, &c, 1))
- {
- /* This address was out of bounds. */
- fprintf (stream,
- "\"*** <Address 0x%x out of bounds>",
- (* (int *) valaddr) + i);
- out_of_bounds = 1;
- break;
- }
- }
- if (!out_of_bounds)
- {
- fputc ('"', stream);
- if (i == print_max)
- fprintf (stream, "...");
- }
- }
- fflush (stream);
- }
- /* Return number of characters printed, plus one for the
- terminating null if we have "reached the end". */
- return i + (print_max && i != print_max);
- }
- break;
-
- case TYPE_CODE_MEMBER:
- error ("not implemented: member type in val_print");
- break;
-
- case TYPE_CODE_REF:
- fprintf (stream, "(0x%x &) = ", * (int *) valaddr);
- /* De-reference the reference. */
- if (deref_ref)
- {
- if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_UNDEF)
- {
- value val = value_at (TYPE_TARGET_TYPE (type), * (int *) valaddr);
- val_print (VALUE_TYPE (val), VALUE_CONTENTS (val),
- VALUE_ADDRESS (val), stream, format, deref_ref);
- }
- else
- fprintf (stream, "???");
- }
- break;
-
- case TYPE_CODE_STRUCT:
- case TYPE_CODE_UNION:
- fprintf (stream, "{");
- len = TYPE_NFIELDS (type);
- n_baseclasses = TYPE_N_BASECLASSES (type);
- for (i = 1; i <= n_baseclasses; i++)
- {
- fprintf (stream, "\n<%s> = ", TYPE_NAME (TYPE_BASECLASS (type, i)));
- val_print (TYPE_FIELD_TYPE (type, 0),
- valaddr + TYPE_FIELD_BITPOS (type, i-1) / 8,
- 0, stream, 0, 0);
- }
- if (i > 1) fprintf (stream, "\nmembers of %s: ", TYPE_NAME (type));
- for (i -= 1; i < len; i++)
- {
- if (i > n_baseclasses) fprintf (stream, ", ");
- fprintf (stream, "%s = ", TYPE_FIELD_NAME (type, i));
- /* check if static field */
- if (TYPE_FIELD_STATIC (type, i))
- {
- value v;
-
- v = value_static_field (type, TYPE_FIELD_NAME (type, i), i);
- val_print (TYPE_FIELD_TYPE (type, i),
- VALUE_CONTENTS (v), 0, stream, format, deref_ref);
- }
- else if (TYPE_FIELD_PACKED (type, i))
- {
- val = unpack_field_as_long (type, valaddr, i);
- val_print (TYPE_FIELD_TYPE (type, i), &val, 0,
- stream, format, deref_ref);
- }
- else
- {
- val_print (TYPE_FIELD_TYPE (type, i),
- valaddr + TYPE_FIELD_BITPOS (type, i) / 8,
- 0, stream, format, deref_ref);
- }
- }
- fprintf (stream, "}");
- break;
-
- case TYPE_CODE_ENUM:
- if (format)
- {
- print_scalar_formatted (valaddr, type, format, 0, stream);
- break;
- }
- len = TYPE_NFIELDS (type);
- val = (long) unpack_long (builtin_type_int, valaddr);
- for (i = 0; i < len; i++)
- {
- QUIT;
- if (val == TYPE_FIELD_BITPOS (type, i))
- break;
- }
- if (i < len)
- fprintf (stream, "%s", TYPE_FIELD_NAME (type, i));
- else
- fprintf (stream, "%d", val);
- break;
-
- case TYPE_CODE_FUNC:
- if (format)
- {
- print_scalar_formatted (valaddr, type, format, 0, stream);
- break;
- }
- fprintf (stream, "{");
- type_print (type, "", stream, -1);
- fprintf (stream, "} ");
- fprintf (stream, "0x%x", address);
- break;
-
- case TYPE_CODE_INT:
- if (format)
- {
- print_scalar_formatted (valaddr, type, format, 0, stream);
- break;
- }
- fprintf (stream,
- TYPE_UNSIGNED (type) ? "%u" : "%d",
- unpack_long (type, valaddr));
- if (TYPE_LENGTH (type) == 1)
- {
- fprintf (stream, " '");
- printchar ((unsigned char) unpack_long (type, valaddr),
- stream, '\'');
- fputc ('\'', stream);
- }
- break;
-
- case TYPE_CODE_FLT:
- if (format)
- {
- print_scalar_formatted (valaddr, type, format, 0, stream);
- break;
- }
- /* FIXME: When printing NaNs or invalid floats, print them
- in raw hex in addition to the message. */
-#ifdef IEEE_FLOAT
- if (is_nan ((void *)valaddr, TYPE_LENGTH(type)))
- {
- fprintf (stream, "NaN");
- break;
- }
-#endif
- {
- double doub;
- int inv;
-
- doub = unpack_double (type, valaddr, &inv);
- if (inv)
- fprintf (stream, "Invalid float value");
- else
- fprintf (stream, TYPE_LENGTH (type) <= 4? "%.6g": "%.16g", doub);
- }
- break;
-
- case TYPE_CODE_VOID:
- fprintf (stream, "void");
- break;
-
- default:
- error ("Invalid type code in symbol table.");
- }
- fflush (stream);
-}
-
-#ifdef IEEE_FLOAT
-
-/* Nonzero if ARG (a double) is a NAN. */
-
-int
-is_nan (fp, len)
- void *fp;
- int len;
-{
- int lowhalf, highhalf;
- union ieee {
- long i[2]; /* ASSUMED 32 BITS */
- float f; /* ASSUMED 32 BITS */
- double d; /* ASSUMED 64 BITS */
- } *arg;
-
- arg = (union ieee *)fp;
-
- /*
- * Single precision float.
- */
- if (len == sizeof(long)) {
- highhalf = arg->i[0];
- return ((((highhalf >> 23) & 0xFF) == 0xFF)
- && 0 != (highhalf & 0x7FFFFF));
- }
-
- /* Separate the high and low words of the double.
- Distinguish big and little-endian machines. */
-#ifdef WORDS_BIG_ENDIAN
- lowhalf = arg->i[1], highhalf = arg->i[0];
-#else
- lowhalf = arg->i[0], highhalf = arg->i[1];
-#endif
-
- /* Nan: exponent is the maximum possible, and fraction is nonzero. */
- return (((highhalf>>20) & 0x7ff) == 0x7ff
- &&
- ! ((highhalf & 0xfffff == 0) && (lowhalf == 0)));
-}
-#endif
-
-/* Print a description of a type TYPE
- in the form of a declaration of a variable named VARSTRING.
- Output goes to STREAM (via stdio).
- If SHOW is positive, we show the contents of the outermost level
- of structure even if there is a type name that could be used instead.
- If SHOW is negative, we never show the details of elements' types. */
-
-void
-type_print (type, varstring, stream, show)
- struct type *type;
- char *varstring;
- FILE *stream;
- int show;
-{
- type_print_1 (type, varstring, stream, show, 0);
-}
-
-/* LEVEL is the depth to indent lines by. */
-
-void
-type_print_1 (type, varstring, stream, show, level)
- struct type *type;
- char *varstring;
- FILE *stream;
- int show;
- int level;
-{
- register enum type_code code;
- type_print_base (type, stream, show, level);
- code = TYPE_CODE (type);
- if ((varstring && *varstring)
- ||
- /* Need a space if going to print stars or brackets;
- but not if we will print just a type name. */
- ((show > 0 || TYPE_NAME (type) == 0)
- &&
- (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC
- || code == TYPE_CODE_ARRAY
- || code == TYPE_CODE_MEMBER
- || code == TYPE_CODE_REF)))
- fprintf (stream, " ");
- type_print_varspec_prefix (type, stream, show, 0);
- fprintf (stream, "%s", varstring);
- type_print_varspec_suffix (type, stream, show, 0);
-}
-
-/* Print the method arguments ARGS to the file STREAM. */
-static void
-type_print_method_args (args, prefix, varstring, stream)
- struct type **args;
- char *prefix, *varstring;
- FILE *stream;
-{
- int i;
-
- fprintf (stream, " %s%s (", prefix, varstring);
- if (args[1] && args[1]->code != TYPE_CODE_VOID)
- {
- i = 1; /* skip the class variable */
- while (1)
- {
- type_print (args[i++], "", stream, 0);
- if (!args[i])
- {
- fprintf (stream, " ...");
- break;
- }
- else if (args[i]->code != TYPE_CODE_VOID)
- {
- fprintf (stream, ", ");
- }
- else break;
- }
- }
- fprintf (stream, ")");
-}
-
-/* If TYPE is a derived type, then print out derivation
- information. Print out all layers of the type heirarchy
- until we encounter one with multiple inheritance.
- At that point, print out that ply, and return. */
-static void
-type_print_derivation_info (stream, type)
- FILE *stream;
- struct type *type;
-{
- char *name;
- int i, n_baseclasses = TYPE_N_BASECLASSES (type);
- struct type *basetype = 0;
-
- while (type && n_baseclasses == 1)
- {
- basetype = TYPE_BASECLASS (type, 1);
- if (TYPE_NAME (basetype) && (name = TYPE_NAME (basetype)))
- {
- while (*name != ' ') name++;
- fprintf (stream, ": %s%s %s ",
- TYPE_VIA_PUBLIC (basetype) ? "public" : "private",
- TYPE_VIA_VIRTUAL (basetype) ? " virtual" : "",
- name + 1);
- }
- n_baseclasses = TYPE_N_BASECLASSES (basetype);
- type = basetype;
- }
-
- if (type)
- {
- if (n_baseclasses != 0)
- fprintf (stream, ": ");
- for (i = 1; i <= n_baseclasses; i++)
- {
- basetype = TYPE_BASECLASS (type, i);
- if (TYPE_NAME (basetype) && (name = TYPE_NAME (basetype)))
- {
- while (*name != ' ') name++;
- fprintf (stream, "%s%s %s",
- TYPE_VIA_PUBLIC (basetype) ? "public" : "private",
- TYPE_VIA_VIRTUAL (basetype) ? " virtual" : "",
- name + 1);
- }
- if (i < n_baseclasses)
- fprintf (stream, ", ");
- }
- putc (' ', stream);
- }
-}
-
-/* Print any asterisks or open-parentheses needed before the
- variable name (to describe its type).
-
- On outermost call, pass 0 for PASSED_A_PTR.
- On outermost call, SHOW > 0 means should ignore
- any typename for TYPE and show its details.
- SHOW is always zero on recursive calls. */
-
-static void
-type_print_varspec_prefix (type, stream, show, passed_a_ptr)
- struct type *type;
- FILE *stream;
- int show;
- int passed_a_ptr;
-{
- if (type == 0)
- return;
-
- if (TYPE_NAME (type) && show <= 0)
- return;
-
- QUIT;
-
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_PTR:
- type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
- fputc ('*', stream);
- break;
-
- case TYPE_CODE_MEMBER:
- type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0,
- passed_a_ptr);
- fputc (' ', stream);
- type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0,
- passed_a_ptr);
- fprintf (stream, "::");
- break;
-
- case TYPE_CODE_REF:
- type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1);
- fputc ('&', stream);
- break;
-
- case TYPE_CODE_FUNC:
- type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0,
- passed_a_ptr);
- if (passed_a_ptr)
- fputc ('(', stream);
- break;
-
- case TYPE_CODE_ARRAY:
- type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0,
- passed_a_ptr);
- }
-}
-
-/* Print any array sizes, function arguments or close parentheses
- needed after the variable name (to describe its type).
- Args work like type_print_varspec_prefix. */
-
-static void
-type_print_varspec_suffix (type, stream, show, passed_a_ptr)
- struct type *type;
- FILE *stream;
- int show;
- int passed_a_ptr;
-{
- if (type == 0)
- return;
-
- if (TYPE_NAME (type) && show <= 0)
- return;
-
- QUIT;
-
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_ARRAY:
- type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
- passed_a_ptr);
- fprintf (stream, "[");
- if (TYPE_LENGTH (type) >= 0
- && TYPE_LENGTH (TYPE_TARGET_TYPE (type)) > 0)
- fprintf (stream, "%d",
- TYPE_LENGTH (type) / TYPE_LENGTH (TYPE_TARGET_TYPE (type)));
- fprintf (stream, "]");
- break;
-
- case TYPE_CODE_MEMBER:
- if (passed_a_ptr)
- fputc (')', stream);
- type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0);
- break;
-
- case TYPE_CODE_PTR:
- case TYPE_CODE_REF:
- type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1);
- break;
-
- case TYPE_CODE_FUNC:
- type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0,
- passed_a_ptr);
- if (passed_a_ptr)
- fprintf (stream, ")");
- fprintf (stream, "()");
- break;
- }
-}
-
-/* Print the name of the type (or the ultimate pointer target,
- function value or array element), or the description of a
- structure or union.
-
- SHOW nonzero means don't print this type as just its name;
- show its real definition even if it has a name.
- SHOW zero means print just typename or struct tag if there is one
- SHOW negative means abbreviate structure elements.
- SHOW is decremented for printing of structure elements.
-
- LEVEL is the depth to indent by.
- We increase it for some recursive calls. */
-
-static void
-type_print_base (type, stream, show, level)
- struct type *type;
- FILE *stream;
- int show;
- int level;
-{
- char *name;
- register int i;
- register int len;
- register int lastval;
-
- QUIT;
-
- if (type == 0)
- {
- fprintf (stream, "type unknown");
- return;
- }
-
- if (TYPE_NAME (type) && show <= 0)
- {
- fprintf (stream, TYPE_NAME (type));
- return;
- }
-
- switch (TYPE_CODE (type))
- {
- case TYPE_CODE_ARRAY:
- case TYPE_CODE_PTR:
- case TYPE_CODE_MEMBER:
- case TYPE_CODE_REF:
- case TYPE_CODE_FUNC:
- type_print_base (TYPE_TARGET_TYPE (type), stream, show, level);
- break;
-
- case TYPE_CODE_STRUCT:
- fprintf (stream, "struct ");
- goto struct_union;
-
- case TYPE_CODE_UNION:
- fprintf (stream, "union ");
- struct_union:
- if (TYPE_NAME (type) && (name = TYPE_NAME (type)))
- {
- while (*name != ' ') name++;
- fprintf (stream, "%s ", name + 1);
- }
- if (show < 0)
- fprintf (stream, "{...}");
- else
- {
- int i;
-
- type_print_derivation_info (stream, type);
-
- fprintf (stream, "{");
- len = TYPE_NFIELDS (type);
- if (len) fprintf (stream, "\n");
- else fprintf (stream, "<no data fields>\n");
-
- /* If there is a base class for this type,
- do not print the field that it occupies. */
- for (i = TYPE_N_BASECLASSES (type); i < len; i++)
- {
- QUIT;
- /* Don't print out virtual function table. */
- if (! strncmp (TYPE_FIELD_NAME (type, i),
- "_vptr$", 6))
- continue;
-
- print_spaces (level + 4, stream);
- if (TYPE_FIELD_STATIC (type, i))
- {
- fprintf (stream, "static ");
- }
- type_print_1 (TYPE_FIELD_TYPE (type, i),
- TYPE_FIELD_NAME (type, i),
- stream, show - 1, level + 4);
- if (!TYPE_FIELD_STATIC (type, i)
- && TYPE_FIELD_PACKED (type, i))
- {
- /* ??? don't know what to put here ??? */;
- }
- fprintf (stream, ";\n");
- }
-
- /* C++: print out the methods */
- len = TYPE_NFN_FIELDS (type);
- if (len) fprintf (stream, "\n");
- for (i = 0; i < len; i++)
- {
- struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i);
- int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i);
-
- for (j = 0; j < len2; j++)
- {
- QUIT;
- print_spaces (level + 4, stream);
- if (TYPE_FN_FIELD_VIRTUAL_P (f, j))
- fprintf (stream, "virtual ");
- type_print (TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (TYPE_FN_FIELD_TYPE (f, j))), "", stream, 0);
- if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_'
- && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$')
- type_print_method_args
- (TYPE_FN_FIELD_ARGS (f, j) + 1, "~",
- TYPE_FN_FIELDLIST_NAME (type, i), stream);
- else
- type_print_method_args
- (TYPE_FN_FIELD_ARGS (f, j), "",
- TYPE_FN_FIELDLIST_NAME (type, i), stream);
-
- fprintf (stream, ";\n");
- }
- if (len2) fprintf (stream, "\n");
- }
-
- print_spaces (level, stream);
- fputc ('}', stream);
- }
- break;
-
- case TYPE_CODE_ENUM:
- fprintf (stream, "enum ");
- if (TYPE_NAME (type))
- {
- name = TYPE_NAME (type);
- while (*name != ' ') name++;
- fprintf (stream, "%s ", name + 1);
- }
- if (show < 0)
- fprintf (stream, "{...}");
- else
- {
- fprintf (stream, "{");
- len = TYPE_NFIELDS (type);
- lastval = 0;
- for (i = 0; i < len; i++)
- {
- QUIT;
- if (i) fprintf (stream, ", ");
- fprintf (stream, "%s", TYPE_FIELD_NAME (type, i));
- if (lastval != TYPE_FIELD_BITPOS (type, i))
- {
- fprintf (stream, " : %d", TYPE_FIELD_BITPOS (type, i));
- lastval = TYPE_FIELD_BITPOS (type, i);
- }
- lastval++;
- }
- fprintf (stream, "}");
- }
- break;
-
- case TYPE_CODE_INT:
- if (TYPE_UNSIGNED (type))
- name = unsigned_type_table[TYPE_LENGTH (type)];
- else
- name = signed_type_table[TYPE_LENGTH (type)];
- fprintf (stream, "%s", name);
- break;
-
- case TYPE_CODE_FLT:
- name = float_type_table[TYPE_LENGTH (type)];
- fprintf (stream, "%s", name);
- break;
-
- case TYPE_CODE_VOID:
- fprintf (stream, "void");
- break;
-
- case 0:
- fprintf (stream, "struct unknown");
- break;
-
- default:
- error ("Invalid type code in symbol table.");
- }
-}
-
-static void
-set_maximum_command (arg)
- char *arg;
-{
- if (!arg) error_no_arg ("value for maximum elements to print");
- print_max = atoi (arg);
-}
-
-extern struct cmd_list_element *setlist;
-
-void
-_initialize_valprint ()
-{
- add_cmd ("array-max", class_vars, set_maximum_command,
- "Set NUMBER as limit on string chars or array elements to print.",
- &setlist);
-
- print_max = 200;
-
- unsigned_type_table
- = (char **) xmalloc ((1 + sizeof (unsigned LONGEST)) * sizeof (char *));
- bzero (unsigned_type_table, (1 + sizeof (unsigned LONGEST)));
- unsigned_type_table[sizeof (unsigned char)] = "unsigned char";
- unsigned_type_table[sizeof (unsigned short)] = "unsigned short";
- unsigned_type_table[sizeof (unsigned long)] = "unsigned long";
- unsigned_type_table[sizeof (unsigned int)] = "unsigned int";
-#ifdef LONG_LONG
- unsigned_type_table[sizeof (unsigned long long)] = "unsigned long long";
-#endif
-
- signed_type_table
- = (char **) xmalloc ((1 + sizeof (LONGEST)) * sizeof (char *));
- bzero (signed_type_table, (1 + sizeof (LONGEST)));
- signed_type_table[sizeof (char)] = "char";
- signed_type_table[sizeof (short)] = "short";
- signed_type_table[sizeof (long)] = "long";
- signed_type_table[sizeof (int)] = "int";
-#ifdef LONG_LONG
- signed_type_table[sizeof (long long)] = "long long";
-#endif
-
- float_type_table
- = (char **) xmalloc ((1 + sizeof (double)) * sizeof (char *));
- bzero (float_type_table, (1 + sizeof (double)));
- float_type_table[sizeof (float)] = "float";
- float_type_table[sizeof (double)] = "double";
-}
-
-@
-
-
-1.2
-log
-@(1) Use XXX_BIG_ENDIAN macros rather than testing at runtime.
-(2) Change args to is_nan, support floats, change one call to it.
-(3) Change args to unpack_double.
-@
-text
-@d488 1
-a488 1
- fprintf (stream, "Nan");
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d483 2
-d486 1
-a486 1
- if (is_nan (unpack_double (type, valaddr)))
-d492 10
-a501 4
- if (TYPE_LENGTH (type) <= 4)
- fprintf (stream, "%.6g", unpack_double (type, valaddr));
- else
- fprintf (stream, "%.16g", unpack_double (type, valaddr));
-a515 5
-union ieee {
- int i[2];
- double d;
-};
-
-d519 3
-a521 2
-is_nan (arg)
- union ieee arg;
-d524 16
-a539 1
- union { int i; char c; } test;
-d543 5
-a547 6
- test.i = 1;
- if (test.c != 1)
- /* Big-endian machine */
- lowhalf = arg.i[1], highhalf = arg.i[0];
- else
- lowhalf = arg.i[0], highhalf = arg.i[1];
-@
diff --git a/gdb/RCS/values.c,v b/gdb/RCS/values.c,v
deleted file mode 100644
index bc32f31..0000000
--- a/gdb/RCS/values.c,v
+++ /dev/null
@@ -1,1047 +0,0 @@
-head 1.2;
-access ;
-symbols ;
-locks ; strict;
-comment @ * @;
-
-
-1.2
-date 89.04.26.01.05.45; author gnu; state Exp;
-branches ;
-next 1.1;
-
-1.1
-date 89.04.25.15.38.44; author gnu; state Exp;
-branches ;
-next ;
-
-
-desc
-@@
-
-
-1.2
-log
-@(1) use XXX_BIG_ENDIAN macros rather than runtime tests.
-(2) Invalid values aren't stored in the value history, but they do
-not cause an error; a -1 is returned as their value index.
-(3) unpack_double takes a new arg, and callers check it.
-@
-text
-@
-/* Low level packing and unpacking of values for GDB.
- Copyright (C) 1986, 1987 Free Software Foundation, Inc.
-
-GDB is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY. No author or distributor accepts responsibility to anyone
-for the consequences of using it or for whether it serves any
-particular purpose or works at all, unless he says so in writing.
-Refer to the GDB General Public License for full details.
-
-Everyone is granted permission to copy, modify and redistribute GDB,
-but only under the conditions described in the GDB General Public
-License. A copy of this license is supposed to have been given to you
-along with GDB so you can know your rights and responsibilities. It
-should be in a file named COPYING. Among other things, the copyright
-notice and this notice must be preserved on all copies.
-
-In other words, go ahead and share GDB, but don't try to stop
-anyone else from sharing it farther. Help stamp out software hoarding!
-*/
-
-#include <stdio.h>
-#include "defs.h"
-#include "param.h"
-#include "symtab.h"
-#include "value.h"
-
-/* The value-history records all the values printed
- by print commands during this session. Each chunk
- records 60 consecutive values. The first chunk on
- the chain records the most recent values.
- The total number of values is in value_history_count. */
-
-#define VALUE_HISTORY_CHUNK 60
-
-struct value_history_chunk
-{
- struct value_history_chunk *next;
- value values[VALUE_HISTORY_CHUNK];
-};
-
-/* Chain of chunks now in use. */
-
-static struct value_history_chunk *value_history_chain;
-
-static int value_history_count; /* Abs number of last entry stored */
-
-
-/* List of all value objects currently allocated
- (except for those released by calls to release_value)
- This is so they can be freed after each command. */
-
-static value all_values;
-
-/* Allocate a value that has the correct length for type TYPE. */
-
-value
-allocate_value (type)
- struct type *type;
-{
- register value val;
-
- val = (value) xmalloc (sizeof (struct value) + TYPE_LENGTH (type));
- VALUE_NEXT (val) = all_values;
- all_values = val;
- VALUE_TYPE (val) = type;
- VALUE_LVAL (val) = not_lval;
- VALUE_ADDRESS (val) = 0;
- VALUE_FRAME (val) = 0;
- VALUE_OFFSET (val) = 0;
- VALUE_BITPOS (val) = 0;
- VALUE_BITSIZE (val) = 0;
- VALUE_REPEATED (val) = 0;
- VALUE_REPETITIONS (val) = 0;
- VALUE_REGNO (val) = -1;
- return val;
-}
-
-/* Allocate a value that has the correct length
- for COUNT repetitions type TYPE. */
-
-value
-allocate_repeat_value (type, count)
- struct type *type;
- int count;
-{
- register value val;
-
- val = (value) xmalloc (sizeof (struct value) + TYPE_LENGTH (type) * count);
- VALUE_NEXT (val) = all_values;
- all_values = val;
- VALUE_TYPE (val) = type;
- VALUE_LVAL (val) = not_lval;
- VALUE_ADDRESS (val) = 0;
- VALUE_FRAME (val) = 0;
- VALUE_OFFSET (val) = 0;
- VALUE_BITPOS (val) = 0;
- VALUE_BITSIZE (val) = 0;
- VALUE_REPEATED (val) = 1;
- VALUE_REPETITIONS (val) = count;
- VALUE_REGNO (val) = -1;
- return val;
-}
-
-/* Free all the values that have been allocated (except for those released).
- Called after each command, successful or not. */
-
-void
-free_all_values ()
-{
- register value val, next;
-
- for (val = all_values; val; val = next)
- {
- next = VALUE_NEXT (val);
- free (val);
- }
-
- all_values = 0;
-}
-
-/* Remove VAL from the chain all_values
- so it will not be freed automatically. */
-
-void
-release_value (val)
- register value val;
-{
- register value v;
-
- if (all_values == val)
- {
- all_values = val->next;
- return;
- }
-
- for (v = all_values; v; v = v->next)
- {
- if (v->next == val)
- {
- v->next = val->next;
- break;
- }
- }
-}
-
-/* Return a copy of the value ARG.
- It contains the same contents, for same memory address,
- but it's a different block of storage. */
-
-static value
-value_copy (arg)
- value arg;
-{
- register value val;
- register struct type *type = VALUE_TYPE (arg);
- if (VALUE_REPEATED (arg))
- val = allocate_repeat_value (type, VALUE_REPETITIONS (arg));
- else
- val = allocate_value (type);
- VALUE_LVAL (val) = VALUE_LVAL (arg);
- VALUE_ADDRESS (val) = VALUE_ADDRESS (arg);
- VALUE_OFFSET (val) = VALUE_OFFSET (arg);
- VALUE_BITPOS (val) = VALUE_BITPOS (arg);
- VALUE_BITSIZE (val) = VALUE_BITSIZE (arg);
- VALUE_REGNO (val) = VALUE_REGNO (arg);
- bcopy (VALUE_CONTENTS (arg), VALUE_CONTENTS (val),
- TYPE_LENGTH (VALUE_TYPE (arg))
- * (VALUE_REPEATED (arg) ? VALUE_REPETITIONS (arg) : 1));
- return val;
-}
-
-/* Access to the value history. */
-
-/* Record a new value in the value history.
- Returns the absolute history index of the entry. */
-
-int
-record_latest_value (val)
- value val;
-{
- int i;
- double foo;
-
- /* Check error now if about to store an invalid float. We return -1
- to the caller, but allow them to continue, e.g. to print it as "Nan". */
- if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FLT) {
- foo = unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &i);
- if (i) return -1; /* Indicate value not saved in history */
- }
-
- /* Here we treat value_history_count as origin-zero
- and applying to the value being stored now. */
-
- i = value_history_count % VALUE_HISTORY_CHUNK;
- if (i == 0)
- {
- register struct value_history_chunk *new
- = (struct value_history_chunk *) xmalloc (sizeof (struct value_history_chunk));
- bzero (new->values, sizeof new->values);
- new->next = value_history_chain;
- value_history_chain = new;
- }
-
- value_history_chain->values[i] = val;
- release_value (val);
-
- /* Now we regard value_history_count as origin-one
- and applying to the value just stored. */
-
- return ++value_history_count;
-}
-
-/* Return a copy of the value in the history with sequence number NUM. */
-
-value
-access_value_history (num)
- int num;
-{
- register struct value_history_chunk *chunk;
- register int i;
- register int absnum = num;
-
- if (absnum <= 0)
- absnum += value_history_count;
-
- if (absnum <= 0)
- {
- if (num == 0)
- error ("The history is empty.");
- else if (num == 1)
- error ("There is only one value in the history.");
- else
- error ("History does not go back to $$%d.", -num);
- }
- if (absnum > value_history_count)
- error ("History has not yet reached $%d.", absnum);
-
- absnum--;
-
- /* Now absnum is always absolute and origin zero. */
-
- chunk = value_history_chain;
- for (i = (value_history_count - 1) / VALUE_HISTORY_CHUNK - absnum / VALUE_HISTORY_CHUNK;
- i > 0; i--)
- chunk = chunk->next;
-
- return value_copy (chunk->values[absnum % VALUE_HISTORY_CHUNK]);
-}
-
-/* Clear the value history entirely.
- Must be done when new symbol tables are loaded,
- because the type pointers become invalid. */
-
-void
-clear_value_history ()
-{
- register struct value_history_chunk *next;
- register int i;
- register value val;
-
- while (value_history_chain)
- {
- for (i = 0; i < VALUE_HISTORY_CHUNK; i++)
- if (val = value_history_chain->values[i])
- free (val);
- next = value_history_chain->next;
- free (value_history_chain);
- value_history_chain = next;
- }
- value_history_count = 0;
-}
-
-static void
-history_info (num_exp)
- char *num_exp;
-{
- register int i;
- register value val;
- register int num;
-
- if (num_exp)
- num = parse_and_eval_address (num_exp) - 5;
- else
- num = value_history_count - 9;
-
- if (num <= 0)
- num = 1;
-
- for (i = num; i < num + 10 && i <= value_history_count; i++)
- {
- val = access_value_history (i);
- printf ("$%d = ", i);
- value_print (val, stdout, 0);
- printf ("\n");
- }
-}
-
-/* Internal variables. These are variables within the debugger
- that hold values assigned by debugger commands.
- The user refers to them with a '$' prefix
- that does not appear in the variable names stored internally. */
-
-static struct internalvar *internalvars;
-
-/* Look up an internal variable with name NAME. NAME should not
- normally include a dollar sign.
-
- If the specified internal variable does not exist,
- one is created, with a void value. */
-
-struct internalvar *
-lookup_internalvar (name)
- char *name;
-{
- register struct internalvar *var;
-
- for (var = internalvars; var; var = var->next)
- if (!strcmp (var->name, name))
- return var;
-
- var = (struct internalvar *) xmalloc (sizeof (struct internalvar));
- var->name = concat (name, "", "");
- var->value = allocate_value (builtin_type_void);
- release_value (var->value);
- var->next = internalvars;
- internalvars = var;
- return var;
-}
-
-value
-value_of_internalvar (var)
- struct internalvar *var;
-{
- register value val = value_copy (var->value);
- VALUE_LVAL (val) = lval_internalvar;
- VALUE_INTERNALVAR (val) = var;
- return val;
-}
-
-void
-set_internalvar_component (var, offset, bitpos, bitsize, newval)
- struct internalvar *var;
- int offset, bitpos, bitsize;
- value newval;
-{
- register char *addr = VALUE_CONTENTS (var->value) + offset;
- if (bitsize)
- modify_field (addr, (int) value_as_long (newval),
- bitpos, bitsize);
- else
- bcopy (VALUE_CONTENTS (newval), addr,
- TYPE_LENGTH (VALUE_TYPE (newval)));
-}
-
-void
-set_internalvar (var, val)
- struct internalvar *var;
- value val;
-{
- free (var->value);
- var->value = value_copy (val);
- release_value (var->value);
-}
-
-char *
-internalvar_name (var)
- struct internalvar *var;
-{
- return var->name;
-}
-
-/* Free all internalvars. Done when new symtabs are loaded,
- because that makes the values invalid. */
-
-void
-clear_internalvars ()
-{
- register struct internalvar *var;
-
- while (internalvars)
- {
- var = internalvars;
- internalvars = var->next;
- free (var->name);
- free (var->value);
- free (var);
- }
-}
-
-static void
-convenience_info ()
-{
- register struct internalvar *var;
-
- if (internalvars)
- printf ("Debugger convenience variables:\n\n");
- else
- printf ("No debugger convenience variables now defined.\n\
-Convenience variables have names starting with \"$\";\n\
-use \"set\" as in \"set $foo = 5\" to define them.\n");
-
- for (var = internalvars; var; var = var->next)
- {
- printf ("$%s: ", var->name);
- value_print (var->value, stdout, 0);
- printf ("\n");
- }
-}
-
-/* Extract a value as a C number (either long or double).
- Knows how to convert fixed values to double, or
- floating values to long.
- Does not deallocate the value. */
-
-LONGEST
-value_as_long (val)
- register value val;
-{
- return unpack_long (VALUE_TYPE (val), VALUE_CONTENTS (val));
-}
-
-double
-value_as_double (val)
- register value val;
-{
- double foo;
- int inv;
-
- foo = unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val), &inv);
- if (inv)
- error ("Invalid floating value found in program.");
- return foo;
-}
-
-/* Unpack raw data (copied from debugee) at VALADDR
- as a long, or as a double, assuming the raw data is described
- by type TYPE. Knows how to convert different sizes of values
- and can convert between fixed and floating point.
-
- C++: It is assumed that the front-end has taken care of
- all matters concerning pointers to members. A pointer
- to member which reaches here is considered to be equivalent
- to an INT (or some size). After all, it is only an offset. */
-
-LONGEST
-unpack_long (type, valaddr)
- struct type *type;
- char *valaddr;
-{
- register enum type_code code = TYPE_CODE (type);
- register int len = TYPE_LENGTH (type);
- register int nosign = TYPE_UNSIGNED (type);
-
- if (code == TYPE_CODE_ENUM)
- code = TYPE_CODE_INT;
- if (code == TYPE_CODE_FLT)
- {
- if (len == sizeof (float))
- return * (float *) valaddr;
-
- if (len == sizeof (double))
- return * (double *) valaddr;
- }
- else if (code == TYPE_CODE_INT && nosign)
- {
- if (len == sizeof (char))
- return * (unsigned char *) valaddr;
-
- if (len == sizeof (short))
- return * (unsigned short *) valaddr;
-
- if (len == sizeof (int))
- return * (unsigned int *) valaddr;
-
- if (len == sizeof (long))
- return * (unsigned long *) valaddr;
- }
- else if (code == TYPE_CODE_INT)
- {
- if (len == sizeof (char))
- return * (char *) valaddr;
-
- if (len == sizeof (short))
- return * (short *) valaddr;
-
- if (len == sizeof (int))
- return * (int *) valaddr;
-
- if (len == sizeof (long))
- return * (long *) valaddr;
-
-#ifdef LONG_LONG
- if (len == sizeof (long long))
- return * (long long *) valaddr;
-#endif
- }
- else if (code == TYPE_CODE_PTR
- || code == TYPE_CODE_REF)
- {
- if (len == sizeof (char *))
- return (CORE_ADDR) * (char **) valaddr;
- }
- else if (code == TYPE_CODE_MEMBER)
- error ("not implemented: member types in unpack_long");
-
- error ("Value not integer or pointer.");
-}
-
-/* Return a double value from the specified type and address.
- * INVP points to an int which is set to 0 for valid value,
- * 1 for invalid value (bad float format). In either case,
- * the returned double is OK to use. */
-
-double
-unpack_double (type, valaddr, invp)
- struct type *type;
- char *valaddr;
- int *invp;
-{
- register enum type_code code = TYPE_CODE (type);
- register int len = TYPE_LENGTH (type);
- register int nosign = TYPE_UNSIGNED (type);
-
- *invp = 0; /* Assume valid */
- if (code == TYPE_CODE_FLT)
- {
- if (INVALID_FLOAT (valaddr, len)) {
- *invp = 1;
- return 1.234567891011121314;
- }
-
- if (len == sizeof (float))
- return * (float *) valaddr;
-
- if (len == sizeof (double))
- {
- /* Some machines require doubleword alignment for doubles.
- This code works on them, and on other machines. */
- double temp;
- bcopy ((char *) valaddr, (char *) &temp, sizeof (double));
- return temp;
- }
- }
- else if (code == TYPE_CODE_INT && nosign)
- {
- if (len == sizeof (char))
- return * (unsigned char *) valaddr;
-
- if (len == sizeof (short))
- return * (unsigned short *) valaddr;
-
- if (len == sizeof (int))
- return * (unsigned int *) valaddr;
-
- if (len == sizeof (long))
- return * (unsigned long *) valaddr;
-
-#ifdef LONG_LONG
- if (len == sizeof (long long))
- return * (unsigned long long *) valaddr;
-#endif
- }
- else if (code == TYPE_CODE_INT)
- {
- if (len == sizeof (char))
- return * (char *) valaddr;
-
- if (len == sizeof (short))
- return * (short *) valaddr;
-
- if (len == sizeof (int))
- return * (int *) valaddr;
-
- if (len == sizeof (long))
- return * (long *) valaddr;
-
-#ifdef LONG_LONG
- if (len == sizeof (long long))
- return * (long long *) valaddr;
-#endif
- }
-
- error ("Value not floating number.");
-}
-
-/* Given a value ARG1 of a struct or union type,
- extract and return the value of one of its fields.
- FIELDNO says which field.
-
- For C++, must also be able to return values from static fields */
-
-value
-value_field (arg1, fieldno)
- register value arg1;
- register int fieldno;
-{
- register value v;
- register struct type *type = TYPE_FIELD_TYPE (VALUE_TYPE (arg1), fieldno);
- register int offset;
-
- /* Handle packed fields */
-
- offset = TYPE_FIELD_BITPOS (VALUE_TYPE (arg1), fieldno) / 8;
- if (TYPE_FIELD_BITSIZE (VALUE_TYPE (arg1), fieldno))
- {
- v = value_from_long (type,
- (LONGEST) unpack_field_as_long (VALUE_TYPE (arg1),
- VALUE_CONTENTS (arg1),
- fieldno));
- VALUE_BITPOS (v) = TYPE_FIELD_BITPOS (VALUE_TYPE (arg1), fieldno) % 8;
- VALUE_BITSIZE (v) = TYPE_FIELD_BITSIZE (VALUE_TYPE (arg1), fieldno);
- }
- else
- {
- v = allocate_value (type);
- bcopy (VALUE_CONTENTS (arg1) + offset,
- VALUE_CONTENTS (v),
- TYPE_LENGTH (type));
- }
- VALUE_LVAL (v) = VALUE_LVAL (arg1);
- if (VALUE_LVAL (arg1) == lval_internalvar)
- VALUE_LVAL (v) = lval_internalvar_component;
- VALUE_ADDRESS (v) = VALUE_ADDRESS (arg1);
- VALUE_OFFSET (v) = offset + VALUE_OFFSET (arg1);
- return v;
-}
-
-value
-value_fn_field (arg1, fieldno, subfieldno)
- register value arg1;
- register int fieldno;
-{
- register value v;
- struct fn_field *f = TYPE_FN_FIELDLIST1 (VALUE_TYPE (arg1), fieldno);
- register struct type *type = TYPE_FN_FIELD_TYPE (f, subfieldno);
- struct symbol *sym;
-
- sym = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, subfieldno),
- 0, VAR_NAMESPACE, 0);
- if (! sym) error ("Internal error: could not find physical method named %s",
- TYPE_FN_FIELD_PHYSNAME (f, subfieldno));
-
- v = allocate_value (type);
- VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym));
- VALUE_TYPE (v) = type;
- return v;
-}
-
-/* Return a virtual function as a value.
- ARG1 is the object which provides the virtual function
- table pointer.
- F is the list of member functions which contains the desired virtual
- function.
- J is an index into F which provides the desired virtual function.
- TYPE is the basetype which first provides the virtual function table. */
-value
-value_virtual_fn_field (arg1, f, j, type)
- value arg1;
- struct fn_field *f;
- int j;
- struct type *type;
-{
- /* First, get the virtual function table pointer. That comes
- with a strange type, so cast it to type `pointer to long' (which
- should serve just fine as a function type). Then, index into
- the table, and convert final value to appropriate function type. */
- value vfn, vtbl;
- value vi = value_from_long (builtin_type_int,
- (LONGEST) TYPE_FN_FIELD_VOFFSET (f, j));
- VALUE_TYPE (arg1) = TYPE_VPTR_BASETYPE (type);
-
- /* This type may have been defined before its virtual function table
- was. If so, fill in the virtual function table entry for the
- type now. */
- if (TYPE_VPTR_FIELDNO (type) < 0)
- TYPE_VPTR_FIELDNO (type)
- = fill_in_vptr_fieldno (type);
-
- /* Pretend that this array is just an array of pointers to integers.
- This will have to change for multiple inheritance. */
- vtbl = value_copy (value_field (arg1, TYPE_VPTR_FIELDNO (type)));
- VALUE_TYPE (vtbl) = lookup_pointer_type (builtin_type_int);
-
- /* Index into the virtual function table. */
- vfn = value_subscript (vtbl, vi);
-
- /* Reinstantiate the function pointer with the correct type. */
- VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j));
- return vfn;
-}
-
-/* The value of a static class member does not depend
- on its instance, only on its type. If FIELDNO >= 0,
- then fieldno is a valid field number and is used directly.
- Otherwise, FIELDNAME is the name of the field we are
- searching for. If it is not a static field name, an
- error is signaled. TYPE is the type in which we look for the
- static field member. */
-value
-value_static_field (type, fieldname, fieldno)
- register struct type *type;
- char *fieldname;
- register int fieldno;
-{
- register value v;
- struct symbol *sym;
-
- if (fieldno < 0)
- {
- register struct type *t = type;
- /* Look for static field. */
- while (t)
- {
- int i;
- for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--)
- if (! strcmp (TYPE_FIELD_NAME (t, i), fieldname))
- {
- if (TYPE_FIELD_STATIC (t, i))
- {
- fieldno = i;
- goto found;
- }
- else
- error ("field `%s' is not static");
- }
- t = TYPE_BASECLASSES (t) ? TYPE_BASECLASS (t, 1) : 0;
- }
-
- t = type;
-
- if (destructor_name_p (fieldname, t))
- error ("use `info method' command to print out value of destructor");
-
- while (t)
- {
- int i, j;
-
- for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; i--)
- {
- if (! strcmp (TYPE_FN_FIELDLIST_NAME (t, i), fieldname))
- {
- error ("use `info method' command to print value of method \"%s\"", fieldname);
- }
- }
- t = TYPE_BASECLASSES (t) ? TYPE_BASECLASS (t, 1) : 0;
- }
- error("there is no field named %s", fieldname);
- }
-
- found:
-
- sym = lookup_symbol (TYPE_FIELD_STATIC_PHYSNAME (type, fieldno),
- 0, VAR_NAMESPACE, 0);
- if (! sym) error ("Internal error: could not find physical static variable named %s", TYPE_FIELD_BITSIZE (type, fieldno));
-
- type = TYPE_FIELD_TYPE (type, fieldno);
- v = value_at (type, (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym));
- return v;
-}
-
-long
-unpack_field_as_long (type, valaddr, fieldno)
- struct type *type;
- char *valaddr;
- int fieldno;
-{
- long val;
- int bitpos = TYPE_FIELD_BITPOS (type, fieldno);
- int bitsize = TYPE_FIELD_BITSIZE (type, fieldno);
-
- bcopy (valaddr + bitpos / 8, &val, sizeof val);
-
- /* Extracting bits depends on endianness of the target machine. */
-#ifdef BITS_BIG_ENDIAN
- val = val >> (sizeof val * 8 - bitpos % 8 - bitsize);
-#else
- val = val >> (bitpos % 8);
-#endif
-
- val &= (1 << bitsize) - 1;
- return val;
-}
-
-void
-modify_field (addr, fieldval, bitpos, bitsize)
- char *addr;
- int fieldval;
- int bitpos, bitsize;
-{
- long oword;
-
- bcopy (addr, &oword, sizeof oword);
-
- /* Shifting for bit field depends on endianness of the target machine. */
-#ifdef BITS_BIG_ENDIAN
- bitpos = sizeof oword * 8 - bitpos - bitsize;
-#endif
-
- oword &= ~(((1 << bitsize) - 1) << bitpos);
- oword |= fieldval << bitpos;
- bcopy (&oword, addr, sizeof oword);
-}
-
-/* Convert C numbers into newly allocated values */
-
-value
-value_from_long (type, num)
- struct type *type;
- register LONGEST num;
-{
- register value val = allocate_value (type);
- register enum type_code code = TYPE_CODE (type);
- register int len = TYPE_LENGTH (type);
-
- if (code == TYPE_CODE_INT || code == TYPE_CODE_ENUM)
- {
- if (len == sizeof (char))
- * (char *) VALUE_CONTENTS (val) = num;
- else if (len == sizeof (short))
- * (short *) VALUE_CONTENTS (val) = num;
- else if (len == sizeof (int))
- * (int *) VALUE_CONTENTS (val) = num;
- else if (len == sizeof (long))
- * (long *) VALUE_CONTENTS (val) = num;
-#ifdef LONG_LONG
- else if (len == sizeof (long long))
- * (long long *) VALUE_CONTENTS (val) = num;
-#endif
- else
- error ("Integer type encountered with unexpected data length.");
- }
- else
- error ("Unexpected type encountered for integer constant.");
-
- return val;
-}
-
-value
-value_from_double (type, num)
- struct type *type;
- double num;
-{
- register value val = allocate_value (type);
- register enum type_code code = TYPE_CODE (type);
- register int len = TYPE_LENGTH (type);
-
- if (code == TYPE_CODE_FLT)
- {
- if (len == sizeof (float))
- * (float *) VALUE_CONTENTS (val) = num;
- else if (len == sizeof (double))
- * (double *) VALUE_CONTENTS (val) = num;
- else
- error ("Floating type encountered with unexpected data length.");
- }
- else
- error ("Unexpected type encountered for floating constant.");
-
- return val;
-}
-
-/* Deal with the value that is "about to be returned". */
-
-/* Return the value that a function returning now
- would be returning to its caller, assuming its type is VALTYPE.
- RETBUF is where we look for what ought to be the contents
- of the registers (in raw form). This is because it is often
- desirable to restore old values to those registers
- after saving the contents of interest, and then call
- this function using the saved values.
- struct_return is non-zero when the function in question is
- using the structure return conventions on the machine in question;
- 0 when it is using the value returning conventions (this often
- means returning pointer to where structure is vs. returning value). */
-
-value
-value_being_returned (valtype, retbuf, struct_return)
- register struct type *valtype;
- char retbuf[REGISTER_BYTES];
- int struct_return;
-{
- register value val;
-
- if (struct_return)
- return value_at (valtype, EXTRACT_STRUCT_VALUE_ADDRESS (retbuf));
-
- val = allocate_value (valtype);
- EXTRACT_RETURN_VALUE (valtype, retbuf, VALUE_CONTENTS (val));
-
- return val;
-}
-
-/* Return true if the function specified is using the structure returning
- convention on this machine to return arguments, or 0 if it is using
- the value returning convention. FUNCTION is the value representing
- the function, FUNCADDR is the address of the function, and VALUE_TYPE
- is the type returned by the function */
-
-struct block *block_for_pc ();
-
-int
-using_struct_return (function, funcaddr, value_type)
- value function;
- CORE_ADDR funcaddr;
- struct type *value_type;
-{
- register enum type_code code = TYPE_CODE (value_type);
-
- if (code == TYPE_CODE_STRUCT ||
- code == TYPE_CODE_ENUM ||
- code == TYPE_CODE_ARRAY)
- {
- struct block *b = block_for_pc (funcaddr);
-
- if (!(BLOCK_GCC_COMPILED (b) && TYPE_LENGTH (value_type) < 8))
- return 1;
- }
-
- return 0;
-}
-
-/* Store VAL so it will be returned if a function returns now.
- Does not verify that VAL's type matches what the current
- function wants to return. */
-
-void
-set_return_value (val)
- value val;
-{
- register enum type_code code = TYPE_CODE (VALUE_TYPE (val));
- char regbuf[REGISTER_BYTES];
- double dbuf;
- LONGEST lbuf;
-
- if (code == TYPE_CODE_STRUCT
- || code == TYPE_CODE_UNION)
- error ("Specifying a struct or union return value is not supported.");
-
- if (code == TYPE_CODE_FLT)
- {
- dbuf = value_as_double (val);
-
- STORE_RETURN_VALUE (VALUE_TYPE (val), &dbuf);
- }
- else
- {
- lbuf = value_as_long (val);
- STORE_RETURN_VALUE (VALUE_TYPE (val), &lbuf);
- }
-}
-
-void
-_initialize_values ()
-{
- add_info ("convenience", convenience_info,
- "Debugger convenience (\"$foo\") variables.\n\
-These variables are created when you assign them values;\n\
-thus, \"print $foo=1\" gives \"$foo\" the value 1. Values may be any type.\n\n\
-A few convenience variables are given values automatically GDB:\n\
-\"$_\"holds the last address examined with \"x\" or \"info lines\",\n\
-\"$__\" holds the contents of the last address examined with \"x\".");
-
- add_info ("history", history_info,
- "Elements of value history (around item number IDX, or last ten).");
-}
-
-@
-
-
-1.1
-log
-@Initial revision
-@
-text
-@d182 2
-a183 1
- register int i;
-d185 6
-a190 3
- /* Get error now if about to store an invalid float. */
- if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_FLT)
- value_as_double (val);
-d427 7
-a433 1
- return unpack_double (VALUE_TYPE (val), VALUE_CONTENTS (val));
-d510 5
-d516 1
-a516 1
-unpack_double (type, valaddr)
-d519 1
-d525 1
-d528 4
-a531 2
- if (INVALID_FLOAT (valaddr, len))
- error ("Invalid floating value found in program.");
-a770 1
- union { int i; char c; } test;
-d774 6
-a779 7
- /* Extracting bits depends on endianness of the machine. */
- test.i = 1;
- if (test.c == 1)
- /* Little-endian. */
- val = val >> (bitpos % 8);
- else
- val = val >> (sizeof val * 8 - bitpos % 8 - bitsize);
-a791 1
- union { int i; char c; } test;
-d795 4
-a798 5
- /* Shifting for bit field depends on endianness of the machine. */
- test.i = 1;
- if (test.c != 1)
- /* not little-endian: assume big-endian. */
- bitpos = sizeof oword * 8 - bitpos - bitsize;
-@