This commit is contained in:
gdb-3.5 1990-02-08 06:14:00 +00:00 committed by Pedro Alves
parent 1c997a4ae8
commit 7a67dd45ca
61 changed files with 4687 additions and 1103 deletions

View File

@ -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.

View File

@ -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

1578
gdb/TAGS

File diff suppressed because it is too large Load Diff

View File

@ -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__ */

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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++)

View File

@ -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"

View File

@ -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", &regnum) == 1)
if (sscanf (arg, "0x%x", &regnum) == 1
|| sscanf (argc, "%d", &regnum) == 1)
{
if (regnum > 0)
regnum &= ~0x8000;
}
else if (sscanf (arg, "%d", &regnum) == 1)
;
else if (sscanf (arg, "$c%d", &regnum) == 1)
;
else if (sscanf (arg, "$C%d", &regnum) == 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);
}

View File

@ -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. */

View File

@ -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,

View File

@ -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 */

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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})

View File

@ -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;

View File

@ -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>

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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>

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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. */

View File

@ -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). */

View File

@ -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

View File

@ -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
View 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. */

View File

@ -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,

View File

@ -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

View File

@ -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"},

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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
View 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
View 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
View 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 ();
}

View File

@ -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".

View File

@ -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

View 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

View File

@ -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

View 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

View File

@ -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>

View File

@ -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)

View File

@ -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;

View File

@ -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 (&registers[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers,
sizeof inferior_fp_registers.fps_regs);
#endif
inferior_registers.r_ps = *(int *)&registers[REGISTER_BYTE (PS_REGNUM)];
inferior_registers.r_pc = *(int *)&registers[REGISTER_BYTE (PC_REGNUM)];
#ifdef FP0_REGNUM
bcopy (&registers[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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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.");

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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";

View File

@ -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"*/