gdb-3.5
This commit is contained in:
parent
1c997a4ae8
commit
7a67dd45ca
250
gdb/ChangeLog
250
gdb/ChangeLog
@ -1,6 +1,254 @@
|
||||
Thu Feb 8 01:11:55 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
|
||||
|
||||
* GDB 3.5 released.
|
||||
|
||||
* version.c: Change version number to 3.5
|
||||
|
||||
Tue Feb 6 15:58:06 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
|
||||
|
||||
* m-hp9k320.h: define ATTACH_DETACH.
|
||||
hp9k320-dep.c [ATTACH_DETACH]: New code.
|
||||
|
||||
Thu Feb 1 17:43:00 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
|
||||
|
||||
* valprint.c (is_nan, val_print): Use char * not void *.
|
||||
|
||||
* symmisc.c (print_symbol): Print newline after label.
|
||||
|
||||
Tue Jan 30 15:35:52 1990 Jim Kingdon (kingdon at albert.ai.mit.edu)
|
||||
|
||||
* Makefile.dist (READLINE): Add {readline,history}.texinfo.
|
||||
|
||||
* m-merlin.h: Put in clarifying comments about SHELL_FILE.
|
||||
config.gdb (merlin): Explain about /usr/local/lib/gdb-sh.
|
||||
|
||||
Sat Jan 27 02:30:27 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
|
||||
|
||||
* version.c: Change version number to 3.5alpha.1.
|
||||
|
||||
* dbxread.c (process_one_symbol): Compare context_stack_depth
|
||||
with !VARIABLES_INSIDE_BLOCK, not VARIABLES_INSIDE_BLOCK.
|
||||
|
||||
Fri Jan 26 01:21:51 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
|
||||
|
||||
* main.c [ALIGN_STACK_ON_STARTUP]: New code.
|
||||
m-i386.h: Define ALIGN_STACK_ON_STARTUP.
|
||||
|
||||
* m-merlin.h (NO_SIGINTERRUPT, SHELL_FILE): Define.
|
||||
|
||||
* umax-dep.c (exec_file_command): Add commas to call to
|
||||
read_section_hdr.
|
||||
|
||||
Tue Jan 23 15:49:47 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
|
||||
|
||||
* dbxread.c (define_symbol): Deal with deftype 'X'.
|
||||
|
||||
* convex-dep.c (wait): Make it pid_t.
|
||||
|
||||
* convex-dep.c (comm_registers_info): accept decimal comm register
|
||||
specification, as "i comm 32768".
|
||||
|
||||
* dbxread.c (process_one_symbol): Make VARIABLES_INSIDE_BLOCK
|
||||
macro say by itself where variables are. Pass it desc.
|
||||
m-convex.h (VARIABLES_INSIDE_BLOCK): Nonzero for native compiler.
|
||||
|
||||
* m-convex.h (SET_STACK_LIMIT_HUGE): Define.
|
||||
(IGNORE_SYMBOL): Take out #ifdef N_MONPT and put in 0xc4.
|
||||
|
||||
Fri Jan 19 20:04:15 1990 Jim Kingdon (kingdon at albert.ai.mit.edu)
|
||||
|
||||
* printcmd.c (print_frame_args): Always set highest_offset to
|
||||
current_offset when former is -1.
|
||||
|
||||
* dbxread.c (read_struct_type): Print nice error message
|
||||
when encountering multiple inheritance.
|
||||
|
||||
Thu Jan 18 13:43:30 1990 Jim Kingdon (kingdon at mole.ai.mit.edu)
|
||||
|
||||
* dbxread.c (read_dbx_symtab): Always treat N_FN as a potential
|
||||
source for a x.o or -lx symbol, ignoring OFILE_FN_FLAGGED.
|
||||
|
||||
* printcmd.c (print_frame_args): Cast -1 to (CORE_ADDR).
|
||||
|
||||
* hp300bsd-dep.c (_initialize_hp300_dep): Get kernel_u_addr.
|
||||
m-hp300bsd.h (KERNEL_U_ADDR): Use kernel_u_addr.
|
||||
|
||||
* infcmd.c (run_command): #if 0 out call to
|
||||
breakpoint_clear_ignore_counts.
|
||||
|
||||
Thu Jan 11 12:58:12 1990 Jim Kingdon (kingdon at mole)
|
||||
|
||||
* printcmd.c (print_frame_args) [STRUCT_ARG_SYM_GARBAGE]:
|
||||
Try looking up name of var before giving up & printing '?'.
|
||||
|
||||
Wed Jan 10 14:00:14 1990 Jim Kingdon (kingdon at pogo)
|
||||
|
||||
* many files: Move stdio.h before param.h.
|
||||
|
||||
* sun3-dep.c (store_inferior_registers): Only try to write FP
|
||||
regs #ifdef FP0_REGNUM.
|
||||
|
||||
Mon Jan 8 17:56:15 1990 Jim Kingdon (kingdon at pogo)
|
||||
|
||||
* symtab.c: #if 0 out "info methods" code.
|
||||
|
||||
Sat Jan 6 12:33:04 1990 Jim Kingdon (kingdon at pogo)
|
||||
|
||||
* dbxread.c (read_struct_type): Set TYPE_NFN_FIELDS_TOTAL
|
||||
from all baseclasses; remove vestigial variable baseclass.
|
||||
|
||||
* findvar.c (read_var_value): Check REG_STRUCT_HAS_ADDR.
|
||||
printcmd.c (print_frame_args): Check STRUCT_ARG_SYM_GARBAGE.
|
||||
m-sparc.h: Define REG_STRUCT_HAS_ADDR and STRUCT_ARG_SYM_GARBAGE.
|
||||
|
||||
* blockframe.c (get_frame_block): Subtract one from pc if not
|
||||
innermost frame.
|
||||
|
||||
Fri Dec 29 15:26:33 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* printcmd.c (print_frame_args): check highest_offset != -1, not i.
|
||||
|
||||
Thu Dec 28 16:21:02 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* valops.c (value_struct_elt): Clean up error msg.
|
||||
|
||||
* breakpoint.c (describe_other_breakpoints):
|
||||
Delete extra space before "also set at" and add period at end.
|
||||
|
||||
Tue Dec 19 10:28:42 1989 Jim Kingdon (kingdon at pogo)
|
||||
|
||||
* source.c (print_source_lines): Tell user which line number
|
||||
was out of range when printing error message.
|
||||
|
||||
Sun Dec 17 14:14:09 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* blockframe.c (find_pc_partial_function): Use
|
||||
BLOCK_START (SYMBOL_BLOCK_VALUE (f)) instead of
|
||||
SYMBOL_VALUE (f) to get start of function.
|
||||
|
||||
* dbxread.c: Make xxmalloc just a #define for xmalloc.
|
||||
|
||||
Thu Dec 14 16:13:16 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* m68k-opcode.h (fseq & following fp instructions):
|
||||
Change @ to $.
|
||||
|
||||
Fri Dec 8 19:06:44 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* breakpoint.c (breakpoint_clear_ignore_counts): New function.
|
||||
infcmd.c (run_command): Call it.
|
||||
|
||||
Wed Dec 6 15:03:38 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* valprint.c: Change it so "array-max 0" means there is
|
||||
no limit.
|
||||
|
||||
* expread.y (yylex): Change error message "invalid token in
|
||||
expression" to "invalid character '%c' in expression".
|
||||
|
||||
Mon Dec 4 16:12:54 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* blockframe.c (find_pc_partial_function): Always return 1
|
||||
for success, 0 for failure, and set *NAME and *ADDRESS to
|
||||
match the return value.
|
||||
|
||||
* dbxread.c (symbol_file_command): Use perror_with_name on
|
||||
error from stat.
|
||||
(psymtab_to_symtab, add_file_command),
|
||||
core.c (validate_files), source.c (find_source_lines),
|
||||
default-dep.c (exec_file_command): Check for errors from stat,
|
||||
fstat, and myread.
|
||||
|
||||
Fri Dec 1 05:16:42 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* valops.c (check_field): When following pointers, just get
|
||||
their types; don't call value_ind.
|
||||
|
||||
Thu Nov 30 14:45:29 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* config.gdb (pyr): New machine.
|
||||
core.c [REG_STACK_SEGMENT]: New code.
|
||||
dbxread.c (process_one_symbol): Cast return from copy_pending
|
||||
to long before casting to enum namespace.
|
||||
infrun.c: Split registers_info into DO_REGISTERS_INFO
|
||||
and registers_info.
|
||||
m-pyr.h, pyr-{dep.c,opcode.h,pinsn.c}: New files.
|
||||
|
||||
* hp300bsd-dep.c: Stay in sync with default-dep.c.
|
||||
|
||||
* m-hp300bsd.h (IN_SIGTRAMP): Define.
|
||||
|
||||
Mon Nov 27 23:48:21 1989 Jim Kingdon (kingdon at apple-gunkies.ai.mit.edu)
|
||||
|
||||
* m-sparc.h (EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE):
|
||||
Return floating point values in %f0.
|
||||
|
||||
Tue Nov 21 00:34:46 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* dbxread.c (read_type): #if 0 out code which skips to
|
||||
comma following x-ref.
|
||||
|
||||
Sat Nov 18 20:10:54 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* valprint.c (val_print): Undo changes of Nov 11 & 16.
|
||||
(print_string): Add parameter force_ellipses.
|
||||
(val_print): Pass force_ellipses true when we stop fetching string
|
||||
before we get to the end, else pass false.
|
||||
|
||||
Thu Nov 16 11:59:50 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* infrun.c (restore_inferior_status): Don't try to restore
|
||||
selected frame if the inferior no longer exists.
|
||||
|
||||
* valprint.c (val_print): Rewrite string printing code not to
|
||||
call print_string.
|
||||
|
||||
* Makefile.dist (clean): Remove xgdb and xgdb.o.
|
||||
|
||||
Tue Nov 14 12:41:47 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* Makefile.dist (XGDB, bindir, xbindir, install, all): New stuff.
|
||||
|
||||
Sat Nov 11 15:29:38 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* valprint.c (val_print): chars_to_get: New variable.
|
||||
|
||||
Thu Nov 9 12:31:47 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* main.c (main): Process "-help" as a switch that doesn't
|
||||
take an argument.
|
||||
|
||||
Wed Nov 8 13:07:02 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* Makefile.dist (gdb.tar.Z): Add "else true".
|
||||
|
||||
Tue Nov 7 12:25:14 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* infrun.c (restore_inferior_status): Don't dereference fid if NULL.
|
||||
|
||||
* config.gdb (sun3, sun4): Accept "sun3" and "sun4".
|
||||
|
||||
Mon Nov 6 09:49:23 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* Makefile.dist (Makefile): Move comments after commands.
|
||||
|
||||
* *-dep.c [READ_COFF_SYMTAB]: Pass optional header size to
|
||||
read_section_hdr().
|
||||
|
||||
* inflow.c: Include <fcntl.h> regardless of USG.
|
||||
|
||||
* coffread.c (read_section_hdr): Add optional_header_size.
|
||||
(symbol_file_command): Pass optional header size to
|
||||
read_section_hdr().
|
||||
(read_coff_symtab): Initialize filestring.
|
||||
|
||||
* version.c: Change version to 3.4.xxx.
|
||||
|
||||
* GDB 3.4 released.
|
||||
|
||||
Sun Nov 5 11:39:01 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* version.c: Change version to 3.4
|
||||
* version.c: Change version to 3.4.
|
||||
|
||||
* symtab.c (decode_line_1): Only skip past "struct" if it
|
||||
is there.
|
||||
|
@ -1,12 +1,17 @@
|
||||
/* This file should be run through the C preprocessor by config.gdb
|
||||
to produce the Makefile. */
|
||||
|
||||
/* System V:
|
||||
If your system has a broken alloca(), define ALLOCA & ALLOCA1 below.
|
||||
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. */
|
||||
/* Define this to xgdb if you want to compile xgdb as well as gdb. */
|
||||
XGDB=
|
||||
/* Place to install binaries. */
|
||||
bindir=/usr/local/bin
|
||||
/* Place to install X binaries. */
|
||||
xbindir=$(bindir)
|
||||
|
||||
/* System V: If you compile gdb with a compiler which uses the coff
|
||||
encapsulation feature (this is a function of the compiler used, NOT
|
||||
of the m-?.h file selected by config.gdb), you must make sure that
|
||||
the GNU nm is the one that is used by munch. */
|
||||
|
||||
/* If you are compiling with GCC, make sure that either 1) You use the
|
||||
-traditional flag, or 2) You have the fixed include files where GCC
|
||||
@ -105,7 +110,7 @@ MUNCH_DEFINE = ${SYSV_DEFINE}
|
||||
TERMCAP = -ltermcap
|
||||
|
||||
/* M_CLIBS, if defined, has system-dependent libs
|
||||
For example, -lPW for System V */
|
||||
For example, -lPW for System V to get alloca(). */
|
||||
#ifndef M_CLIBS
|
||||
#define M_CLIBS
|
||||
#endif
|
||||
@ -123,23 +128,24 @@ SFILES = blockframe.c breakpoint.c dbxread.c coffread.c command.c core.c \
|
||||
|
||||
DEPFILES = umax-dep.c gould-dep.c default-dep.c sun3-dep.c \
|
||||
sparc-dep.c hp9k320-dep.c hp300bsd-dep.c news-dep.c i386-dep.c \
|
||||
symmetry-dep.c convex-dep.c altos-dep.c isi-dep.c
|
||||
symmetry-dep.c convex-dep.c altos-dep.c isi-dep.c pyr-dep.c
|
||||
|
||||
PINSNS = gld-pinsn.c i386-pinsn.c sparc-pinsn.c vax-pinsn.c m68k-pinsn.c \
|
||||
ns32k-pinsn.c convex-pinsn.c
|
||||
ns32k-pinsn.c convex-pinsn.c pyr-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 convex-opcode.h
|
||||
ns32k-opcode.h convex-opcode.h pyr-opcode.h
|
||||
|
||||
MFILES = m-hp9k320.h m-hp300bsd.h m-i386.h m-i386gas.h \
|
||||
m-i386-sv32.h m-i386g-sv32.h m-isi.h m-merlin.h \
|
||||
m-altos.h m-news.h m-newsos3.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 m-symmetry.h m-convex.h
|
||||
m-sun3os4.h m-sun4os4.h m-umax.h m-vax.h m-symmetry.h m-convex.h \
|
||||
m-pyr.h
|
||||
|
||||
/* This list of files really shouldn't be in this makefile, but I can't think
|
||||
of any good way to get the readline makefile to tell us what files
|
||||
@ -148,6 +154,7 @@ READLINE = readline.c history.c funmap.c \
|
||||
emacs_keymap.c vi_keymap.c vi_mode.c keymaps.c \
|
||||
readline.h history.h keymaps.h chardefs.h \
|
||||
inc-readline.texinfo inc-history.texinfo \
|
||||
readline.texinfo history.texinfo \
|
||||
Makefile ChangeLog
|
||||
|
||||
REMOTE_EXAMPLES = remote-sa.m68k.shar remote-multi.shar
|
||||
@ -193,6 +200,16 @@ MD=M_MAKEDEFINE
|
||||
${CC} -c ${CFLAGS} $< */
|
||||
TARGET_ARCH=
|
||||
|
||||
all: gdb $(XGDB)
|
||||
|
||||
install: gdb $(XGDB)
|
||||
cp gdb $(bindir)/gdb.new
|
||||
mv $(bindir)/gdb.new $(bindir)/gdb
|
||||
-if [ "$(XGDB)" = xgdb ]; then \
|
||||
cp xgdb $(xbindir)/xgdb.new; \
|
||||
mv $(xbindir)/xgdb.new $(xbindir)xgdb; \
|
||||
fi
|
||||
|
||||
gdb : $(OBS) $(TSOBS) ${ADD_DEPS} ${RL_LIB}
|
||||
rm -f init.c
|
||||
./munch ${MUNCH_DEFINE} $(OBS) $(TSOBS) > init.c
|
||||
@ -206,11 +223,11 @@ gdb1 : gdb
|
||||
|
||||
Makefile : Makefile.dist
|
||||
cp Makefile.dist tmp.c
|
||||
$(CC) -E >Makefile tmp.c $(MD) "-DM_MAKEDEFINE=$(MD)"
|
||||
-rm tmp.c
|
||||
/* This did not work-- -Usparc became "-Usparc" became "-Usparc.
|
||||
Or something like that. */
|
||||
/* $(CC) -E >Makefile tmp.c $(MD) "-DM_MAKEDEFINE=\"$(MD)\"" */
|
||||
$(CC) -E >Makefile tmp.c $(MD) "-DM_MAKEDEFINE=$(MD)"
|
||||
-rm tmp.c
|
||||
|
||||
xgdb : $(OBS) $(TSOBS) xgdb.o ${ADD_DEPS} ${RL_LIB}
|
||||
rm -f init.c
|
||||
@ -251,12 +268,13 @@ gdb.tar: ${TARFILES}
|
||||
overwrite it. compress -f is not what we want, because we do want
|
||||
to know if compress would not make it smaller. */
|
||||
gdb.tar.Z: gdb.tar
|
||||
if [ -f gdb.tar.Z ]; then rm -f gdb.tar.Z; fi
|
||||
if [ -f gdb.tar.Z ]; then rm -f gdb.tar.Z; else true; fi
|
||||
compress gdb.tar
|
||||
|
||||
clean:
|
||||
rm -f ${OBS} ${TSOBS} ${NTSOBS} ${OBSTACK} ${REGEX} ${GNU_MALLOC}
|
||||
rm -f init.c init.o
|
||||
rm -f xgdb.o xgdb
|
||||
rm -f gdb core gdb.tar gdb.tar.Z make.log
|
||||
rm -f gdb[0-9]
|
||||
cd readline ; make clean
|
||||
|
@ -21,15 +21,33 @@ struct exec
|
||||
|
||||
/* these go in the N_MACHTYPE field */
|
||||
enum machine_type {
|
||||
#if defined (M_OLDSUN2)
|
||||
M__OLDSUN2 = M_OLDSUN2,
|
||||
#else
|
||||
M_OLDSUN2 = 0,
|
||||
#endif
|
||||
#if defined (M_68010)
|
||||
M__68010 = M_68010,
|
||||
#else
|
||||
M_68010 = 1,
|
||||
#endif
|
||||
#if defined (M_68020)
|
||||
M__68020 = M_68020,
|
||||
#else
|
||||
M_68020 = 2,
|
||||
#endif
|
||||
#if defined (M_SPARC)
|
||||
M__SPARC = M_SPARC
|
||||
#else
|
||||
M_SPARC = 3,
|
||||
#endif
|
||||
/* skip a bunch so we don't run into any of sun's numbers */
|
||||
M_386 = 100,
|
||||
};
|
||||
|
||||
#if !defined (N_MAGIC)
|
||||
#define N_MAGIC(exec) ((exec).a_info & 0xffff)
|
||||
#endif
|
||||
#define N_MACHTYPE(exec) ((enum machine_type)(((exec).a_info >> 16) & 0xff))
|
||||
#define N_FLAGS(exec) (((exec).a_info >> 24) & 0xff)
|
||||
#define N_SET_INFO(exec, magic, type, flags) \
|
||||
@ -54,9 +72,11 @@ enum machine_type {
|
||||
/* Code indicating demand-paged executable. */
|
||||
#define ZMAGIC 0413
|
||||
|
||||
#if !defined (N_BADMAG)
|
||||
#define N_BADMAG(x) \
|
||||
(N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \
|
||||
&& N_MAGIC(x) != ZMAGIC)
|
||||
#endif
|
||||
|
||||
#define _N_BADMAG(x) \
|
||||
(N_MAGIC(x) != OMAGIC && N_MAGIC(x) != NMAGIC \
|
||||
@ -64,26 +84,40 @@ enum machine_type {
|
||||
|
||||
#define _N_HDROFF(x) (1024 - sizeof (struct exec))
|
||||
|
||||
#if !defined (N_TXTOFF)
|
||||
#define N_TXTOFF(x) \
|
||||
(N_MAGIC(x) == ZMAGIC ? _N_HDROFF((x)) + sizeof (struct exec) : sizeof (struct exec))
|
||||
#endif
|
||||
|
||||
#if !defined (N_DATOFF)
|
||||
#define N_DATOFF(x) (N_TXTOFF(x) + (x).a_text)
|
||||
#endif
|
||||
|
||||
#if !defined (N_TRELOFF)
|
||||
#define N_TRELOFF(x) (N_DATOFF(x) + (x).a_data)
|
||||
#endif
|
||||
|
||||
#if !defined (N_DRELOFF)
|
||||
#define N_DRELOFF(x) (N_TRELOFF(x) + (x).a_trsize)
|
||||
#endif
|
||||
|
||||
#if !defined (N_SYMOFF)
|
||||
#define N_SYMOFF(x) (N_DRELOFF(x) + (x).a_drsize)
|
||||
#endif
|
||||
|
||||
#if !defined (N_STROFF)
|
||||
#define N_STROFF(x) (N_SYMOFF(x) + (x).a_syms)
|
||||
#endif
|
||||
|
||||
/* Address of text segment in memory after it is loaded. */
|
||||
#if !defined (N_TXTADDR)
|
||||
#define N_TXTADDR(x) 0
|
||||
#endif
|
||||
|
||||
/* Address of data segment in memory after it is loaded.
|
||||
Note that it is up to you to define SEGMENT_SIZE
|
||||
on machines not listed here. */
|
||||
#ifdef vax
|
||||
#if defined(vax) || defined(hp300) || defined(pyr)
|
||||
#define SEGMENT_SIZE page_size
|
||||
#endif
|
||||
#ifdef sony
|
||||
@ -104,8 +138,11 @@ enum machine_type {
|
||||
#endif
|
||||
|
||||
/* Address of bss segment in memory after it is loaded. */
|
||||
#if !defined (N_BSSADDR)
|
||||
#define N_BSSADDR(x) (N_DATADDR(x) + (x).a_data)
|
||||
#endif
|
||||
|
||||
#if !defined (N_NLIST_DECLARED)
|
||||
struct nlist {
|
||||
union {
|
||||
char *n_name;
|
||||
@ -117,17 +154,36 @@ struct nlist {
|
||||
short n_desc;
|
||||
unsigned long n_value;
|
||||
};
|
||||
#endif /* no N_NLIST_DECLARED. */
|
||||
|
||||
#if !defined (N_UNDF)
|
||||
#define N_UNDF 0
|
||||
#endif
|
||||
#if !defined (N_ABS)
|
||||
#define N_ABS 2
|
||||
#endif
|
||||
#if !defined (N_TEXT)
|
||||
#define N_TEXT 4
|
||||
#endif
|
||||
#if !defined (N_DATA)
|
||||
#define N_DATA 6
|
||||
#endif
|
||||
#if !defined (N_BSS)
|
||||
#define N_BSS 8
|
||||
#endif
|
||||
#if !defined (N_FN)
|
||||
#define N_FN 15
|
||||
#endif
|
||||
|
||||
#if !defined (N_EXT)
|
||||
#define N_EXT 1
|
||||
#endif
|
||||
#if !defined (N_TYPE)
|
||||
#define N_TYPE 036
|
||||
#endif
|
||||
#if !defined (N_STAB)
|
||||
#define N_STAB 0340
|
||||
#endif
|
||||
|
||||
/* The following type indicates the definition of a symbol as being
|
||||
an indirect reference to another symbol. The other symbol
|
||||
@ -159,6 +215,7 @@ struct nlist {
|
||||
/* This is output from LD. */
|
||||
#define N_SETV 0x1C /* Pointer to set vector in data area. */
|
||||
|
||||
#if !defined (N_RELOCATION_INFO_DECLARED)
|
||||
/* This structure describes a single relocation to be performed.
|
||||
The text-relocation section of the file is a vector of these structures,
|
||||
all of which apply to the text section.
|
||||
@ -188,6 +245,7 @@ struct relocation_info
|
||||
it is desirable to clear them. */
|
||||
unsigned int r_pad:4;
|
||||
};
|
||||
#endif /* no N_RELOCATION_INFO_DECLARED. */
|
||||
|
||||
|
||||
#endif /* __A_OUT_GNU_H__ */
|
||||
|
@ -18,6 +18,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
@ -27,7 +28,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <signal.h>
|
||||
@ -526,10 +526,12 @@ exec_file_command (filename, from_tty)
|
||||
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)
|
||||
if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read text section header", execfile);
|
||||
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read data section header", execfile);
|
||||
|
||||
text_start = exec_aouthdr.text_start;
|
||||
|
@ -180,7 +180,8 @@ get_frame_info (frame)
|
||||
}
|
||||
|
||||
/* Return a structure containing various interesting information
|
||||
about the frame that called NEXT_FRAME. */
|
||||
about the frame that called NEXT_FRAME. Returns NULL
|
||||
if there is no such frame. */
|
||||
|
||||
struct frame_info *
|
||||
get_prev_frame_info (next_frame)
|
||||
@ -302,9 +303,19 @@ get_frame_block (frame)
|
||||
FRAME frame;
|
||||
{
|
||||
struct frame_info *fi;
|
||||
CORE_ADDR pc;
|
||||
|
||||
fi = get_frame_info (frame);
|
||||
return block_for_pc (fi->pc);
|
||||
|
||||
pc = fi->pc;
|
||||
if (fi->next_frame != 0)
|
||||
/* We are not in the innermost frame. We need to subtract one to
|
||||
get the correct block, in case the call instruction was the
|
||||
last instruction of the block. If there are any machines on
|
||||
which the saved pc does not point to after the call insn, we
|
||||
probably want to make fi->pc point after the call insn anyway. */
|
||||
--pc;
|
||||
return block_for_pc (pc);
|
||||
}
|
||||
|
||||
struct block *
|
||||
@ -431,15 +442,9 @@ find_pc_function (pc)
|
||||
/* Finds the "function" (text symbol) that is smaller than PC
|
||||
but greatest of all of the potential text symbols. Sets
|
||||
*NAME and/or *ADDRESS conditionally if that pointer is non-zero.
|
||||
Returns 0 if it couldn't find anything, 1 if it did.
|
||||
|
||||
Note that there are several possible responses:
|
||||
* Set *NAME and *ADDRESS to nonzero values and return 0
|
||||
* Set *NAME and *ADDRESS to zero and return 0
|
||||
* Don't set *NAME and *ADDRESS and return 1
|
||||
(I don't know whether it *should* work this way, but I'd rather
|
||||
document it than risk breaking code
|
||||
which depends on this behavior). */
|
||||
Returns 0 if it couldn't find anything, 1 if it did. On a zero
|
||||
return, *NAME and *ADDRESS are always set to zero. On a 1 return,
|
||||
*NAME and *ADDRESS contain real information. */
|
||||
|
||||
int
|
||||
find_pc_partial_function (pc, name, address)
|
||||
@ -462,6 +467,7 @@ find_pc_partial_function (pc, name, address)
|
||||
f = find_pc_function (pc);
|
||||
if (!f)
|
||||
{
|
||||
return_error:
|
||||
/* No availible symbol. */
|
||||
if (name != 0)
|
||||
*name = 0;
|
||||
@ -473,7 +479,8 @@ find_pc_partial_function (pc, name, address)
|
||||
if (name)
|
||||
*name = SYMBOL_NAME (f);
|
||||
if (address)
|
||||
*address = SYMBOL_VALUE (f);
|
||||
*address = BLOCK_START (SYMBOL_BLOCK_VALUE (f));
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get the information from a combination of the pst
|
||||
@ -484,20 +491,18 @@ find_pc_partial_function (pc, name, address)
|
||||
|
||||
if (!psb && miscfunc == -1)
|
||||
{
|
||||
if (address != 0)
|
||||
*address = 0;
|
||||
if (name != 0)
|
||||
*name = 0;
|
||||
return 0;
|
||||
goto return_error;
|
||||
}
|
||||
if (!psb
|
||||
|| (miscfunc != -1
|
||||
&& SYMBOL_VALUE(psb) < misc_function_vector[miscfunc].address))
|
||||
&& (SYMBOL_VALUE(psb)
|
||||
< misc_function_vector[miscfunc].address)))
|
||||
{
|
||||
if (address)
|
||||
*address = misc_function_vector[miscfunc].address;
|
||||
if (name)
|
||||
*name = misc_function_vector[miscfunc].name;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -505,6 +510,7 @@ find_pc_partial_function (pc, name, address)
|
||||
*address = SYMBOL_VALUE (psb);
|
||||
if (name)
|
||||
*name = SYMBOL_NAME (psb);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -512,13 +518,13 @@ find_pc_partial_function (pc, name, address)
|
||||
{
|
||||
miscfunc = find_pc_misc_function (pc);
|
||||
if (miscfunc == -1)
|
||||
return 0;
|
||||
goto return_error;
|
||||
if (address)
|
||||
*address = misc_function_vector[miscfunc].address;
|
||||
if (name)
|
||||
*name = misc_function_vector[miscfunc].name;
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Find the misc function whose address is the largest
|
||||
|
@ -17,13 +17,12 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "symtab.h"
|
||||
#include "frame.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* This is the sequence of bytes we insert for a breakpoint. */
|
||||
|
||||
static char break_insn[] = BREAKPOINT;
|
||||
@ -527,7 +526,7 @@ describe_other_breakpoints (pc)
|
||||
(b->enable == disabled) ? " (disabled)" : "",
|
||||
(others > 1) ? "," : ((others == 1) ? " and" : ""));
|
||||
}
|
||||
printf (" also set at pc 0x%x\n", pc);
|
||||
printf ("also set at pc 0x%x.\n", pc);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1044,6 +1043,16 @@ set_ignore_count (bptnum, count, from_tty)
|
||||
error ("No breakpoint number %d.", bptnum);
|
||||
}
|
||||
|
||||
/* Clear the ignore counts of all breakpoints. */
|
||||
void
|
||||
breakpoint_clear_ignore_counts ()
|
||||
{
|
||||
struct breakpoint *b;
|
||||
|
||||
ALL_BREAKPOINTS (b)
|
||||
b->ignore_count = 0;
|
||||
}
|
||||
|
||||
/* Command to set ignore-count of breakpoint N to COUNT. */
|
||||
|
||||
static void
|
||||
|
@ -20,6 +20,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#ifdef COFF_FORMAT
|
||||
@ -31,7 +32,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#endif
|
||||
|
||||
#include <a.out.h>
|
||||
#include <stdio.h>
|
||||
#include <obstack.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/file.h>
|
||||
@ -762,7 +762,8 @@ symbol_file_command (name)
|
||||
num_sections = file_hdr.f_nscns;
|
||||
symtab_offset = file_hdr.f_symptr;
|
||||
|
||||
if (read_section_hdr (desc, _TEXT, &text_hdr, num_sections) < 0)
|
||||
if (read_section_hdr (desc, _TEXT, &text_hdr, num_sections,
|
||||
file_hdr.f_opthdr) < 0)
|
||||
error ("\"%s\": can't read text section header", name);
|
||||
|
||||
/* Read the line number table, all at once. */
|
||||
@ -865,7 +866,9 @@ read_coff_symtab (desc, nsyms)
|
||||
|
||||
int num_object_files = 0;
|
||||
int next_file_symnum = -1;
|
||||
char *filestring;
|
||||
|
||||
/* Name of the current file. */
|
||||
char *filestring = "";
|
||||
int depth;
|
||||
int fcn_first_line;
|
||||
int fcn_last_line;
|
||||
@ -1151,15 +1154,22 @@ read_aout_hdr (chan, aout_hdr, size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
read_section_hdr (chan, section_name, section_hdr, nsects)
|
||||
/* Read a section header. OPTIONAL_HEADER_SIZE is the size of the
|
||||
optional header (normally f_opthdr from the file header).
|
||||
|
||||
Return nonnegative for success, -1 for failure. */
|
||||
int
|
||||
read_section_hdr (chan, section_name, section_hdr, nsects,
|
||||
optional_header_size)
|
||||
register int chan;
|
||||
register char *section_name;
|
||||
SCNHDR *section_hdr;
|
||||
register int nsects;
|
||||
int optional_header_size;
|
||||
{
|
||||
register int i;
|
||||
|
||||
if (lseek (chan, FILHSZ + sizeof (AOUTHDR), 0) < 0)
|
||||
if (lseek (chan, FILHSZ + optional_header_size, 0) < 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < nsects; i++)
|
||||
|
@ -70,6 +70,13 @@ sun3)
|
||||
machine=sun3os3
|
||||
os=""
|
||||
;;
|
||||
*)
|
||||
# Arguably, the default should be sun3os4, but in that case we'd want
|
||||
# to change the list of machine types given by "config.gdb" so it
|
||||
# doesn't list "sun3 sun3os4".
|
||||
machine=sun3os3
|
||||
os=""
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
sparc|sun4)
|
||||
@ -78,6 +85,13 @@ sparc|sun4)
|
||||
machine=sun4os4
|
||||
os=""
|
||||
;;
|
||||
*)
|
||||
# Arguably, the default should be sun4os4, but in that case we'd want
|
||||
# to change the list of machine types given by "config.gdb" so it
|
||||
# doesn't list "sun4 sun4os4".
|
||||
machine=sun4os3
|
||||
os=""
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
# GCC accepts sequent-i386 or symmetry, so be consistent.
|
||||
@ -120,6 +134,11 @@ altosgas)
|
||||
depfile=altos-dep.c
|
||||
opcodefile=m68k-opcode.h
|
||||
;;
|
||||
pyramid)
|
||||
echo
|
||||
echo "Note that GDB on Pyramids only works with GCC."
|
||||
echo
|
||||
;;
|
||||
vax)
|
||||
echo
|
||||
# The following types of /bin/cc failures have been observed:
|
||||
@ -147,7 +166,6 @@ hp9k320)
|
||||
opcodefile=m68k-opcode.h
|
||||
;;
|
||||
hp300bsd)
|
||||
# Not sure what makefile editing (if any) is necessary for this machine.
|
||||
pinsnfile=m68k-pinsn.c
|
||||
opcodefile=m68k-opcode.h
|
||||
;;
|
||||
@ -197,6 +215,15 @@ i386g-sv32)
|
||||
opcodefile=m-i386.h
|
||||
;;
|
||||
merlin)
|
||||
echo ""
|
||||
echo "To install GDB on this machine you must copy /bin/sh"
|
||||
echo "to /usr/local/lib/gdb-sh, and make it world readable"
|
||||
echo "and writeable. For example:"
|
||||
echo " cp /bin/sh /usr/local/lib/gdb-sh"
|
||||
echo " chmod ogu+rw /usr/local/lib/gdb-sh"
|
||||
echo "If you want to put it somewhere other than /usr/local/lib,"
|
||||
echo "edit the definition of SHELL_FILE in m-merlin.h"
|
||||
echo ""
|
||||
pinsnfile=ns32k-pinsn.c
|
||||
opcodefile=ns32k-opcode.h
|
||||
;;
|
||||
@ -228,6 +255,9 @@ sun2os2|sun2-os2)
|
||||
;;
|
||||
sun2os4|sun2-os4)
|
||||
# Compile GDB without shared libraries so that it can be run on itself.
|
||||
# -Bstatic is the right flag for cc.
|
||||
# For gcc, -Bstatic is (probably) a no-op, and -g (which is specified by
|
||||
# Makefile.dist prevents use of shared libraries).
|
||||
makedefine=-DM_CFLAGS=-Bstatic
|
||||
echo
|
||||
echo "Make sure to compile any program on which you want to run gdb"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* Convex stuff for GDB.
|
||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||
Copyright (C) 1990 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "command.h"
|
||||
@ -26,7 +27,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "inferior.h"
|
||||
#include "wait.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <a.out.h>
|
||||
@ -220,7 +220,6 @@ extern int exec_mtime;
|
||||
|
||||
/* Virtual addresses of bounds of the two areas of memory in the core file.
|
||||
NB: These variables are set to plausible but useless values on convex. */
|
||||
|
||||
|
||||
extern CORE_ADDR data_start;
|
||||
extern CORE_ADDR data_end;
|
||||
@ -718,6 +717,7 @@ thread_continue (thread, step, signal)
|
||||
running; we will do a real wait, the thread will do something, and
|
||||
we will return that. */
|
||||
|
||||
pid_t
|
||||
wait (w)
|
||||
union wait *w;
|
||||
{
|
||||
@ -1774,13 +1774,12 @@ comm_registers_info (arg)
|
||||
|
||||
if (arg)
|
||||
{
|
||||
if (sscanf (arg, "0x%x", ®num) == 1)
|
||||
if (sscanf (arg, "0x%x", ®num) == 1
|
||||
|| sscanf (argc, "%d", ®num) == 1)
|
||||
{
|
||||
if (regnum > 0)
|
||||
regnum &= ~0x8000;
|
||||
}
|
||||
else if (sscanf (arg, "%d", ®num) == 1)
|
||||
;
|
||||
else if (sscanf (arg, "$c%d", ®num) == 1)
|
||||
;
|
||||
else if (sscanf (arg, "$C%d", ®num) == 1)
|
||||
@ -1861,7 +1860,6 @@ psw_info (arg)
|
||||
};
|
||||
|
||||
long psw;
|
||||
|
||||
struct pswbit *p;
|
||||
|
||||
if (arg)
|
||||
@ -1948,4 +1946,3 @@ set parallel on normal mode, parallel execution on random available CPUs\n\
|
||||
&cmdlist);
|
||||
|
||||
}
|
||||
|
||||
|
34
gdb/core.c
34
gdb/core.c
@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h" /* required by inferior.h */
|
||||
@ -39,7 +40,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define N_MAGIC(exec) ((exec).a_magic)
|
||||
#endif
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
@ -98,6 +98,12 @@ CORE_ADDR data_end;
|
||||
CORE_ADDR stack_start;
|
||||
CORE_ADDR stack_end;
|
||||
|
||||
#if defined (REG_STACK_SEGMENT)
|
||||
/* Start and end of the register stack segment. */
|
||||
CORE_ADDR reg_stack_start;
|
||||
CORE_ADDR reg_stack_end;
|
||||
#endif /* REG_STACK_SEGMENT */
|
||||
|
||||
/* 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. */
|
||||
|
||||
@ -188,7 +194,11 @@ validate_files ()
|
||||
{
|
||||
struct stat st_core;
|
||||
|
||||
fstat (corechan, &st_core);
|
||||
if (fstat (corechan, &st_core) < 0)
|
||||
/* It might be a good idea to print an error message.
|
||||
On the other hand, if the user tries to *do* anything with
|
||||
the core file, (s)he'll find out soon enough. */
|
||||
return;
|
||||
|
||||
if (N_MAGIC (core_aouthdr) != 0
|
||||
&& bcmp (&core_aouthdr, &exec_aouthdr, sizeof core_aouthdr))
|
||||
@ -368,6 +378,18 @@ xfer_core_file (memaddr, myaddr, len)
|
||||
xferfile = &corefile;
|
||||
xferchan = corechan;
|
||||
}
|
||||
#ifdef REG_STACK_SEGMENT
|
||||
/* Pyramids have an extra segment in the virtual address space
|
||||
for the (control) stack of register-window frames */
|
||||
else if (memaddr >= reg_stack_start && memaddr < reg_stack_end)
|
||||
{
|
||||
i = min (len, reg_stack_end - memaddr);
|
||||
fileptr = memaddr - reg_stack_start + reg_stack_offset;
|
||||
xferfile = &corefile;
|
||||
xferchan = corechan;
|
||||
}
|
||||
#endif /* REG_STACK_SEGMENT */
|
||||
|
||||
else if (corechan < 0
|
||||
&& memaddr >= exec_data_start && memaddr < exec_data_end)
|
||||
{
|
||||
@ -404,7 +426,15 @@ xfer_core_file (memaddr, myaddr, len)
|
||||
stack, set i to do the rest of the operation now. */
|
||||
i = len;
|
||||
}
|
||||
#ifdef REG_STACK_SEGMENT
|
||||
else if (memaddr >= reg_stack_end && reg_stack_end != 0)
|
||||
{
|
||||
i = min (len, reg_stack_start - memaddr);
|
||||
}
|
||||
else if (memaddr >= stack_end && memaddr < reg_stack_start)
|
||||
#else /* no REG_STACK_SEGMENT. */
|
||||
else if (memaddr >= stack_end && stack_end != 0)
|
||||
#endif /* no REG_STACK_SEGMENT. */
|
||||
{
|
||||
/* Since there is nothing at higher addresses than
|
||||
the stack, set i to do the rest of the operation now. */
|
||||
|
121
gdb/dbxread.c
121
gdb/dbxread.c
@ -17,6 +17,18 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Symbol read-in occurs in two phases:
|
||||
1. A scan (read_dbx_symtab()) of the entire executable, whose sole
|
||||
purpose is to make a list of symbols (partial symbol table)
|
||||
which will cause symbols
|
||||
to be read in if referenced. This scan happens when the
|
||||
"symbol-file" command is given (symbol_file_command()).
|
||||
2. Full read-in of symbols. (psymtab_to_symtab()). This happens
|
||||
when a symbol in a file for which symbols have not yet been
|
||||
read in is referenced.
|
||||
2a. The "add-file" command. Similar to #2. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "param.h"
|
||||
|
||||
#ifdef READ_DBX_FORMAT
|
||||
@ -110,7 +122,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#endif /* not __GNU_STAB__ */
|
||||
#endif /* NO_GNU_STABS */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <obstack.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/file.h>
|
||||
@ -466,6 +477,10 @@ static int undef_types_allocated, undef_types_length;
|
||||
#define HASH_OFFSET 0
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
/* I'm not sure why this is here. To debug bugs which cause
|
||||
an infinite loop of allocations, I suppose. In any event,
|
||||
dumping core when out of memory isn't usually right. */
|
||||
static int
|
||||
xxmalloc (n)
|
||||
{
|
||||
@ -477,6 +492,9 @@ xxmalloc (n)
|
||||
}
|
||||
return v;
|
||||
}
|
||||
#else /* not 0 */
|
||||
#define xxmalloc xmalloc
|
||||
#endif /* not 0 */
|
||||
|
||||
/* 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).
|
||||
@ -1634,7 +1652,7 @@ symbol_file_command (name, from_tty)
|
||||
if (val < 0)
|
||||
perror_with_name (name);
|
||||
if (stat (name, &statbuf) == -1)
|
||||
error ("internal: error in stat of already open file.");
|
||||
perror_with_name (name);
|
||||
READ_STRING_TABLE_SIZE (buffer);
|
||||
if (buffer >= 0 && buffer < statbuf.st_size)
|
||||
{
|
||||
@ -2096,14 +2114,18 @@ read_dbx_symtab (desc, stringtab, stringtab_size, nlistlen, inclink,
|
||||
#ifdef N_NBTEXT
|
||||
case N_NBTEXT:
|
||||
#endif
|
||||
#ifdef OFILE_FN_FLAGGED
|
||||
|
||||
/* We need to be able to deal with both N_FN or N_TEXT,
|
||||
because we have no way of knowing whether the sys-supplied ld
|
||||
or GNU ld was used to make the executable. */
|
||||
/* #ifdef OFILE_FN_FLAGGED */
|
||||
#if ! (N_FN & N_EXT)
|
||||
case N_FN:
|
||||
#endif
|
||||
case N_FN | N_EXT:
|
||||
#else
|
||||
/* #else */
|
||||
case N_TEXT:
|
||||
#endif
|
||||
/* #endif */
|
||||
SET_NAMESTRING();
|
||||
if ((namestring[0] == '-' && namestring[1] == 'l')
|
||||
|| (namestring [(nsl = strlen (namestring)) - 1] == 'o'
|
||||
@ -2131,6 +2153,8 @@ read_dbx_symtab (desc, stringtab, stringtab_size, nlistlen, inclink,
|
||||
}
|
||||
continue;
|
||||
|
||||
#if 0
|
||||
/* See comments at N_FN above. */
|
||||
#ifdef OFILE_FN_FLAGGED
|
||||
case N_TEXT:
|
||||
#else
|
||||
@ -2139,6 +2163,7 @@ read_dbx_symtab (desc, stringtab, stringtab_size, nlistlen, inclink,
|
||||
#endif
|
||||
case N_FN | N_EXT:
|
||||
#endif
|
||||
#endif /* 0 */
|
||||
case N_UNDF:
|
||||
case N_UNDF | N_EXT:
|
||||
case N_ABS:
|
||||
@ -2866,7 +2891,8 @@ psymtab_to_symtab(pst)
|
||||
}
|
||||
|
||||
/* Open symbol file and read in string table */
|
||||
stat (name, &statbuf);
|
||||
if (stat (name, &statbuf) < 0)
|
||||
perror_with_name (name);
|
||||
desc = open(name, O_RDONLY, 0); /* symbol_file_command
|
||||
guarrantees that the symbol file name
|
||||
will be absolute, so there is no
|
||||
@ -3267,13 +3293,16 @@ process_one_symbol (type, desc, value, name)
|
||||
if (desc != new->depth)
|
||||
error ("Invalid symbol data: N_LBRAC/N_RBRAC symbol mismatch, symtab pos %d.", symnum);
|
||||
|
||||
/* Some native compilers put the variable decls inside of an
|
||||
LBRAC/RBRAC block. This macro should be nonzero if this
|
||||
is true. DESC is N_DESC from the N_RBRAC symbol. */
|
||||
#if !defined (VARIABLES_INSIDE_BLOCK)
|
||||
#define VARIABLES_INSIDE_BLOCK(desc) 0
|
||||
#endif
|
||||
|
||||
/* Can only use new->locals as local symbols here if we're in
|
||||
gcc or on a machine that puts them before the lbrack. */
|
||||
/* Some native compilers put the variable decls inside of an
|
||||
LBRAC/RBRAC block. */
|
||||
#ifdef VARIABLES_INSIDE_BLOCK
|
||||
if (processing_gcc_compilation)
|
||||
#endif
|
||||
if (!VARIABLES_INSIDE_BLOCK(desc))
|
||||
local_symbols = new->locals;
|
||||
|
||||
/* If this is not the outermost LBRAC...RBRAC pair in the
|
||||
@ -3285,11 +3314,8 @@ process_one_symbol (type, desc, value, name)
|
||||
to be attached to the function's own block. However, if
|
||||
it is so, we need to indicate that we just moved outside
|
||||
of the function. */
|
||||
#ifdef VARIABLES_INSIDE_BLOCK
|
||||
if (local_symbols && context_stack_depth > processing_gcc_compilation)
|
||||
#else
|
||||
if (local_symbols && context_stack_depth > 1)
|
||||
#endif
|
||||
if (local_symbols
|
||||
&& context_stack_depth > !VARIABLES_INSIDE_BLOCK(desc))
|
||||
{
|
||||
/* Muzzle a compiler bug that makes end < start. */
|
||||
if (new->start_addr > value)
|
||||
@ -3303,11 +3329,9 @@ process_one_symbol (type, desc, value, name)
|
||||
{
|
||||
within_function = 0;
|
||||
}
|
||||
#ifdef VARIABLES_INSIDE_BLOCK
|
||||
/* gcc: normal. pcc: now pop locals of block just finished. */
|
||||
if (!processing_gcc_compilation)
|
||||
if (VARIABLES_INSIDE_BLOCK(desc))
|
||||
/* Now pop locals of block just finished. */
|
||||
local_symbols = new->locals;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case N_FN | N_EXT:
|
||||
@ -3386,8 +3410,8 @@ process_one_symbol (type, desc, value, name)
|
||||
bzero (sym, sizeof *sym);
|
||||
SYMBOL_NAME (sym) = savestring (name, strlen (name));
|
||||
SYMBOL_CLASS (sym) = LOC_BLOCK;
|
||||
SYMBOL_NAMESPACE (sym) = (enum namespace)
|
||||
copy_pending (local_symbols, common_block_i, common_block);
|
||||
SYMBOL_NAMESPACE (sym) = (enum namespace)((long)
|
||||
copy_pending (local_symbols, common_block_i, common_block));
|
||||
i = hashname (SYMBOL_NAME (sym));
|
||||
SYMBOL_VALUE (sym) = (int) global_sym_chain[i];
|
||||
global_sym_chain[i] = sym;
|
||||
@ -3673,7 +3697,8 @@ add_file_command (arg_string)
|
||||
val = lseek (desc, STRING_TABLE_OFFSET, 0);
|
||||
if (val < 0)
|
||||
perror_with_name (name);
|
||||
stat (name, &statbuf);
|
||||
if (stat (name, &statbuf) < 0)
|
||||
perror_with_name (name);
|
||||
READ_STRING_TABLE_SIZE (buffer);
|
||||
if (buffer >= 0 && buffer < statbuf.st_size)
|
||||
{
|
||||
@ -4059,6 +4084,17 @@ define_symbol (value, string, desc)
|
||||
add_symbol_to_list (sym, &local_symbols);
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
/* This is used by Sun FORTRAN for "function result value".
|
||||
Sun claims ("dbx and dbxtool interfaces", 2nd ed)
|
||||
that Pascal uses it too, but when I tried it Pascal used
|
||||
"x:3" (local symbol) instead. */
|
||||
SYMBOL_CLASS (sym) = LOC_LOCAL;
|
||||
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);
|
||||
}
|
||||
@ -4233,6 +4269,12 @@ read_type (pp)
|
||||
/* Set the pointer ahead of the name which we just read. */
|
||||
*pp = from;
|
||||
|
||||
#if 0
|
||||
/* The following hack is clearly wrong, because it doesn't
|
||||
check whether we are in a baseclass. I tried to reproduce
|
||||
the case that it is trying to fix, but I couldn't get
|
||||
g++ to put out a cross reference to a basetype. Perhaps
|
||||
it doesn't do it anymore. */
|
||||
/* 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 ':'
|
||||
@ -4242,6 +4284,7 @@ read_type (pp)
|
||||
from = (char *) index (*pp, ',');
|
||||
if (from)
|
||||
*pp = from;
|
||||
#endif /* 0 */
|
||||
}
|
||||
|
||||
/* Now check to see whether the type has already been declared. */
|
||||
@ -4476,7 +4519,6 @@ read_struct_type (pp, type)
|
||||
|
||||
register struct next_fnfieldlist *mainlist = 0;
|
||||
int nfn_fields = 0;
|
||||
struct type *baseclass = NULL;
|
||||
int read_possible_virtual_info = 0;
|
||||
|
||||
if (TYPE_MAIN_VARIANT (type) == 0)
|
||||
@ -4549,9 +4591,27 @@ read_struct_type (pp, type)
|
||||
error ("Invalid symbol data: bad visibility format at symtab pos %d.",
|
||||
symnum);
|
||||
}
|
||||
|
||||
/* Offset of the portion of the object corresponding to
|
||||
this baseclass. Always zero in the absence of
|
||||
multiple inheritance. */
|
||||
offset = read_number (pp, ',');
|
||||
baseclass = read_type (pp);
|
||||
*pp += 1; /* skip trailing ';' */
|
||||
|
||||
if (offset != 0)
|
||||
{
|
||||
static int error_printed = 0;
|
||||
|
||||
if (!error_printed)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"\nWarning: GDB has limited understanding of multiple inheritance...");
|
||||
error_printed = 1;
|
||||
}
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
baseclass_vec[i] = lookup_basetype_type (baseclass, offset, via_virtual, via_public);
|
||||
|
||||
/* Since lookup_basetype_type can copy the type,
|
||||
@ -4601,12 +4661,12 @@ read_struct_type (pp, type)
|
||||
new->next = list;
|
||||
list = new;
|
||||
|
||||
/* Read the data. */
|
||||
/* Get the field name. */
|
||||
p = *pp;
|
||||
while (*p != ':') p++;
|
||||
list->field.name = obsavestring (*pp, p - *pp);
|
||||
|
||||
/* C++: Check to see if we have hit the methods yet. */
|
||||
/* C++: Check to see if we have hit the methods yet. */
|
||||
if (p[1] == ':')
|
||||
break;
|
||||
|
||||
@ -4857,8 +4917,13 @@ Therefore GDB will not know about your class variables.\n\
|
||||
|
||||
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);
|
||||
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i <= TYPE_N_BASECLASSES (type); ++i)
|
||||
TYPE_NFN_FIELDS_TOTAL (type) +=
|
||||
TYPE_NFN_FIELDS_TOTAL (TYPE_BASECLASS (type, i));
|
||||
}
|
||||
|
||||
TYPE_FN_FIELDLISTS (type) =
|
||||
(struct fn_fieldlist *) obstack_alloc (symbol_obstack,
|
||||
|
@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
@ -26,7 +27,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <signal.h>
|
||||
@ -525,10 +525,12 @@ exec_file_command (filename, from_tty)
|
||||
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)
|
||||
if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read text section header", execfile);
|
||||
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read data section header", execfile);
|
||||
|
||||
text_start = exec_aouthdr.text_start;
|
||||
@ -565,7 +567,8 @@ exec_file_command (filename, from_tty)
|
||||
data_start = exec_data_start;
|
||||
data_end += exec_data_start;
|
||||
|
||||
fstat (execchan, &st_exec);
|
||||
if (fstat (execchan, &st_exec) < 0)
|
||||
perror_with_name (filename);
|
||||
exec_mtime = st_exec.st_mtime;
|
||||
}
|
||||
#endif /* not COFF_FORMAT */
|
||||
|
@ -17,13 +17,13 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "param.h"
|
||||
#include "expression.h"
|
||||
#include "value.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* These codes indicate operator precedences, least tightly binding first. */
|
||||
/* Adding 1 to a precedence value is done for binary operators,
|
||||
|
@ -40,13 +40,13 @@
|
||||
|
||||
#line 29 "expread.y"
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "symtab.h"
|
||||
#include "frame.h"
|
||||
#include "expression.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <a.out.h>
|
||||
|
||||
static struct expression *expout;
|
||||
@ -137,7 +137,7 @@ typedef union
|
||||
#ifndef YYLTYPE
|
||||
typedef
|
||||
struct yyltype
|
||||
{
|
||||
{
|
||||
int timestamp;
|
||||
int first_line;
|
||||
int first_column;
|
||||
@ -145,7 +145,7 @@ typedef
|
||||
int last_column;
|
||||
char *text;
|
||||
}
|
||||
yyltype;
|
||||
yyltype;
|
||||
|
||||
#define YYLTYPE yyltype
|
||||
#endif
|
||||
@ -197,7 +197,8 @@ static const char yytranslate[] = { 0,
|
||||
50, 51, 52
|
||||
};
|
||||
|
||||
static const short yyrline[] = { 0,
|
||||
#if YYDEBUG != 0
|
||||
static const short yyrline[] = { 0,
|
||||
190, 194, 195, 200, 203, 206, 210, 214, 218, 222,
|
||||
226, 230, 234, 238, 244, 248, 254, 258, 262, 266,
|
||||
272, 275, 279, 283, 289, 295, 301, 305, 309, 313,
|
||||
@ -220,6 +221,7 @@ static const char * const yytname[] = { 0,
|
||||
"DECREMENT","ARROW","'.'","'['","'('","'!'","'~'","']'","')'","'{'",
|
||||
"'}'","':'","start"
|
||||
};
|
||||
#endif
|
||||
|
||||
static const short yyr1[] = { 0,
|
||||
63, 64, 64, 65, 65, 65, 65, 65, 65, 65,
|
||||
@ -548,9 +550,6 @@ yyparse()
|
||||
/* routines */
|
||||
|
||||
int yylen;
|
||||
void yyerror();
|
||||
void bcopy();
|
||||
int yylex();
|
||||
|
||||
#if YYDEBUG != 0
|
||||
if (yydebug)
|
||||
@ -582,9 +581,7 @@ yynewstate:
|
||||
/* Give user a chance to reallocate the stack */
|
||||
/* Use copies of these so that the &'s don't force the real ones into memory. */
|
||||
YYSTYPE *yyvs1 = yyvs;
|
||||
#if defined(yyoverflow) || defined(YYLSP_NEEDED)
|
||||
YYLTYPE *yyls1 = yyls;
|
||||
#endif
|
||||
short *yyss1 = yyss;
|
||||
|
||||
/* Get the current used size of the three stacks, in elements. */
|
||||
@ -639,6 +636,7 @@ yynewstate:
|
||||
|
||||
/* Do appropriate processing given the current state. */
|
||||
/* Read a lookahead token if we need one and don't already have one. */
|
||||
yyresume:
|
||||
|
||||
/* First try to decide what to do without reference to lookahead token. */
|
||||
|
||||
@ -1402,7 +1400,7 @@ case 104:
|
||||
break;}
|
||||
}
|
||||
/* the action file gets copied in in place of this dollarsign */
|
||||
#line 331 "bison.simple"
|
||||
#line 327 "bison.simple"
|
||||
|
||||
yyvsp -= yylen;
|
||||
yyssp -= yylen;
|
||||
@ -2030,7 +2028,8 @@ yylex ()
|
||||
|
||||
if (!(c == '_' || c == '$'
|
||||
|| (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
|
||||
error ("Invalid token in expression.");
|
||||
/* We must have come across a bad character (e.g. ';'). */
|
||||
error ("Invalid character '%c' in expression.", c);
|
||||
|
||||
/* It's a name. See how long it is. */
|
||||
namelen = 0;
|
||||
|
@ -27,13 +27,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
come first in the result. */
|
||||
|
||||
%{
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "symtab.h"
|
||||
#include "frame.h"
|
||||
#include "expression.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <a.out.h>
|
||||
|
||||
static struct expression *expout;
|
||||
@ -1283,7 +1283,8 @@ yylex ()
|
||||
|
||||
if (!(c == '_' || c == '$'
|
||||
|| (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
|
||||
error ("Invalid token in expression.");
|
||||
/* We must have come across a bad character (e.g. ';'). */
|
||||
error ("Invalid character '%c' in expression.", c);
|
||||
|
||||
/* It's a name. See how long it is. */
|
||||
namelen = 0;
|
||||
|
@ -283,11 +283,19 @@ read_var_value (var, frame)
|
||||
addr = val;
|
||||
break;
|
||||
|
||||
/* Nonzero if a struct which is located in a register or a LOC_ARG
|
||||
really contains
|
||||
the address of the struct, not the struct itself. GCC_P is nonzero
|
||||
if the function was compiled with GCC. */
|
||||
#if !defined (REG_STRUCT_HAS_ADDR)
|
||||
#define REG_STRUCT_HAS_ADDR(gcc_p) 0
|
||||
#endif
|
||||
|
||||
case LOC_ARG:
|
||||
fi = get_frame_info (frame);
|
||||
addr = val + FRAME_ARGS_ADDRESS (fi);
|
||||
break;
|
||||
|
||||
|
||||
case LOC_REF_ARG:
|
||||
fi = get_frame_info (frame);
|
||||
addr = val + FRAME_ARGS_ADDRESS (fi);
|
||||
@ -308,8 +316,17 @@ read_var_value (var, frame)
|
||||
|
||||
case LOC_REGISTER:
|
||||
case LOC_REGPARM:
|
||||
v = value_from_register (type, val, frame);
|
||||
return v;
|
||||
{
|
||||
struct block *b = get_frame_block (frame);
|
||||
|
||||
v = value_from_register (type, val, frame);
|
||||
|
||||
if (REG_STRUCT_HAS_ADDR(b->gcc_compile_flag)
|
||||
&& TYPE_CODE (type) == TYPE_CODE_STRUCT)
|
||||
addr = *(CORE_ADDR *)VALUE_CONTENTS (v);
|
||||
else
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
read_memory (addr, VALUE_CONTENTS (v), len);
|
||||
|
@ -2850,6 +2850,8 @@ Print all data types that are defined in the program.
|
||||
Print all data types that are defined in the program whose names
|
||||
contain a match for regular expression @var{regexp}.
|
||||
|
||||
@ignore
|
||||
This was never implemented.
|
||||
@item info methods
|
||||
@itemx info methods @var{regexp}
|
||||
@kindex info methods
|
||||
@ -2860,6 +2862,7 @@ C++ classes provide a large number of methods. Thus, the output
|
||||
from the @samp{ptype} command can be overwhelming and hard to use. The
|
||||
@samp{info-methods} command filters the methods, printing only those
|
||||
which match the regular-expression @var{regexp}.
|
||||
@end ignore
|
||||
|
||||
@item printsyms @var{filename}
|
||||
@kindex printsyms
|
||||
@ -3328,8 +3331,20 @@ Execute one instruction, like the GDB @samp{stepi} command.
|
||||
Execute until exit from the selected stack frame, like the GDB
|
||||
@samp{finish} command.
|
||||
|
||||
@item C-c C-c
|
||||
@item M-c
|
||||
@comment C-c C-p in emacs 19
|
||||
Continue execution of the program, like the GDB @samp{cont} command.
|
||||
|
||||
@item M-u
|
||||
@comment C-c C-u in emacs 19
|
||||
Go up the number of frames indicated by the numeric argument
|
||||
(@pxref{Arguments, , Numeric Arguments, emacs, The GNU Emacs Manual}),
|
||||
like the GDB @samp{up} command.@refill
|
||||
|
||||
@item M-d
|
||||
@comment C-c C-d in emacs 19
|
||||
Go down the number of frames indicated by the numeric argument, like the
|
||||
GDB @samp{down} command.
|
||||
@end table
|
||||
|
||||
In any source file, the Emacs command @kbd{C-x SPC} (@code{gdb-break})
|
||||
|
@ -17,12 +17,12 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <signal.h>
|
||||
@ -499,10 +499,12 @@ exec_file_command (filename, from_tty)
|
||||
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)
|
||||
if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read text section header", execfile);
|
||||
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read data section header", execfile);
|
||||
|
||||
text_start = exec_aouthdr.text_start;
|
||||
|
@ -1,4 +0,0 @@
|
||||
/* The GNU programs do #include <sys/fcntl.h>
|
||||
but on HPUX that file is just fcntl.h.
|
||||
This "redirects" the #include to the proper directory. */
|
||||
#include <fcntl.h>
|
@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
@ -26,13 +27,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <signal.h>
|
||||
#include <sys/user.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
/* #include <fcntl.h> Can we live without this? */
|
||||
|
||||
#ifdef COFF_ENCAPSULATE
|
||||
#include "a.out.encap.h"
|
||||
@ -42,10 +41,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#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>
|
||||
#include <sys/ptrace.h>
|
||||
|
||||
CORE_ADDR kernel_u_addr;
|
||||
|
||||
extern int errno;
|
||||
|
||||
/* This function simply calls ptrace with the given arguments.
|
||||
@ -200,9 +203,17 @@ read_inferior_memory (memaddr, myaddr, len)
|
||||
for (i = 0; i < count; i++, addr += sizeof (int))
|
||||
{
|
||||
errno = 0;
|
||||
#if 0
|
||||
/* This is now done by read_memory, because when this function did it,
|
||||
reading a byte or short int hardware port read whole longs, causing
|
||||
serious side effects
|
||||
such as bus errors and unexpected hardware operation. This would
|
||||
also be a problem with ptrace if the inferior process could read
|
||||
or write hardware registers, but that's not usually the case. */
|
||||
if (remote_debugging)
|
||||
buffer[i] = remote_fetch_word (addr);
|
||||
else
|
||||
#endif
|
||||
buffer[i] = ptrace (PT_READ_I, inferior_pid, addr, 0);
|
||||
if (errno)
|
||||
return errno;
|
||||
@ -275,11 +286,6 @@ write_inferior_memory (memaddr, myaddr, len)
|
||||
/* 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 */
|
||||
@ -296,8 +302,10 @@ write_inferior_memory (memaddr, myaddr, len)
|
||||
#endif
|
||||
|
||||
#ifndef COFF_FORMAT
|
||||
#ifndef AOUTHDR
|
||||
#define AOUTHDR struct exec
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern char *sys_siglist[];
|
||||
|
||||
@ -413,18 +421,30 @@ core_file_command (filename, from_tty)
|
||||
{
|
||||
struct user u;
|
||||
|
||||
int reg_offset;
|
||||
unsigned int reg_offset;
|
||||
|
||||
val = myread (corechan, &u, sizeof u);
|
||||
if (val < 0)
|
||||
perror_with_name (filename);
|
||||
perror_with_name ("Not a core file: reading upage");
|
||||
if (val != sizeof u)
|
||||
error ("Not a core file: could only read %d bytes", val);
|
||||
|
||||
/* We are depending on exec_file_command having been called
|
||||
previously to set exec_data_start. Since the executable
|
||||
and the core file share the same text segment, the address
|
||||
of the data segment will be the same in both. */
|
||||
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);
|
||||
reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR;
|
||||
|
||||
/* Some machines put an absolute address in here and some put
|
||||
the offset in the upage of the regs. */
|
||||
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. */
|
||||
@ -441,12 +461,17 @@ core_file_command (filename, from_tty)
|
||||
char buf[MAX_REGISTER_RAW_SIZE];
|
||||
|
||||
val = lseek (corechan, register_addr (regno, reg_offset), 0);
|
||||
if (val < 0)
|
||||
perror_with_name (filename);
|
||||
if (val < 0
|
||||
|| (val = myread (corechan, buf, sizeof buf)) < 0)
|
||||
{
|
||||
char * buffer = (char *) alloca (strlen (reg_names[regno])
|
||||
+ 30);
|
||||
strcpy (buffer, "Reading register ");
|
||||
strcat (buffer, reg_names[regno]);
|
||||
|
||||
perror_with_name (buffer);
|
||||
}
|
||||
|
||||
val = myread (corechan, buf, sizeof buf);
|
||||
if (val < 0)
|
||||
perror_with_name (filename);
|
||||
supply_register (regno, buf);
|
||||
}
|
||||
}
|
||||
@ -515,10 +540,12 @@ exec_file_command (filename, from_tty)
|
||||
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)
|
||||
if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read text section header", execfile);
|
||||
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read data section header", execfile);
|
||||
|
||||
text_start = exec_aouthdr.text_start;
|
||||
@ -569,3 +596,17 @@ exec_file_command (filename, from_tty)
|
||||
if (exec_file_display_hook)
|
||||
(*exec_file_display_hook) (filename);
|
||||
}
|
||||
|
||||
void
|
||||
_initialize_hp300bsd_dep ()
|
||||
{
|
||||
struct nlist names[2];
|
||||
|
||||
/* Get the address of the u area. */
|
||||
names[0].n_un.n_name = "_u";
|
||||
names[1].n_un.n_name = NULL;
|
||||
if (nlist ("/vmunix", names) == 0)
|
||||
kernel_u_addr = names[0].n_value;
|
||||
else
|
||||
kernel_u_addr = 0x00917000;
|
||||
}
|
||||
|
@ -17,12 +17,12 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#define WOPR
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
@ -51,6 +51,39 @@ int request, pid, arg3, arg4;
|
||||
return ptrace (request, pid, arg3, arg4);
|
||||
}
|
||||
|
||||
#ifdef ATTACH_DETACH
|
||||
|
||||
extern int attach_flag ;
|
||||
|
||||
/* Start debugging the process whose number is PID. */
|
||||
|
||||
attach (pid)
|
||||
int pid;
|
||||
{
|
||||
errno = 0;
|
||||
ptrace (PT_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 (PT_DETACH, inferior_pid, 1, signal);
|
||||
if (errno)
|
||||
perror_with_name ("ptrace");
|
||||
attach_flag = 0;
|
||||
}
|
||||
#endif /* ATTACH_DETACH */
|
||||
|
||||
kill_inferior ()
|
||||
{
|
||||
if (remote_debugging)
|
||||
@ -610,10 +643,12 @@ exec_file_command (filename, from_tty)
|
||||
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)
|
||||
if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read text section header", execfile);
|
||||
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read data section header", execfile);
|
||||
|
||||
text_start = exec_aouthdr.text_start;
|
||||
|
@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
@ -26,7 +27,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <signal.h>
|
||||
@ -504,10 +504,12 @@ exec_file_command (filename, from_tty)
|
||||
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)
|
||||
if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read text section header", execfile);
|
||||
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read data section header", execfile);
|
||||
|
||||
text_start = exec_aouthdr.text_start;
|
||||
|
86
gdb/infcmd.c
86
gdb/infcmd.c
@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "symtab.h"
|
||||
@ -25,7 +26,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "environ.h"
|
||||
#include "value.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
@ -107,6 +107,7 @@ struct environ *inferior_environ;
|
||||
|
||||
CORE_ADDR read_pc ();
|
||||
struct command_line *get_breakpoint_commands ();
|
||||
void breakpoint_clear_ignore_counts ();
|
||||
|
||||
|
||||
int
|
||||
@ -160,6 +161,18 @@ Start it from the beginning? "))
|
||||
kill_inferior ();
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* On the other hand, some users want to do
|
||||
break open
|
||||
ignore 1 40
|
||||
run
|
||||
So it's not clear what is best. */
|
||||
|
||||
/* It is confusing to the user for ignore counts to stick around
|
||||
from previous runs of the inferior. So clear them. */
|
||||
breakpoint_clear_ignore_counts ();
|
||||
#endif
|
||||
|
||||
exec_file = (char *) get_exec_file (1);
|
||||
|
||||
if (remote_debugging)
|
||||
@ -765,33 +778,22 @@ write_pc (val)
|
||||
|
||||
char *reg_names[] = REGISTER_NAMES;
|
||||
|
||||
static void
|
||||
registers_info (addr_exp)
|
||||
char *addr_exp;
|
||||
/* Print out the machine register regnum. If regnum is -1,
|
||||
print all registers.
|
||||
For most machines, having all_registers_info() print the
|
||||
register(s) one per line is good enough. If a different format
|
||||
is required, (eg, for SPARC or Pyramid 90x, which both have
|
||||
lots of regs), or there is an existing convention for showing
|
||||
all the registers, define the macro DO_REGISTERS_INFO(regnum)
|
||||
to provide that format. */
|
||||
#if !defined (DO_REGISTERS_INFO)
|
||||
#define DO_REGISTERS_INFO(regnum) do_registers_info(regnum)
|
||||
static void do_registers_info (regnum)
|
||||
int regnum;
|
||||
{
|
||||
register int i;
|
||||
int regnum;
|
||||
|
||||
if (!have_inferior_p () && !have_core_file_p ())
|
||||
error ("No inferior or core file");
|
||||
|
||||
if (addr_exp)
|
||||
{
|
||||
if (*addr_exp >= '0' && *addr_exp <= '9')
|
||||
regnum = atoi (addr_exp);
|
||||
else
|
||||
{
|
||||
register char *p = addr_exp;
|
||||
if (p[0] == '$')
|
||||
p++;
|
||||
for (regnum = 0; regnum < NUM_REGS; regnum++)
|
||||
if (!strcmp (p, reg_names[regnum]))
|
||||
break;
|
||||
if (regnum == NUM_REGS)
|
||||
error ("%s: invalid register name.", addr_exp);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (regnum == -1)
|
||||
printf_filtered (
|
||||
"Register Contents (relative to selected stack frame)\n\n");
|
||||
|
||||
@ -801,7 +803,7 @@ registers_info (addr_exp)
|
||||
unsigned char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE];
|
||||
REGISTER_TYPE val;
|
||||
|
||||
if (addr_exp != 0 && i != regnum)
|
||||
if (regnum != -1 && i != regnum)
|
||||
continue;
|
||||
|
||||
/* Get the data in raw format, then convert also to virtual format. */
|
||||
@ -852,6 +854,38 @@ registers_info (addr_exp)
|
||||
printf_filtered ("\n");
|
||||
}
|
||||
}
|
||||
#endif /* no DO_REGISTERS_INFO. */
|
||||
|
||||
static void
|
||||
registers_info (addr_exp)
|
||||
char *addr_exp;
|
||||
{
|
||||
int regnum;
|
||||
|
||||
if (!have_inferior_p () && !have_core_file_p ())
|
||||
error ("No inferior or core file");
|
||||
|
||||
if (addr_exp)
|
||||
{
|
||||
if (*addr_exp >= '0' && *addr_exp <= '9')
|
||||
regnum = atoi (addr_exp);
|
||||
else
|
||||
{
|
||||
register char *p = addr_exp;
|
||||
if (p[0] == '$')
|
||||
p++;
|
||||
for (regnum = 0; regnum < NUM_REGS; regnum++)
|
||||
if (!strcmp (p, reg_names[regnum]))
|
||||
break;
|
||||
if (regnum == NUM_REGS)
|
||||
error ("%s: invalid register name.", addr_exp);
|
||||
}
|
||||
}
|
||||
else
|
||||
regnum = -1;
|
||||
|
||||
DO_REGISTERS_INFO(regnum);
|
||||
}
|
||||
|
||||
#ifdef ATTACH_DETACH
|
||||
#define PROCESS_ATTACH_ALLOWED 1
|
||||
|
@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
@ -24,10 +25,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef USG
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
/* Some USG-esque systems (some of which are BSD-esque enough so that USG
|
||||
is not defined) want this header, and it won't do any harm. */
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <signal.h>
|
||||
|
26
gdb/infrun.c
26
gdb/infrun.c
@ -116,6 +116,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "symtab.h"
|
||||
@ -123,7 +124,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "inferior.h"
|
||||
#include "wait.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
|
||||
/* unistd.h is needed to #define X_OK */
|
||||
@ -842,6 +842,9 @@ wait_for_inferior ()
|
||||
if (IN_SIGTRAMP (stop_pc, stop_func_name)
|
||||
&& !IN_SIGTRAMP (prev_pc, prev_func_name))
|
||||
{
|
||||
/* This code is needed at least in the following case:
|
||||
The user types "next" and then a signal arrives (before
|
||||
the "next" is done). */
|
||||
/* We've just taken a signal; go until we are back to
|
||||
the point where we took it and one more. */
|
||||
step_resume_break_address = prev_pc;
|
||||
@ -1083,6 +1086,11 @@ Further execution is probably impossible.\n");
|
||||
if (access (exec_file, X_OK) != 0)
|
||||
printf ("The file \"%s\" is not executable.\n", exec_file);
|
||||
else
|
||||
/* I don't think we should ever get here.
|
||||
wait_for_inferior now ignores SIGSEGV's which happen in
|
||||
the shell (since the Bourne shell (/bin/sh) has some
|
||||
rather, er, uh, *unorthodox* memory management
|
||||
involving catching SIGSEGV). */
|
||||
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\
|
||||
@ -1343,14 +1351,24 @@ restore_inferior_status (inf_status)
|
||||
|
||||
bcopy (inf_status->stop_registers, stop_registers, REGISTER_BYTES);
|
||||
|
||||
if (inf_status->restore_stack_info)
|
||||
/* The inferior can be gone if the user types "print exit(0)"
|
||||
(and perhaps other times). */
|
||||
if (have_inferior_p() && inf_status->restore_stack_info)
|
||||
{
|
||||
fid = find_relative_frame (get_current_frame (),
|
||||
&level);
|
||||
|
||||
if (FRAME_FP (fid) != inf_status->selected_frame_address ||
|
||||
|
||||
if (fid == 0 ||
|
||||
FRAME_FP (fid) != inf_status->selected_frame_address ||
|
||||
level != 0)
|
||||
{
|
||||
/* I'm not sure this error message is a good idea. I have
|
||||
only seen it occur after "Can't continue previously
|
||||
requested operation" (we get called from do_cleanups), in
|
||||
which case it just adds insult to injury (one confusing
|
||||
error message after another. Besides which, does the
|
||||
user really care if we can't restore the previously
|
||||
selected frame? */
|
||||
fprintf (stderr, "Unable to restore previously selected frame.\n");
|
||||
select_frame (get_current_frame (), 0);
|
||||
return;
|
||||
|
@ -18,6 +18,7 @@ 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"
|
||||
@ -27,7 +28,6 @@ anyone else from sharing it farther. Help stamp out software hoarding!
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <signal.h>
|
||||
@ -568,10 +568,12 @@ exec_file_command (filename, from_tty)
|
||||
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)
|
||||
if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read text section header", execfile);
|
||||
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read data section header", execfile);
|
||||
|
||||
text_start = exec_aouthdr.text_start;
|
||||
|
@ -35,7 +35,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Get rid of any system-imposed stack limit if possible. */
|
||||
|
||||
/* #define SET_STACK_LIMIT_HUGE */
|
||||
#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. */
|
||||
@ -56,17 +56,12 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define BELIEVE_PCC_PROMOTION 1
|
||||
|
||||
/* Symbol types to ignore. */
|
||||
|
||||
#if defined (N_MONPT)
|
||||
/* 0xc4 is N_MONPT. Use the numeric value for the benefit of people
|
||||
with (rather) old OS's. */
|
||||
#define IGNORE_SYMBOL(TYPE) \
|
||||
(((TYPE) & ~N_EXT) == N_TBSS \
|
||||
|| ((TYPE) & ~N_EXT) == N_TDATA \
|
||||
|| ((TYPE) & ~N_EXT) == N_MONPT)
|
||||
#else /* no N_MONPT */
|
||||
#define IGNORE_SYMBOL(TYPE) \
|
||||
(((TYPE) & ~N_EXT) == N_TBSS \
|
||||
|| ((TYPE) & ~N_EXT) == N_TDATA)
|
||||
#endif /* no N_MONPT */
|
||||
|| ((TYPE) & ~N_EXT) == 0xc4)
|
||||
|
||||
/* Use SIGCONT rather than SIGTSTP because convex Unix occasionally
|
||||
turkeys SIGTSTP. I think. */
|
||||
@ -341,10 +336,13 @@ extern struct value *value_of_trapped_internalvar ();
|
||||
|
||||
#define PRINT_TYPELESS_INTEGER decout
|
||||
|
||||
/* Specify that variables for a particular lexical context are listed
|
||||
after the beginning LBRAC instead of before in the executables list
|
||||
of symbols. */
|
||||
#define VARIABLES_INSIDE_BLOCK
|
||||
/* For the native compiler, variables for a particular lexical context
|
||||
are listed after the beginning LBRAC instead of before in the
|
||||
executables list of symbols. Using "gcc_compiled." to distinguish
|
||||
between GCC and native compiler doesn't work on Convex because the
|
||||
linker sorts the symbols to put "gcc_compiled." in the wrong place.
|
||||
desc is nonzero for native, zero for gcc. */
|
||||
#define VARIABLES_INSIDE_BLOCK(desc) (desc != 0)
|
||||
|
||||
/* Pcc occaisionally puts an SO where there should be an SOL. */
|
||||
#define PCC_SOL_BROKEN
|
||||
|
@ -76,7 +76,18 @@ 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. */
|
||||
|
||||
#define KERNEL_U_ADDR 0x00917000
|
||||
#define KERNEL_U_ADDR kernel_u_addr
|
||||
|
||||
/* Same as offsetof macro from stddef.h (which 4.3BSD doesn't have). */
|
||||
#define my_offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER)
|
||||
|
||||
/* On the HP300, sigtramp is in the u area. Gak! User struct is not
|
||||
mapped to the same virtual address in user/kernel address space
|
||||
(hence STACK_END_ADDR as opposed to KERNEL_U_ADDR). */
|
||||
#define IN_SIGTRAMP(pc, name) \
|
||||
((pc) >= STACK_END_ADDR + my_offsetof (struct user, u_pcb.pcb_sigc[0]) \
|
||||
&& (pc) < STACK_END_ADDR + my_offsetof (struct user, u_pcb.pcb_sigc[12]) \
|
||||
)
|
||||
|
||||
/* Address of end of stack space. */
|
||||
|
||||
|
@ -258,6 +258,10 @@ read_memory_integer (read_register (SP_REGNUM), 4)
|
||||
: (&u.u_pcb.pcb_mc68881[FMC68881_C + ((regno) - FPC_REGNUM)]))) \
|
||||
- ((char *) (& u)))
|
||||
|
||||
/* Do implement the attach and detach commands. */
|
||||
|
||||
#define ATTACH_DETACH
|
||||
|
||||
/* Describe the pointer in each stack frame to the previous stack frame
|
||||
(its caller). */
|
||||
|
||||
|
13
gdb/m-i386.h
13
gdb/m-i386.h
@ -32,6 +32,19 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define i386
|
||||
#endif
|
||||
|
||||
/* I'm running gdb 3.4 under 386/ix 2.0.2, which is a derivative of AT&T's
|
||||
Sys V/386 3.2.
|
||||
|
||||
On some machines, gdb crashes when it's starting up while calling the
|
||||
vendor's termio tgetent() routine. It always works when run under
|
||||
itself (actually, under 3.2, it's not an infinitely recursive bug.)
|
||||
After some poking around, it appears that depending on the environment
|
||||
size, or whether you're running YP, or the phase of the moon or something,
|
||||
the stack is not always long-aligned when main() is called, and tgetent()
|
||||
takes strong offense at that. On some machines this bug never appears, but
|
||||
on those where it does, it occurs quite reliably. */
|
||||
#define ALIGN_STACK_ON_STARTUP
|
||||
|
||||
/* define USG if you are using sys5 /usr/include's */
|
||||
#define USG
|
||||
|
||||
|
@ -21,6 +21,14 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define ns16000
|
||||
#endif
|
||||
|
||||
/* This machine doesn't have the siginterrupt call. */
|
||||
#define NO_SIGINTERRUPT
|
||||
|
||||
/* Under Utek, a ptrace'd process can be the only active process for
|
||||
an executable. Therefore instead of /bin/sh use gdb-sh (which should
|
||||
just be a copy of /bin/sh which is world readable and writeable). */
|
||||
#define SHELL_FILE "/usr/local/lib/gdb-sh"
|
||||
|
||||
/* Define the bit, byte, and word ordering of the machine. */
|
||||
/* #define BITS_BIG_ENDIAN */
|
||||
/* #define BYTES_BIG_ENDIAN */
|
||||
|
612
gdb/m-pyr.h
Normal file
612
gdb/m-pyr.h
Normal file
@ -0,0 +1,612 @@
|
||||
/* Definitions to make GDB run on a Pyramidax under OSx 4.0 (4.2bsd).
|
||||
Copyright (C) 1988, 1989 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
GDB is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GDB is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* The FSF prefers to define "pyramid on Pyramid 90x machines; the
|
||||
manufacturer insists on "pyr". Define both. */
|
||||
|
||||
#ifndef pyr
|
||||
#define pyr
|
||||
#endif
|
||||
|
||||
#ifndef pyramid
|
||||
#define pyramid
|
||||
#endif
|
||||
|
||||
/* Define PYRAMID_CONTROL_FRAME_DEBUGGING to get copious messages
|
||||
about reading the control stack on standard output. This
|
||||
makes gdb unusable as a debugger. */
|
||||
|
||||
/* #define PYRAMID_CONTROL_FRAME_DEBUGGING */
|
||||
|
||||
/* Define PYRAMID_FRAME_DEBUGGING
|
||||
/* use Pyramid's slightly strange ptrace */
|
||||
#define PYRAMID_PTRACE
|
||||
|
||||
/* Traditional Unix virtual address spaces have thre regions: text,
|
||||
data and stack. The text, initialised data, and uninitialised data
|
||||
are represented in separate segments of the a.out file.
|
||||
When a process dumps core, the data and stack regions are written
|
||||
to a core file. This gives a debugger enough information to
|
||||
reconstruct (and debug) the virtual address space at the time of
|
||||
the coredump.
|
||||
Pyramids have an distinct fourth region of the virtual address
|
||||
space, in which the contents of the windowed registers are stacked
|
||||
in fixed-size frames. Pyramid refer to this region as the control
|
||||
stack. Each call (or trap) automatically allocates a new register
|
||||
frame; each return deallocates the current frame and restores the
|
||||
windowed registers to their values before the call.
|
||||
|
||||
When dumping core, the control stack is written to a core files as
|
||||
a third segment. The core-handling functions need to know to deal
|
||||
with it. */
|
||||
/* Tell core.c there is an extra segment. */
|
||||
#define REG_STACK_SEGMENT
|
||||
/* Tell dep.c what the extra segment is. */
|
||||
#define PYRAMID_CORE
|
||||
|
||||
/* Define the bit, byte, and word ordering of the machine. */
|
||||
#define BITS_BIG_ENDIAN
|
||||
#define BYTES_BIG_ENDIAN
|
||||
#define WORDS_BIG_ENDIAN
|
||||
|
||||
/* Floating point is IEEE compatible on most Pyramid hardware
|
||||
(Older processors do not have IEEE NaNs). */
|
||||
#define IEEE_FLOAT
|
||||
|
||||
#define NO_SIGINTERRUPT
|
||||
|
||||
#define HAVE_WAIT_STRUCT
|
||||
|
||||
/* 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. */
|
||||
|
||||
/* FIXME -- do we want to skip insns to allocate the local frame?
|
||||
If so, what do they look like?
|
||||
This is becoming harder, since tege@sics.SE wants to change
|
||||
gcc to not output a prologue when no frame is needed. */
|
||||
#define SKIP_PROLOGUE(pc) do {} while (0)
|
||||
|
||||
|
||||
/* Immediately after a function call, return the saved pc.
|
||||
Can't always 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) FRAME_SAVED_PC(frame)
|
||||
|
||||
/* This is the amount to subtract from u.u_ar0
|
||||
to get the offset in the core file of the register values. */
|
||||
|
||||
#define KERNEL_U_ADDR (0x80000000 - (UPAGES * NBPG))
|
||||
|
||||
/* Address of end of stack space. */
|
||||
/* This seems to be right for the 90x comp.vuw.ac.nz.
|
||||
The correct value at any site may be a function of the configured
|
||||
maximum control stack depth. If so, I don't know where the
|
||||
control-stack depth is configured, so I can't #include it here. */
|
||||
#define STACK_END_ADDR (0xc00cc000)
|
||||
|
||||
/* Register window stack (Control stack) stack definitions
|
||||
- Address of beginning of control stack.
|
||||
- size of control stack frame
|
||||
(Note that since crts0 is usually the first function called,
|
||||
main()'s control stack is one frame (0x80 bytes) beyond this value. */
|
||||
|
||||
#define CONTROL_STACK_ADDR (0xc00cd000)
|
||||
|
||||
/* Bytes in a register window -- 16 parameter regs, 16 local regs
|
||||
for each call, is 32 regs * 4 bytes */
|
||||
|
||||
#define CONTROL_STACK_FRAME_SIZE (32*4)
|
||||
|
||||
/* FIXME. On a pyr, Data Stack grows downward; control stack goes upwards.
|
||||
Which direction should we use for INNER_THAN, PC_INNER_THAN ?? */
|
||||
|
||||
#define INNER_THAN <
|
||||
#define PC_INNER_THAN >
|
||||
|
||||
/* Stack has strict alignment. */
|
||||
|
||||
#define STACK_ALIGN(ADDR) (((ADDR)+3)&-4)
|
||||
|
||||
/* Sequence of bytes for breakpoint instruction. */
|
||||
|
||||
#define BREAKPOINT {0xf0, 00, 00, 00}
|
||||
|
||||
/* 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.
|
||||
On a pyr, this is either "ret" or "retd".
|
||||
It would be friendly to check that any "retd" always had an
|
||||
argument of 0, since anything else is invalid. */
|
||||
|
||||
#define ABOUT_TO_RETURN(pc) \
|
||||
(((read_memory_integer (pc, 2) & 0x3ff0) == 0x3090) || \
|
||||
((read_memory_integer (pc, 2) & 0x0ff0) == 0x00a0))
|
||||
|
||||
/* Return 1 if P points to an invalid floating point value.
|
||||
LEN is the length in bytes -- not relevant on the Vax. */
|
||||
/* FIXME -- this is ok for a vax, bad for big-endian ieee format.
|
||||
I would use the definition for a Sun; but it is no better! */
|
||||
|
||||
#define INVALID_FLOAT(p, len) ((*(short *) p & 0xff80) == 0x8000)
|
||||
|
||||
/* Larges 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 */
|
||||
/* pyramids have 64, plus one for the PSW; plus perhaps one more for the
|
||||
kernel stack pointer (ksp) and control-stack pointer (CSP) */
|
||||
|
||||
#define NUM_REGS 67
|
||||
|
||||
/* Initializer for an array of names of registers.
|
||||
There should be NUM_REGS strings in this initializer. */
|
||||
|
||||
#define REGISTER_NAMES \
|
||||
{"gr0", "gr1", "gr2", "gr3", "gr4", "gr5", "gr6", "gr7", \
|
||||
"gr8", "gr9", "gr10", "gr11", "logpsw", "cfp", "sp", "pc", \
|
||||
"pr0", "pr1", "pr2", "pr3", "pr4", "pr5", "pr6", "pr7", \
|
||||
"pr8", "pr9", "pr10", "pr11", "pr12", "pr13", "pr14", "pr15", \
|
||||
"lr0", "lr1", "lr2", "lr3", "lr4", "lr5", "lr6", "lr7", \
|
||||
"lr8", "lr9", "lr10", "lr11", "lr12", "lr13", "lr14", "lr15", \
|
||||
"tr0", "tr1", "tr2", "tr3", "tr4", "tr5", "tr6", "tr7", \
|
||||
"tr8", "tr9", "tr10", "tr11", "tr12", "tr13", "tr14", "tr15", \
|
||||
"psw", "ksp", "csp"}
|
||||
|
||||
/* 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. */
|
||||
|
||||
/* pseudo-registers: */
|
||||
#define PS_REGNUM 64 /* Contains processor status */
|
||||
#define PSW_REGNUM 64 /* Contains current psw, whatever it is.*/
|
||||
#define CSP_REGNUM 65 /* address of this control stack frame*/
|
||||
#define KSP_REGNUM 66 /* Contains process's Kernel Stack Pointer */
|
||||
|
||||
#define CFP_REGNUM 13 /* Current data-stack frame ptr */
|
||||
#define TR0_REGNUM 48 /* After function call, contains
|
||||
function result */
|
||||
|
||||
/* Registers interesting to the machine-independent part of gdb*/
|
||||
|
||||
#define FP_REGNUM CSP_REGNUM /* Contains address of executing (control)
|
||||
stack frame */
|
||||
#define SP_REGNUM 14 /* Contains address of top of stack -??*/
|
||||
#define PC_REGNUM 15 /* Contains program counter */
|
||||
|
||||
/* Define DO_REGISTERS_INFO() to do machine-specific formatting
|
||||
of register dumps. */
|
||||
|
||||
#define DO_REGISTERS_INFO(_regnum) pyr_do_registers_info(_regnum)
|
||||
|
||||
/* need this so we can find the global registers: they never get saved. */
|
||||
extern unsigned int global_reg_offset;
|
||||
extern unsigned int last_frame_offset;
|
||||
extern unsigned int reg_stack_start;
|
||||
extern unsigned int reg_stack_end;
|
||||
extern unsigned int reg_stack_offset;
|
||||
|
||||
|
||||
/* Define offsets of registers in the core file (or maybe u area) */
|
||||
#define REGISTER_U_ADDR(addr, blockend, regno) \
|
||||
{ struct user __u; \
|
||||
addr = blockend + (regno - 16 ) * 4; \
|
||||
if (regno == 67) { \
|
||||
printf("\\geting reg 67\\"); \
|
||||
addr = (int)(&__u.u_pcb.pcb_csp) - (int) &__u; \
|
||||
} else if (regno == KSP_REGNUM) { \
|
||||
printf("\\geting KSP (reg %d)\\", KSP_REGNUM); \
|
||||
addr = (int)(&__u.u_pcb.pcb_ksp) - (int) &__u; \
|
||||
} else if (regno == CSP_REGNUM) { \
|
||||
printf("\\geting CSP (reg %d\\",CSP_REGNUM); \
|
||||
addr = (int)(&__u.u_pcb.pcb_csp) - (int) &__u; \
|
||||
} else if (regno == 64) { \
|
||||
printf("\\geting reg 64\\"); \
|
||||
addr = (int)(&__u.u_pcb.pcb_csp) - (int) &__u; \
|
||||
} else if (regno == PS_REGNUM) \
|
||||
addr = blockend - 4; \
|
||||
else if (1 && ((16 > regno) && (regno > 11))) \
|
||||
addr = last_frame_offset + (4 *(regno+32)); \
|
||||
else if (0 && (12 > regno)) \
|
||||
addr = global_reg_offset + (4 *regno); \
|
||||
else if (16 > regno) \
|
||||
addr = global_reg_offset + (4 *regno); \
|
||||
else \
|
||||
addr = blockend + (regno - 16 ) * 4; \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Total amount of space needed to store our copies of the machine's
|
||||
register state, the array `registers'. */
|
||||
#define REGISTER_BYTES (NUM_REGS*4)
|
||||
|
||||
/* the Pyramid 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) >= 16 && (regnum) < 64)
|
||||
|
||||
/* Index within `registers' of the first byte of the space for
|
||||
register N. */
|
||||
|
||||
#define REGISTER_BYTE(N) ((N) * 4)
|
||||
|
||||
/* Number of bytes of storage in the actual machine representation
|
||||
for register N. On the Pyramid, 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 Pyramid, all regs are 4 bytes. */
|
||||
|
||||
#define REGISTER_VIRTUAL_SIZE(N) 4
|
||||
|
||||
/* Largest value REGISTER_RAW_SIZE can have. */
|
||||
|
||||
#define MAX_REGISTER_RAW_SIZE 4
|
||||
|
||||
/* Largest value REGISTER_VIRTUAL_SIZE can have. */
|
||||
|
||||
#define MAX_REGISTER_VIRTUAL_SIZE 4
|
||||
|
||||
/* 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) builtin_type_int
|
||||
|
||||
/* FIXME: It seems impossible for both EXTRACT_RETURN_VALUE and
|
||||
STORE_RETURN_VALUE to be correct. */
|
||||
|
||||
/* Store the address of the place in which to copy the structure the
|
||||
subroutine will return. This is called from call_function. */
|
||||
|
||||
/****FIXME****/
|
||||
#define STORE_STRUCT_RETURN(ADDR, SP) \
|
||||
{ write_register (TR0_REGNUM, (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. */
|
||||
|
||||
/* Note that on a register-windowing machine (eg, Pyr, SPARC), this is
|
||||
where the value is found after the function call -- ie, it should
|
||||
correspond to GNU CC's FUNCTION_VALUE rather than FUNCTION_OUTGOING_VALUE.*/
|
||||
|
||||
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
|
||||
bcopy (((int *)(REGBUF))+TR0_REGNUM, VALBUF, TYPE_LENGTH (TYPE))
|
||||
|
||||
/* Write into appropriate registers a function return value
|
||||
of type TYPE, given in virtual format. */
|
||||
/* on pyrs, values are returned in */
|
||||
|
||||
#define STORE_RETURN_VALUE(TYPE,VALBUF) \
|
||||
write_register_bytes (REGISTER_BYTE(TR0_REGNUM), 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). */
|
||||
/* FIXME */
|
||||
#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) \
|
||||
( ((int *)(REGBUF)) [TR0_REGNUM])
|
||||
|
||||
/* Compensate for lack of `vprintf' function. */
|
||||
#define vprintf(format, ap) _doprnt (format, ap, stdout)
|
||||
|
||||
/* Describe the pointer in each stack frame to the previous stack frame
|
||||
(its caller). */
|
||||
|
||||
#define EXTRA_FRAME_INFO \
|
||||
FRAME_ADDR bottom; \
|
||||
CORE_ADDR frame_cfp; \
|
||||
CORE_ADDR frame_window_addr;
|
||||
|
||||
#define INIT_EXTRA_FRAME_INFO(fci) \
|
||||
do { \
|
||||
(fci)->frame_window_addr = (fci)->frame; \
|
||||
(fci)->bottom = \
|
||||
((fci)->next ? \
|
||||
((fci)->frame == (fci)->next_frame ? \
|
||||
(fci)->next->bottom : (fci)->next->frame) : \
|
||||
read_register (SP_REGNUM)); \
|
||||
(fci)->frame_cfp = \
|
||||
read_register (CFP_REGNUM); \
|
||||
/***fprintf (stderr, \
|
||||
"[[creating new frame for %0x,pc=%0x,csp=%0x]]\n", \
|
||||
(fci)->frame, (fci)->pc,(fci)->frame_cfp);*/ \
|
||||
} while (0);
|
||||
|
||||
/* 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 pyr, the frame's nominal address is the address
|
||||
of parameter register 0. The previous frame is found 32 words up. */
|
||||
|
||||
#define FRAME_CHAIN(thisframe) \
|
||||
( (thisframe) -> frame - CONTROL_STACK_FRAME_SIZE)
|
||||
|
||||
#define FRAME_CHAIN_VALID(chain, thisframe) \
|
||||
(chain != 0 && (outside_startup_file (FRAME_SAVED_PC (thisframe))))
|
||||
|
||||
/*((thisframe) >= CONTROL_STACK_ADDR))*/
|
||||
|
||||
#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain)
|
||||
|
||||
/* Define other aspects of the stack frame. */
|
||||
|
||||
/* A macro that tells us whether the function invocation represented
|
||||
by FI does not have a frame on the stack associated with it. If it
|
||||
does not, FRAMELESS is set to 1, else 0.
|
||||
|
||||
I do not understand what this means on a Pyramid, where functions
|
||||
*always* have a control-stack frame, but may or may not have a
|
||||
frame on the data stack. Since GBD uses the value of the
|
||||
control stack pointer as its "address" of a frame, FRAMELESS
|
||||
is always 1, so does not need to be defined. */
|
||||
|
||||
|
||||
/* Where is the PC for a specific frame */
|
||||
|
||||
#define FRAME_SAVED_PC(fi) \
|
||||
((CORE_ADDR) (read_memory_integer ( (fi) -> frame + 60, 4)))
|
||||
|
||||
/* There may be bugs in FRAME_ARGS_ADDRESS and FRAME_LOCALS_ADDRESS;
|
||||
or there may be bugs in accessing the registers that break
|
||||
their definitions.
|
||||
Having the macros expand into functions makes them easier to debug.
|
||||
When the bug is finally located, the inline macro defintions can
|
||||
be un-#if 0ed, and frame_args_addr and frame_locals_address can
|
||||
be deleted from pyr-dep.c */
|
||||
|
||||
/* If the argument is on the stack, it will be here. */
|
||||
#define FRAME_ARGS_ADDRESS(fi) \
|
||||
frame_args_addr(fi)
|
||||
|
||||
#define FRAME_LOCALS_ADDRESS(fi) \
|
||||
frame_locals_address(fi)
|
||||
|
||||
/* The following definitions doesn't seem to work.
|
||||
I don't understand why. */
|
||||
#if 0
|
||||
#define FRAME_ARGS_ADDRESS(fi) \
|
||||
/*(FRAME_FP(fi) + (13*4))*/ (read_register (CFP_REGNUM))
|
||||
|
||||
#define FRAME_LOCALS_ADDRESS(fi) \
|
||||
((fi)->frame +(16*4))
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
/* Return number of args passed to a frame.
|
||||
Can return -1, meaning no way to tell. */
|
||||
|
||||
#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 0
|
||||
|
||||
/* 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 pyrs, frames of window registers are stored contiguously on a
|
||||
separate stack. All window registers are always stored.
|
||||
The pc and psw (gr15 and gr14) are also always saved: the call
|
||||
insn saves them in pr15 and pr14 of the new frame (tr15,tr14 of the
|
||||
old frame).
|
||||
The data-stack frame pointer (CFP) is only saved in functions which
|
||||
allocate a (data)stack frame (with "adsf"). We detect them by
|
||||
looking at the first insn of the procedure.
|
||||
|
||||
Other non-window registers (gr0-gr11) are never saved. Pyramid's C
|
||||
compiler and gcc currently ignore them, so it's not an issue. */
|
||||
|
||||
#define FRAME_FIND_SAVED_REGS(fi_p, frame_saved_regs) \
|
||||
{ register int regnum; \
|
||||
register CORE_ADDR pc; \
|
||||
register CORE_ADDR fn_start_pc; \
|
||||
register int first_insn; \
|
||||
register CORE_ADDR prev_cf_addr; \
|
||||
register int window_ptr; \
|
||||
FRAME fid = FRAME_INFO_ID (fi_p); \
|
||||
if (!fid) fatal ("Bad frame info struct in FRAME_FIND_SAVED_REGS"); \
|
||||
bzero (&(frame_saved_regs), sizeof (frame_saved_regs)); \
|
||||
\
|
||||
window_ptr = prev_cf_addr = FRAME_FP(fi_p); \
|
||||
\
|
||||
for (regnum = 16 ; regnum < 64; regnum++,window_ptr+=4) \
|
||||
{ \
|
||||
(frame_saved_regs).regs[regnum] = window_ptr; \
|
||||
} \
|
||||
\
|
||||
/* In each window, psw, and pc are "saved" in tr14,tr15. */ \
|
||||
/*** psw is sometimes saved in gr12 (so sez <sys/pcb.h>) */ \
|
||||
(frame_saved_regs).regs[PS_REGNUM] = FRAME_FP(fi_p) + (14*4); \
|
||||
\
|
||||
/*(frame_saved_regs).regs[PC_REGNUM] = (frame_saved_regs).regs[31];*/ \
|
||||
(frame_saved_regs).regs[PC_REGNUM] = FRAME_FP(fi_p) + ((15+32)*4); \
|
||||
\
|
||||
/* Functions that allocate a frame save sp *where*? */ \
|
||||
/*first_insn = read_memory_integer (get_pc_function_start ((fi_p)->pc),4); */ \
|
||||
\
|
||||
fn_start_pc = (get_pc_function_start ((fi_p)->pc)); \
|
||||
first_insn = read_memory_integer(fn_start_pc, 4); \
|
||||
\
|
||||
if (0x08 == ((first_insn >> 20) &0x0ff)) { \
|
||||
/* NB: because WINDOW_REGISTER_P(cfp) is false, a saved cfp \
|
||||
in this frame is only visible in this frame's callers. \
|
||||
That means the cfp we mark saved is my caller's cfp, ie pr13. \
|
||||
I don't understand why we don't have to do that for pc, too. */ \
|
||||
\
|
||||
(frame_saved_regs).regs[CFP_REGNUM] = FRAME_FP(fi_p)+(13*4); \
|
||||
\
|
||||
(frame_saved_regs).regs[SP_REGNUM] = \
|
||||
read_memory_integer (FRAME_FP(fi_p)+((13+32)*4),4); \
|
||||
} \
|
||||
\
|
||||
/* \
|
||||
*(frame_saved_regs).regs[CFP_REGNUM] = (frame_saved_regs).regs[61]; \
|
||||
* (frame_saved_regs).regs[SP_REGNUM] = \
|
||||
* read_memory_integer (FRAME_FP(fi_p)+((13+32)*4),4); \
|
||||
*/ \
|
||||
\
|
||||
(frame_saved_regs).regs[CSP_REGNUM] = prev_cf_addr; \
|
||||
}
|
||||
|
||||
/* Things needed for making the inferior call functions. */
|
||||
|
||||
/* These are all lies. These macro definitions are appropriate for a
|
||||
SPARC. On a pyramid, pushing a dummy frame will
|
||||
surely involve writing the control stack pointer,
|
||||
then saving the pc. This requires a privileged instruction.
|
||||
Maybe one day Pyramid can be persuaded to add a syscall to do this.
|
||||
Until then, we are out of luck. */
|
||||
|
||||
/* 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; \
|
||||
sp = push_word (sp, 0); /* arglist */ \
|
||||
for (regnum = 11; regnum >= 0; regnum--) \
|
||||
sp = push_word (sp, read_register (regnum)); \
|
||||
sp = push_word (sp, read_register (PC_REGNUM)); \
|
||||
sp = push_word (sp, read_register (FP_REGNUM)); \
|
||||
/* sp = push_word (sp, read_register (AP_REGNUM));*/ \
|
||||
sp = push_word (sp, (read_register (PS_REGNUM) & 0xffef) \
|
||||
+ 0x2fff0000); \
|
||||
sp = push_word (sp, 0); \
|
||||
write_register (SP_REGNUM, sp); \
|
||||
write_register (FP_REGNUM, sp); \
|
||||
/* write_register (AP_REGNUM, sp + 17 * sizeof (int));*/ }
|
||||
|
||||
/* Discard from the stack the innermost frame, restoring all registers. */
|
||||
|
||||
#define POP_FRAME \
|
||||
{ register CORE_ADDR fp = read_register (FP_REGNUM); \
|
||||
register int regnum; \
|
||||
register int regmask = read_memory_integer (fp + 4, 4); \
|
||||
write_register (PS_REGNUM, \
|
||||
(regmask & 0xffff) \
|
||||
| (read_register (PS_REGNUM) & 0xffff0000)); \
|
||||
write_register (PC_REGNUM, read_memory_integer (fp + 16, 4)); \
|
||||
write_register (FP_REGNUM, read_memory_integer (fp + 12, 4)); \
|
||||
/* write_register (AP_REGNUM, read_memory_integer (fp + 8, 4));*/ \
|
||||
fp += 16; \
|
||||
for (regnum = 0; regnum < 12; regnum++) \
|
||||
if (regmask & (0x10000 << regnum)) \
|
||||
write_register (regnum, read_memory_integer (fp += 4, 4)); \
|
||||
fp = fp + 4 + ((regmask >> 30) & 3); \
|
||||
if (regmask & 0x20000000) \
|
||||
{ regnum = read_memory_integer (fp, 4); \
|
||||
fp += (regnum + 1) * 4; } \
|
||||
write_register (SP_REGNUM, fp); \
|
||||
set_current_frame (read_register (FP_REGNUM)); }
|
||||
|
||||
/* This sequence of words is the instructions
|
||||
calls #69, @#32323232
|
||||
bpt
|
||||
Note this is 8 bytes. */
|
||||
|
||||
#define CALL_DUMMY {0x329f69fb, 0x03323232}
|
||||
|
||||
#define CALL_DUMMY_START_OFFSET 0 /* Start execution at beginning of dummy */
|
||||
|
||||
/* 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) \
|
||||
{ *((char *) dummyname + 1) = nargs; \
|
||||
*(int *)((char *) dummyname + 3) = fun; }
|
||||
|
||||
/* Interface definitions for kernel debugger KDB. */
|
||||
|
||||
/* I have *no idea* how to debug OSx kernels, so this
|
||||
is flushed, possible forever. */
|
@ -42,6 +42,18 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#define READ_DBX_FORMAT
|
||||
|
||||
/* When passing a structure to a function, Sun cc passes the address
|
||||
in a register, not the structure itself. It (under SunOS4) creates
|
||||
two symbols, so we get a LOC_ARG saying the address is on the stack
|
||||
(a lie, and a serious one since we don't know which register to
|
||||
use), and a LOC_REGISTER saying that the struct is in a register
|
||||
(sort of a lie, but fixable with REG_STRUCT_HAS_ADDR).
|
||||
|
||||
This still doesn't work if the argument is not one passed in a
|
||||
register (i.e. it's the 7th or later argument). */
|
||||
#define REG_STRUCT_HAS_ADDR(gcc_p) (!gcc_p)
|
||||
#define STRUCT_ARG_SYM_GARBAGE(gcc_p) (!gcc_p)
|
||||
|
||||
/* If Pcc says that a parameter is a short, it's a short. This is
|
||||
because the parameter does get passed in in a register as an int,
|
||||
but pcc puts it onto the stack frame as a short (not nailing
|
||||
@ -240,14 +252,31 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
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))
|
||||
#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \
|
||||
{ \
|
||||
if (TYPE_CODE (TYPE) == TYPE_CODE_FLT) \
|
||||
{ \
|
||||
bcopy (((int *)(REGBUF))+FP0_REGNUM, \
|
||||
(VALBUF), TYPE_LENGTH(TYPE)); \
|
||||
} \
|
||||
else \
|
||||
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))
|
||||
{ \
|
||||
if (TYPE_CODE (TYPE) = TYPE_CODE_FLT) \
|
||||
/* Floating-point values are returned in the register pair */ \
|
||||
/* formed by %f0 and %f1 (doubles are, anyway). */ \
|
||||
write_register_bytes (REGISTER_BYTE (FP0_REGNUM), (VALBUF), \
|
||||
TYPE_LENGTH (TYPE)); \
|
||||
else \
|
||||
/* Other values are returned in register %o0. */ \
|
||||
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,
|
||||
|
@ -22,6 +22,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#define FPU
|
||||
|
||||
/* There is a bug which can cause alloca to fail to allocate large
|
||||
areas of memory one time in every 4096 (we think). Hard to reproduce
|
||||
so it will be hard to detect when this bug is fixed. */
|
||||
areas of memory one time in every 4096 (we think). */
|
||||
/* chase@orc.olivetti.com says that 4 megabyte alloca's consistently fail,
|
||||
even though the stack limit (SET_STACK_LIMIT_HUGE) has been set
|
||||
to 250 megabytes. */
|
||||
#define BROKEN_LARGE_ALLOCA
|
||||
|
@ -1088,38 +1088,41 @@ struct m68k_opcode m68k_opcodes[] =
|
||||
{"fscalex", two(0xF000, 0x4826), two(0xF1C0, 0xFC7F), "Ii;xF7"},
|
||||
/* {"fscalex", two(0xF000, 0x0026), two(0xF1C0, 0xE07F), "IiFt"}, JF */
|
||||
|
||||
{"fseq", two(0xF040, 0x0001), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsf", two(0xF040, 0x0000), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsge", two(0xF040, 0x0013), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsgl", two(0xF040, 0x0016), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsgle", two(0xF040, 0x0017), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsgt", two(0xF040, 0x0012), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsle", two(0xF040, 0x0015), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fslt", two(0xF040, 0x0014), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsne", two(0xF040, 0x000E), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsnge", two(0xF040, 0x001C), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsngl", two(0xF040, 0x0019), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsngle", two(0xF040, 0x0018), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsngt", two(0xF040, 0x001D), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsnle", two(0xF040, 0x001A), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsnlt", two(0xF040, 0x001B), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsoge", two(0xF040, 0x0003), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsogl", two(0xF040, 0x0006), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsogt", two(0xF040, 0x0002), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsole", two(0xF040, 0x0005), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsolt", two(0xF040, 0x0004), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsor", two(0xF040, 0x0007), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsseq", two(0xF040, 0x0011), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fssf", two(0xF040, 0x0010), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fssne", two(0xF040, 0x001E), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsst", two(0xF040, 0x001F), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fst", two(0xF040, 0x000F), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsueq", two(0xF040, 0x0009), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsuge", two(0xF040, 0x000B), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsugt", two(0xF040, 0x000A), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsule", two(0xF040, 0x000D), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsult", two(0xF040, 0x000C), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
{"fsun", two(0xF040, 0x0008), two(0xF1C0, 0xFFFF), "Ii@s"},
|
||||
/* $ is necessary to prevent the assembler from using PC-relative.
|
||||
If @ were used, "label: fseq label" could produce "ftrapeq",
|
||||
because "label" became "pc@label". */
|
||||
{"fseq", two(0xF040, 0x0001), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsf", two(0xF040, 0x0000), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsge", two(0xF040, 0x0013), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsgl", two(0xF040, 0x0016), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsgle", two(0xF040, 0x0017), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsgt", two(0xF040, 0x0012), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsle", two(0xF040, 0x0015), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fslt", two(0xF040, 0x0014), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsne", two(0xF040, 0x000E), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsnge", two(0xF040, 0x001C), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsngl", two(0xF040, 0x0019), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsngle", two(0xF040, 0x0018), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsngt", two(0xF040, 0x001D), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsnle", two(0xF040, 0x001A), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsnlt", two(0xF040, 0x001B), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsoge", two(0xF040, 0x0003), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsogl", two(0xF040, 0x0006), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsogt", two(0xF040, 0x0002), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsole", two(0xF040, 0x0005), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsolt", two(0xF040, 0x0004), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsor", two(0xF040, 0x0007), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsseq", two(0xF040, 0x0011), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fssf", two(0xF040, 0x0010), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fssne", two(0xF040, 0x001E), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsst", two(0xF040, 0x001F), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fst", two(0xF040, 0x000F), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsueq", two(0xF040, 0x0009), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsuge", two(0xF040, 0x000B), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsugt", two(0xF040, 0x000A), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsule", two(0xF040, 0x000D), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsult", two(0xF040, 0x000C), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
{"fsun", two(0xF040, 0x0008), two(0xF1C0, 0xFFFF), "Ii$s"},
|
||||
|
||||
{"fsgldivb", two(0xF000, 0x5824), two(0xF1C0, 0xFC7F), "Ii;bF7"},
|
||||
{"fsgldivd", two(0xF000, 0x5424), two(0xF1C0, 0xFC7F), "Ii;FF7"},
|
||||
|
@ -795,28 +795,31 @@ convert_from_68881 (from, to)
|
||||
*to = 0.0;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef HPUX_ASM
|
||||
asm ("mov.l 8(%a6),%a0");
|
||||
asm ("mov.l 12(%a6),%a1");
|
||||
asm ("fmove.x (%a0),%fp0");
|
||||
asm ("fmove.d %fp0,(%a1)");
|
||||
asm ("mov.l 8(%a6),%a0");
|
||||
asm ("mov.l 12(%a6),%a1");
|
||||
asm ("fmove.x (%a0),%fp0");
|
||||
asm ("fmove.d %fp0,(%a1)");
|
||||
#else /* not HPUX_ASM */
|
||||
#if 0
|
||||
asm ("movl a6@(8),a0");
|
||||
asm ("movl a6@(12),a1");
|
||||
asm ("fmovex a0@,fp0");
|
||||
asm ("fmoved fp0,a1@");
|
||||
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");
|
||||
/* 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 HPUX_ASM */
|
||||
}
|
||||
}
|
||||
|
||||
/* The converse: convert the double *FROM to an extended float
|
||||
@ -828,27 +831,30 @@ convert_to_68881 (from, to)
|
||||
{
|
||||
if (!have_fpu)
|
||||
return;
|
||||
else
|
||||
{
|
||||
#ifdef HPUX_ASM
|
||||
asm ("mov.l 8(%a6),%a0");
|
||||
asm ("mov.l 12(%a6),%a1");
|
||||
asm ("fmove.d (%a0),%fp0");
|
||||
asm ("fmove.x %fp0,(%a1)");
|
||||
asm ("mov.l 8(%a6),%a0");
|
||||
asm ("mov.l 12(%a6),%a1");
|
||||
asm ("fmove.d (%a0),%fp0");
|
||||
asm ("fmove.x %fp0,(%a1)");
|
||||
#else /* not HPUX_ASM */
|
||||
#if 0
|
||||
asm ("movl a6@(8),a0");
|
||||
asm ("movl a6@(12),a1");
|
||||
asm ("fmoved a0@,fp0");
|
||||
asm ("fmovex fp0,a1@");
|
||||
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");
|
||||
/* 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 HPUX_ASM */
|
||||
}
|
||||
}
|
||||
|
||||
static jmp_buf fpu_check;
|
||||
|
71
gdb/main.c
71
gdb/main.c
@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "param.h"
|
||||
@ -27,7 +28,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#endif
|
||||
|
||||
#include <sys/file.h>
|
||||
#include <stdio.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <sys/param.h>
|
||||
@ -239,6 +239,12 @@ main (argc, argv, envp)
|
||||
int batch = 0;
|
||||
register int i;
|
||||
|
||||
#if defined (ALIGN_STACK_ON_STARTUP)
|
||||
i = (int) &count & 0x3;
|
||||
if (i != 0)
|
||||
alloca (4 - i);
|
||||
#endif
|
||||
|
||||
quit_flag = 0;
|
||||
linesize = 100;
|
||||
line = (char *) xmalloc (linesize);
|
||||
@ -276,7 +282,38 @@ main (argc, argv, envp)
|
||||
frame_file_full_name = 1;
|
||||
else if (!strcmp (argv[i], "-xgdb_verbose"))
|
||||
xgdb_verbose = 1;
|
||||
/* -help: print a summary of command line switches. */
|
||||
else if (!strcmp (argv[i], "-help"))
|
||||
{
|
||||
fputs ("\
|
||||
This is GDB, the GNU debugger. Use the command\n\
|
||||
gdb [options] [executable [core-file]]\n\
|
||||
to enter the debugger.\n\
|
||||
\n\
|
||||
Options available are:\n\
|
||||
-help Print this message.\n\
|
||||
-quiet Do not print version number on startup.\n\
|
||||
-fullname Output information used by emacs-GDB interface.\n\
|
||||
-batch Exit after processing options.\n\
|
||||
-nx Do not read .gdbinit file.\n\
|
||||
-tty TTY Use TTY for input/output by the program being debugged.\n\
|
||||
-cd DIR Change current directory to DIR.\n\
|
||||
-directory DIR Search for source files in DIR.\n\
|
||||
-command FILE Execute GDB commands from FILE.\n\
|
||||
-symbols SYMFILE Read symbols from SYMFILE.\n\
|
||||
-exec EXECFILE Use EXECFILE as the executable.\n\
|
||||
-se FILE Use FILE as symbol file and executable file.\n\
|
||||
-core COREFILE Analyze the core dump COREFILE.\n\
|
||||
\n\
|
||||
For more information, type \"help\" from within GDB, or consult the\n\
|
||||
GDB manual (available as on-line info or a printed manual).\n", stderr);
|
||||
/* Exiting after printing this message seems like
|
||||
the most useful thing to do. */
|
||||
exit (0);
|
||||
}
|
||||
else if (argv[i][0] == '-')
|
||||
/* Other options take arguments, so don't confuse an
|
||||
argument with an option. */
|
||||
i++;
|
||||
}
|
||||
|
||||
@ -307,7 +344,8 @@ main (argc, argv, envp)
|
||||
if (!strcmp (arg, "-q") || !strcmp (arg, "-nx")
|
||||
|| !strcmp (arg, "-quiet") || !strcmp (arg, "-batch")
|
||||
|| !strcmp (arg, "-fullname") || !strcmp (arg, "-nw")
|
||||
|| !strcmp (arg, "-xgdb_verbose"))
|
||||
|| !strcmp (arg, "-xgdb_verbose")
|
||||
|| !strcmp (arg, "-help"))
|
||||
/* Already processed above */
|
||||
continue;
|
||||
|
||||
@ -348,35 +386,6 @@ main (argc, argv, envp)
|
||||
else if (!strcmp (arg, "-t") || !strcmp (arg, "-tty"))
|
||||
tty_command (argv[i], 0);
|
||||
|
||||
/* -help: print a summary of command line switches. */
|
||||
else if (!strcmp (arg, "-help"))
|
||||
{
|
||||
fputs ("\
|
||||
This is GDB, the GNU debugger. Use the command\n\
|
||||
gdb [options] [executable [core-file]]\n\
|
||||
to enter the debugger.\n\
|
||||
\n\
|
||||
Options available are:\n\
|
||||
-help Print this message.\n\
|
||||
-quiet Do not print version number on startup.\n\
|
||||
-fullname Output information used by emacs-GDB interface.\n\
|
||||
-batch Exit after processing options.\n\
|
||||
-nx Do not read .gdbinit file.\n\
|
||||
-tty TTY Use TTY for input/output by the program being debugged.\n\
|
||||
-cd DIR Change current directory to DIR.\n\
|
||||
-directory DIR Search for source files in DIR.\n\
|
||||
-command FILE Execute GDB commands from FILE.\n\
|
||||
-symbols SYMFILE Read symbols from SYMFILE.\n\
|
||||
-exec EXECFILE Use EXECFILE as the executable.\n\
|
||||
-se FILE Use FILE as symbol file and executable file.\n\
|
||||
-core COREFILE Analyze the core dump COREFILE.\n\
|
||||
\n\
|
||||
For more information, type \"help\" from within GDB, or consult the\n\
|
||||
GDB manual (available as on-line info or a printed manual).\n", stderr);
|
||||
/* Exiting after printing this message seems like
|
||||
the most useful thing to do. */
|
||||
exit (0);
|
||||
}
|
||||
else
|
||||
error ("Unknown command-line switch: \"%s\"\n", arg);
|
||||
}
|
||||
|
@ -17,12 +17,12 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <signal.h>
|
||||
@ -538,10 +538,12 @@ exec_file_command (filename, from_tty)
|
||||
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)
|
||||
if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read text section header", execfile);
|
||||
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read data section header", execfile);
|
||||
|
||||
text_start = exec_aouthdr.text_start;
|
||||
|
@ -1233,7 +1233,9 @@ print_frame_args (func, fi, num, stream)
|
||||
register int last_regparm = 0;
|
||||
register struct symbol *lastsym, *sym, *nextsym;
|
||||
register value val;
|
||||
CORE_ADDR highest_offset = 0;
|
||||
/* Offset of stack argument that is at the highest offset.
|
||||
-1 if we haven't come to a stack argument yet. */
|
||||
CORE_ADDR highest_offset = (CORE_ADDR) -1;
|
||||
register CORE_ADDR addr = FRAME_ARGS_ADDRESS (fi);
|
||||
|
||||
if (func)
|
||||
@ -1273,10 +1275,12 @@ print_frame_args (func, fi, num, stream)
|
||||
current_offset
|
||||
= (((current_offset + sizeof (int) - 1) / sizeof (int))
|
||||
* sizeof (int));
|
||||
|
||||
if ((current_offset
|
||||
+ (arg_size - sizeof (int) + 3) / (sizeof (int)))
|
||||
> highest_offset)
|
||||
|
||||
/* If this is the highest offset seen yet, set highest_offset. */
|
||||
if (highest_offset == (CORE_ADDR)-1
|
||||
|| ((current_offset
|
||||
+ (arg_size - sizeof (int) + 3) / (sizeof (int)))
|
||||
> highest_offset))
|
||||
highest_offset = current_offset;
|
||||
}
|
||||
|
||||
@ -1284,6 +1288,32 @@ print_frame_args (func, fi, num, stream)
|
||||
fprintf_filtered (stream, ", ");
|
||||
fputs_filtered (SYMBOL_NAME (sym), stream);
|
||||
fputs_filtered ("=", stream);
|
||||
|
||||
/* Nonzero if a LOC_ARG which is a struct is useless. */
|
||||
#if !defined (STRUCT_ARG_SYM_GARBAGE)
|
||||
#define STRUCT_ARG_SYM_GARBAGE(gcc_p) 0
|
||||
#endif
|
||||
|
||||
if (STRUCT_ARG_SYM_GARBAGE (b->gcc_compile_flag)
|
||||
&& TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT
|
||||
&& SYMBOL_CLASS (sym) == LOC_ARG)
|
||||
{
|
||||
/* Try looking up that name. SunOS4 puts out a usable
|
||||
symbol as a local variable (in addition to the one
|
||||
for the arg). */
|
||||
struct symbol *sym2 =
|
||||
lookup_symbol (SYMBOL_NAME (sym), b, VAR_NAMESPACE, 0);
|
||||
|
||||
if (sym2 != NULL)
|
||||
val = value_of_variable (sym2);
|
||||
else
|
||||
{
|
||||
fputs_filtered ("?", stream);
|
||||
first = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
value_print (val, stream, 0, Val_no_prettyprint);
|
||||
first = 0;
|
||||
}
|
||||
@ -1292,7 +1322,8 @@ print_frame_args (func, fi, num, stream)
|
||||
enough about the stack to find them. */
|
||||
if (num != -1)
|
||||
{
|
||||
if (i && num * sizeof (int) + FRAME_ARGS_SKIP > highest_offset)
|
||||
if (highest_offset != (CORE_ADDR) -1
|
||||
&& num * sizeof (int) + FRAME_ARGS_SKIP > highest_offset)
|
||||
print_frame_nameless_args (addr,
|
||||
highest_offset + sizeof (int),
|
||||
num * sizeof (int) + FRAME_ARGS_SKIP,
|
||||
|
819
gdb/pyr-dep.c
Normal file
819
gdb/pyr-dep.c
Normal file
@ -0,0 +1,819 @@
|
||||
/* Low level interface to ptrace, for GDB when running under Unix.
|
||||
Copyright (C) 1988, 1989 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB.
|
||||
|
||||
GDB is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GDB is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ioctl.h>
|
||||
/* #include <fcntl.h> Can we live without this? */
|
||||
|
||||
#include <a.out.h>
|
||||
#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. */
|
||||
int
|
||||
call_ptrace (request, pid, arg3, arg4)
|
||||
int request, pid, arg3, arg4;
|
||||
{
|
||||
return ptrace (request, pid, arg3, arg4);
|
||||
}
|
||||
|
||||
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, datum;
|
||||
register unsigned int regaddr;
|
||||
int reg_buf[NUM_REGS+1];
|
||||
struct user u;
|
||||
register int skipped_frames = 0;
|
||||
|
||||
if (remote_debugging)
|
||||
remote_fetch_registers ();
|
||||
else
|
||||
{
|
||||
for (regno = 0; regno < 64; regno++) {
|
||||
reg_buf[regno] = ptrace (3, inferior_pid, regno, 0);
|
||||
|
||||
#if defined(PYRAMID_CONTROL_FRAME_DEBUGGING)
|
||||
printf ("Fetching %s from inferior, got %0x\n",
|
||||
reg_names[regno],
|
||||
reg_buf[regno]);
|
||||
#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
|
||||
|
||||
if (reg_buf[regno] == -1 && errno == EIO) {
|
||||
printf("fetch_interior_registers: fetching %s from inferior\n",
|
||||
reg_names[regno]);
|
||||
errno = 0;
|
||||
}
|
||||
supply_register (regno, reg_buf+regno);
|
||||
}
|
||||
/* that leaves regs 64, 65, and 66 */
|
||||
datum = ptrace (3, inferior_pid,
|
||||
((char *)&u.u_pcb.pcb_csp) -
|
||||
((char *)&u), 0);
|
||||
|
||||
|
||||
|
||||
/* FIXME: Find the Current Frame Pointer (CFP). CFP is a global
|
||||
register (ie, NOT windowed), that gets saved in a frame iff
|
||||
the code for that frame has a prologue (ie, "adsf N"). If
|
||||
there is a prologue, the adsf insn saves the old cfp in
|
||||
pr13, cfp is set to sp, and N bytes of locals are allocated
|
||||
(sp is decremented by n).
|
||||
This makes finding CFP hard. I guess the right way to do it
|
||||
is:
|
||||
- If this is the innermost frame, believe ptrace() or
|
||||
the core area.
|
||||
- Otherwise:
|
||||
Find the first insn of the current frame.
|
||||
- find the saved pc;
|
||||
- find the call insn that saved it;
|
||||
- figure out where the call is to;
|
||||
- if the first insn is an adsf, we got a frame
|
||||
pointer. */
|
||||
|
||||
|
||||
/* Normal processors have separate stack pointers for user and
|
||||
kernel mode. Getting the last user mode frame on such
|
||||
machines is easy: the kernel context of the ptrace()'d
|
||||
process is on the kernel stack, and the USP points to what
|
||||
we want. But Pyramids only have a single cfp for both user and
|
||||
kernel mode. And processes being ptrace()'d have some
|
||||
kernel-context control frames on their stack.
|
||||
To avoid tracing back into the kernel context of an inferior,
|
||||
we skip 0 or more contiguous control frames where the pc is
|
||||
in the kernel. */
|
||||
|
||||
while (1) {
|
||||
register int inferior_saved_pc;
|
||||
inferior_saved_pc = ptrace (1, inferior_pid, datum+((32+15)*4), 0);
|
||||
if (inferior_saved_pc > 0) break;
|
||||
#if defined(PYRAMID_CONTROL_FRAME_DEBUGGING)
|
||||
printf("skipping kernel frame %08x, pc=%08x\n", datum,
|
||||
inferior_saved_pc);
|
||||
#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
|
||||
skipped_frames++;
|
||||
datum -= CONTROL_STACK_FRAME_SIZE;
|
||||
}
|
||||
|
||||
reg_buf[CSP_REGNUM] = datum;
|
||||
supply_register(CSP_REGNUM, reg_buf+CSP_REGNUM);
|
||||
#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
|
||||
if (skipped_frames) {
|
||||
fprintf (stderr,
|
||||
"skipped %d frames from %x to %x; cfp was %x, now %x\n",
|
||||
skipped_frames, reg_buf[CSP_REGNUM]);
|
||||
}
|
||||
#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
|
||||
}
|
||||
}
|
||||
|
||||
/* 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];
|
||||
|
||||
if (regno >= 0)
|
||||
{
|
||||
if ((0 <= regno) && (regno < 64)) {
|
||||
/*regaddr = register_addr (regno, offset);*/
|
||||
regaddr = regno;
|
||||
errno = 0;
|
||||
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);*/
|
||||
regaddr = regno;
|
||||
errno = 0;
|
||||
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 0
|
||||
/*This is now done by read_memory, because when this function did it,
|
||||
reading a byte or short int hardware port read whole longs, causing
|
||||
serious side effects
|
||||
such as bus errors and unexpected hardware operation. This would
|
||||
also be a problem with ptrace if the inferior process could read
|
||||
or write hardware registers, but that's not usually the case. */
|
||||
if (remote_debugging)
|
||||
buffer[i] = remote_fetch_word (addr);
|
||||
else
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
/*** Extensions to core and dump files, for GDB. */
|
||||
|
||||
extern unsigned int last_frame_offset;
|
||||
|
||||
#ifdef PYRAMID_CORE
|
||||
|
||||
/* Can't make definitions here static, since core.c needs them
|
||||
to do bounds checking on the core-file areas. O well. */
|
||||
|
||||
/* have two stacks: one for data, one for register windows. */
|
||||
extern CORE_ADDR reg_stack_start;
|
||||
extern CORE_ADDR reg_stack_end;
|
||||
|
||||
/* need this so we can find the global registers: they never get saved. */
|
||||
static CORE_ADDR global_reg_offset;
|
||||
static CORE_ADDR last_frame_address;
|
||||
static CORE_ADDR last_frame_offset;
|
||||
|
||||
|
||||
/* Address in core file of start of register window stack area.
|
||||
Don't know if is this any of meaningful, useful or necessary. */
|
||||
static CORE_ADDR reg_stack_offset;
|
||||
|
||||
#endif /* PYRAMID_CORE */
|
||||
|
||||
|
||||
/* Work with core dump and executable files, for GDB.
|
||||
This code would be in core.c if it weren't machine-dependent. */
|
||||
|
||||
#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
|
||||
#ifndef AOUTHDR
|
||||
#define AOUTHDR struct exec
|
||||
#endif
|
||||
#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;
|
||||
|
||||
#ifdef PYRAMID_CORE
|
||||
/* Well, "two areas of memory" on most machines; but pyramids have a
|
||||
third area, for the register-window stack, and we need its
|
||||
base and bound too. */
|
||||
|
||||
extern CORE_ADDR reg_stack_start;
|
||||
extern CORE_ADDR reg_stack_start;
|
||||
#endif /* PYRAMID_CORE */
|
||||
|
||||
/* 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;
|
||||
|
||||
#ifdef PYRAMID_CORE
|
||||
reg_stack_start = CONTROL_STACK_ADDR;
|
||||
reg_stack_end = CONTROL_STACK_ADDR; /* this isn't strictly true...*/
|
||||
#endif /* PYRAMID_CORE */
|
||||
|
||||
/* Now, if a new core file was specified, open it and digest it. */
|
||||
|
||||
if (filename)
|
||||
{
|
||||
filename = tilde_expand (filename);
|
||||
make_cleanup (free, 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;
|
||||
|
||||
unsigned 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;
|
||||
data_offset = NBPG * UPAGES;
|
||||
stack_offset = NBPG * (UPAGES + u.u_dsize);
|
||||
|
||||
/* find registers in core file */
|
||||
#ifdef PYRAMID_PTRACE
|
||||
stack_start = stack_end - NBPG * u.u_ussize;
|
||||
reg_stack_offset = stack_offset + (NBPG *u.u_ussize);
|
||||
reg_stack_end = reg_stack_start + NBPG * u.u_cssize;
|
||||
|
||||
last_frame_address = ((int) u.u_pcb.pcb_csp);
|
||||
last_frame_offset = reg_stack_offset + last_frame_address
|
||||
- CONTROL_STACK_ADDR ;
|
||||
global_reg_offset = (char *)&u - (char *)&u.u_pcb.pcb_gr0 ;
|
||||
|
||||
/* skip any control-stack frames that were executed in the
|
||||
kernel. */
|
||||
|
||||
while (1) {
|
||||
char buf[4];
|
||||
val = lseek (corechan, last_frame_offset+(47*4), 0);
|
||||
if (val < 0)
|
||||
perror_with_name (filename);
|
||||
val = myread (corechan, buf, sizeof buf);
|
||||
if (val < 0)
|
||||
perror_with_name (filename);
|
||||
|
||||
if (*(int *)buf >= 0)
|
||||
break;
|
||||
printf ("skipping frame %0x\n", last_frame_address);
|
||||
last_frame_offset -= CONTROL_STACK_FRAME_SIZE;
|
||||
last_frame_address -= CONTROL_STACK_FRAME_SIZE;
|
||||
}
|
||||
reg_offset = last_frame_offset;
|
||||
|
||||
#if 1 || defined(PYRAMID_CONTROL_FRAME_DEBUGGING)
|
||||
printf ("Control stack pointer = 0x%08x\n",
|
||||
u.u_pcb.pcb_csp);
|
||||
printf ("offset to control stack %d outermost frame %d (%0x)\n",
|
||||
reg_stack_offset, reg_offset, last_frame_address);
|
||||
#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
|
||||
|
||||
#else /* not PYRAMID_CORE */
|
||||
stack_start = stack_end - NBPG * u.u_ssize;
|
||||
reg_offset = (int) u.u_ar0 - KERNEL_U_ADDR;
|
||||
#endif /* not PYRAMID_CORE */
|
||||
|
||||
#ifdef __not_on_pyr_yet
|
||||
/* Some machines put an absolute address in here and some put
|
||||
the offset in the upage of the regs. */
|
||||
reg_offset = (int) u.u_ar0;
|
||||
if (reg_offset > NBPG * UPAGES)
|
||||
reg_offset -= KERNEL_U_ADDR;
|
||||
#endif
|
||||
|
||||
/* 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 < 64; regno++)
|
||||
{
|
||||
char buf[MAX_REGISTER_RAW_SIZE];
|
||||
|
||||
val = lseek (corechan, register_addr (regno, reg_offset), 0);
|
||||
if (val < 0
|
||||
|| (val = myread (corechan, buf, sizeof buf)) < 0)
|
||||
{
|
||||
char * buffer = (char *) alloca (strlen (reg_names[regno])
|
||||
+ 30);
|
||||
strcpy (buffer, "Reading register ");
|
||||
strcat (buffer, reg_names[regno]);
|
||||
|
||||
perror_with_name (buffer);
|
||||
}
|
||||
|
||||
if (val < 0)
|
||||
perror_with_name (filename);
|
||||
#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
|
||||
printf ("[reg %s(%d), offset in file %s=0x%0x, addr =0x%0x, =%0x]\n",
|
||||
reg_names[regno], regno, filename,
|
||||
register_addr(regno, reg_offset),
|
||||
regno * 4 + last_frame_address,
|
||||
*((int *)buf));
|
||||
#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
|
||||
supply_register (regno, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (filename[0] == '/')
|
||||
corefile = savestring (filename, strlen (filename));
|
||||
else
|
||||
{
|
||||
corefile = concat (current_directory, "/", filename);
|
||||
}
|
||||
|
||||
#if 1 || defined(PYRAMID_CONTROL_FRAME_DEBUGGING)
|
||||
printf ("Providing CSP (%0x) as nominal address of current frame.\n",
|
||||
last_frame_address);
|
||||
#endif PYRAMID_CONTROL_FRAME_DEBUGGING
|
||||
/* FIXME: Which of the following is correct? */
|
||||
#if 0
|
||||
set_current_frame ( create_new_frame (read_register (FP_REGNUM),
|
||||
read_pc ()));
|
||||
#else
|
||||
set_current_frame ( create_new_frame (last_frame_address,
|
||||
read_pc ()));
|
||||
#endif
|
||||
|
||||
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)
|
||||
{
|
||||
filename = tilde_expand (filename);
|
||||
make_cleanup (free, filename);
|
||||
|
||||
execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0,
|
||||
&execfile);
|
||||
if (execchan < 0)
|
||||
perror_with_name (filename);
|
||||
|
||||
#ifdef COFF_FORMAT
|
||||
#else /* not COFF_FORMAT */
|
||||
{
|
||||
struct stat st_exec;
|
||||
|
||||
#ifdef gould
|
||||
#endif /* gould */
|
||||
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);
|
||||
#ifdef gould
|
||||
#else
|
||||
text_offset = N_TXTOFF (exec_aouthdr);
|
||||
exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text;
|
||||
#endif
|
||||
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);
|
||||
}
|
||||
|
||||
/*** Prettier register printing. ***/
|
||||
|
||||
/* Print registers in the same format as pyramid's dbx, adb, sdb. */
|
||||
pyr_print_registers(reg_buf, regnum)
|
||||
long *reg_buf[];
|
||||
{
|
||||
register int regno;
|
||||
int usp, ksp;
|
||||
struct user u;
|
||||
|
||||
for (regno = 0; regno < 16; regno++) {
|
||||
printf/*_filtered*/ ("%6.6s: %8x %6.6s: %8x %6s: %8x %6s: %8x\n",
|
||||
reg_names[regno], reg_buf[regno],
|
||||
reg_names[regno+16], reg_buf[regno+16],
|
||||
reg_names[regno+32], reg_buf[regno+32],
|
||||
reg_names[regno+48], reg_buf[regno+48]);
|
||||
}
|
||||
usp = ptrace (3, inferior_pid,
|
||||
((char *)&u.u_pcb.pcb_usp) -
|
||||
((char *)&u), 0);
|
||||
ksp = ptrace (3, inferior_pid,
|
||||
((char *)&u.u_pcb.pcb_ksp) -
|
||||
((char *)&u), 0);
|
||||
printf/*_filtered*/ ("\n%6.6s: %8x %6.6s: %8x (%08x) %6.6s %8x\n",
|
||||
reg_names[CSP_REGNUM],reg_buf[CSP_REGNUM],
|
||||
reg_names[KSP_REGNUM], reg_buf[KSP_REGNUM], ksp,
|
||||
"usp", usp);
|
||||
}
|
||||
|
||||
/* Print the register regnum, or all registers if regnum is -1. */
|
||||
|
||||
pyr_do_registers_info (regnum)
|
||||
int regnum;
|
||||
{
|
||||
/* On a pyr, we know a virtual register can always fit in an long.
|
||||
Here (and elsewhere) we take advantage of that. Yuk. */
|
||||
long raw_regs[MAX_REGISTER_RAW_SIZE*NUM_REGS];
|
||||
register int i;
|
||||
|
||||
for (i = 0 ; i < 64 ; i++) {
|
||||
read_relative_register_raw_bytes(i, raw_regs+i);
|
||||
}
|
||||
if (regnum == -1)
|
||||
pyr_print_registers (raw_regs, regnum);
|
||||
else
|
||||
for (i = 0; i < NUM_REGS; i++)
|
||||
if (i == regnum) {
|
||||
long val = raw_regs[i];
|
||||
|
||||
fputs_filtered (reg_names[i], stdout);
|
||||
printf_filtered(":");
|
||||
print_spaces_filtered (6 - strlen (reg_names[i]), stdout);
|
||||
if (val == 0)
|
||||
printf_filtered ("0");
|
||||
else
|
||||
printf_filtered ("0x%08x %d", val, val);
|
||||
printf_filtered("\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*** Debugging editions of various macros from m-pyr.h ****/
|
||||
|
||||
CORE_ADDR frame_locals_address (frame)
|
||||
FRAME frame;
|
||||
{
|
||||
register int addr = find_saved_register (frame,CFP_REGNUM);
|
||||
register int result = read_memory_integer (addr, 4);
|
||||
#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
|
||||
fprintf (stderr,
|
||||
"\t[[..frame_locals:%8x, %s= %x @%x fcfp= %x foo= %x\n\t gr13=%x pr13=%x tr13=%x @%x]]\n",
|
||||
frame->frame,
|
||||
reg_names[CFP_REGNUM],
|
||||
result, addr,
|
||||
frame->frame_cfp, (CFP_REGNUM),
|
||||
|
||||
|
||||
read_register(13), read_register(29), read_register(61),
|
||||
find_saved_register(frame, 61));
|
||||
#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
|
||||
|
||||
/* FIXME: I thought read_register (CFP_REGNUM) should be the right answer;
|
||||
or at least CFP_REGNUM relative to FRAME (ie, result).
|
||||
There seems to be a bug in the way the innermost frame is set up. */
|
||||
|
||||
return ((frame->next) ? result: frame->frame_cfp);
|
||||
}
|
||||
|
||||
CORE_ADDR frame_args_addr (frame)
|
||||
FRAME frame;
|
||||
{
|
||||
register int addr = find_saved_register (frame,CFP_REGNUM);
|
||||
register int result = read_memory_integer (addr, 4);
|
||||
|
||||
#ifdef PYRAMID_CONTROL_FRAME_DEBUGGING
|
||||
fprintf (stderr,
|
||||
"\t[[..frame_args:%8x, %s= %x @%x fcfp= %x r_r= %x\n\t gr13=%x pr13=%x tr13=%x @%x]]\n",
|
||||
frame->frame,
|
||||
reg_names[CFP_REGNUM],
|
||||
result, addr,
|
||||
frame->frame_cfp, read_register(CFP_REGNUM),
|
||||
|
||||
read_register(13), read_register(29), read_register(61),
|
||||
find_saved_register(frame, 61));
|
||||
#endif /* PYRAMID_CONTROL_FRAME_DEBUGGING */
|
||||
|
||||
/* FIXME: I thought read_register (CFP_REGNUM) should be the right answer;
|
||||
or at least CFP_REGNUM relative to FRAME (ie, result).
|
||||
There seems to be a bug in the way the innermost frame is set up. */
|
||||
return ((frame->next) ? result: frame->frame_cfp);
|
||||
}
|
287
gdb/pyr-opcode.h
Normal file
287
gdb/pyr-opcode.h
Normal file
@ -0,0 +1,287 @@
|
||||
/* pyramid.opcode.h -- gdb initial attempt. */
|
||||
|
||||
/* pyramid opcode table: wot to do with this
|
||||
particular opcode */
|
||||
|
||||
struct pyr_datum
|
||||
{
|
||||
char nargs;
|
||||
char * args; /* how to compile said opcode */
|
||||
unsigned long mask; /* Bit vector: which operand modes are valid
|
||||
for this opcode */
|
||||
unsigned char code; /* op-code (always 6(?) bits */
|
||||
};
|
||||
|
||||
typedef struct pyr_insn_format {
|
||||
unsigned int mode :4;
|
||||
unsigned int operator :8;
|
||||
unsigned int index_scale :2;
|
||||
unsigned int index_reg :6;
|
||||
unsigned int operand_1 :6;
|
||||
unsigned int operand_2:6;
|
||||
} pyr_insn_format;
|
||||
|
||||
|
||||
/* We store four bytes of opcode for all opcodes.
|
||||
Pyramid is sufficiently RISCy that:
|
||||
- insns are always an integral number of words;
|
||||
- the length of any insn can be told from the first word of
|
||||
the insn. (ie, if there are zero, one, or two words of
|
||||
immediate operand/offset).
|
||||
|
||||
|
||||
The args component is a string containing two characters for each
|
||||
operand of the instruction. The first specifies the kind of operand;
|
||||
the second, the place it is stored. */
|
||||
|
||||
/* Kinds of operands:
|
||||
mask assembler syntax description
|
||||
0x0001: movw Rn,Rn register to register
|
||||
0x0002: movw K,Rn quick immediate to register
|
||||
0x0004: movw I,Rn long immediate to register
|
||||
0x0008: movw (Rn),Rn register indirect to register
|
||||
movw (Rn)[x],Rn register indirect to register
|
||||
0x0010: movw I(Rn),Rn offset register indirect to register
|
||||
movw I(Rn)[x],Rn offset register indirect, indexed, to register
|
||||
|
||||
0x0020: movw Rn,(Rn) register to register indirect
|
||||
0x0040: movw K,(Rn) quick immediate to register indirect
|
||||
0x0080: movw I,(Rn) long immediate to register indirect
|
||||
0x0100: movw (Rn),(Rn) register indirect to-register indirect
|
||||
0x0100: movw (Rn),(Rn) register indirect to-register indirect
|
||||
0x0200: movw I(Rn),(Rn) register indirect+offset to register indirect
|
||||
0x0200: movw I(Rn),(Rn) register indirect+offset to register indirect
|
||||
|
||||
0x0400: movw Rn,I(Rn) register to register indirect+offset
|
||||
0x0800: movw K,I(Rn) quick immediate to register indirect+offset
|
||||
0x1000: movw I,I(Rn) long immediate to register indirect+offset
|
||||
0x1000: movw (Rn),I(Rn) register indirect to-register indirect+offset
|
||||
0x1000: movw I(Rn),I(Rn) register indirect+offset to register indirect
|
||||
+offset
|
||||
0x0000: (irregular) ???
|
||||
|
||||
|
||||
Each insn has a four-bit field encoding the type(s) of its operands.
|
||||
*/
|
||||
|
||||
/* Some common combinations
|
||||
*/
|
||||
|
||||
/* the first 5,(0x1|0x2|0x4|0x8|0x10) ie (1|2|4|8|16), ie ( 32 -1)*/
|
||||
#define GEN_TO_REG (31)
|
||||
|
||||
#define UNKNOWN ((unsigned long)-1)
|
||||
#define ANY (GEN_TO_REG | (GEN_TO_REG << 5) | (GEN_TO_REG << 15))
|
||||
|
||||
#define CONVERT (1|8|0x10|0x20|0x200)
|
||||
|
||||
#define K_TO_REG (2)
|
||||
#define I_TO_REG (4)
|
||||
#define NOTK_TO_REG (GEN_TO_REG & ~K_TO_REG)
|
||||
#define NOTI_TO_REG (GEN_TO_REG & ~I_TO_REG)
|
||||
|
||||
/* The assembler requires that this array be sorted as follows:
|
||||
all instances of the same mnemonic must be consecutive.
|
||||
All instances of the same mnemonic with the same number of operands
|
||||
must be consecutive.
|
||||
*/
|
||||
|
||||
struct pyr_opcode /* pyr opcode text */
|
||||
{
|
||||
char * name; /* opcode name: lowercase string [key] */
|
||||
struct pyr_datum datum; /* rest of opcode table [datum] */
|
||||
};
|
||||
|
||||
#define pyr_how args
|
||||
#define pyr_nargs nargs
|
||||
#define pyr_mask mask
|
||||
#define pyr_name name
|
||||
|
||||
struct pyr_opcode pyr_opcodes[] =
|
||||
{
|
||||
{"movb", { 2, "", UNKNOWN, 0x11}, },
|
||||
{"movh", { 2, "", UNKNOWN, 0x12} },
|
||||
{"movw", { 2, "", ANY, 0x10} },
|
||||
{"movl", { 2, "", ANY, 0x13} },
|
||||
{"mnegw", { 2, "", (0x1|0x8|0x10), 0x14} },
|
||||
{"mnegf", { 2, "", 0x1, 0x15} },
|
||||
{"mnegd", { 2, "", 0x1, 0x16} },
|
||||
{"mcomw", { 2, "", (0x1|0x8|0x10), 0x17} },
|
||||
{"mabsw", { 2, "", (0x1|0x8|0x10), 0x18} },
|
||||
{"mabsf", { 2, "", 0x1, 0x19} },
|
||||
{"mabsd", { 2, "", 0x1, 0x1a} },
|
||||
{"mtstw", { 2, "", (0x1|0x8|0x10), 0x1c} },
|
||||
{"mtstf", { 2, "", 0x1, 0x1d} },
|
||||
{"mtstd", { 2, "", 0x1, 0x1e} },
|
||||
{"mova", { 2, "", 0x8|0x10, 0x1f} },
|
||||
{"movzbw", { 2, "", (0x1|0x8|0x10), 0x20} },
|
||||
{"movzhw", { 2, "", (0x1|0x8|0x10), 0x21} },
|
||||
/* 2 insns out of order here */
|
||||
{"movbl", { 2, "", 1, 0x4f} },
|
||||
{"filbl", { 2, "", 1, 0x4e} },
|
||||
|
||||
{"cvtbw", { 2, "", CONVERT, 0x22} },
|
||||
{"cvthw", { 2, "", CONVERT, 0x23} },
|
||||
{"cvtwb", { 2, "", CONVERT, 0x24} },
|
||||
{"cvtwh", { 2, "", CONVERT, 0x25} },
|
||||
{"cvtwf", { 2, "", CONVERT, 0x26} },
|
||||
{"cvtwd", { 2, "", CONVERT, 0x27} },
|
||||
{"cvtfw", { 2, "", CONVERT, 0x28} },
|
||||
{"cvtfd", { 2, "", CONVERT, 0x29} },
|
||||
{"cvtdw", { 2, "", CONVERT, 0x2a} },
|
||||
{"cvtdf", { 2, "", CONVERT, 0x2b} },
|
||||
|
||||
{"addw", { 2, "", GEN_TO_REG, 0x40} },
|
||||
{"addwc", { 2, "", GEN_TO_REG, 0x41} },
|
||||
{"subw", { 2, "", GEN_TO_REG, 0x42} },
|
||||
{"subwb", { 2, "", GEN_TO_REG, 0x43} },
|
||||
{"rsubw", { 2, "", GEN_TO_REG, 0x44} },
|
||||
{"mulw", { 2, "", GEN_TO_REG, 0x45} },
|
||||
{"emul", { 2, "", GEN_TO_REG, 0x47} },
|
||||
{"umulw", { 2, "", GEN_TO_REG, 0x46} },
|
||||
{"divw", { 2, "", GEN_TO_REG, 0x48} },
|
||||
{"ediv", { 2, "", GEN_TO_REG, 0x4a} },
|
||||
{"rdivw", { 2, "", GEN_TO_REG, 0x4b} },
|
||||
{"udivw", { 2, "", GEN_TO_REG, 0x49} },
|
||||
{"modw", { 2, "", GEN_TO_REG, 0x4c} },
|
||||
{"umodw", { 2, "", GEN_TO_REG, 0x4d} },
|
||||
|
||||
|
||||
{"addf", { 2, "", 1, 0x50} },
|
||||
{"addd", { 2, "", 1, 0x51} },
|
||||
{"subf", { 2, "", 1, 0x52} },
|
||||
{"subd", { 2, "", 1, 0x53} },
|
||||
{"mulf", { 2, "", 1, 0x56} },
|
||||
{"muld", { 2, "", 1, 0x57} },
|
||||
{"divf", { 2, "", 1, 0x58} },
|
||||
{"divd", { 2, "", 1, 0x59} },
|
||||
|
||||
|
||||
{"cmpb", { 2, "", UNKNOWN, 0x61} },
|
||||
{"cmph", { 2, "", UNKNOWN, 0x62} },
|
||||
{"cmpw", { 2, "", UNKNOWN, 0x60} },
|
||||
{"ucmpb", { 2, "", UNKNOWN, 0x66} },
|
||||
/* WHY no "ucmph"??? */
|
||||
{"ucmpw", { 2, "", UNKNOWN, 0x65} },
|
||||
{"xchw", { 2, "", UNKNOWN, 0x0f} },
|
||||
|
||||
|
||||
{"andw", { 2, "", GEN_TO_REG, 0x30} },
|
||||
{"orw", { 2, "", GEN_TO_REG, 0x31} },
|
||||
{"xorw", { 2, "", GEN_TO_REG, 0x32} },
|
||||
{"bicw", { 2, "", GEN_TO_REG, 0x33} },
|
||||
{"lshlw", { 2, "", GEN_TO_REG, 0x38} },
|
||||
{"ashlw", { 2, "", GEN_TO_REG, 0x3a} },
|
||||
{"ashll", { 2, "", GEN_TO_REG, 0x3c} },
|
||||
{"ashrw", { 2, "", GEN_TO_REG, 0x3b} },
|
||||
{"ashrl", { 2, "", GEN_TO_REG, 0x3d} },
|
||||
{"rotlw", { 2, "", GEN_TO_REG, 0x3e} },
|
||||
{"rotrw", { 2, "", GEN_TO_REG, 0x3f} },
|
||||
|
||||
/* push and pop insns are "going away next release". */
|
||||
{"pushw", { 2, "", GEN_TO_REG, 0x0c} },
|
||||
{"popw", { 2, "", (0x1|0x8|0x10), 0x0d} },
|
||||
{"pusha", { 2, "", (0x8|0x10), 0x0e} },
|
||||
|
||||
{"bitsw", { 2, "", UNKNOWN, 0x35} },
|
||||
{"bitcw", { 2, "", UNKNOWN, 0x36} },
|
||||
/* some kind of ibra/dbra insns??*/
|
||||
{"icmpw", { 2, "", UNKNOWN, 0x67} },
|
||||
{"dcmpw", { 2, "", (1|4|0x20|0x80|0x400|0x1000), 0x69} },/*FIXME*/
|
||||
{"acmpw", { 2, "", 1, 0x6b} },
|
||||
|
||||
/* Call is written as a 1-op insn, but is always (dis)assembled as a 2-op
|
||||
insn with a 2nd op of tr14. The assembler will have to grok this. */
|
||||
{"call", { 2, "", GEN_TO_REG, 0x04} },
|
||||
{"call", { 1, "", GEN_TO_REG, 0x04} },
|
||||
|
||||
{"callk", { 1, "", UNKNOWN, 0x06} },/* system call?*/
|
||||
/* Ret is usually written as a 0-op insn, but gets disassembled as a
|
||||
1-op insn. The operand is always tr15. */
|
||||
{"ret", { 0, "", UNKNOWN, 0x09} },
|
||||
{"ret", { 1, "", UNKNOWN, 0x09} },
|
||||
{"adsf", { 2, "", (1|2|4), 0x08} },
|
||||
{"retd", { 2, "", UNKNOWN, 0x0a} },
|
||||
{"btc", { 2, "", UNKNOWN, 0x01} },
|
||||
{"bfc", { 2, "", UNKNOWN, 0x02} },
|
||||
/* Careful: halt is 0x00000000. Jump must have some other (mode?)bit set?? */
|
||||
{"jump", { 1, "", UNKNOWN, 0x00} },
|
||||
{"btp", { 2, "", UNKNOWN, 0xf00} },
|
||||
/* read control-stack pointer is another 1-or-2 operand insn. */
|
||||
{"rcsp", { 2, "", UNKNOWN, 0x01f} },
|
||||
{"rcsp", { 1, "", UNKNOWN, 0x01f} }
|
||||
};
|
||||
|
||||
/* end: pyramid.opcode.h */
|
||||
/* One day I will have to take the time to find out what operands
|
||||
are valid for these insns, and guess at what they mean.
|
||||
|
||||
I can't imagine what the "I???" insns (iglob, etc) do.
|
||||
|
||||
the arithmetic-sounding insns ending in "p" sound awfully like BCD
|
||||
arithmetic insns:
|
||||
dshlp -> Decimal SHift Left Packed
|
||||
dshrp -> Decimal SHift Right Packed
|
||||
and cvtlp would be convert long to packed.
|
||||
I have no idea how the operands are interpreted; but having them be
|
||||
a long register with (address, length) of an in-memory packed BCD operand
|
||||
would not be surprising.
|
||||
They are unlikely to be a packed bcd string: 64 bits of long give
|
||||
is only 15 digits+sign, which isn't enough for COBOL.
|
||||
*/
|
||||
#if 0
|
||||
{"wcsp", { 2, "", UNKNOWN, 0x00} }, /*write csp?*/
|
||||
/* The OSx Operating System Porting Guide claims SSL does things
|
||||
with tr12 (a register reserved to it) to do with static block-structure
|
||||
references. SSL=Set Static Link? It's "Going away next release". */
|
||||
{"ssl", { 2, "", UNKNOWN, 0x00} },
|
||||
{"ccmps", { 2, "", UNKNOWN, 0x00} },
|
||||
{"lcd", { 2, "", UNKNOWN, 0x00} },
|
||||
{"uemul", { 2, "", UNKNOWN, 0x00} }, /*unsigned emul*/
|
||||
{"srf", { 2, "", UNKNOWN, 0x00} }, /*Gidget time???*/
|
||||
{"mnegp", { 2, "", UNKNOWN, 0x00} }, /move-neg phys?*/
|
||||
{"ldp", { 2, "", UNKNOWN, 0x00} }, /*load phys?*/
|
||||
{"ldti", { 2, "", UNKNOWN, 0x00} },
|
||||
{"ldb", { 2, "", UNKNOWN, 0x00} },
|
||||
{"stp", { 2, "", UNKNOWN, 0x00} },
|
||||
{"stti", { 2, "", UNKNOWN, 0x00} },
|
||||
{"stb", { 2, "", UNKNOWN, 0x00} },
|
||||
{"stu", { 2, "", UNKNOWN, 0x00} },
|
||||
{"addp", { 2, "", UNKNOWN, 0x00} },
|
||||
{"subp", { 2, "", UNKNOWN, 0x00} },
|
||||
{"mulp", { 2, "", UNKNOWN, 0x00} },
|
||||
{"divp", { 2, "", UNKNOWN, 0x00} },
|
||||
{"dshlp", { 2, "", UNKNOWN, 0x00} }, /* dec shl packed? */
|
||||
{"dshrp", { 2, "", UNKNOWN, 0x00} }, /* dec shr packed? */
|
||||
{"movs", { 2, "", UNKNOWN, 0x00} }, /*move (string?)?*/
|
||||
{"cmpp", { 2, "", UNKNOWN, 0x00} }, /* cmp phys?*/
|
||||
{"cmps", { 2, "", UNKNOWN, 0x00} }, /* cmp (string?)?*/
|
||||
{"cvtlp", { 2, "", UNKNOWN, 0x00} }, /* cvt long to p??*/
|
||||
{"cvtpl", { 2, "", UNKNOWN, 0x00} }, /* cvt p to l??*/
|
||||
{"dintr", { 2, "", UNKNOWN, 0x00} }, /* ?? intr ?*/
|
||||
{"rphysw", { 2, "", UNKNOWN, 0x00} }, /* read phys word?*/
|
||||
{"wphysw", { 2, "", UNKNOWN, 0x00} }, /* write phys word?*/
|
||||
{"cmovs", { 2, "", UNKNOWN, 0x00} },
|
||||
{"rsubw", { 2, "", UNKNOWN, 0x00} },
|
||||
{"bicpsw", { 2, "", UNKNOWN, 0x00} }, /* clr bit in psw? */
|
||||
{"bispsw", { 2, "", UNKNOWN, 0x00} }, /* set bit in psw? */
|
||||
{"eio", { 2, "", UNKNOWN, 0x00} }, /* ?? ?io ? */
|
||||
{"callp", { 2, "", UNKNOWN, 0x00} }, /* call phys?*/
|
||||
{"callr", { 2, "", UNKNOWN, 0x00} },
|
||||
{"lpcxt", { 2, "", UNKNOWN, 0x00} }, /*load proc context*/
|
||||
{"rei", { 2, "", UNKNOWN, 0x00} }, /*ret from intrpt*/
|
||||
{"rport", { 2, "", UNKNOWN, 0x00} }, /*read-port?*/
|
||||
{"rtod", { 2, "", UNKNOWN, 0x00} }, /*read-time-of-day?*/
|
||||
{"ssi", { 2, "", UNKNOWN, 0x00} },
|
||||
{"vtpa", { 2, "", UNKNOWN, 0x00} }, /*virt-to-phys-addr?*/
|
||||
{"wicl", { 2, "", UNKNOWN, 0x00} }, /* write icl ? */
|
||||
{"wport", { 2, "", UNKNOWN, 0x00} }, /*write-port?*/
|
||||
{"wtod", { 2, "", UNKNOWN, 0x00} }, /*write-time-of-day?*/
|
||||
{"flic", { 2, "", UNKNOWN, 0x00} },
|
||||
{"iglob", { 2, "", UNKNOWN, 0x00} }, /* I global? */
|
||||
{"iphys", { 2, "", UNKNOWN, 0x00} }, /* I physical? */
|
||||
{"ipid", { 2, "", UNKNOWN, 0x00} }, /* I pid? */
|
||||
{"ivect", { 2, "", UNKNOWN, 0x00} }, /* I vector? */
|
||||
{"lamst", { 2, "", UNKNOWN, 0x00} },
|
||||
{"tio", { 2, "", UNKNOWN, 0x00} },
|
||||
#endif
|
346
gdb/pyr-pinsn.c
Normal file
346
gdb/pyr-pinsn.c
Normal file
@ -0,0 +1,346 @@
|
||||
/* Disassembler for the Pyramid Technology 90x
|
||||
Copyright (C) 1988,1989 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GDB, the GNU disassembler.
|
||||
|
||||
GDB is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 1, or (at your option)
|
||||
any later version.
|
||||
|
||||
GDB is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "symtab.h"
|
||||
#include "opcode.h"
|
||||
|
||||
|
||||
/* A couple of functions used for debugging frame-handling on
|
||||
Pyramids. (The Pyramid-dependent handling of register values for
|
||||
windowed registers is known to be buggy.)
|
||||
|
||||
When debugging, these functions supplant the normal definitions of some
|
||||
of the macros in m-pyramid.h The quantity of information produced
|
||||
when these functions are used makes the gdb unusable as a
|
||||
debugger for user programs. */
|
||||
|
||||
extern unsigned pyr_saved_pc(), pyr_frame_chain();
|
||||
|
||||
CORE_ADDR pyr_frame_chain(frame)
|
||||
CORE_ADDR frame;
|
||||
{
|
||||
int foo=frame - CONTROL_STACK_FRAME_SIZE;
|
||||
/* printf ("...following chain from %x: got %x\n", frame, foo);*/
|
||||
return foo;
|
||||
}
|
||||
|
||||
CORE_ADDR pyr_saved_pc(frame)
|
||||
CORE_ADDR frame;
|
||||
{
|
||||
int foo=0;
|
||||
foo = read_memory_integer (((CORE_ADDR)(frame))+60, 4);
|
||||
printf ("..reading pc from frame 0x%0x+%d regs: got %0x\n",
|
||||
frame, 60/4, foo);
|
||||
return foo;
|
||||
}
|
||||
|
||||
|
||||
/* Pyramid instructions are never longer than this many bytes. */
|
||||
#define MAXLEN 24
|
||||
|
||||
/* Number of elements in the opcode table. */
|
||||
/*const*/ static int nopcodes = (sizeof (pyr_opcodes) / sizeof( pyr_opcodes[0]));
|
||||
#define NOPCODES (nopcodes)
|
||||
|
||||
extern char *reg_names[];
|
||||
|
||||
/* Let's be byte-independent so we can use this as a cross-assembler.
|
||||
(will this ever be useful?
|
||||
*/
|
||||
|
||||
#define NEXTLONG(p) \
|
||||
(p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])
|
||||
|
||||
|
||||
/* Print one 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, nargs, insn_size =4;
|
||||
register unsigned char *p;
|
||||
register char *d;
|
||||
register int insn_opcode, operand_mode;
|
||||
register int index_multiplier, index_reg_regno, op_1_regno, op_2_regno ;
|
||||
long insn; /* first word of the insn, not broken down. */
|
||||
pyr_insn_format insn_decode; /* the same, broken out into op{code,erands} */
|
||||
long extra_1, extra_2;
|
||||
|
||||
read_memory (memaddr, buffer, MAXLEN);
|
||||
insn_decode = *((pyr_insn_format *) buffer);
|
||||
insn = * ((int *) buffer);
|
||||
insn_opcode = insn_decode.operator;
|
||||
operand_mode = insn_decode.mode;
|
||||
index_multiplier = insn_decode.index_scale;
|
||||
index_reg_regno = insn_decode.index_reg;
|
||||
op_1_regno = insn_decode.operand_1;
|
||||
op_2_regno = insn_decode.operand_2;
|
||||
|
||||
|
||||
if (*((int *)buffer) == 0x0) {
|
||||
/* "halt" looks just like an invalid "jump" to the insn decoder,
|
||||
so is dealt with as a special case */
|
||||
fprintf (stream, "halt");
|
||||
return (4);
|
||||
}
|
||||
|
||||
for (i = 0; i < NOPCODES; i++)
|
||||
if (pyr_opcodes[i].datum.code == insn_opcode)
|
||||
break;
|
||||
|
||||
if (i == NOPCODES)
|
||||
/* FIXME: Handle unrecognised instructions better. */
|
||||
fprintf (stream, "???\t#%08x\t(op=%x mode =%x)",
|
||||
insn, insn_decode.operator, insn_decode.mode);
|
||||
else
|
||||
{
|
||||
/* Print the mnemonic for the instruction. Pyramid insn operands
|
||||
are so regular that we can deal with almost all of them
|
||||
separately.
|
||||
Unconditional branches are an exception: they are encoded as
|
||||
conditional branches (branch if false condition, I think)
|
||||
with no condition specified. The average user will not be
|
||||
aware of this. To maintain their illusion that an
|
||||
unconditional branch insn exists, we will have to FIXME to
|
||||
treat the insn mnemnonic of all branch instructions here as a
|
||||
special case: check the operands of branch insn and print an
|
||||
appropriate mnemonic. */
|
||||
|
||||
fprintf (stream, "%s\t", pyr_opcodes[i].name);
|
||||
|
||||
/* Print the operands of the insn (as specified in
|
||||
insn.operand_mode).
|
||||
Branch operands of branches are a special case: they are a word
|
||||
offset, not a byte offset. */
|
||||
|
||||
if (insn_decode.operator == 0x01 || insn_decode.operator == 0x02) {
|
||||
register int bit_codes=(insn >> 16)&0xf;
|
||||
register int i;
|
||||
register int displacement = (insn & 0x0000ffff) << 2;
|
||||
|
||||
static char cc_bit_names[] = "cvzn"; /* z,n,c,v: strange order? */
|
||||
|
||||
/* Is bfc and no bits specified an unconditional branch?*/
|
||||
for (i=0;i<4;i++) {
|
||||
if ((bit_codes) & 0x1)
|
||||
fputc (cc_bit_names[i], stream);
|
||||
bit_codes >>= 1;
|
||||
}
|
||||
|
||||
fprintf (stream, ",%0x",
|
||||
displacement + memaddr);
|
||||
return (insn_size);
|
||||
}
|
||||
|
||||
switch (operand_mode) {
|
||||
case 0:
|
||||
fprintf (stream, "%s,%s",
|
||||
reg_names [op_1_regno],
|
||||
reg_names [op_2_regno]);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
fprintf (stream, " 0x%0x,%s",
|
||||
op_1_regno,
|
||||
reg_names [op_2_regno]);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
read_memory (memaddr+4, buffer, MAXLEN);
|
||||
insn_size += 4;
|
||||
extra_1 = * ((int *) buffer);
|
||||
fprintf (stream, " $0x%0x,%s",
|
||||
extra_1,
|
||||
reg_names [op_2_regno]);
|
||||
break;
|
||||
case 3:
|
||||
fprintf (stream, " (%s),%s",
|
||||
reg_names [op_1_regno],
|
||||
reg_names [op_2_regno]);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
read_memory (memaddr+4, buffer, MAXLEN);
|
||||
insn_size += 4;
|
||||
extra_1 = * ((int *) buffer);
|
||||
fprintf (stream, " 0x%0x(%s),%s",
|
||||
extra_1,
|
||||
reg_names [op_1_regno],
|
||||
reg_names [op_2_regno]);
|
||||
break;
|
||||
|
||||
/* S1 destination mode */
|
||||
case 5:
|
||||
fprintf (stream,
|
||||
((index_reg_regno) ? "%s,(%s)[%s*%1d]" : "%s,(%s)"),
|
||||
reg_names [op_1_regno],
|
||||
reg_names [op_2_regno],
|
||||
reg_names [index_reg_regno],
|
||||
index_multiplier);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
fprintf (stream,
|
||||
((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]"
|
||||
: " $%#0x,(%s)"),
|
||||
op_1_regno,
|
||||
reg_names [op_2_regno],
|
||||
reg_names [index_reg_regno],
|
||||
index_multiplier);
|
||||
break;
|
||||
|
||||
case 7:
|
||||
read_memory (memaddr+4, buffer, MAXLEN);
|
||||
insn_size += 4;
|
||||
extra_1 = * ((int *) buffer);
|
||||
fprintf (stream,
|
||||
((index_reg_regno) ? " $%#0x,(%s)[%s*%1d]"
|
||||
: " $%#0x,(%s)"),
|
||||
extra_1,
|
||||
reg_names [op_2_regno],
|
||||
reg_names [index_reg_regno],
|
||||
index_multiplier);
|
||||
break;
|
||||
|
||||
case 8:
|
||||
fprintf (stream,
|
||||
((index_reg_regno) ? " (%s),(%s)[%s*%1d]" : " (%s),(%s)"),
|
||||
reg_names [op_1_regno],
|
||||
reg_names [op_2_regno],
|
||||
reg_names [index_reg_regno],
|
||||
index_multiplier);
|
||||
break;
|
||||
|
||||
case 9:
|
||||
read_memory (memaddr+4, buffer, MAXLEN);
|
||||
insn_size += 4;
|
||||
extra_1 = * ((int *) buffer);
|
||||
fprintf (stream,
|
||||
((index_reg_regno)
|
||||
? "%#0x(%s),(%s)[%s*%1d]"
|
||||
: "%#0x(%s),(%s)"),
|
||||
extra_1,
|
||||
reg_names [op_1_regno],
|
||||
reg_names [op_2_regno],
|
||||
reg_names [index_reg_regno],
|
||||
index_multiplier);
|
||||
break;
|
||||
|
||||
/* S2 destination mode */
|
||||
case 10:
|
||||
read_memory (memaddr+4, buffer, MAXLEN);
|
||||
insn_size += 4;
|
||||
extra_1 = * ((int *) buffer);
|
||||
fprintf (stream,
|
||||
((index_reg_regno) ? "%s,%#0x(%s)[%s*%1d]" : "%s,%#0x(%s)"),
|
||||
reg_names [op_1_regno],
|
||||
extra_1,
|
||||
reg_names [op_2_regno],
|
||||
reg_names [index_reg_regno],
|
||||
index_multiplier);
|
||||
break;
|
||||
case 11:
|
||||
read_memory (memaddr+4, buffer, MAXLEN);
|
||||
insn_size += 4;
|
||||
extra_1 = * ((int *) buffer);
|
||||
fprintf (stream,
|
||||
((index_reg_regno) ?
|
||||
" $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
|
||||
op_1_regno,
|
||||
extra_1,
|
||||
reg_names [op_2_regno],
|
||||
reg_names [index_reg_regno],
|
||||
index_multiplier);
|
||||
break;
|
||||
case 12:
|
||||
read_memory (memaddr+4, buffer, MAXLEN);
|
||||
insn_size += 4;
|
||||
extra_1 = * ((int *) buffer);
|
||||
read_memory (memaddr+8, buffer, MAXLEN);
|
||||
insn_size += 4;
|
||||
extra_2 = * ((int *) buffer);
|
||||
fprintf (stream,
|
||||
((index_reg_regno) ?
|
||||
" $%#0x,%#0x(%s)[%s*%1d]" : " $%#0x,%#0x(%s)"),
|
||||
extra_1,
|
||||
extra_2,
|
||||
reg_names [op_2_regno],
|
||||
reg_names [index_reg_regno],
|
||||
index_multiplier);
|
||||
break;
|
||||
|
||||
case 13:
|
||||
read_memory (memaddr+4, buffer, MAXLEN);
|
||||
insn_size += 4;
|
||||
extra_1 = * ((int *) buffer);
|
||||
fprintf (stream,
|
||||
((index_reg_regno)
|
||||
? " (%s),%#0x(%s)[%s*%1d]"
|
||||
: " (%s),%#0x(%s)"),
|
||||
reg_names [op_1_regno],
|
||||
extra_1,
|
||||
reg_names [op_2_regno],
|
||||
reg_names [index_reg_regno],
|
||||
index_multiplier);
|
||||
break;
|
||||
case 14:
|
||||
read_memory (memaddr+4, buffer, MAXLEN);
|
||||
insn_size += 4;
|
||||
extra_1 = * ((int *) buffer);
|
||||
read_memory (memaddr+8, buffer, MAXLEN);
|
||||
insn_size += 4;
|
||||
extra_2 = * ((int *) buffer);
|
||||
fprintf (stream,
|
||||
((index_reg_regno) ? "%#0x(%s),%#0x(%s)[%s*%1d]"
|
||||
: "%#0x(%s),%#0x(%s) "),
|
||||
extra_1,
|
||||
reg_names [op_1_regno],
|
||||
extra_2,
|
||||
reg_names [op_2_regno],
|
||||
reg_names [index_reg_regno],
|
||||
index_multiplier);
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf (stream,
|
||||
((index_reg_regno) ? "%s,%s [%s*%1d]" : "%s,%s"),
|
||||
reg_names [op_1_regno],
|
||||
reg_names [op_2_regno],
|
||||
reg_names [index_reg_regno],
|
||||
index_multiplier);
|
||||
fprintf (stream,
|
||||
"\t\t# unknown mode in %08x",
|
||||
insn);
|
||||
break;
|
||||
} /* switch */
|
||||
}
|
||||
|
||||
{
|
||||
return insn_size;
|
||||
}
|
||||
abort ();
|
||||
}
|
@ -1,9 +1,22 @@
|
||||
Thu Feb 8 01:04:00 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
|
||||
|
||||
* Makefile (the *other* libreadline.a): Uncomment out ranlib line.
|
||||
|
||||
Thu Feb 1 17:50:22 1990 Jim Kingdon (kingdon at pogo.ai.mit.edu)
|
||||
|
||||
* Makefile (libreadline.a): Uncomment out ranlib line.
|
||||
|
||||
Sun Nov 26 16:29:11 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* readline.c (rl_deprep_terminal): Only restore local_mode_flags
|
||||
if they had been set.
|
||||
|
||||
Thu Oct 19 17:18:40 1989 Jim Kingdon (kingdon at hobbes.ai.mit.edu)
|
||||
|
||||
* Move vi_doing_insert from vi_mode.c to readline.c
|
||||
|
||||
* readline.c: Move compare_strings before its use.
|
||||
Remove definitions.
|
||||
Remove declarations.
|
||||
|
||||
* readline.c: Move defining_kbd_macro above rl_dispatch.
|
||||
(rl_dispatch): Remove "extern int defining_kbd_macro".
|
||||
|
@ -65,7 +65,7 @@ all: libreadline.a
|
||||
libreadline.a: readline.o history.o funmap.o keymaps.o
|
||||
$(RM) -f libreadline.a
|
||||
$(AR) clq libreadline.a readline.o history.o funmap.o keymaps.o
|
||||
# if [ -f $(RANLIB) ]; then $(RANLIB) libreadline.a; fi
|
||||
if [ -f $(RANLIB) ]; then $(RANLIB) libreadline.a; fi
|
||||
|
||||
readline.o: readline.h chardefs.h keymaps.h history.h readline.c vi_mode.c
|
||||
$(CC) -c $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
|
||||
@ -111,4 +111,4 @@ clean:
|
||||
$(DESTDIR)/libreadline.a: libreadline.a
|
||||
-mv $(DESTDIR)/libreadline.a $(DESTDIR)/libreadline.old
|
||||
cp libreadline.a $(DESTDIR)/libreadline.a
|
||||
# $(RANLIB) -t $(DESTDIR)/libreadline.a
|
||||
$(RANLIB) -t $(DESTDIR)/libreadline.a
|
||||
|
194
gdb/readline/history.texinfo
Normal file
194
gdb/readline/history.texinfo
Normal file
@ -0,0 +1,194 @@
|
||||
\input texinfo.tex
|
||||
@setfilename history.info
|
||||
|
||||
@ifinfo
|
||||
This file documents the GNU History library.
|
||||
|
||||
Copyright (C) 1988 Free Software Foundation, Inc.
|
||||
Authored by Brian Fox.
|
||||
|
||||
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
|
||||
GNU Copyright statement is available to the distributee, 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.
|
||||
@end ifinfo
|
||||
|
||||
@node Top, Introduction, , (DIR)
|
||||
|
||||
This document describes the GNU History library, a programming tool that
|
||||
provides a consistent user interface for recalling lines of previously
|
||||
typed input.
|
||||
|
||||
@menu
|
||||
* Introduction:: What is the GNU History library for?
|
||||
* Interactive Use:: What it feels like using History as a user.
|
||||
* Programming:: How to use History in your programs.
|
||||
@end menu
|
||||
|
||||
@node Introduction, Interactive Use, , Top
|
||||
@unnumbered Introduction
|
||||
|
||||
Many programs read input from the user a line at a time. The GNU history
|
||||
library is able to keep track of those lines, associate arbitrary data with
|
||||
each line, and utilize information from previous lines in making up new
|
||||
ones.
|
||||
|
||||
The programmer using the History library has available to him functions for
|
||||
remembering lines on a history stack, associating arbitrary data with a
|
||||
line, removing lines from the stack, searching through the stack for a
|
||||
line containing an arbitrary text string, and referencing any line on the
|
||||
stack directly. In addition, a history @dfn{expansion} function is
|
||||
available which provides for a consistent user interface across many
|
||||
different programs.
|
||||
|
||||
The end-user using programs written with the History library has the
|
||||
benifit of a consistent user interface, with a set of well-known commands
|
||||
for manipulating the text of previous lines and using that text in new
|
||||
commands. The basic history manipulation commands are similar to the
|
||||
history substitution used by Csh.
|
||||
|
||||
If the programmer desires, he can use the Readline library, which includes
|
||||
history manipulation by default, and has the added advantage of Emacs style
|
||||
command line editing.
|
||||
|
||||
@node Interactive Use, Programming, Introduction, Top
|
||||
@chapter Interactive Use
|
||||
|
||||
@section History Expansion
|
||||
@cindex expansion
|
||||
|
||||
The History library provides a history expansion feature that is similar to
|
||||
the history expansion in Csh. The following text describes what syntax
|
||||
features are available.
|
||||
|
||||
History expansion takes place in two parts. The first is to determine
|
||||
which line from the previous history should be used during substitution.
|
||||
The second is to select portions of that line for inclusion into the
|
||||
current one. The line selected from the previous history is called the
|
||||
@dfn{event}, and the portions of that line that are acted upon are called
|
||||
@dfn{words}. The line is broken into words in the same fashion that the
|
||||
Bash shell does, so that several English (or Unix) words surrounded by
|
||||
quotes are considered as one word.
|
||||
|
||||
@menu
|
||||
* Event Designators:: How to specify which history line to use.
|
||||
* Word Designators:: Specifying which words are of interest.
|
||||
* Modifiers:: Modifying the results of susbstitution.
|
||||
@end menu
|
||||
|
||||
@node Event Designators, Word Designators, , Interactive Use
|
||||
@subsection Event Designators
|
||||
@cindex event designators
|
||||
|
||||
An event designator is a reference to a command line entry in the history
|
||||
list.
|
||||
|
||||
@table @var
|
||||
|
||||
@item !
|
||||
Start a history subsititution, except when followed by a @key{SPC},
|
||||
@key{TAB}, @key{RET}, @key{=} or @key{(}.
|
||||
|
||||
@item !!
|
||||
Refer to the previous command. This is a synonym for @code{!-1}.
|
||||
|
||||
@item !n
|
||||
Refer to command line @var{n}.
|
||||
|
||||
@item !-n
|
||||
Refer to the current command line minus @var{n}.
|
||||
|
||||
@item !string
|
||||
Refer to the most recent command starting with @var{string}.
|
||||
|
||||
@item !?string[?]
|
||||
Refer to the most recent command containing @var{string}.
|
||||
|
||||
@end table
|
||||
|
||||
@node Word Designators, Modifiers, Event Designators, Interactive Use
|
||||
@subsection Word Designators
|
||||
|
||||
A @key{:} separates the event specification from the word designator. It
|
||||
can be omitted if the word designator begins with a @key{^}, @key{$},
|
||||
@key{*} or @key{%}. Words are numbered from the beginning of the line,
|
||||
with the first word being denoted by a 0 (zero).
|
||||
|
||||
@table @asis
|
||||
|
||||
@item @var{0} (zero)
|
||||
The zero'th word. For many applications, this is the command word.
|
||||
|
||||
@item n
|
||||
The @var{n}'th word.
|
||||
|
||||
@item @var{^}
|
||||
The first argument. that is, word 1.
|
||||
|
||||
@item @var{$}
|
||||
The last argument.
|
||||
|
||||
@item @var{%}
|
||||
The word matched by the most recent @code{?string?} search.
|
||||
|
||||
@item @var{x}-@var{y}
|
||||
A range of words; @code{-@var{y}} is equivalent to @code{0-@var{y}}.
|
||||
|
||||
@item @var{*}
|
||||
All of the words, excepting the zero'th. This is a synonym for @samp{1-$}.
|
||||
It is not an error to use @samp{*} if there is just one word in the event.
|
||||
The empty string is returned in that case.
|
||||
|
||||
@end table
|
||||
|
||||
@node Modifiers, , Word Designators, Interactive Use
|
||||
@subsection Modifiers
|
||||
|
||||
After the optional word designator, you can add a sequence of one or more
|
||||
of the following modifiers, each preceded by a @key{:}.
|
||||
|
||||
@table @code
|
||||
|
||||
@item #
|
||||
The entire command line typed so far. This means the current command,
|
||||
not the previous command, so it really isn't a word designator, and doesn't
|
||||
belong in this section.
|
||||
|
||||
@item h
|
||||
Remove a trailing pathname component, leaving only the head.
|
||||
|
||||
@item r
|
||||
Remove a trailing suffix of the form ".xxx", leaving the basename.
|
||||
|
||||
@item e
|
||||
Remove all but the suffix.
|
||||
|
||||
@item t
|
||||
Remove all leading pathname components, leaving the tail.
|
||||
|
||||
@item p
|
||||
Print the new command but do not execute it. This takes effect
|
||||
immediately, so it should be the last specifier on the line.
|
||||
|
||||
@end table
|
||||
|
||||
@node Programming, , Interactive Use, Top
|
||||
@chapter Programming
|
||||
|
||||
@bye
|
||||
|
@ -2078,7 +2078,8 @@ rl_deprep_terminal ()
|
||||
int tty = fileno (rl_instream);
|
||||
|
||||
#if defined (TIOCLGET) && defined (LPASS8)
|
||||
ioctl (tty, TIOCLSET, &local_mode_flags);
|
||||
if ((the_ttybuff.sg_flags & (ODDP | EVENP)) == (ODDP | EVENP))
|
||||
ioctl (tty, TIOCLSET, &local_mode_flags);
|
||||
#endif
|
||||
|
||||
#ifdef TIOCSLTC
|
||||
|
425
gdb/readline/readline.texinfo
Normal file
425
gdb/readline/readline.texinfo
Normal file
@ -0,0 +1,425 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@comment %**start of header (This is for running Texinfo on a region.)
|
||||
@setfilename readline.info
|
||||
@settitle Line Editing Commands
|
||||
@comment %**end of header (This is for running Texinfo on a region.)
|
||||
@synindex fn vr
|
||||
|
||||
@iftex
|
||||
@comment finalout
|
||||
@end iftex
|
||||
|
||||
@ifinfo
|
||||
This document describes the GNU Readline Library, a utility for aiding
|
||||
in the consitency of user interface across discrete programs that need
|
||||
to provide a command line interface.
|
||||
|
||||
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
|
||||
pare 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 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 this permission notice may be stated in a translation approved
|
||||
by the Foundation.
|
||||
@end ifinfo
|
||||
|
||||
@setchapternewpage odd
|
||||
@titlepage
|
||||
@sp 11
|
||||
@center @titlefont{GNU Readline Library}
|
||||
@sp 2
|
||||
@center by Brian Fox
|
||||
@sp 2
|
||||
@center Version 1.0
|
||||
@sp 2
|
||||
@center February 1989
|
||||
|
||||
@comment Include the Distribution inside the titlepage environment so
|
||||
@c that headings are turned off.
|
||||
|
||||
@page
|
||||
@vskip 0pt plus 1filll
|
||||
Copyright @copyright{} 1989 Free Software Foundation, Inc.
|
||||
|
||||
@sp 2
|
||||
This document describes the GNU Readline Library, a utility for aiding
|
||||
in the consistency of user interface across discrete programs that need
|
||||
to provide a command line interface.
|
||||
@sp 2
|
||||
|
||||
Published by the Free Software Foundation @*
|
||||
675 Massachusetts Avenue, @*
|
||||
Cambridge, MA 02139 USA
|
||||
|
||||
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 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 this permission notice may be stated in a translation approved
|
||||
by the Foundation.
|
||||
|
||||
@end titlepage
|
||||
|
||||
@node Top, Readline Top, ,(DIR)
|
||||
@chapter GNU Readline Library
|
||||
|
||||
@ifinfo
|
||||
This document describes the GNU Readline Library, a utility for aiding
|
||||
in the consistency of user interface across discrete programs that need
|
||||
to provide a command line interface.
|
||||
@end ifinfo
|
||||
|
||||
@menu
|
||||
* Readline Top:: GNU Readline User's Manual
|
||||
* Readline Technical:: GNU Readline Programmer's Manual
|
||||
@end menu
|
||||
@include inc-readline.texinfo
|
||||
@node Readline Technical, , Top, Top
|
||||
@chapter Readline Programmer's Manual
|
||||
|
||||
This manual describes the interface between the GNU Readline Library and
|
||||
user programs. If you are a programmer, and you wish to include the
|
||||
features found in GNU Readline in your own programs, such as completion,
|
||||
line editing, and interactive history manipulation, this documentation
|
||||
is for you.
|
||||
|
||||
@menu
|
||||
* Default Behaviour:: Using the default behaviour of Readline.
|
||||
* Custom Functions:: Adding your own functions to Readline.
|
||||
* Custom Completers:: Supplanting or supplementing Readline's
|
||||
completion functions.
|
||||
* Variable Index:: Index of externally tweakable variables.
|
||||
@end menu
|
||||
|
||||
@node Default Behaviour, Custom Functions, Readline Technical, Readline Technical
|
||||
@section Default Behaviour
|
||||
|
||||
Many programs provide a command line interface, such as @code{mail},
|
||||
@code{ftp}, and @code{sh}. For such programs, the default behaviour of
|
||||
Readline is sufficient. This section describes how to use Readline in
|
||||
the simplest way possible, perhaps to replace calls in your code to
|
||||
@code{gets ()}.
|
||||
|
||||
@findex readline ()
|
||||
@cindex readline, function
|
||||
The function @code{readline} prints a prompt and then reads and returns
|
||||
a single line of text from the user. The line which @code{readline ()}
|
||||
returns is allocated with @code{malloc ()}; you should @code{free ()}
|
||||
the line when you are done with it. The declaration in ANSI C is
|
||||
|
||||
@example
|
||||
@code{char *readline (char *@var{prompt});}
|
||||
@end example
|
||||
|
||||
So, one might say
|
||||
@example
|
||||
@code{char *line = readline ("Enter a line: ");}
|
||||
@end example
|
||||
in order to read a line of text from the user.
|
||||
|
||||
The line which is returned has the final newline removed, so only the
|
||||
text of the line remains.
|
||||
|
||||
If readline encounters an EOF while reading the line, and the line is
|
||||
empty at that point, then @code{(char *)NULL} is returned. Otherwise,
|
||||
the line is ended just as if a newline was typed.
|
||||
|
||||
If you want the user to be able to get at the line later, (with
|
||||
@key{C-p} for example), you must call @code{add_history ()} to save the
|
||||
line away in a @dfn{history} list of such lines.
|
||||
|
||||
@example
|
||||
@code{add_history (line)};
|
||||
@end example
|
||||
|
||||
For full details on the GNU History Library, see the associated manual.
|
||||
|
||||
It is polite to avoid saving empty lines on the history list, since
|
||||
no one has a burning need to reuse a blank line. Here is a function
|
||||
which usefully replaces the standard @code{gets ()} library function:
|
||||
|
||||
@example
|
||||
/* A static variable for holding the line. */
|
||||
static char *my_gets_line = (char *)NULL;
|
||||
|
||||
/* Read a string, and return a pointer to it. Returns NULL on EOF. */
|
||||
char *
|
||||
my_gets ()
|
||||
@{
|
||||
/* If the buffer has already been allocated, return the memory
|
||||
to the free pool. */
|
||||
if (my_gets_line != (char *)NULL)
|
||||
free (my_gets_line);
|
||||
|
||||
/* Get a line from the user. */
|
||||
my_gets_line = readline ("");
|
||||
|
||||
/* If the line has any text in it, save it on the history. */
|
||||
if (my_get_line && *my_gets_line)
|
||||
add_history (my_gets_line);
|
||||
|
||||
return (my_gets_line);
|
||||
@}
|
||||
@end example
|
||||
|
||||
The above code gives the user the default behaviour of @key{TAB}
|
||||
completion: completion on file names. If you do not want readline to
|
||||
complete on filenames, you can change the binding of the @key{TAB} key
|
||||
with @code{rl_bind_key ()}.
|
||||
|
||||
@findex rl_bind_key ()
|
||||
|
||||
@example
|
||||
@code{int rl_bind_key (int @var{key}, (int (*)())@var{function});}
|
||||
@end example
|
||||
|
||||
@code{rl_bind_key ()} takes 2 arguments; @var{key} is the character that
|
||||
you want to bind, and @var{function} is the address of the function to
|
||||
run when @var{key} is pressed. Binding @key{TAB} to @code{rl_insert ()}
|
||||
makes @key{TAB} just insert itself.
|
||||
|
||||
@code{rl_bind_key ()} returns non-zero if @var{key} is not a valid
|
||||
ASCII character code (between 0 and 255).
|
||||
|
||||
@example
|
||||
@code{rl_bind_key ('\t', rl_insert);}
|
||||
@end example
|
||||
|
||||
@node Custom Functions, Custom Completers, Default Behaviour, Readline Technical
|
||||
@section Custom Functions
|
||||
|
||||
Readline provides a great many functions for manipulating the text of
|
||||
the line. But it isn't possible to anticipate the needs of all
|
||||
programs. This section describes the various functions and variables
|
||||
defined in within the Readline library which allow a user program to add
|
||||
customized functionality to Readline.
|
||||
|
||||
@menu
|
||||
* The Function Type:: C declarations to make code readable.
|
||||
* Function Naming:: How to give a function you write a name.
|
||||
* Keymaps:: Making keymaps.
|
||||
* Binding Keys:: Changing Keymaps.
|
||||
* Function Writing:: Variables and calling conventions.
|
||||
* Allowing Undoing:: How to make your functions undoable.
|
||||
@end menu
|
||||
|
||||
@node The Function Type, Function Naming, Custom Functions, Custom Functions
|
||||
For the sake of readabilty, we declare a new type of object, called
|
||||
@dfn{Function}. `Function' is a C language function which returns an
|
||||
@code{int}. The type declaration for `Function' is:
|
||||
|
||||
@code{typedef int Function ();}
|
||||
|
||||
The reason for declaring this new type is to make it easier to discuss
|
||||
pointers to C functions. Let us say we had a variable called @var{func}
|
||||
which was a pointer to a function. Instead of the classic C declaration
|
||||
|
||||
@code{int (*)()func;}
|
||||
|
||||
we have
|
||||
|
||||
@code{Function *func;}
|
||||
|
||||
@node Function Naming, Keymaps, The Function Type, Custom Functions
|
||||
@subsection Naming a Function
|
||||
|
||||
The user can dynamically change the bindings of keys while using
|
||||
Readline. This is done by representing the function with a descriptive
|
||||
name. The user is able to type the descriptive name when referring to
|
||||
the function. Thus, in an init file, one might find
|
||||
|
||||
@example
|
||||
Meta-Rubout: backward-kill-word
|
||||
@end example
|
||||
|
||||
This binds @key{Meta-Rubout} to the function @emph{descriptively} named
|
||||
@code{backward-kill-word}. You, as a programmer, should bind the
|
||||
functions you write to descriptive names as well. Here is how to do
|
||||
that.
|
||||
|
||||
@defun rl_add_defun (char *name, Function *function, int key)
|
||||
Add @var{name} to the list of named functions. Make @var{function} be
|
||||
the function that gets called. If @var{key} is not -1, then bind it to
|
||||
@var{function} using @code{rl_bind_key ()}.
|
||||
@end defun
|
||||
|
||||
Using this function alone is sufficient for most applications. It is
|
||||
the recommended way to add a few functions to the default functions that
|
||||
Readline has built in already. If you need to do more or different
|
||||
things than adding a function to Readline, you may need to use the
|
||||
underlying functions described below.
|
||||
|
||||
@node Keymaps, Binding Keys, Function Naming, Custom Functions
|
||||
@subsection Selecting a Keymap
|
||||
|
||||
Key bindings take place on a @dfn{keymap}. The keymap is the
|
||||
association between the keys that the user types and the functions that
|
||||
get run. You can make your own keymaps, copy existing keymaps, and tell
|
||||
Readline which keymap to use.
|
||||
|
||||
@defun rl_make_bare_keymap ()
|
||||
Returns a new, empty keymap. The space for the keymap is allocated with
|
||||
@code{malloc ()}; you should @code{free ()} it when you are done.
|
||||
@end defun
|
||||
|
||||
@defun rl_copy_keymap (Keymap map)
|
||||
Return a new keymap which is a copy of @var{map}.
|
||||
@end defun
|
||||
|
||||
@defun rl_make_keymap ()
|
||||
Return a new keymap with the printing characters bound to rl_insert,
|
||||
the lowercase Meta characters bound to run their equivalents, and
|
||||
the Meta digits bound to produce numeric arguments.
|
||||
@end defun
|
||||
|
||||
@node Binding Keys, Function Writing, Keymaps, Custom Functions
|
||||
@subsection Binding Keys
|
||||
|
||||
You associate keys with functions through the keymap. Here are
|
||||
the functions for doing that.
|
||||
|
||||
@defun rl_bind_key (int key, Function *function)
|
||||
Binds @var{key} to @var{function} in the currently selected keymap.
|
||||
Returns non-zero in the case of an invalid @var{key}.
|
||||
@end defun
|
||||
|
||||
@defun rl_bind_key_in_map (int key, Function *function, Keymap map)
|
||||
Bind @var{key} to @var{function} in @var{map}. Returns non-zero in the case
|
||||
of an invalid @var{key}.
|
||||
@end defun
|
||||
|
||||
@defun rl_unbind_key (int key)
|
||||
Make @var{key} do nothing in the currently selected keymap.
|
||||
Returns non-zero in case of error.
|
||||
@end defun
|
||||
|
||||
@defun rl_unbind_key_in_map (int key, Keymap map)
|
||||
Make @var{key} be bound to the null function in @var{map}.
|
||||
Returns non-zero in case of error.
|
||||
@end defun
|
||||
|
||||
@node Function Writing, Allowing Undoing, Binding Keys, Custom Functions
|
||||
@subsection Writing a New Function
|
||||
|
||||
In order to write new functions for Readline, you need to know the
|
||||
calling conventions for keyboard invoked functions, and the names of the
|
||||
variables that describe the current state of the line gathered so far.
|
||||
|
||||
@defvar char *rl_line_buffer
|
||||
This is the line gathered so far. You are welcome to modify the
|
||||
contents of this, but see Undoing, below.
|
||||
@end defvar
|
||||
|
||||
@defvar int rl_point
|
||||
The offset of the current cursor position in @var{rl_line_buffer}.
|
||||
@end defvar
|
||||
|
||||
@defvar int rl_end
|
||||
The number of characters present in @code{rl_line_buffer}. When
|
||||
@code{rl_point} is at the end of the line, then @code{rl_point} and
|
||||
@code{rl_end} are equal.
|
||||
@end defvar
|
||||
|
||||
The calling sequence for a command @code{foo} looks like
|
||||
|
||||
@example
|
||||
@code{foo (count, key)}
|
||||
@end example
|
||||
|
||||
where @var{count} is the numeric argument (or 1 if defaulted) and
|
||||
@var{key} is the key that invoked this function.
|
||||
|
||||
It is completely up to the function as to what should be done with the
|
||||
numeric argument; some functions use it as a repeat count, other
|
||||
functions as a flag, and some choose to ignore it. In general, if a
|
||||
function uses the numeric argument as a repeat count, it should be able
|
||||
to do something useful with a negative argument as well as a positive
|
||||
argument. At the very least, it should be aware that it can be passed a
|
||||
negative argument.
|
||||
|
||||
@node Allowing Undoing, , Function Writing, Custom Functions
|
||||
@subsection Allowing Undoing
|
||||
|
||||
Supporting the undo command is a painless thing to do, and makes your
|
||||
function much more useful to the end user. It is certainly easy to try
|
||||
something if you know you can undo it. I could use an undo function for
|
||||
the stock market.
|
||||
|
||||
If your function simply inserts text once, or deletes text once, and it
|
||||
calls @code{rl_insert_text ()} or @code{rl_delete_text ()} to do it, then
|
||||
undoing is already done for you automatically, and you can safely skip
|
||||
this section.
|
||||
|
||||
If you do multiple insertions or multiple deletions, or any combination
|
||||
of these operations, you will want to group them together into one
|
||||
operation. This can be done with @code{rl_begin_undo_group ()} and
|
||||
@code{rl_end_undo_group ()}.
|
||||
|
||||
@defun rl_begin_undo_group ()
|
||||
Begins saving undo information in a group construct. The undo
|
||||
information usually comes from calls to @code{rl_insert_text ()} and
|
||||
@code{rl_delete_text ()}, but they could be direct calls to
|
||||
@code{rl_add_undo ()}.
|
||||
@end defun
|
||||
|
||||
@defun rl_end_undo_group ()
|
||||
Closes the current undo group started with @code{rl_begin_undo_group
|
||||
()}. There should be exactly one call to @code{rl_end_undo_group ()}
|
||||
for every call to @code{rl_begin_undo_group ()}.
|
||||
@end defun
|
||||
|
||||
Finally, if you neither insert nor delete text, but directly modify the
|
||||
existing text (e.g. change its case), you call @code{rl_modifying ()}
|
||||
once, just before you modify the text. You must supply the indices of
|
||||
the text range that you are going to modify.
|
||||
|
||||
@defun rl_modifying (int start, int end)
|
||||
Tell Readline to save the text between @var{start} and @var{end} as a
|
||||
single undo unit. It is assumed that subsequent to this call you will
|
||||
modify that range of text in some way.
|
||||
@end defun
|
||||
|
||||
@subsection An Example
|
||||
|
||||
Let us say that we are actually going to put an example here.
|
||||
|
||||
@node Custom Completers, Variable Index, Custom Functions, Readline Technical
|
||||
|
||||
Typically, a program that reads commands from the user has a way of
|
||||
disambiguating between commands and data. If your program is one of
|
||||
these, then it can provide completion for either commands, or data, or
|
||||
both commands and data. The following sections describe how your
|
||||
program and Readline cooperate to provide this service to end users.
|
||||
|
||||
@menu
|
||||
@end menu
|
||||
|
||||
@node Variable Index, , Custom Completers, Readline Technical
|
||||
@appendix Variable Index
|
||||
@printindex vr
|
||||
@contents
|
||||
|
||||
@bye
|
||||
|
@ -66,6 +66,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
kill req k
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
@ -78,7 +79,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/file.h>
|
||||
|
12
gdb/source.c
12
gdb/source.c
@ -17,6 +17,7 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "param.h"
|
||||
@ -26,7 +27,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
@ -370,12 +370,14 @@ find_source_lines (s, desc)
|
||||
int *line_charpos = (int *) xmalloc (lines_allocated * sizeof (int));
|
||||
extern int exec_mtime;
|
||||
|
||||
fstat (desc, &st);
|
||||
if (fstat (desc, &st) < 0)
|
||||
perror_with_name (s->filename);
|
||||
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);
|
||||
if (myread (desc, data, st.st_size) < 0)
|
||||
perror_with_name (s->filename);
|
||||
end = data + st.st_size;
|
||||
p = data;
|
||||
line_charpos[0] = 0;
|
||||
@ -525,8 +527,8 @@ print_source_lines (s, line, stopline, noerror)
|
||||
if (line < 1 || line > s->nlines)
|
||||
{
|
||||
close (desc);
|
||||
error ("Line number out of range; %s has %d lines.",
|
||||
s->filename, s->nlines);
|
||||
error ("Line number %d out of range; %s has %d lines.",
|
||||
line, s->filename, s->nlines);
|
||||
}
|
||||
|
||||
if (lseek (desc, s->line_charpos[line - 1], 0) < 0)
|
||||
|
@ -19,13 +19,13 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
#include "obstack.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <sys/user.h>
|
||||
@ -700,10 +700,12 @@ exec_file_command (filename, from_tty)
|
||||
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)
|
||||
if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read text section header", execfile);
|
||||
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read data section header", execfile);
|
||||
|
||||
text_start = exec_aouthdr.text_start;
|
||||
|
@ -18,12 +18,12 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <sys/user.h>
|
||||
@ -175,16 +175,23 @@ store_inferior_registers (regno)
|
||||
else
|
||||
{
|
||||
bcopy (registers, &inferior_registers, 16 * 4);
|
||||
#ifdef FP0_REGNUM
|
||||
bcopy (®isters[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
|
||||
sizeof inferior_fp_registers.fps_regs);
|
||||
#endif
|
||||
inferior_registers.r_ps = *(int *)®isters[REGISTER_BYTE (PS_REGNUM)];
|
||||
inferior_registers.r_pc = *(int *)®isters[REGISTER_BYTE (PC_REGNUM)];
|
||||
|
||||
#ifdef FP0_REGNUM
|
||||
bcopy (®isters[REGISTER_BYTE (FPC_REGNUM)],
|
||||
&inferior_fp_registers.fps_control,
|
||||
sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs);
|
||||
#endif
|
||||
|
||||
ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers);
|
||||
#if FP0_REGNUM
|
||||
ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -548,10 +555,12 @@ exec_file_command (filename, from_tty)
|
||||
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)
|
||||
if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read text section header", execfile);
|
||||
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read data section header", execfile);
|
||||
|
||||
text_start = exec_aouthdr.text_start;
|
||||
|
@ -19,13 +19,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* many 387-specific items of use taken from i386-dep.c */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
#include "symtab.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/user.h>
|
||||
@ -570,10 +570,12 @@ exec_file_command (filename, from_tty)
|
||||
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)
|
||||
if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read text section header", execfile);
|
||||
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read data section header", execfile);
|
||||
|
||||
text_start = exec_aouthdr.text_start;
|
||||
|
@ -456,7 +456,7 @@ print_symbol (symbol, depth, outfile)
|
||||
print_spaces (depth, outfile);
|
||||
if (SYMBOL_NAMESPACE (symbol) == LABEL_NAMESPACE)
|
||||
{
|
||||
fprintf (outfile, "label %s at 0x%x", SYMBOL_NAME (symbol),
|
||||
fprintf (outfile, "label %s at 0x%x\n", SYMBOL_NAME (symbol),
|
||||
SYMBOL_VALUE (symbol));
|
||||
return;
|
||||
}
|
||||
|
12
gdb/symseg.h
12
gdb/symseg.h
@ -286,7 +286,12 @@ struct type
|
||||
/* If this type has a base class, put it here.
|
||||
If this type is a pointer type, the chain of member pointer
|
||||
types goes here.
|
||||
Unused otherwise. */
|
||||
Unused otherwise.
|
||||
|
||||
Contrary to all maxims of C style and common sense, the baseclasses
|
||||
are indexed from 1 to N_BASECLASSES rather than 0 to N_BASECLASSES-1
|
||||
(i.e. BASECLASSES points to one *before* the first element of
|
||||
the array). */
|
||||
struct type **baseclasses;
|
||||
};
|
||||
|
||||
@ -444,7 +449,10 @@ struct partial_symbol
|
||||
/* Address class (for info_symbols) */
|
||||
enum address_class class;
|
||||
/* Value (only used for static functions currently). Done this
|
||||
way so that we can use the struct symbol macros. */
|
||||
way so that we can use the struct symbol macros.
|
||||
Note that the address of a function is SYMBOL_VALUE (pst)
|
||||
in a partial symbol table, but BLOCK_START (SYMBOL_BLOCK_VALUE (st))
|
||||
in a symbol table. */
|
||||
union
|
||||
{
|
||||
long value;
|
||||
|
12
gdb/symtab.c
12
gdb/symtab.c
@ -17,11 +17,11 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "symtab.h"
|
||||
#include "param.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <obstack.h>
|
||||
#include <assert.h>
|
||||
|
||||
@ -1802,6 +1802,9 @@ decode_line_spec (string, funfirstline)
|
||||
return sals;
|
||||
}
|
||||
|
||||
/* Given a list of NELTS symbols in sym_arr (with corresponding
|
||||
mangled names in physnames), return a list of lines to operate on
|
||||
(ask user if necessary). */
|
||||
struct symtabs_and_lines
|
||||
decode_line_2 (argptr, sym_arr, physnames, nelts, funfirstline)
|
||||
char **argptr;
|
||||
@ -2130,8 +2133,8 @@ list_symbols (regexp, class)
|
||||
}
|
||||
else
|
||||
{
|
||||
char buf[1024];
|
||||
# if 0
|
||||
char buf[1024];
|
||||
type_print_base (TYPE_FN_FIELD_TYPE(t, i), stdout, 0, 0);
|
||||
type_print_varspec_prefix (TYPE_FN_FIELD_TYPE(t, i), stdout, 0);
|
||||
sprintf (buf, " %s::", TYPE_NAME (t));
|
||||
@ -2166,12 +2169,15 @@ types_info (regexp)
|
||||
list_symbols (regexp, 2);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Tiemann says: "info methods was never implemented." */
|
||||
static void
|
||||
methods_info (regexp)
|
||||
char *regexp;
|
||||
{
|
||||
list_symbols (regexp, 3);
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
/* Call sort_block_syms to sort alphabetically the symbols of one block. */
|
||||
|
||||
@ -2393,11 +2399,13 @@ _initialize_symtab ()
|
||||
"All function names, or those matching REGEXP.");
|
||||
add_info ("types", types_info,
|
||||
"All types names, or those matching REGEXP.");
|
||||
#if 0
|
||||
add_info ("methods", methods_info,
|
||||
"All method names, or those matching REGEXP::REGEXP.\n\
|
||||
If the class qualifier is ommited, it is assumed to be the current scope.\n\
|
||||
If the first REGEXP is ommited, then all methods matching the second REGEXP\n\
|
||||
are listed.");
|
||||
#endif
|
||||
add_info ("sources", sources_info,
|
||||
"Source files in the program.");
|
||||
|
||||
|
@ -17,12 +17,12 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "frame.h"
|
||||
#include "inferior.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/dir.h>
|
||||
#include <signal.h>
|
||||
@ -534,10 +534,12 @@ exec_file_command (filename, from_tty)
|
||||
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)
|
||||
if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read text section header", execfile);
|
||||
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0)
|
||||
if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections,
|
||||
aout_hdrsize) < 0)
|
||||
error ("\"%s\": can't read data section header", execfile);
|
||||
|
||||
text_start = exec_aouthdr.text_start;
|
||||
|
12
gdb/valops.c
12
gdb/valops.c
@ -534,6 +534,9 @@ call_function (function, nargs, args)
|
||||
save_inferior_status (&inf_status, 1);
|
||||
old_chain = make_cleanup (restore_inferior_status, &inf_status);
|
||||
|
||||
/* PUSH_DUMMY_FRAME is responsible for saving the inferior registers
|
||||
(and POP_FRAME for restoring them). (At least on most machines)
|
||||
they are saved on the stack in the inferior. */
|
||||
PUSH_DUMMY_FRAME;
|
||||
|
||||
old_sp = sp = read_register (SP_REGNUM);
|
||||
@ -872,7 +875,7 @@ value_struct_elt (arg1, args, name, static_memfuncp, err)
|
||||
}
|
||||
|
||||
if (found == 0)
|
||||
error ("there is no field named %s", name);
|
||||
error ("There is no field named %s.", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1008,11 +1011,7 @@ check_field (arg1, name)
|
||||
/* Follow pointers until we get to a non-pointer. */
|
||||
|
||||
while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
|
||||
{
|
||||
arg1 = value_ind (arg1);
|
||||
COERCE_ARRAY (arg1);
|
||||
t = VALUE_TYPE (arg1);
|
||||
}
|
||||
t = TYPE_TARGET_TYPE (t);
|
||||
|
||||
if (TYPE_CODE (t) == TYPE_CODE_MEMBER)
|
||||
error ("not implemented: member type in check_field");
|
||||
@ -1037,7 +1036,6 @@ check_field (arg1, name)
|
||||
break;
|
||||
|
||||
t = TYPE_BASECLASS (t, 1);
|
||||
VALUE_TYPE (arg1) = t; /* side effect! */
|
||||
}
|
||||
|
||||
/* C++: If it was not found as a data field, then try to
|
||||
|
@ -23,10 +23,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include "symtab.h"
|
||||
#include "value.h"
|
||||
|
||||
/* Maximum number of chars to print for a string pointer value
|
||||
or vector contents. */
|
||||
/* GNU software is only expected to run on systems with 32-bit integers. */
|
||||
#define UINT_MAX 0xffffffff
|
||||
|
||||
static int print_max;
|
||||
/* Maximum number of chars to print for a string pointer value
|
||||
or vector contents, or UINT_MAX for no limit. */
|
||||
|
||||
static unsigned int print_max;
|
||||
|
||||
static void type_print_varspec_suffix ();
|
||||
static void type_print_varspec_prefix ();
|
||||
@ -45,13 +48,15 @@ char **float_type_table;
|
||||
|
||||
/* Print the character string STRING, printing at most LENGTH characters.
|
||||
Printing stops early if the number hits print_max; repeat counts
|
||||
are printed as appropriate. */
|
||||
are printed as appropriate. Print ellipses at the end if we
|
||||
had to stop before printing LENGTH characters, or if FORCE_ELLIPSES. */
|
||||
|
||||
void
|
||||
print_string (stream, string, length)
|
||||
print_string (stream, string, length, force_ellipses)
|
||||
FILE *stream;
|
||||
char *string;
|
||||
unsigned int length;
|
||||
int force_ellipses;
|
||||
{
|
||||
register unsigned int i;
|
||||
unsigned int things_printed = 0;
|
||||
@ -118,8 +123,7 @@ print_string (stream, string, length)
|
||||
if (in_quotes)
|
||||
fputs_filtered ("\"", stream);
|
||||
|
||||
/* Print ellipses if we stopped before printing LENGTH characters. */
|
||||
if (i < length)
|
||||
if (force_ellipses || i < length)
|
||||
fputs_filtered ("...", stream);
|
||||
}
|
||||
|
||||
@ -149,7 +153,7 @@ value_print (val, stream, format, pretty)
|
||||
/* Print arrays of characters using string syntax. */
|
||||
if (typelen == 1 && TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_INT
|
||||
&& format == 0)
|
||||
print_string (stream, VALUE_CONTENTS (val), n);
|
||||
print_string (stream, VALUE_CONTENTS (val), n, 0);
|
||||
else
|
||||
{
|
||||
unsigned int things_printed = 0;
|
||||
@ -292,7 +296,7 @@ val_print (type, valaddr, address, stream, format,
|
||||
/* For an array of chars, print with string syntax. */
|
||||
if (eltlen == 1 && TYPE_CODE (elttype) == TYPE_CODE_INT
|
||||
&& format == 0)
|
||||
print_string (stream, valaddr, len);
|
||||
print_string (stream, valaddr, len, 0);
|
||||
else
|
||||
{
|
||||
unsigned int things_printed = 0;
|
||||
@ -478,7 +482,9 @@ val_print (type, valaddr, address, stream, format,
|
||||
&& TYPE_CODE (elttype) == TYPE_CODE_INT
|
||||
&& format == 0
|
||||
&& unpack_long (type, valaddr) != 0
|
||||
&& print_max)
|
||||
/* If print_max is UINT_MAX, the alloca below will fail.
|
||||
In that case don't try to print the string. */
|
||||
&& print_max < UINT_MAX)
|
||||
{
|
||||
fprintf_filtered (stream, " ");
|
||||
|
||||
@ -497,6 +503,16 @@ val_print (type, valaddr, address, stream, format,
|
||||
int out_of_bounds = 0;
|
||||
char *string = (char *) alloca (print_max);
|
||||
|
||||
/* If the loop ends by us hitting print_max characters,
|
||||
we need to have elipses at the end. */
|
||||
int force_ellipses = 1;
|
||||
|
||||
/* This loop only fetches print_max characters, even
|
||||
though print_string might want to print more
|
||||
(with repeated characters). This is so that
|
||||
we don't spend forever fetching if we print
|
||||
a long string consisting of the same character
|
||||
repeated. */
|
||||
while (i < print_max)
|
||||
{
|
||||
QUIT;
|
||||
@ -504,19 +520,23 @@ val_print (type, valaddr, address, stream, format,
|
||||
+ i, &c, 1))
|
||||
{
|
||||
out_of_bounds = 1;
|
||||
force_ellipses = 0;
|
||||
break;
|
||||
}
|
||||
else if (c == '\0')
|
||||
break;
|
||||
{
|
||||
force_ellipses = 0;
|
||||
break;
|
||||
}
|
||||
else
|
||||
string[i++] = c;
|
||||
}
|
||||
|
||||
if (i != 0)
|
||||
print_string (stream, string, i);
|
||||
print_string (stream, string, i, force_ellipses);
|
||||
if (out_of_bounds)
|
||||
fprintf_filtered (stream,
|
||||
"*** <Address 0x%x out of bounds>",
|
||||
" <Address 0x%x out of bounds>",
|
||||
(*(int *) valaddr) + i);
|
||||
}
|
||||
|
||||
@ -699,7 +719,7 @@ val_print (type, valaddr, address, stream, format,
|
||||
break;
|
||||
}
|
||||
#ifdef IEEE_FLOAT
|
||||
if (is_nan ((void *) valaddr, TYPE_LENGTH (type)))
|
||||
if (is_nan ((char *) valaddr, TYPE_LENGTH (type)))
|
||||
{
|
||||
fprintf_filtered (stream, "NaN");
|
||||
break;
|
||||
@ -735,7 +755,7 @@ val_print (type, valaddr, address, stream, format,
|
||||
|
||||
int
|
||||
is_nan (fp, len)
|
||||
void *fp;
|
||||
char *fp;
|
||||
int len;
|
||||
{
|
||||
int lowhalf, highhalf;
|
||||
@ -1276,6 +1296,8 @@ set_maximum_command (arg)
|
||||
{
|
||||
if (!arg) error_no_arg ("value for maximum elements to print");
|
||||
print_max = parse_and_eval_address (arg);
|
||||
if (print_max == 0)
|
||||
print_max = UINT_MAX;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1304,8 +1326,12 @@ format_info (arg, from_tty)
|
||||
prettyprint ? "on" : "off");
|
||||
printf ("Printing of unions interior to structures is %s.\n",
|
||||
unionprint ? "on" : "off");
|
||||
printf ("The maximum number of array elements printed is %d.\n",
|
||||
print_max);
|
||||
if (print_max == UINT_MAX)
|
||||
printf_filtered
|
||||
("There is no maximum number of array elements printed.\n");
|
||||
else
|
||||
printf_filtered
|
||||
("The maximum number of array elements printed is %d.\n", print_max);
|
||||
}
|
||||
|
||||
extern struct cmd_list_element *setlist;
|
||||
@ -1314,7 +1340,8 @@ void
|
||||
_initialize_valprint ()
|
||||
{
|
||||
add_cmd ("array-max", class_vars, set_maximum_command,
|
||||
"Set NUMBER as limit on string chars or array elements to print.",
|
||||
"Set NUMBER as limit on string chars or array elements to print.\n\
|
||||
\"set array-max 0\" causes there to be no limit.",
|
||||
&setlist);
|
||||
|
||||
add_cmd ("prettyprint", class_support, set_prettyprint_command,
|
||||
|
@ -17,4 +17,4 @@ You should have received a copy of the GNU General Public License
|
||||
along with GDB; see the file COPYING. If not, write to
|
||||
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
char *version = "3.4";
|
||||
char *version = "3.5";
|
||||
|
@ -19,6 +19,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Original version was contributed by Derek Beatty, 30 June 87. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include "defs.h"
|
||||
#include "param.h"
|
||||
#include "symtab.h"
|
||||
@ -32,7 +33,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
#include <X11/Box.h>
|
||||
#include <X11/VPaned.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*#define XtNfunction "function"*/
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user