diff options
Diffstat (limited to 'gdb/RCS')
-rw-r--r-- | gdb/RCS/Makefile,v | 160 | ||||
-rw-r--r-- | gdb/RCS/coffread.c,v | 304 | ||||
-rw-r--r-- | gdb/RCS/core.c,v | 763 | ||||
-rw-r--r-- | gdb/RCS/infcmd.c,v | 966 | ||||
-rw-r--r-- | gdb/RCS/inflow.c,v | 731 | ||||
-rw-r--r-- | gdb/RCS/m-mac-aux.h,v | 523 | ||||
-rw-r--r-- | gdb/RCS/m-mac-auxinit.h,v | 43 | ||||
-rw-r--r-- | gdb/RCS/m68k-pinsn.c,v | 828 | ||||
-rw-r--r-- | gdb/RCS/main.c,v | 1110 | ||||
-rw-r--r-- | gdb/RCS/source.c,v | 705 | ||||
-rw-r--r-- | gdb/RCS/symmisc.c,v | 575 | ||||
-rw-r--r-- | gdb/RCS/symtab.c,v | 1153 | ||||
-rw-r--r-- | gdb/RCS/utils.c,v | 461 |
13 files changed, 0 insertions, 8322 deletions
diff --git a/gdb/RCS/Makefile,v b/gdb/RCS/Makefile,v deleted file mode 100644 index d942be0..0000000 --- a/gdb/RCS/Makefile,v +++ /dev/null @@ -1,160 +0,0 @@ -head 1.4; -access ; -symbols RMS-has:1.2; -locks ; strict; -comment @# @; - - -1.4 -date 88.06.08.23.14.28; author gnu; state Exp; -branches ; -next 1.3; - -1.3 -date 88.02.28.03.38.17; author gnu; state Exp; -branches ; -next 1.2; - -1.2 -date 88.01.26.05.14.43; author gnu; state Exp; -branches ; -next 1.1; - -1.1 -date 88.01.26.05.14.07; author gnu; state Exp; -branches ; -next ; - - -desc -@Original from RMS's wheaties devl dirs -@ - - -1.4 -log -@Add -DEBUG -@ -text -@# -I. for "#include <obstack.h>" -CFLAGS = -g -I. -Dvfork=fork -DDEBUG -# NOTE!!! -O may FAIL TO WORK! See initialize.h for some weird hacks. - -# define this to be "obstack.o" if you don't have the obstack library installed -# you must at the same time define OBSTACK1 as "obstack.o" -# so that the dependencies work right. -OBSTACK = obstack.o alloca.o -lPW -OBSTACK1 = obstack.o alloca.o - -STARTOBS = main.o firstfile.o - -OBS = blockframe.o breakpoint.o findvar.o stack.o source.o \ - values.o eval.o valops.o valarith.o valprint.o printcmd.o \ - symtab.o symmisc.o coffread.o dbxread.o infcmd.o infrun.o - -TSOBS = core.o inflow.o - -NTSOBS = standalone.o - -ENDOBS = lastfile.o command.o utils.o expread.o expprint.o pinsn.o \ - environ.o version.o - -TSSTART = /lib/crt0.o - -NTSSTART = kdb-start.o - -gdb : $(STARTOBS) $(OBS) $(TSOBS) $(ENDOBS) $(OBSTACK1) - $(CC) -o gdb $(STARTOBS) $(OBS) $(TSOBS) $(ENDOBS) -lg $(OBSTACK) - -xgdb : $(STARTOBS) $(OBS) xgdb.o $(TSOBS) $(ENDOBS) $(OBSTACK1) - $(CC) -o xgdb $(STARTOBS) $(OBS) xgdb.o $(TSOBS) $(ENDOBS) \ - -lXtk11 -lXrm -lX11 -lg $(OBSTACK) - -kdb : $(NTSSTART) $(STARTOBS) $(OBS) $(NTSOBS) $(ENDOBS) $(OBSTACK1) - ld -o kdb $(NTSSTART) $(STARTOBS) $(OBS) $(NTSOBS) $(ENDOBS) -lc -lg $(OBSTACK) - -clean: - rm -f $(STARTOBS) $(OBS) $(TSOBS) $(OBSTACK1) $(NTSSTART) $(NTSOBS) - rm -f xgdb.o gdb xgdb kdb tags errs expread.tab.c - -blockframe.o : blockframe.c defs.h initialize.h param.h symtab.h frame.h -breakpoint.o : breakpoint.c defs.h initialize.h param.h symtab.h frame.h -command.o : command.c command.h -coffread.o : coffread.c defs.h initialize.h param.h symtab.h -core.o : core.c defs.h initialize.h param.h -dbxread.o : dbxread.c defs.h initialize.h param.h symtab.h -environ.o : environ.c environ.h -expprint.o : expprint.c defs.h symtab.h expression.h -expread.tab.c : expread.y - @@echo 'Expect 96 shift/reduce conflicts.' - yacc expread.y - mv y.tab.c expread.tab.c -expread.o : expread.tab.c defs.h param.h symtab.h frame.h expression.h - $(CC) -c ${CFLAGS} expread.tab.c - mv expread.tab.o expread.o -eval.o : eval.c defs.h initialize.h symtab.h value.h expression.h -findvar.o : findvar.c defs.h initialize.h param.h symtab.h frame.h value.h -firstfile.o : firstfile.c initialize.h -infcmd.o : infcmd.c defs.h initialize.h param.h symtab.h frame.h inferior.h environ.h value.h -inflow.o : inflow.c defs.h initialize.h param.h frame.h inferior.h -infrun.o : infrun.c defs.h initialize.h param.h symtab.h frame.h inferior.h wait.h -kdb-start.o : kdb-start.c defs.h param.h -lastfile.o : lastfile.c -main.o : main.c defs.h command.h -# pinsn.o depends on ALL the opcode printers -# since we don't know which one is really being used. -pinsn.o : pinsn.c defs.h param.h symtab.h \ - vax-opcode.h vax-pinsn.c m68k-opcode.h m68k-pinsn.c -printcmd.o : printcmd.c defs.h initialize.h param.h symtab.h value.h expression.h -source.o : source.c defs.h initialize.h symtab.h -stack.o : stack.c defs.h initialize.h param.h symtab.h frame.h -standalone.o : standalone.c defs.h initialize.h param.h symtab.h frame.h inferior.h wait.h -symmisc.o : symmisc.c defs.h initialize.h symtab.h -symtab.o : symtab.c defs.h initialize.h param.h symtab.h -utils.o : utils.c defs.h -valarith.o : valarith.c defs.h initialize.h param.h symtab.h value.h expression.h -valops.o : valops.c defs.h initialize.h param.h symtab.h value.h -valprint.o : valprint.c defs.h initialize.h symtab.h value.h -values.o : values.c defs.h initialize.h param.h symtab.h value.h -version.o : version.c -xgdb.o : xgdb.c defs.h initialize.h param.h symtab.h frame.h - $(CC) -c $(CFLAGS) xgdb.c -o $@@ - -obstack.o : obstack.c -@ - - -1.3 -log -@Make clean -@ -text -@d2 1 -a2 1 -CFLAGS = -g -I. -Dvfork=fork -@ - - -1.2 -log -@We don't have vfork or alloca, and regexp routines are in libPW.a for -no good reason. -@ -text -@d38 4 -@ - - -1.1 -log -@Initial revision -@ -text -@d2 1 -a2 1 -CFLAGS = -g -I. -d8 2 -a9 2 -OBSTACK = obstack.o -OBSTACK1 = obstack.o -@ diff --git a/gdb/RCS/coffread.c,v b/gdb/RCS/coffread.c,v deleted file mode 100644 index 7542030..0000000 --- a/gdb/RCS/coffread.c,v +++ /dev/null @@ -1,304 +0,0 @@ -head 1.4; -access ; -symbols RMS-has:1.2; -locks ; strict; -comment @ * @; - - -1.4 -date 88.06.08.23.13.40; author gnu; state Exp; -branches ; -next 1.3; - -1.3 -date 88.02.28.03.37.53; author gnu; state Exp; -branches ; -next 1.2; - -1.2 -date 88.01.26.05.02.32; author gnu; state Exp; -branches ; -next 1.1; - -1.1 -date 88.01.26.00.38.04; author gnu; state Exp; -branches ; -next ; - - -desc -@Original from RMS's work dirs on Wheaties -@ - - -1.4 -log -@Half reasonable reading of coff files. Problem was that it assumed -that a .text would show up sometime, and it never did. We have to close -out each source file's symtab as we hit the next one. -@ -text -@/* Read coff symbol tables and convert to internal format, for GDB. - Design and support routines derived from dbxread.c, and UMAX COFF - specific routines written 9/1/87 by David D. Johnson, Brown University. - Revised 11/27/87 ddj@@cs.brown.edu - Copyright (C) 1987 Free Software Foundation, Inc. - -GDB is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY. No author or distributor accepts responsibility to anyone -for the consequences of using it or for whether it serves any -particular purpose or works at all, unless he says so in writing. -Refer to the GDB General Public License for full details. - -Everyone is granted permission to copy, modify and redistribute GDB, -but only under the conditions described in the GDB General Public -License. A copy of this license is supposed to have been given to you -along with GDB so you can know your rights and responsibilities. It -should be in a file named COPYING. Among other things, the copyright -notice and this notice must be preserved on all copies. - -In other words, go ahead and share GDB, but don't try to stop -anyone else from sharing it farther. Help stamp out software hoarding! -*/ - -#include "defs.h" -#include "param.h" -#ifdef COFF_FORMAT -#include "initialize.h" -#include "symtab.h" - -#include <a.out.h> -#include <stdio.h> -#include <obstack.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/file.h> - -static void add_symbol_to_list (); -static void read_coff_symtab (); -static void patch_opaque_types (); -static struct type *decode_function_type (); -static struct type *decode_type (); -static struct type *decode_base_type (); -static struct type *read_enum_type (); -static struct type *read_struct_type (); -static void finish_block (); -static struct blockvector *make_blockvector (); -static struct symbol *process_coff_symbol (); -static int init_stringtab (); -static void free_stringtab (); -static char *getfilename (); -static char *getsymname (); -static int init_lineno (); -static void enter_linenos (); - -START_FILE - -/* Name of source file whose symbol data we are now processing. - This comes from a symbol named ".file". */ - -static char *last_source_file; - -/* Core address of start and end of text of current source file. - This comes from a ".text" symbol where x_nlinno > 0. */ - -static CORE_ADDR cur_src_start_addr; -static CORE_ADDR cur_src_end_addr; - -/* End of the text segment of the executable file, - as found in the symbol _etext. */ - -static CORE_ADDR end_of_text_addr; - -/* The addresses of the symbol table stream and number of symbols - of the object file we are reading (as copied into core). */ - -static FILE *nlist_stream_global; -static int nlist_nsyms_global; - -/* The file and text section headers of the symbol file */ - -static FILHDR file_hdr; -static SCNHDR text_hdr; - -/* The index in the symbol table of the last coff symbol that was processed. */ - -static int symnum; - -/* Vector of types defined so far, indexed by their coff symnum. */ - -static struct typevector *type_vector; - -/* Number of elements allocated for type_vector currently. */ - -static int type_vector_length; - -/* Vector of line number information. */ - -static struct linetable *line_vector; - -/* Index of next entry to go in line_vector_index. */ - -static int line_vector_index; - -/* Last line number recorded in the line vector. */ - -static int prev_line_number; - -/* Number of elements allocated for line_vector currently. */ - -static int line_vector_length; - -/* Chain of typedefs of pointers to empty struct/union types. - They are chained thru the SYMBOL_VALUE. */ - -#define HASHSIZE 127 -static struct symbol *opaque_type_chain[HASHSIZE]; - -/* Record the symbols defined for each context in a list. - We don't create a struct block for the context until we - know how long to make it. */ - -struct pending -{ - struct pending *next; - struct symbol *symbol; -}; - -/* Here are the three lists that symbols are put on. */ - -struct pending *file_symbols; /* static at top level, and types */ - -struct pending *global_symbols; /* global functions and variables */ - -struct pending *local_symbols; /* everything local to lexical context */ - -/* List of unclosed lexical contexts - (that will become blocks, eventually). */ - -struct context_stack -{ - struct context_stack *next; - struct pending *locals; - struct pending_block *old_blocks; - struct symbol *name; - CORE_ADDR start_addr; - int depth; -}; - -struct context_stack *context_stack; - -/* Nonzero if within a function (so symbols should be local, - if nothing says specifically). */ - -int within_function; - -/* List of blocks already made (lexical contexts already closed). - This is used at the end to make the blockvector. */ - -struct pending_block -{ - struct pending_block *next; - struct block *block; -}; - -struct pending_block *pending_blocks; - -extern CORE_ADDR first_object_file_end; /* From blockframe.c */ - -/* File name symbols were loaded from. */ - -static char *symfile; - -int debug = 1; - - -/* Look up a coff type-number index. Return the address of the slot - where the type for that index is stored. - The type-number is in INDEX. - - This can be used for finding the type associated with that index - or for associating a new type with the index. */ - -static struct type ** -coff_lookup_type (index) - register int index; -{ - if (index >= type_vector_length) - { - type_vector_length *= 2; - type_vector = (struct typevector *) - xrealloc (type_vector, sizeof (struct typevector) - + type_vector_length * sizeof (struct type *)); - bzero (&type_vector->type[type_vector_length / 2], - type_vector_length * sizeof (struct type *) / 2); - } - return &type_vector->type[index]; -} - -/* Make sure there is a type allocated for type number index - and return the type object. - This can create an empty (zeroed) type object. */ - -static struct type * -coff_alloc_type (index) - int index; -{ - register struct type **type_addr = coff_lookup_type (index); - register struct type *type = *type_addr; - - /* If we are referring to a type not known at all yet, - allocate an empty type for it. - We will fill it in later if we find out how. */ - if (type == 0) - { - type = (struct type *) obstack_alloc (symbol_obstack, - sizeof (struct type)); - bzero (type, sizeof (struct type)); - *type_addr = type; - } - return type; -} - -/* maintain the lists of symbols and blocks */ - -/* Add a symbol to one of the lists of symbols. */ -static void -add_symbol_to_list (symbol, listhead) - struct symbol *symbol; - struct pending **listhead; -{ - register struct pending *link - = (struct pending *) xmalloc (sizeof (struct pending)); - - link->next = *listhead; - link->symbol = symbol; - *listhead = link; -} - -/* Take one of the lists of symbols and make a block from it. - Put the block on the list of pending blocks. */ - -static void -finish_block (symbol, listhead, old_blocks, start, end) - struct symbol *symbol; - struct pending **listhead; - struct pending_block *old_blocks; - CORE_ADDR start, end; -{ - register struct pending *next, *next1; - register struct block *block; - register struct pending_block *pblock; - struct pending_block *opblock; - register int i; - - /* Count the length of the list of symbols. */ - - for (next = *listhead, i = 0; next; next = next->next, i++); - - block = (struct block *) xmalloc (sizeof (struct block) + (i - 1) * sizeof (struct symbol *)); - - /* Copy the symbols into the block. */ - - BLOCK_NSYMS (block) = i; - for (next = *listhead; next; next = next->next
\ No newline at end of file diff --git a/gdb/RCS/core.c,v b/gdb/RCS/core.c,v deleted file mode 100644 index 99547f8..0000000 --- a/gdb/RCS/core.c,v +++ /dev/null @@ -1,763 +0,0 @@ -head 1.2; -access ; -symbols RMS-has:1.2; -locks ; strict; -comment @ * @; - - -1.2 -date 88.01.26.05.04.52; author gnu; state Exp; -branches ; -next 1.1; - -1.1 -date 88.01.21.05.04.03; author gnu; state Exp; -branches ; -next ; - - -desc -@From RMS's development version on wheaties, 20Jan88 -@ - - -1.2 -log -@Hacks to get it to compile on a/ux. Needs work at finding the registers -in a core file. -@ -text -@/* Work with core dump and executable files, for GDB. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - -GDB is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY. No author or distributor accepts responsibility to anyone -for the consequences of using it or for whether it serves any -particular purpose or works at all, unless he says so in writing. -Refer to the GDB General Public License for full details. - -Everyone is granted permission to copy, modify and redistribute GDB, -but only under the conditions described in the GDB General Public -License. A copy of this license is supposed to have been given to you -along with GDB so you can know your rights and responsibilities. It -should be in a file named COPYING. Among other things, the copyright -notice and this notice must be preserved on all copies. - -In other words, go ahead and share GDB, but don't try to stop -anyone else from sharing it farther. Help stamp out software hoarding! -*/ - -#include "initialize.h" -#include "defs.h" -#include "param.h" - -#include <a.out.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/dir.h> -#include <sys/file.h> -#include <sys/stat.h> - -/* Recognize COFF format systems because a.out.h defines AOUTHDR. */ -#ifdef AOUTHDR -#define COFF_FORMAT -#endif - -#ifdef NEW_SUN_CORE -#include <sys/core.h> -#else /* not NEW_SUN_CORE */ -#ifdef UMAX_CORE -#include <sys/ptrace.h> -#else /* not UMAX_CORE */ -#ifdef mac_aux -#include <sys/seg.h> -#include <sys/mmu.h> -#include <sys/signal.h> -#include <sys/time.h> -#include <sys/user.h> -#else -#include <sys/user.h> -#endif /* mac_aux */ -#endif /* UMAX_CORE */ -#endif /* NEW_SUN_CORE */ - -#ifndef N_TXTADDR -#define N_TXTADDR(hdr) 0 -#endif /* no N_TXTADDR */ - -#ifndef N_DATADDR -#define N_DATADDR(hdr) hdr.a_text -#endif /* no N_DATADDR */ - -/* Make COFF and non-COFF names for things a little more compatible - to reduce conditionals later. */ - -#ifdef COFF_FORMAT -#define a_magic magic -#endif - -#ifndef COFF_FORMAT -#define AOUTHDR struct exec -#endif - -START_FILE - -/* Hook for `exec_file_command' command to call. */ - -void (*exec_file_display_hook) (); - -/* File names of core file and executable file. */ - -static char *corefile; -static 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. */ - -static int corechan; -static int execchan; - -/* Last modification time of executable file. - Also used in source.c to compare against mtime of a source file. */ - -int exec_mtime; - -/* Virtual addresses of bounds of the two areas of memory in the core file. */ - -static CORE_ADDR data_start; -static CORE_ADDR data_end; -static CORE_ADDR stack_start; -static CORE_ADDR stack_end; - -/* Virtual addresses of bounds of two areas of memory in the exec file. - Note that the data area in the exec file is used only when there is no core file. */ - -static CORE_ADDR text_start; -static CORE_ADDR text_end; -static CORE_ADDR exec_data_start; -static CORE_ADDR exec_data_end; - -/* Address in executable file of start of text area data. */ - -static int text_offset; - -/* Address in executable file of start of data area data. */ - -static int exec_data_offset; - -/* Address in core file of start of data area data. */ - -static int data_offset; - -/* Address in core file of start of stack area data. */ - -static int stack_offset; - -#ifdef COFF_FORMAT -/* various coff data structures */ - -static FILHDR file_hdr; -static SCNHDR text_hdr; -static SCNHDR data_hdr; - -#endif /* not COFF_FORMAT */ - -/* a.out header saved in core file. */ - -static AOUTHDR core_aouthdr; - -/* a.out header of exec file. */ - -static AOUTHDR exec_aouthdr; - -static void validate_files (); -unsigned int register_addr (); - -core_file_command (filename, from_tty) - char *filename; - int from_tty; -{ - int val; - extern char registers[]; - - /* Discard all vestiges of any previous core file - and mark data and stack spaces as empty. */ - - if (corefile) - free (corefile); - corefile = 0; - - if (corechan >= 0) - close (corechan); - corechan = -1; - - data_start = 0; - data_end = 0; - stack_start = STACK_END_ADDR; - stack_end = STACK_END_ADDR; - - /* Now, if a new core file was specified, open it and digest it. */ - - if (filename) - { - if (have_inferior_p ()) - error ("To look at a core file, you must kill the inferior with \"kill\"."); - corechan = open (filename, O_RDONLY, 0); - if (corechan < 0) - perror_with_name (filename); -#ifdef NEW_SUN_CORE - { - struct core corestr; - - val = myread (corechan, &corestr, sizeof corestr); - if (val < 0) - perror_with_name (filename); - if (corestr.c_magic != CORE_MAGIC) - error ("\"%s\" does not appear to be a core dump file (magic 0x%x, expected 0x%x)", - filename, corestr.c_magic, (int) CORE_MAGIC); - else if (sizeof (struct core) != corestr.c_len) - error ("\"%s\" has an invalid struct core length (%d, expected %d)", - filename, corestr.c_len, (int) sizeof (struct core)); - - data_start = exec_data_start; - data_end = data_start + corestr.c_dsize; - stack_start = stack_end - corestr.c_ssize; - data_offset = sizeof corestr; - stack_offset = sizeof corestr + corestr.c_dsize; - - bcopy (&corestr.c_regs, registers, 16 * 4); - *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = corestr.c_regs.r_ps; - *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = corestr.c_regs.r_pc; - bcopy (corestr.c_fpstatus.fps_regs, - ®isters[REGISTER_BYTE (FP0_REGNUM)], - sizeof corestr.c_fpstatus.fps_regs); - bcopy (&corestr.c_fpstatus.fps_control, - ®isters[REGISTER_BYTE (FPC_REGNUM)], - sizeof corestr.c_fpstatus - sizeof corestr.c_fpstatus.fps_regs); - - bcopy (&corestr.c_aouthdr, &core_aouthdr, sizeof (struct exec)); - - printf ("Core file is from \"%s\".\n", corestr.c_cmdname); - } -#else /* not NEW_SUN_CORE */ - /* 4.2-style (and perhaps also sysV-style) core dump file. */ - { -#ifdef UMAX_CORE - struct ptrace_user u; -#else - struct user u; -#endif - int reg_offset; - - val = myread (corechan, &u, sizeof u); - if (val < 0) - perror_with_name (filename); - data_start = exec_data_start; - -#ifdef UMAX_CORE - data_end = data_start + u.pt_dsize; - stack_start = stack_end - u.pt_ssize; - data_offset = sizeof u; - stack_offset = data_offset + u.pt_dsize; - reg_offset = 0; - - bcopy (&u.pt_aouthdr, &core_aouthdr, sizeof (AOUTHDR)); - -#else /* not UMAX_CORE */ -#ifdef mac_aux - /* This may well not work for 0407 (nonshared text) a.out's */ - data_end = data_start + u.u_dsize << PAGESHIFT; - stack_start = stack_end - u.u_ssize << PAGESHIFT; - data_offset = USIZE; - stack_offset = USIZE + u.u_dsize << PAGESHIFT; - reg_offset = (int) &u.u_ar0[0] - (int) &u; - - core_aouthdr.a_magic = u.u_exdata.ux_mag; -#else - 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; - - /* I don't know where to find this info. - So, for now, mark it as not available. */ - core_aouthdr.a_magic = 0; -#endif /* not mac_aux */ -#endif /* not UMAX_CORE */ - - /* Read the register values out of the core file and store - them where `read_register' will find them. */ - - { - register int regno; - - for (regno = 0; regno < NUM_REGS; regno++) - { - char buf[MAX_REGISTER_RAW_SIZE]; - - val = lseek (corechan, register_addr (regno, reg_offset), 0); - if (val < 0) - perror_with_name (filename); - - val = myread (corechan, buf, sizeof buf); - if (val < 0) - perror_with_name (filename); - supply_register (regno, buf); - } - } - } -#endif /* not NEW_SUN_CORE */ - if (filename[0] == '/') - corefile = savestring (filename, strlen (filename)); - else - { - char dirname[MAXPATHLEN]; - - getwd (dirname); - corefile = concat (dirname, "/", filename); - } - - set_current_frame (read_register (FP_REGNUM)); - select_frame (get_current_frame (), 0); - validate_files (); - } - else if (from_tty) - printf ("No core file now.\n"); -} - -exec_file_command (filename, from_tty) - char *filename; - int from_tty; -{ - int val; - - /* Eliminate all traces of old exec file. - Mark text segment as empty. */ - - if (execfile) - free (execfile); - execfile = 0; - data_start = 0; - data_end -= exec_data_start; - text_start = 0; - text_end = 0; - exec_data_start = 0; - exec_data_end = 0; - if (execchan >= 0) - close (execchan); - execchan = -1; - - /* Now open and digest the file the user requested, if any. */ - - if (filename) - { - execchan = openp (getenv ("PATH"), 1, filename, O_RDONLY, 0, - &execfile); - if (execchan < 0) - perror_with_name (filename); - -#ifdef COFF_FORMAT - { - int aout_hdrsize; - int num_sections; - - if (read_file_hdr (execchan, &file_hdr) < 0) - error ("\"%s\": not in executable format.", execfile); - - aout_hdrsize = file_hdr.f_opthdr; - num_sections = file_hdr.f_nscns; - - if (read_aout_hdr (execchan, &exec_aouthdr, aout_hdrsize) < 0) - error ("\"%s\": can't read optional aouthdr", execfile); - - if (read_section_hdr (execchan, _TEXT, &text_hdr, num_sections) < 0) - error ("\"%s\": can't read text section header", execfile); - - if (read_section_hdr (execchan, _DATA, &data_hdr, num_sections) < 0) - error ("\"%s\": can't read data section header", execfile); - - text_start = exec_aouthdr.text_start; - text_end = text_start + exec_aouthdr.tsize; - text_offset = text_hdr.s_scnptr; - exec_data_start = exec_aouthdr.data_start; - exec_data_end = exec_data_start + exec_aouthdr.dsize; - exec_data_offset = data_hdr.s_scnptr; - data_start = exec_data_start; - data_end += exec_data_start; - exec_mtime = file_hdr.f_timdat; - } -#else /* not COFF_FORMAT */ - { - struct stat st_exec; - - val = myread (execchan, &exec_aouthdr, sizeof (AOUTHDR)); - - if (val < 0) - perror_with_name (filename); - - text_start = N_TXTADDR (exec_aouthdr); - text_end = text_start + exec_aouthdr.a_text; - text_offset = N_TXTOFF (exec_aouthdr); - exec_data_start = N_DATADDR (exec_aouthdr); - exec_data_end = exec_data_start + exec_aouthdr.a_data; - exec_data_offset = N_TXTOFF (exec_aouthdr) + exec_aouthdr.a_text; - 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 ? filename : "No executable specified.\n"); -} - -/* Call this to specify the hook for exec_file_command to call back. - This is called from the x-window display code. */ - -specify_exec_file_hook (hook) - void (*hook) (); -{ - exec_file_display_hook = hook; -} - -/* The exec file must be closed before running an inferior. - If it is needed again after the inferior dies, it must - be reopened. */ - -close_exec_file () -{ - if (execchan >= 0) - close (execchan); - execchan = -1; -} - -reopen_exec_file () -{ - if (execchan < 0 && execfile != 0) - { - char *filename = concat (execfile, "", ""); - exec_file_command (filename, 0); - free (filename); - } -} - -/* If we have both a core file and an exec file, - print a warning if they don't go together. - This should really check that the core file came - from that exec file, but I don't know how to do it. */ - -static void -validate_files () -{ - if (execfile != 0 && corefile != 0) - { - struct stat st_core; - - fstat (corechan, &st_core); - - if (core_aouthdr.a_magic != 0 - && bcmp (&core_aouthdr, &exec_aouthdr, sizeof core_aouthdr)) - printf ("Warning: core file does not match specified executable file.\n"); - else if (exec_mtime > st_core.st_mtime) - printf ("Warning: exec file is newer than core file.\n"); - } -} - -char * -get_exec_file () -{ - if (execfile == 0) - error ("No executable file specified.\n\ -Use the \"exec-file\" and \"symbol-file\" commands."); - return execfile; -} - -int -have_core_file_p () -{ - return corefile != 0; -} - -static void -files_info () -{ - char *symfile; - extern char *get_sym_file (); - - if (execfile) - printf ("Executable file \"%s\".\n", execfile); - else - printf ("No executable file\n"); - if (corefile == 0) - printf ("No core dump file\n"); - else - printf ("Core dump file \"%s\".\n", corefile); - - if (have_inferior_p ()) - printf ("Using the running image of the program, rather than these files.\n"); - - symfile = get_sym_file (); - if (symfile != 0) - printf ("Symbols loaded from \"%s\".\n", symfile); - - if (! have_inferior_p ()) - { - if (execfile) - { - printf ("Text segment from 0x%x to 0x%x.\n", - text_start, text_end); - } - if (corefile) - { - printf ("Data segment from 0x%x to 0x%x.\nStack segment from 0x%x to 0x%x.\n", - data_start, data_end, stack_start, stack_end); - } - else - { - printf ("Data segment in executable from 0x%x to 0x%x.\n", - exec_data_start, exec_data_end); - } - } -} - -/* Read "memory data" from core file and/or executable file */ - -read_memory (memaddr, myaddr, len) - CORE_ADDR memaddr; - char *myaddr; - int len; -{ - if (have_inferior_p ()) - read_inferior_memory (memaddr, myaddr, len); - else - xfer_core_file (memaddr, myaddr, len, 0); -} - -/* Write LEN bytes of data starting at address MYADDR - into debugged program memory at address MEMADDR. - Returns zero if successful, or an errno value if ptrace failed. */ - -int -write_memory (memaddr, myaddr, len) - CORE_ADDR memaddr; - char *myaddr; - int len; -{ - if (have_inferior_p ()) - return write_inferior_memory (memaddr, myaddr, len); - else - error ("Can write memory only when program being debugged is running."); -} - -xfer_core_file (memaddr, myaddr, len) - CORE_ADDR memaddr; - char *myaddr; - int len; -{ - register int i; - register int val; - int xferchan; - char **xferfile; - int fileptr; - - while (len > 0) - { - xferfile = 0; - xferchan = 0; - - /* Determine which file the next bunch of addresses reside in, - and where in the file. Set the file's read/write pointer - to point at the proper place for the desired address - and set xferfile and xferchan for the correct file. - If desired address is nonexistent, leave them zero. - i is set to the number of bytes that can be handled - along with the next address. */ - - if (memaddr < text_start) - { - i = min (len, text_start - memaddr); - } - else if (memaddr >= text_end && memaddr < data_start) - { - i = min (len, data_start - memaddr); - } - else if (memaddr >= (corechan >= 0 ? data_end : exec_data_end) - && memaddr < stack_start) - { - i = min (len, stack_start - memaddr); - } - else if (memaddr >= stack_end && stack_end != 0) - { - i = min (len, - memaddr); - } - /* Note that if there is no core file - data_start and data_end are equal. */ - else if (memaddr >= data_start && memaddr < data_end) - { - i = min (len, data_end - memaddr); - fileptr = memaddr - data_start + data_offset; - xferfile = &corefile; - xferchan = corechan; - } - /* Note that if there is no core file - stack_start and stack_end are equal. */ - else if (memaddr >= stack_start && memaddr < stack_end) - { - i = min (len, stack_end - memaddr); - fileptr = memaddr - stack_start + stack_offset; - xferfile = &corefile; - xferchan = corechan; - } - else if (corechan < 0 - && memaddr >= exec_data_start && memaddr < exec_data_end) - { - i = min (len, exec_data_end - memaddr); - fileptr = memaddr - exec_data_start + exec_data_offset; - xferfile = &execfile; - xferchan = execchan; - } - else if (memaddr >= text_start && memaddr < text_end) - { - i = min (len, text_end - memaddr); - fileptr = memaddr - text_start + text_offset; - xferfile = &execfile; - xferchan = execchan; - } - - /* Now we know which file to use. - Set up its pointer and transfer the data. */ - if (xferfile) - { - if (*xferfile == 0) - if (xferfile == &execfile) - error ("No program file to examine."); - else - error ("No core dump file or running program to examine."); - val = lseek (xferchan, fileptr, 0); - if (val < 0) - perror_with_name (*xferfile); - val = myread (xferchan, myaddr, i); - if (val < 0) - perror_with_name (*xferfile); - } - /* If this address is for nonexistent memory, - read zeros if reading, or do nothing if writing. */ - else - bzero (myaddr, i); - - memaddr += i; - myaddr += i; - len -= i; - } -} - -/* My replacement for the read system call. - Used like `read' but keeps going if `read' returns too soon. */ - -myread (desc, addr, len) - int desc; - char *addr; - int len; -{ - register int val; - int orglen = len; - - while (len > 0) - { - val = read (desc, addr, len); - if (val < 0) - return val; - if (val == 0) - return orglen - len; - len -= val; - addr += val; - } -} - -#ifndef NEW_SUN_CORE - -/* Return the address in the core dump or inferior of register REGNO. - BLOCKEND is the address of the end of the user structure. */ - -unsigned int -register_addr (regno, blockend) - int regno; - int blockend; -{ - int addr; - - if (regno < 0 || regno >= NUM_REGS) - error ("Invalid register number %d.", regno); - -#ifdef mac_aux -/* FIXME, we don't know where the regs are. Maybe the test command - * that tests what parts of the upage are writeable will find 'em for us. - */ -#define REGISTER_U_ADDR(addr, foo, bar) addr = 0; -#endif - REGISTER_U_ADDR (addr, blockend, regno); - - return addr; -} - -#endif /* not NEW_SUN_CORE */ - -static -initialize () -{ - corechan = -1; - execchan = -1; - corefile = 0; - execfile = 0; - exec_file_display_hook = 0; - - text_start = 0; - text_end = 0; - data_start = 0; - data_end = 0; - exec_data_start = 0; - exec_data_end = 0; - stack_start = STACK_END_ADDR; - stack_end = STACK_END_ADDR; - - add_com ("core-file", class_files, core_file_command, - "Use FILE as core dump for examining memory and registers.\n\ -No arg means have no core file."); - add_com ("exec-file", class_files, exec_file_command, - "Use FILE as program for getting contents of pure memory.\n\ -If FILE cannot be found as specified, your execution directory path\n\ -is searched for a command of that name.\n\ -No arg means have no executable file."); - add_info ("files", files_info, "Names of files being debugged."); -} - -END_FILE -@ - - -1.1 -log -@Initial revision -@ -text -@d27 1 -d44 5 -d50 4 -a53 1 -#endif -d240 10 -d259 1 -d675 6 -@ diff --git a/gdb/RCS/infcmd.c,v b/gdb/RCS/infcmd.c,v deleted file mode 100644 index cc30fe4..0000000 --- a/gdb/RCS/infcmd.c,v +++ /dev/null @@ -1,966 +0,0 @@ -head 1.2; -access ; -symbols RMS-has:1.2; -locks ; strict; -comment @ * @; - - -1.2 -date 88.01.26.05.06.19; author gnu; state Exp; -branches ; -next 1.1; - -1.1 -date 88.01.26.01.19.05; author gnu; state Exp; -branches ; -next ; - - -desc -@Original from RMS's wheaties devl sources -@ - - -1.2 -log -@Add local sys_siglist for a/ux because they don't provide one, sigh. -@ -text -@/* Memory-access and commands for inferior process, for GDB. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - -GDB is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY. No author or distributor accepts responsibility to anyone -for the consequences of using it or for whether it serves any -particular purpose or works at all, unless he says so in writing. -Refer to the GDB General Public License for full details. - -Everyone is granted permission to copy, modify and redistribute GDB, -but only under the conditions described in the GDB General Public -License. A copy of this license is supposed to have been given to you -along with GDB so you can know your rights and responsibilities. It -should be in a file named COPYING. Among other things, the copyright -notice and this notice must be preserved on all copies. - -In other words, go ahead and share GDB, but don't try to stop -anyone else from sharing it farther. Help stamp out software hoarding! -*/ - -#include "defs.h" -#include "initialize.h" -#include "symtab.h" -#include "param.h" -#include "frame.h" -#include "inferior.h" -#include "environ.h" -#include "value.h" - -#include <stdio.h> -#include <signal.h> -#include <sys/param.h> - -#ifdef mac_aux -/* Warning! This table is positional and highly dependent on the local - system. Check it closely against <sys/signal.h> when porting. */ -char *sys_siglist[] = { - "Signal 0", - "Hangup", - "Interrupt", - "Quit", - "Invalid instruction", - "Trace/breakpoint trap", - "IOT trap", - "EMT trap", - "Floating point exception", - "Killed", - "Bus error", - "Segmentation fault", - "Bad system call", - "Broken pipe", - "Alarm clock", - "Terminated", - "User signal 1", - "User signal 2", - "Child exited", - "Power-fail restart", - "Stopped", - "Stopped (tty input)", - "Stopped (tty output)", - "Stopped (signal)", - "Cputime limit exceeded", - "File size limit exceeded", - "Virtual timer expired", - "Profiling timer expired", - "Window changed", - "Continued", - "Urgent I/O condition", - "I/O possible", -}; -#else -/* More portable systems do it for you */ -extern char *sys_siglist[]; -#endif - -#define ERROR_NO_INFERIOR \ - if (inferior_pid == 0) error ("The program is not being run."); - -/* String containing arguments to give to the program, - with a space added at the front. Just a space means no args. */ - -static char *inferior_args; - -/* File name for default use for standard in/out in the inferior. */ - -char *inferior_io_terminal; - -/* Pid of our debugged inferior, or 0 if no inferior now. */ - -int inferior_pid; - -/* Last signal that the inferior received (why it stopped). */ - -int stop_signal; - -/* Address at which inferior stopped. */ - -CORE_ADDR stop_pc; - -/* Stack frame when program stopped. */ - -FRAME stop_frame; - -/* Number of breakpoint it stopped at, or 0 if none. */ - -int stop_breakpoint; - -/* Nonzero if stopped due to a step command. */ - -int stop_step; - -/* Nonzero if stopped due to completion of a stack dummy routine. */ - -int stop_stack_dummy; - -/* Range to single step within. - If this is nonzero, respond to a single-step signal - by continuing to step if the pc is in this range. */ - -CORE_ADDR step_range_start; /* Inclusive */ -CORE_ADDR step_range_end; /* Exclusive */ - -/* Stack frame address as of when stepping command was issued. - This is how we know when we step into a subroutine call, - and how to set the frame for the breakpoint used to step out. */ - -CORE_ADDR step_frame; - -/* 1 means step over all subroutine calls. - -1 means step over calls to undebuggable functions. */ - -int step_over_calls; - -/* If stepping, nonzero means step count is > 1 - so don't print frame next time inferior stops - if it stops due to stepping. */ - -int step_multi; - -/* Environment to use for running inferior, - in format described in environ.h. */ - -struct environ *inferior_environ; - -CORE_ADDR read_pc (); -struct command_line *get_breakpoint_commands (); - -START_FILE - -int -have_inferior_p () -{ - return inferior_pid != 0; -} - -static void -set_args_command (args) - char *args; -{ - free (inferior_args); - if (!args) args = ""; - inferior_args = concat (" ", args, ""); -} - -void -tty_command (file) - char *file; -{ - if (file == 0) - error_no_arg ("terminal name for running target process"); - - inferior_io_terminal = savestring (file, strlen (file)); -} - -static void -run_command (args, from_tty) - char *args; - int from_tty; -{ - extern char **environ; - register int i; - char *exec_file; - char *allargs; - - extern int sys_nerr; - extern char *sys_errlist[]; - extern int errno; - - dont_repeat (); - - if (inferior_pid) - { - if (query ("The program being debugged has been started already.\n\ -Start it from the beginning? ")) - kill_inferior (); - else - error ("Program already started."); - } - - if (args) - set_args_command (args); - - exec_file = (char *) get_exec_file (); - if (from_tty) - { - printf ("Starting program: %s%s\n", - exec_file, inferior_args); - fflush (stdout); - } - - allargs = concat ("exec ", exec_file, inferior_args); - inferior_pid = create_inferior (allargs, environ_vector (inferior_environ)); - - clear_proceed_status (); - - start_inferior (); -} - -void -cont_command (proc_count_exp, from_tty) - char *proc_count_exp; - int from_tty; -{ - ERROR_NO_INFERIOR; - - clear_proceed_status (); - - /* If have argument, set proceed count of breakpoint we stopped at. */ - - if (stop_breakpoint && proc_count_exp) - { - set_ignore_count (stop_breakpoint, - parse_and_eval_address (proc_count_exp) - 1, - from_tty); - if (from_tty) - printf (" "); - } - - if (from_tty) - printf ("Continuing.\n"); - - proceed (-1, -1, 0); -} - -/* Step until outside of current statement. */ -static void step_1 (); - -static void -step_command (count_string) -{ - step_1 (0, 0, count_string); -} - -/* Likewise, but skip over subroutine calls as if single instructions. */ - -static void -next_command (count_string) -{ - step_1 (1, 0, count_string); -} - -/* Likewise, but step only one instruction. */ - -static void -stepi_command (count_string) -{ - step_1 (0, 1, count_string); -} - -static void -nexti_command (count_string) -{ - step_1 (1, 1, count_string); -} - -static void -step_1 (skip_subroutines, single_inst, count_string) - int skip_subroutines; - int single_inst; - char *count_string; -{ - register int count = 1; - - ERROR_NO_INFERIOR; - count = count_string ? parse_and_eval_address (count_string) : 1; - - for (; count > 0; count--) - { - clear_proceed_status (); - - step_frame = get_current_frame (); - - if (! single_inst) - { - find_pc_line_pc_range (stop_pc, &step_range_start, &step_range_end); - if (step_range_end == 0) - { - terminal_ours (); - error ("Current function has no line number information."); - } - } - else - { - /* Say we are stepping, but stop after one insn whatever it does. - Don't step through subroutine calls even to undebuggable functions. */ - step_range_start = step_range_end = 1; - if (!skip_subroutines) - step_over_calls = 0; - } - - if (skip_subroutines) - step_over_calls = 1; - - step_multi = (count > 1); - proceed (-1, -1, 1); - if (! stop_step) - break; - } -} - -/* Continue program at specified address. */ - -static void -jump_command (arg, from_tty) - char *arg; - int from_tty; -{ - register CORE_ADDR addr; - struct symtab_and_line sal; - - ERROR_NO_INFERIOR; - - if (!arg) - error_no_arg ("starting address"); - - sal = decode_line_spec (arg, 1); - - if (sal.symtab == 0 && sal.pc == 0) - error ("No source file has been specified."); - - if (sal.pc == 0) - sal.pc = find_line_pc (sal.symtab, sal.line); - - { - struct symbol *fn = get_frame_function (get_current_frame ()); - struct symbol *sfn = find_pc_function (sal.pc); - if (fn != 0 && sfn != fn - && ! query ("That is not in function %s. Continue there? ", - sal.line, SYMBOL_NAME (fn))) - error ("Not confirmed."); - } - - if (sal.pc == 0) - error ("No line %d in file \"%s\".", sal.line, sal.symtab->filename); - - addr = sal.pc; - - clear_proceed_status (); - - if (from_tty) - printf ("Continuing at 0x%x.\n", addr); - - proceed (addr, 0, 0); -} - -/* Continue program giving it specified signal. */ - -static void -signal_command (signum_exp, from_tty) - char *signum_exp; - int from_tty; -{ - register int signum; - - dont_repeat (); /* Too dangerous. */ - ERROR_NO_INFERIOR; - - if (!signum_exp) - error_no_arg ("signal number"); - - signum = parse_and_eval_address (signum_exp); - - clear_proceed_status (); - - if (from_tty) - printf ("Continuing with signal %d.\n", signum); - - proceed (stop_pc, signum, 0); -} - -/* Execute a "stack dummy", a piece of code stored in the stack - by the debugger to be executed in the inferior. - - To call: first, do PUSH_DUMMY_FRAME. - Then push the contents of the dummy. It should end with a breakpoint insn. - Then call here, passing address at which to start the dummy. - - The contents of all registers are saved before the dummy frame is popped - and copied into the buffer BUFFER. - - The dummy's frame is automatically popped whenever that break is hit. - If that is the first time the program stops, run_stack_dummy - returns to its caller with that frame already gone. - Otherwise, the caller never gets returned to. */ - -/* 4 => return instead of letting the stack dummy run. */ - -static int stack_dummy_testing = 0; - -void -run_stack_dummy (addr, buffer) - CORE_ADDR addr; - REGISTER_TYPE *buffer; -{ - int saved_pc_changed = pc_changed; - int saved_stop_signal = stop_signal; - int saved_stop_pc = stop_pc; - int saved_stop_frame = stop_frame; - int saved_stop_breakpoint = stop_breakpoint; - int saved_stop_step = stop_step; - int saved_stop_stack_dummy = stop_stack_dummy; - FRAME saved_selected_frame; - int saved_selected_level; - struct command_line *saved_breakpoint_commands - = get_breakpoint_commands (); - - record_selected_frame (&saved_selected_frame, &saved_selected_level); - - /* Now proceed, having reached the desired place. */ - clear_proceed_status (); - if (stack_dummy_testing & 4) - { - POP_FRAME; - return; - } - proceed (addr, 0, 0); - - if (!stop_stack_dummy) - error ("Cannot continue previously requested operation."); - - set_breakpoint_commands (saved_breakpoint_commands); - select_frame (saved_selected_frame, saved_selected_level); - stop_signal = saved_stop_signal; - stop_pc = saved_stop_pc; - stop_frame = saved_stop_frame; - stop_breakpoint = saved_stop_breakpoint; - stop_step = saved_stop_step; - stop_stack_dummy = saved_stop_stack_dummy; - pc_changed = saved_pc_changed; - - /* On return, the stack dummy has been popped already. */ - - bcopy (stop_registers, buffer, sizeof stop_registers); -} - -/* "finish": Set a temporary breakpoint at the place - the selected frame will return to, then continue. */ - -static void -finish_command (arg, from_tty) - char *arg; - int from_tty; -{ - struct symtab_and_line sal; - register FRAME frame; - struct frame_info fi; - - register struct symbol *function; - - if (!have_inferior_p ()) - error ("The program is not being run."); - if (arg) - error ("The \"finish\" command does not take any arguments."); - - frame = get_prev_frame (selected_frame); - if (frame == 0) - error ("\"finish\" not meaningful in the outermost frame."); - - clear_proceed_status (); - - fi = get_frame_info (frame); - sal = find_pc_line (fi.pc, 0); - sal.pc = fi.pc; - set_momentary_breakpoint (sal, frame); - - /* Find the function we will return from. */ - - fi = get_frame_info (fi.next_frame); - function = find_pc_function (fi.pc); - - if (from_tty) - { - printf ("Run till exit from "); - print_selected_frame (); - } - - proceed (-1, -1, 0); - - if (stop_breakpoint == -3 && function != 0) - { - struct type *value_type; - register value val; - - if (TYPE_CODE (SYMBOL_TYPE (function)) != TYPE_CODE_VOID) - value_type = SYMBOL_TYPE (function); - else - return; - - val = value_being_returned (value_type, stop_registers); - printf ("Value returned is $%d = ", record_latest_value (val)); - value_print (val, stdout); - putchar ('\n'); - } -} - -static void -program_info () -{ - if (inferior_pid == 0) - { - printf ("The program being debugged is not being run.\n"); - return; - } - - printf ("Program being debugged is in process %d, stopped at 0x%x.\n", - inferior_pid, stop_pc); - if (stop_step) - printf ("It stopped after being stepped.\n"); - else if (stop_breakpoint) - printf ("It stopped at breakpoint %d.\n", stop_breakpoint); - else if (stop_signal) - printf ("It stopped with signal %d (%s).\n", - stop_signal, sys_siglist[stop_signal]); - - printf ("\nType \"info stack\" or \"info reg\" for more information.\n"); -} - -static void -environment_info (var) - char *var; -{ - if (var) - { - register char *val = get_in_environ (inferior_environ, var); - if (val) - printf ("%s = %s\n", var, val); - else - printf ("Environment variable \"%s\" not defined.\n", var); - } - else - { - register char **vector = environ_vector (inferior_environ); - while (*vector) - printf ("%s\n", *vector++); - } -} - -static void -set_environment_command (arg) - char *arg; -{ - register char *p, *val, *var; - - if (arg == 0) - error_no_arg ("environment variable and value"); - - p = (char *) index (arg, '='); - val = (char *) index (arg, ' '); - if (p != 0 && val != 0) - p = arg + min (p - arg, val - arg); - else if (val != 0 && p == 0) - p = val; - - if (p == 0) - error ("Space or \"=\" must separate variable name and its value"); - if (p[1] == 0) - error_no_arg ("value for the variable"); - if (p == arg) - error_no_arg ("environment variable to set"); - - val = p + 1; - while (*val == ' ' || *val == '\t') val++; - while (p != arg && (p[-1] == ' ' || p[-1] == '\t')) p--; - - var = savestring (arg, p - arg); - set_in_environ (inferior_environ, var, val); - free (var); -} - -static void -unset_environment_command (var) - char *var; -{ - if (var == 0) - error_no_arg ("environment variable"); - - unset_in_environ (inferior_environ, var); -} - -/* Read an integer from debugged memory, given address and number of bytes. */ - -read_memory_integer (memaddr, len) - CORE_ADDR memaddr; - int len; -{ - char cbuf; - short sbuf; - int ibuf; - long lbuf; - - if (len == sizeof (char)) - { - read_memory (memaddr, &cbuf, len); - return cbuf; - } - if (len == sizeof (short)) - { - read_memory (memaddr, &sbuf, len); - return sbuf; - } - if (len == sizeof (int)) - { - read_memory (memaddr, &ibuf, len); - return ibuf; - } - if (len == sizeof (lbuf)) - { - read_memory (memaddr, &lbuf, len); - return lbuf; - } - error ("Cannot handle integers of %d bytes.", len); -} - -CORE_ADDR -read_pc () -{ - return (CORE_ADDR) read_register (PC_REGNUM); -} - -write_pc (val) - CORE_ADDR val; -{ - write_register (PC_REGNUM, (long) val); -} - -char *reg_names[] = REGISTER_NAMES; - -static void -registers_info (addr_exp) - char *addr_exp; -{ - register int i; - int regnum; - - 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 - printf ("Reg\tContents\n\n"); - - for (i = 0; i < NUM_REGS; i++) - { - unsigned char raw_buffer[MAX_REGISTER_RAW_SIZE]; - unsigned char virtual_buffer[MAX_REGISTER_VIRTUAL_SIZE]; - REGISTER_TYPE val; - - if (addr_exp != 0 && i != regnum) - continue; - - /* On machines with lots of registers, pause every 16 lines - so user can read the output. */ - if (addr_exp == 0 && i > 0 && i % 16 == 0) - { - printf ("--Type Return to print more--"); - fflush (stdout); - read_line (); - } - - /* Get the data in raw format, then convert also to virtual format. */ - read_relative_register_raw_bytes (i, raw_buffer); - REGISTER_CONVERT_TO_VIRTUAL (i, raw_buffer, virtual_buffer); - - printf ("%s\t", reg_names[i]); - - /* If virtual format is floating, print it that way. */ - if (TYPE_CODE (REGISTER_VIRTUAL_TYPE (i)) == TYPE_CODE_FLT - && ! INVALID_FLOAT (virtual_buffer, REGISTER_VIRTUAL_SIZE (i))) - val_print (REGISTER_VIRTUAL_TYPE (i), virtual_buffer, 0, stdout); - /* Else if virtual format is too long for printf, - print in hex a byte at a time. */ - else if (REGISTER_VIRTUAL_SIZE (i) > sizeof (long)) - { - register int j; - printf ("0x"); - for (j = 0; j < REGISTER_VIRTUAL_SIZE (i); j++) - printf ("%02x", virtual_buffer[j]); - } - /* Else print as integer in hex and in decimal. */ - else - { - long val; - - bcopy (virtual_buffer, &val, sizeof (long)); - if (val == 0) - printf ("0"); - else - printf ("0x%08x %d", val, val); - } - - /* If register has different raw and virtual formats, - print the raw format in hex now. */ - - if (REGISTER_CONVERTIBLE (i)) - { - register int j; - - printf (" (raw 0x"); - for (j = 0; j < REGISTER_RAW_SIZE (i); j++) - printf ("%02x", raw_buffer[j]); - printf (")"); - } - printf ("\n"); - } - - printf ("Contents are relative to selected stack frame.\n"); -} - -#ifdef ATTACH_DETACH -/* - * TODO: - * Should save/restore the tty state since it might be that the - * program to be debugged was started on this tty and it wants - * the tty in some state other than what we want. If it's running - * on another terminal or without a terminal, then saving and - * restoring the tty state is a harmless no-op. - */ - -/* - * attach_command -- - * takes a program started up outside of gdb and ``attaches'' to it. - * This stops it cold in it's tracks and allows us to start tracing - * it. For this to work, we must be able to send the process a - * signal and we must have the same effective uid as the program. - */ -static void -attach_command (args, from_tty) - char *args; - int from_tty; -{ - char *exec_file; - int pid; - - dont_repeat(); - - if (!args) - error_no_arg ("process-id to attach"); - else - pid = atoi (args); - - if (inferior_pid) - { - if (query ("A program is being debugged already. Kill it? ")) - kill_inferior (); - else - error ("Inferior not killed."); - } - - exec_file = (char *) get_exec_file (); - - if (from_tty) - { - printf ("Attaching program: %s pid %d\n", - exec_file, pid); - fflush (stdout); - } - - attach_program (pid); -} - -/* - * detach_command -- - * takes a program previously attached to and detaches it. - * The program resumes execution and will no longer stop - * on signals, etc. We better not have left any breakpoints - * in the program or it'll die when it hits one. For this - * to work, it may be necessary for the process to have been - * previously attached. It *might* work if the program was - * started via the normal ptrace (PTRACE_TRACEME). - */ - -static void -detach_command (args, from_tty) - char *args; - int from_tty; -{ - char *exec_file = (char *)get_exec_file (); - int signal = 0; - - if (!inferior_pid) - error ("Not currently tracing a program\n"); - if (from_tty) - { - printf ("Detaching program: %s pid %d\n", - exec_file, inferior_pid); - fflush (stdout); - } - if (args) - signal = atoi (args); - - detach (signal); - inferior_pid = 0; -} -#endif /* ATTACH_DETACH */ - -static -initialize () -{ - add_com ("tty", class_run, tty_command, - "Set terminal for future runs of program being debugged."); - - add_com ("set-args", class_run, set_args_command, - "Specify arguments to give program being debugged when it is started.\n\ -Follow this command with any number of args, to be passed to the program."); - - add_info ("environment", environment_info, - "The environment to give the program, or one variable's value.\n\ -With an argument VAR, prints the value of environment variable VAR to\n\ -give the program being debugged. With no arguments, prints the entire\n\ -environment to be given to the program."); - - add_com ("unset-environment", class_run, unset_environment_command, - "Cancel environment variable VAR for the program.\n\ -This does not affect the program until the next \"run\" command."); - add_com ("set-environment", class_run, set_environment_command, - "Set environment variable value to give the program.\n\ -Arguments are VAR VALUE where VAR is variable name and VALUE is value.\n\ -VALUES of environment variables are uninterpreted strings.\n\ -This does not affect the program until the next \"run\" command."); - -#ifdef ATTACH_DETACH - add_com ("attach", class_run, attach_command, - "Attach to a process that was started up outside of GDB.\n\ -To do this, you must have permission to send the process a signal.\n\ -And it must have the same effective uid as the debugger.\n\n\ -Before using \"attach\", you must use the \"exec-file\" command\n\ -to specify the program running in the process,\n\ -and the \"symbol-file\" command to load its symbol table."); - add_com ("detach", class_run, detach_command, - "Detach the process previously attached.\n\ -The process is no longer traced and continues its execution."); -#endif /* ATTACH_DETACH */ - - add_com ("signal", class_run, signal_command, - "Continue program giving it signal number SIGNUMBER."); - - add_com ("stepi", class_run, stepi_command, - "Step one instruction exactly.\n\ -Argument N means do this N times (or till program stops for another reason)."); - add_com_alias ("si", "stepi", class_alias, 0); - - add_com ("nexti", class_run, nexti_command, - "Step one instruction, but proceed through subroutine calls.\n\ -Argument N means do this N times (or till program stops for another reason)."); - add_com_alias ("ni", "nexti", class_alias, 0); - - add_com ("finish", class_run, finish_command, - "Execute until selected stack frame returns.\n\ -Upon return, the value returned is printed and put in the value history."); - - add_com ("next", class_run, next_command, - "Step program, proceeding through subroutine calls.\n\ -Like the \"step\" command as long as subroutine calls do not happen;\n\ -when they do, the call is treated as one instruction.\n\ -Argument N means do this N times (or till program stops for another reason)."); - add_com_alias ("n", "next", class_run, 1); - - add_com ("step", class_run, step_command, - "Step program until it reaches a different source line.\n\ -Argument N means do this N times (or till program stops for another reason)."); - add_com_alias ("s", "step", class_run, 1); - - add_com ("jump", class_run, jump_command, - "Continue program being debugged at specified line or address.\n\ -Give as argument either LINENUM or *ADDR, where ADDR is an expression\n\ -for an address to start at."); - - add_com ("cont", class_run, cont_command, - "Continue program being debugged, after signal or breakpoint.\n\ -If proceeding from breakpoint, a number N may be used as an argument:\n\ -then the same breakpoint won't break until the Nth time it is reached."); - add_com_alias ("c", "cont", class_run, 1); - - add_com ("run", class_run, run_command, - "Start debugged program. You may specify arguments to give it.\n\ -Args may include \"*\", or \"[...]\"; they are expanded using \"sh\".\n\ -Input and output redirection with \">\", \"<\", or \">>\" are also allowed.\n\n\ -With no arguments, uses arguments last specified (with \"run\" or \"set-args\".\n\ -To cancel previous arguments and run with no arguments,\n\ -use \"set-args\" without arguments."); - add_com_alias ("r", "run", class_run, 1); - - add_info ("registers", registers_info, - "List of registers and their contents, for selected stack frame.\n\ -Register name as argument means describe only that register."); - - add_info ("program", program_info, - "Execution status of the program."); - - inferior_args = savestring (" ", 1); /* By default, no args. */ - inferior_environ = make_environ (); - init_environ (inferior_environ); -} - -END_FILE -@ - - -1.1 -log -@Initial revision -@ -text -@d34 39 -d74 1 -@ diff --git a/gdb/RCS/inflow.c,v b/gdb/RCS/inflow.c,v deleted file mode 100644 index 83f44d9..0000000 --- a/gdb/RCS/inflow.c,v +++ /dev/null @@ -1,731 +0,0 @@ -head 1.2; -access ; -symbols RMS-has:1.2; -locks ; strict; -comment @ * @; - - -1.2 -date 88.01.26.05.07.38; author gnu; state Exp; -branches ; -next 1.1; - -1.1 -date 88.01.21.05.04.57; author gnu; state Exp; -branches ; -next ; - - -desc -@From RMS's development sources on wheaties, 20Jan88 -@ - - -1.2 -log -@Major Sys V tty changes, and a few changes to try to find the registers -in the upage (untested yet). -@ -text -@/* Low level interface to ptrace, for GDB when running under Unix. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - -GDB is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY. No author or distributor accepts responsibility to anyone -for the consequences of using it or for whether it serves any -particular purpose or works at all, unless he says so in writing. -Refer to the GDB General Public License for full details. - -Everyone is granted permission to copy, modify and redistribute GDB, -but only under the conditions described in the GDB General Public -License. A copy of this license is supposed to have been given to you -along with GDB so you can know your rights and responsibilities. It -should be in a file named COPYING. Among other things, the copyright -notice and this notice must be preserved on all copies. - -In other words, go ahead and share GDB, but don't try to stop -anyone else from sharing it farther. Help stamp out software hoarding! -*/ - -#include "defs.h" -#include "initialize.h" -#include "param.h" -#include "frame.h" -#include "inferior.h" - -#include <stdio.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/dir.h> -#include <signal.h> -#include <sys/ioctl.h> -#include <sgtty.h> -#include <fcntl.h> - -#ifdef mac_aux -#include <sys/seg.h> -#include <sys/mmu.h> -#include <sys/signal.h> -#include <sys/time.h> -#include <sys/user.h> -#else -#include <sys/user.h> -#endif /* mac_aux */ - - -#ifdef UMAX_PTRACE -#include <a.out.h> -#endif - -#ifdef NEW_SUN_PTRACE -#include <sys/ptrace.h> -#include <machine/reg.h> -#endif - -#ifdef SYSV_TTYS -#include <termio.h> -#endif - -extern int errno; - -/* Nonzero if we are debugging an attached outside process - rather than an inferior. */ - -static int attach_flag; - -#define UPAGE_MASK 0x00003FFF - -START_FILE - -/* Record terminal status separately for debugger and inferior. */ - -#ifdef SYSV_TTYS -static struct termio ti_inferior; -#else -static struct sgttyb sg_inferior; -static struct tchars tc_inferior; -static struct ltchars ltc_inferior; -static int lmode_inferior; -#endif -static int tflags_inferior; -static int pgrp_inferior; - -#ifdef SYSV_TTYS -static struct termio ti_ours; -#else -static struct sgttyb sg_ours; -static struct tchars tc_ours; -static struct ltchars ltc_ours; -static int lmode_ours; -#endif -static int tflags_ours; -static int pgrp_ours; - -/* Copy of inferior_io_terminal when inferior was last started. */ -static char *inferior_thisrun_terminal; - -static void terminal_ours_1 (); - -/* Nonzero if our terminal settings are in effect. - Zero if the inferior's settings are in effect. */ -static int terminal_is_ours; - -/* Initialize the terminal settings we record for the inferior, - before we actually run the inferior. */ - -void -terminal_init_inferior () -{ - -#ifdef SYSV_TTYS - ti_inferior = ti_ours; -#else - sg_inferior = sg_ours; - tc_inferior = tc_ours; - ltc_inferior = ltc_ours; - lmode_inferior = lmode_ours; -#endif - tflags_inferior = tflags_ours; - pgrp_inferior = inferior_pid; - - terminal_is_ours = 1; -} - -/* Put the inferior's terminal settings into effect. - This is preparation for starting or resuming the inferior. */ - -void -terminal_inferior () -{ - if (terminal_is_ours) /* && inferior_thisrun_terminal == 0) */ - { - fcntl (0, F_SETFL, tflags_inferior); - fcntl (0, F_SETFL, tflags_inferior); -#ifdef SYSV_TTYS - ioctl (0, TCSETA, &ti_inferior); -#else - ioctl (0, TIOCSETN, &sg_inferior); - ioctl (0, TIOCSETC, &tc_inferior); - ioctl (0, TIOCSLTC, <c_inferior); - ioctl (0, TIOCLSET, &lmode_inferior); -#endif - ioctl (0, TIOCSPGRP, &pgrp_inferior); - } - terminal_is_ours = 0; -} - -/* Put some of our terminal settings into effect, - enough to get proper results from our output, - but do not change into or out of RAW mode - so that no input is discarded. - - After doing this, either terminal_ours or terminal_inferior - should be called to get back to a normal state of affairs. */ - -void -terminal_ours_for_output () -{ - terminal_ours_1 (1); -} - -/* Put our terminal settings into effect. - First record the inferior's terminal settings - so they can be restored properly later. */ - -void -terminal_ours () -{ - terminal_ours_1 (0); -} - -static void -terminal_ours_1 (output_only) - int output_only; -{ - /* Ignore this signal since it will happen when we try to set the pgrp. */ - int (*osigttou) (); - - if (!terminal_is_ours) /* && inferior_thisrun_terminal == 0) */ - { - terminal_is_ours = 1; - - osigttou = signal (SIGTTOU, SIG_IGN); - - ioctl (0, TIOCGPGRP, &pgrp_inferior); - ioctl (0, TIOCSPGRP, &pgrp_ours); - - signal (SIGTTOU, osigttou); - - tflags_inferior = fcntl (0, F_GETFL, 0); -#ifdef SYSV_TTYS - ioctl (0, TCGETA, &ti_inferior); -#else - ioctl (0, TIOCGETP, &sg_inferior); - ioctl (0, TIOCGETC, &tc_inferior); - ioctl (0, TIOCGLTC, <c_inferior); - ioctl (0, TIOCLGET, &lmode_inferior); -#endif - } - - fcntl (0, F_SETFL, tflags_ours); - fcntl (0, F_SETFL, tflags_ours); - - -#ifdef SYSV_TTYS - ti_ours.c_lflag |= ICANON | ISIG; - if (output_only) - ti_ours.c_lflag &= ~((ICANON|ISIG)&ti_inferior.c_lflag); - ioctl (0, TCSETA, &ti_ours); - ti_ours.c_lflag |= ICANON | ISIG; -#else - sg_ours.sg_flags &= ~RAW & ~CBREAK; - if (output_only) - sg_ours.sg_flags |= (RAW | CBREAK) & sg_inferior.sg_flags; - ioctl (0, TIOCSETN, &sg_ours); - ioctl (0, TIOCSETC, &tc_ours); - ioctl (0, TIOCSLTC, <c_ours); - ioctl (0, TIOCLSET, &lmode_ours); - sg_ours.sg_flags &= ~RAW & ~CBREAK; -#endif -} - -static void -term_status_command () -{ - register int i; - printf ("Inferior's terminal status (currently saved by GDB):\n"); -#ifdef SYSV_TTYS - printf ("fcntl flags = 0x%x, owner pid = %d.\n", - tflags_inferior, pgrp_inferior); - printf ("iflag = 0x%04x, oflag = 0x%04x, cflag = 0x%04x, lflag = 0x%04x\n", - ti_inferior.c_iflag, ti_inferior.c_oflag, - ti_inferior.c_cflag, ti_inferior.c_lflag); - printf ("line discipline = %d\n", ti_inferior.c_line); - printf ("control chars: "); - for (i = 0; i < NCC; i++) - printf ("0x%x ", ti_inferior.c_cc[i]); - printf ("\n"); -#else - printf ("fcntl flags = 0x%x, lmode = 0x%x,\nsgttyb.sg_flags = 0x%x, owner pid = %d.\n", - tflags_inferior, lmode_inferior, - sg_inferior.sg_flags, pgrp_inferior); - printf ("tchars: "); - for (i = 0; i < sizeof (struct tchars); i++) - printf ("0x%x ", ((char *)&tc_inferior)[i]); - printf ("\n"); - printf ("ltchars: "); - for (i = 0; i < sizeof (struct ltchars); i++) - printf ("0x%x ", ((char *)<c_inferior)[i]); - printf ("\n"); -#endif -} - -static void -new_tty (ttyname) - char *ttyname; -{ - register int tty; - register int fd; - -#if 0 - /* I think it is better not to do this. Then C-z on the GDB terminal - will still stop the program, while C-z on the data terminal - will be input. */ - - /* Disconnect the child process from our controlling terminal. */ - tty = open("/dev/tty", O_RDWR); - if (tty > 0) - { - ioctl(tty, TIOCNOTTY, 0); - close(tty); - } -#endif - /* Now open the specified new terminal. */ - - tty = open(ttyname, O_RDWR); - if (tty == -1) - _exit(1); - - dup2(tty, 0); - dup2(tty, 1); - dup2(tty, 2); - close(tty); -} - -/* Start an inferior process and returns its pid. - ALLARGS is a vector of program-name and args. - ENV is the environment vector to pass. */ - -int -create_inferior (allargs, env) - char **allargs; - char **env; -{ - int pid; - extern int sys_nerr; - extern char *sys_errlist[]; - extern int errno; - - /* exec is said to fail if the executable is open. */ - close_exec_file (); - - pid = vfork (); - if (pid < 0) - perror_with_name ("vfork"); - - if (pid == 0) - { - /* Run inferior in a separate process group. */ - setpgrp (getpid (), getpid ()); - - inferior_thisrun_terminal = inferior_io_terminal; - if (inferior_io_terminal != 0) - new_tty (inferior_io_terminal); - -/* Not needed on Sun, at least, and loses there - because it clobbers the superior. */ -/*??? signal (SIGQUIT, SIG_DFL); - signal (SIGINT, SIG_DFL); */ - - ptrace (0); - execle ("/bin/sh", "sh", "-c", allargs, 0, env); - - fprintf (stderr, "Cannot exec /bin/sh: %s.\n", - errno < sys_nerr ? sys_errlist[errno] : "unknown error"); - fflush (stderr); - _exit (0177); - } - return pid; -} - -/* Kill the inferior process. Make us have no inferior. */ - -static void -kill_command () -{ - if (inferior_pid == 0) - error ("The program is not being run."); - if (!query ("Kill the inferior process? ")) - error ("Not confirmed."); - kill_inferior (); -} - -kill_inferior () -{ - if (inferior_pid == 0) - return; - ptrace (8, inferior_pid, 0, 0); - wait (0); - inferior_died (); -} - -inferior_died () -{ - inferior_pid = 0; - attach_flag = 0; - mark_breakpoints_out (); - reopen_exec_file (); - if (have_core_file_p ()) - set_current_frame (read_register (FP_REGNUM)); -} - -/* 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; - ptrace (step ? 9 : 7, inferior_pid, 1, signal); - if (errno) - perror_with_name ("ptrace"); -} - -#ifdef NEW_SUN_PTRACE - -/* Start debugging the process whose number is PID. */ - -attach (pid) - int pid; -{ - errno = 0; - ptrace (PTRACE_ATTACH, pid, 0, 0); - if (errno) - perror_with_name ("ptrace"); - attach_flag = 1; - return pid; -} - -/* Stop debugging the process whose number is PID - and continue it with signal number SIGNAL. - SIGNAL = 0 means just continue it. */ - -void -detach (signal) - int signal; -{ - errno = 0; - ptrace (PTRACE_DETACH, inferior_pid, 1, signal); - if (errno) - perror_with_name ("ptrace"); - attach_flag = 0; -} -#endif - -#ifdef NEW_SUN_PTRACE - -void -fetch_inferior_registers () -{ - struct regs inferior_registers; - struct fp_status inferior_fp_registers; - extern char registers[]; - - ptrace (PTRACE_GETREGS, inferior_pid, &inferior_registers); - ptrace (PTRACE_GETFPREGS, inferior_pid, &inferior_fp_registers); - - bcopy (&inferior_registers, registers, 16 * 4); - bcopy (&inferior_fp_registers, ®isters[REGISTER_BYTE (FP0_REGNUM)], - sizeof inferior_fp_registers.fps_regs); - *(int *)®isters[REGISTER_BYTE (PS_REGNUM)] = inferior_registers.r_ps; - *(int *)®isters[REGISTER_BYTE (PC_REGNUM)] = inferior_registers.r_pc; - bcopy (&inferior_fp_registers.fps_control, - ®isters[REGISTER_BYTE (FPC_REGNUM)], - sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs); -} - -/* 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; -{ - struct regs inferior_registers; - struct fp_status inferior_fp_registers; - extern char registers[]; - - bcopy (registers, &inferior_registers, 16 * 4); - bcopy (®isters[REGISTER_BYTE (FP0_REGNUM)], &inferior_fp_registers, - sizeof inferior_fp_registers.fps_regs); - inferior_registers.r_ps = *(int *)®isters[REGISTER_BYTE (PS_REGNUM)]; - inferior_registers.r_pc = *(int *)®isters[REGISTER_BYTE (PC_REGNUM)]; - bcopy (®isters[REGISTER_BYTE (FPC_REGNUM)], - &inferior_fp_registers.fps_control, - sizeof inferior_fp_registers - sizeof inferior_fp_registers.fps_regs); - - ptrace (PTRACE_SETREGS, inferior_pid, &inferior_registers); - ptrace (PTRACE_SETFPREGS, inferior_pid, &inferior_fp_registers); -} - -#else - -void -fetch_inferior_registers () -{ - register int regno; - register unsigned int regaddr; - char buf[MAX_REGISTER_RAW_SIZE]; - register int i; - -#ifdef UMAX_PTRACE - unsigned int offset = 0; -#else - struct user u; - unsigned int offset = (char *) &u.u_ar0 - (char *) &u; - offset = ptrace (3, inferior_pid, offset, 0) & UPAGE_MASK; -#endif - - for (regno = 0; regno < NUM_REGS; regno++) - { - regaddr = register_addr (regno, offset); - for (i = 0; i < REGISTER_RAW_SIZE (regno); i += sizeof (int)) - { - *(int *) &buf[i] = ptrace (3, inferior_pid, regaddr, 0); - regaddr += sizeof (int); - } - supply_register (regno, buf); - } -} - -/* Store our register values back into the inferior. - If REGNO is -1, do this for all registers. - Otherwise, REGNO specifies which register (so we can save time). */ - -store_inferior_registers (regno) - int regno; -{ - register unsigned int regaddr; - char buf[80]; - -#ifdef UMAX_PTRACE - unsigned int offset = 0; -#else - struct user u; - unsigned int offset = (char *) &u.u_ar0 - (char *) &u; - offset = ptrace (3, inferior_pid, offset, 0) & UPAGE_MASK; -#endif - - if (regno >= 0) - { - regaddr = register_addr (regno, offset); - 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); - errno = 0; - ptrace (6, inferior_pid, regaddr, read_register (regno)); - if (errno != 0) - { - sprintf (buf, "writing register number %d", regno); - perror_with_name (buf); - } - } -} - -#endif /* not NEW_SUN_PTRACE */ - -/* NOTE! I tried using PTRACE_READDATA, etc., to read and write memory - in the NEW_SUN_PTRACE case. - It ought to be straightforward. But it appears that writing did - not write the data that I specified. I cannot understand where - it got the data that it actually did write. */ - -/* Copy LEN bytes from inferior's memory starting at MEMADDR - to debugger memory starting at MYADDR. */ - -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)); - - /* Read all the longwords */ - for (i = 0; i < count; i++, addr += sizeof (int)) - buffer[i] = ptrace (1, inferior_pid, addr, 0); - - /* Copy appropriate bytes out of the buffer. */ - bcopy ((char *) buffer + (memaddr & (sizeof (int) - 1)), myaddr, len); -} - -/* Copy LEN bytes of data from debugger memnory 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. */ - - buffer[0] = ptrace (1, inferior_pid, addr, 0); - if (count > 1) - 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; - ptrace (4, inferior_pid, addr, buffer[i]); - if (errno) - return errno; - } - - return 0; -} - -static void -try_writing_regs_command () -{ - register int i; - register int value; - extern int errno; - - if (inferior_pid == 0) - error ("The program is not being run."); - - for (i = 0; ; i += 2) - { - QUIT; - errno = 0; - value = ptrace (3, inferior_pid, i, 0); - ptrace (6, inferior_pid, i, value); - if (errno == 0) - { - printf (" Succeeded with address 0x%x; value 0x%x (%d).\n", - i, value, value); - } - else if ((i & 0377) == 0) - printf (" Failed at 0x%x.\n", i); - } -} - -static -initialize () -{ - add_com ("term-status", class_obscure, term_status_command, - "Print info on inferior's saved terminal status."); - - add_com ("try-writing-regs", class_obscure, try_writing_regs_command, - "Try writing all locations in inferior's system block.\n\ -Report which ones can be written."); - - add_com ("kill", class_run, kill_command, - "Kill execution of program being debugged."); - - inferior_pid = 0; - -#ifdef SYSV_TTYS - ioctl (0, TCGETA, &ti_ours); -#else - ioctl (0, TIOCGETP, &sg_ours); - ioctl (0, TIOCGETC, &tc_ours); - ioctl (0, TIOCGLTC, <c_ours); - ioctl (0, TIOCLGET, &lmode_ours); -#endif - fcntl (0, F_GETFL, tflags_ours); - ioctl (0, TIOCGPGRP, &pgrp_ours); - - terminal_is_ours = 1; -} - -END_FILE -@ - - -1.1 -log -@Initial revision -@ -text -@d28 1 -a30 1 -#include <sys/user.h> -d36 11 -d56 4 -d67 2 -d73 3 -d80 1 -d84 3 -d91 1 -d110 4 -d118 1 -d135 3 -d142 1 -d191 3 -d198 1 -d201 11 -a214 3 - - fcntl (0, F_SETFL, tflags_ours); - fcntl (0, F_SETFL, tflags_ours); -d220 1 -d228 12 -d251 1 -d470 1 -a470 1 - offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; -d500 1 -a500 1 - offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; -d647 3 -d654 1 -@ diff --git a/gdb/RCS/m-mac-aux.h,v b/gdb/RCS/m-mac-aux.h,v deleted file mode 100644 index eaac3dd..0000000 --- a/gdb/RCS/m-mac-aux.h,v +++ /dev/null @@ -1,523 +0,0 @@ -head 1.2; -access ; -symbols RMS-has:1.2; -locks ; strict; -comment @ * @; - - -1.2 -date 88.01.26.05.16.06; author gnu; state Exp; -branches ; -next 1.1; - -1.1 -date 88.01.26.05.15.44; author gnu; state Exp; -branches ; -next ; - - -desc -@Originally nonexistent, I create it. -@ - - -1.2 -log -@Original new config file for Mac-II running A/UX. -@ -text -@/* Parameters for execution on Macintosh under A/UX, for GDB, the GNU debugger. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - -GDB is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY. No author or distributor accepts responsibility to anyone -for the consequences of using it or for whether it serves any -particular purpose or works at all, unless he says so in writing. -Refer to the GDB General Public License for full details. - -Everyone is granted permission to copy, modify and redistribute GDB, -but only under the conditions described in the GDB General Public -License. A copy of this license is supposed to have been given to you -along with GDB so you can know your rights and responsibilities. It -should be in a file named COPYING. Among other things, the copyright -notice and this notice must be preserved on all copies. - -In other words, go ahead and share GDB, but don't try to stop -anyone else from sharing it farther. Help stamp out software hoarding! -*/ - -#ifndef mac_aux -#define mac_aux -#endif - -/* Get rid of any system-imposed stack limit if possible. */ - -#undef 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. */ - -#undef NAMES_HAVE_UNDERSCORE - -/* COFF format object files */ - -#define COFF_FORMAT - -/* System eVil ttys */ - -#define SYSV_TTYS - -/* Debugger information will not be in DBX format. */ - -#undef READ_DBX_FORMAT - -/* Offset from address of function to start of its code. - Zero on most machines. */ - -#define FUNCTION_START_OFFSET 0 - -/* Advance PC across any function entry prologue instructions - to reach some "real" code. */ - -#define SKIP_PROLOGUE(pc) \ -{ register int op = read_memory_integer (pc, 2); \ - if (op == 0047126) \ - pc += 4; /* Skip link #word */ \ - else if (op == 0044016) \ - pc += 6; /* Skip link #long */ \ -} - -/* Immediately after a function call, return the saved pc. - Can't go through the frames for this because on some machines - the new frame is not set up until the new function executes - some instructions. */ - -#define SAVED_PC_AFTER_CALL(frame) \ -read_memory_integer (read_register (SP_REGNUM), 4) - -/* Address of end of stack space. */ - -#define STACK_END_ADDR 0x20000000 - -/* Stack grows downward. */ - -#define INNER_THAN < - -/* Sequence of bytes for breakpoint instruction. */ - -#define BREAKPOINT {0x4e, 0x4f} - -/* Amount PC must be decremented by after a breakpoint. - This is often the number of bytes in BREAKPOINT - but not always. */ - -#define DECR_PC_AFTER_BREAK 2 - -/* Nonzero if instruction at PC is a return instruction. */ - -#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 2) == 0x4e76) - -/* Return 1 if P points to an invalid floating point value. */ - -#define INVALID_FLOAT(p, len) 0 /* Just a first guess; not checked */ - -/* Say how long (ordinary) registers are. */ - -#define REGISTER_TYPE long - -/* Number of machine registers */ - -#define NUM_REGS 31 - -/* Initializer for an array of names of registers. - There should be NUM_REGS strings in this initializer. */ - -#define REGISTER_NAMES \ - {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \ - "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \ - "ps", "pc", \ - "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", \ - "fpcontrol", "fpstatus", "fpiaddr", "fpcode", "fpflags" } - -/* Register numbers of various important registers. - Note that some of these values are "real" register numbers, - and correspond to the general registers of the machine, - and some are "phony" register numbers which are too large - to be actual register numbers as far as the user is concerned - but do serve to get the desired values when passed to read_register. */ - -#define FP_REGNUM 14 /* Contains address of executing stack frame */ -#define SP_REGNUM 15 /* Contains address of top of stack */ -#define PS_REGNUM 16 /* Contains processor status */ -#define PC_REGNUM 17 /* Contains program counter */ -#define FP0_REGNUM 18 /* Floating point register 0 */ -#define FPC_REGNUM 26 /* 68881 control register */ - -/* Total amount of space needed to store our copies of the machine's - register state, the array `registers'. */ -#define REGISTER_BYTES (16*4+8*12+8+20) - -/* Index within `registers' of the first byte of the space for - register N. */ - -#define REGISTER_BYTE(N) \ - ((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 168 \ - : (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 12) + 72 \ - : (N) * 4) - -/* Number of bytes of storage in the actual machine representation - for register N. On the 68000, all regs are 4 bytes - except the floating point regs which are 12 bytes. */ - -#define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 12 : 4) - -/* Number of bytes of storage in the program's representation - for register N. On the 68000, all regs are 4 bytes - except the floating point regs which are 8-byte doubles. */ - -#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 8 : 4) - -/* Largest value REGISTER_RAW_SIZE can have. */ - -#define MAX_REGISTER_RAW_SIZE 12 - -/* Largest value REGISTER_VIRTUAL_SIZE can have. */ - -#define MAX_REGISTER_VIRTUAL_SIZE 8 - -/* Nonzero if register N requires conversion - from raw format to virtual format. */ - -#define REGISTER_CONVERTIBLE(N) (((unsigned)(N) - FP0_REGNUM) < 8) - -/* Convert data from raw format for register REGNUM - to virtual format for register REGNUM. */ - -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \ -{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \ - convert_from_68881 ((FROM), (TO)); \ - else \ - bcopy ((FROM), (TO), 4); } - -/* Convert data from virtual format for register REGNUM - to raw format for register REGNUM. */ - -#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \ -{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \ - convert_to_68881 ((FROM), (TO)); \ - else \ - bcopy ((FROM), (TO), 4); } - -/* Return the GDB type object for the "standard" data type - of data in register N. */ - -#define REGISTER_VIRTUAL_TYPE(N) \ - (((unsigned)(N) - FP0_REGNUM) < 8 ? builtin_type_double : builtin_type_int) - -/* Extract from an array REGBUF containing the (raw) register state - a function return value of type TYPE, and copy that, in virtual format, - into VALBUF. */ - -#define EXTRACT_RETURN_VALUE(TYPE,REGBUF,VALBUF) \ - bcopy (REGBUF, VALBUF, TYPE_LENGTH (TYPE)) - -/* Write into appropriate registers a function return value - of type TYPE, given in virtual format. */ - -#define STORE_RETURN_VALUE(TYPE,VALBUF) \ - write_register_bytes (0, VALBUF, TYPE_LENGTH (TYPE)) - -/* Extract from an array REGBUF containing the (raw) register state - the address in which a function should return its structure value, - as a CORE_ADDR (or an expression that can be used as one). */ - -#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF)) - -/* Enable use of alternate code to read and write registers. */ - -#undef NEW_SUN_PTRACE - -/* Enable use of alternate code for Sun's format of core dump file. */ - -#undef NEW_SUN_CORE - -/* Do implement the attach and detach commands. */ - -#undef ATTACH_DETACH - -/* It is safe to look for symsegs on a Sun, because Sun's ld - does not screw up with random garbage at end of file. */ - -#define READ_GDB_SYMSEGS - -/* Describe the pointer in each stack frame to the previous stack frame - (its caller). */ - -/* FRAME_CHAIN takes a frame's nominal address - and produces the frame's chain-pointer. - - FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address - and produces the nominal address of the caller frame. - - However, if FRAME_CHAIN_VALID returns zero, - it means the given frame is the outermost one and has no caller. - In that case, FRAME_CHAIN_COMBINE is not used. */ - -/* In the case of the Sun, the frame's nominal address - is the address of a 4-byte word containing the calling frame's address. */ - -#define FRAME_CHAIN(thisframe) (read_memory_integer (thisframe, 4)) - -#define FRAME_CHAIN_VALID(chain, thisframe) \ - (chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end)) - -#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain) - -/* Define other aspects of the stack frame. */ - -#define FRAME_SAVED_PC(frame) (read_memory_integer (frame + 4, 4)) - -#define FRAME_ARGS_ADDRESS(fi) (fi.frame) - -#define FRAME_LOCALS_ADDRESS(fi) (fi.frame) - -/* Set VAL to the number of args passed to frame described by FI. - Can set VAL to -1, meaning no way to tell. */ - -/* We can't tell how many args there are - now that the C compiler delays popping them. */ -#define FRAME_NUM_ARGS(val,fi) (val = -1) - -#if 0 -#define FRAME_NUM_ARGS(val, fi) \ -{ register CORE_ADDR pc = FRAME_SAVED_PC (fi.frame); \ - register int insn = 0177777 & read_memory_integer (pc, 2); \ - val = 0; \ - if (insn == 0047757 || insn == 0157374) /* lea W(sp),sp or addaw #W,sp */ \ - val = read_memory_integer (pc + 2, 2); \ - else if ((insn & 0170777) == 0050217 /* addql #N, sp */ \ - || (insn & 0170777) == 0050117) /* addqw */ \ - { val = (insn >> 9) & 7; if (val == 0) val = 8; } \ - else if (insn == 0157774) /* addal #WW, sp */ \ - val = read_memory_integer (pc + 2, 4); \ - val >>= 2; } -#endif - -/* Return number of bytes at start of arglist that are not really args. */ - -#define FRAME_ARGS_SKIP 8 - -/* Put here the code to store, into a struct frame_saved_regs, - the addresses of the saved registers of frame described by FRAME_INFO. - This includes special registers such as pc and fp saved in special - ways in the stack frame. sp is even more special: - the address we return for it IS the sp for the next frame. */ - -#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \ -{ register int regnum; \ - register int regmask; \ - register CORE_ADDR next_addr; \ - register CORE_ADDR pc; \ - int nextinsn; \ - bzero (&frame_saved_regs, sizeof frame_saved_regs); \ - if ((frame_info).pc >= (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM*4 - 8*12 - 4 \ - && (frame_info).pc <= (frame_info).frame) \ - { next_addr = (frame_info).frame; \ - pc = (frame_info).frame - CALL_DUMMY_LENGTH - FP_REGNUM * 4 - 8*12 - 4; }\ - else \ - { pc = get_pc_function_start ((frame_info).pc); \ - /* Verify we have a link a6 instruction next; \ - if not we lose. If we win, find the address above the saved \ - regs using the amount of storage from the link instruction. */\ - if (044016 == read_memory_integer (pc, 2)) \ - next_addr = (frame_info).frame + read_memory_integer (pc += 2, 4), pc+=4; \ - else if (047126 == read_memory_integer (pc, 2)) \ - next_addr = (frame_info).frame + read_memory_integer (pc += 2, 2), pc+=2; \ - else goto lose; \ - /* If have an addal #-n, sp next, adjust next_addr. */ \ - if ((0177777 & read_memory_integer (pc, 2)) == 0157774) \ - next_addr += read_memory_integer (pc += 2, 4), pc += 4; \ - } \ - /* next should be a moveml to (sp) or -(sp) or a movl r,-(sp) */ \ - regmask = read_memory_integer (pc + 2, 2); \ - /* But before that can come an fmovem. Check for it. */ \ - nextinsn = 0xffff & read_memory_integer (pc, 2); \ - if (0xf227 == nextinsn \ - && (regmask & 0xff00) == 0xe000) \ - { pc += 4; /* Regmask's low bit is for register fp7, the first pushed */ \ - for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \ - if (regmask & 1) \ - (frame_saved_regs).regs[regnum] = (next_addr -= 12); \ - regmask = read_memory_integer (pc + 2, 2); } \ - if (0044327 == read_memory_integer (pc, 2)) \ - { pc += 4; /* Regmask's low bit is for register 0, the first written */ \ - for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \ - if (regmask & 1) \ - (frame_saved_regs).regs[regnum] = (next_addr += 4) - 4; } \ - else if (0044347 == read_memory_integer (pc, 2)) \ - { pc += 4; /* Regmask's low bit is for register 15, the first pushed */ \ - for (regnum = 15; regnum >= 0; regnum--, regmask >>= 1) \ - if (regmask & 1) \ - (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \ - else if (0x2f00 == 0xfff0 & read_memory_integer (pc, 2)) \ - { regnum = 0xf & read_memory_integer (pc, 2); pc += 2; \ - (frame_saved_regs).regs[regnum] = (next_addr -= 4); } \ - /* fmovemx to index of sp may follow. */ \ - regmask = read_memory_integer (pc + 2, 2); \ - nextinsn = 0xffff & read_memory_integer (pc, 2); \ - if (0xf236 == nextinsn \ - && (regmask & 0xff00) == 0xf000) \ - { pc += 10; /* Regmask's low bit is for register fp0, the first written */ \ - for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--, regmask >>= 1) \ - if (regmask & 1) \ - (frame_saved_regs).regs[regnum] = (next_addr += 12) - 12; \ - regmask = read_memory_integer (pc + 2, 2); } \ - /* clrw -(sp); movw ccr,-(sp) may follow. */ \ - if (0x426742e7 == read_memory_integer (pc, 4)) \ - (frame_saved_regs).regs[PS_REGNUM] = (next_addr -= 4); \ - lose: ; \ - (frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 8; \ - (frame_saved_regs).regs[FP_REGNUM] = (frame_info).frame; \ - (frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4; \ -} - -/* Things needed for making the inferior call functions. */ - -/* Push an empty stack frame, to record the current PC, etc. */ - -#define PUSH_DUMMY_FRAME \ -{ register CORE_ADDR sp = read_register (SP_REGNUM); \ - register int regnum; \ - char raw_buffer[12]; \ - sp = push_word (sp, read_register (PC_REGNUM)); \ - sp = push_word (sp, read_register (FP_REGNUM)); \ - write_register (FP_REGNUM, sp); \ - for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \ - { read_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); \ - sp = push_bytes (sp, raw_buffer, 12); } \ - for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \ - sp = push_word (sp, read_register (regnum)); \ - sp = push_word (sp, read_register (PS_REGNUM)); \ - write_register (SP_REGNUM, sp); } - -/* Discard from the stack the innermost frame, - restoring all saved registers. */ - -#define POP_FRAME \ -{ register CORE_ADDR fp = read_register (FP_REGNUM); \ - register int regnum; \ - struct frame_saved_regs fsr; \ - struct frame_info fi; \ - char raw_buffer[12]; \ - fi = get_frame_info (fp); \ - get_frame_saved_regs (&fi, &fsr); \ - for (regnum = FP0_REGNUM + 7; regnum >= FP0_REGNUM; regnum--) \ - if (fsr.regs[regnum]) \ - { read_memory (fsr.regs[regnum], raw_buffer, 12); \ - write_register_bytes (REGISTER_BYTE (regnum), raw_buffer, 12); }\ - for (regnum = FP_REGNUM - 1; regnum >= 0; regnum--) \ - if (fsr.regs[regnum]) \ - write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \ - if (fsr.regs[PS_REGNUM]) \ - write_register (PS_REGNUM, read_memory_integer (fsr.regs[PS_REGNUM], 4)); \ - write_register (FP_REGNUM, read_memory_integer (fp, 4)); \ - write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \ - write_register (SP_REGNUM, fp + 8); \ - set_current_frame (read_register (FP_REGNUM)); } - -/* This sequence of words is the instructions - fmovem 0xff,-(sp) - moveml 0xfffc,-(sp) - clrw -(sp) - movew ccr,-(sp) - /..* The arguments are pushed at this point by GDB; - no code is needed in the dummy for this. - The CALL_DUMMY_START_OFFSET gives the position of - the following jsr instruction. *../ - jsr @@#32323232 - addl #69696969,sp - bpt - nop -Note this is 28 bytes. -We actually start executing at the jsr, since the pushing of the -registers is done by PUSH_DUMMY_FRAME. If this were real code, -the arguments for the function called by the jsr would be pushed -between the moveml and the jsr, and we could allow it to execute through. -But the arguments have to be pushed by GDB after the PUSH_DUMMY_FRAME is done, -and we cannot allow the moveml to push the registers again lest they be -taken for the arguments. */ - -#define CALL_DUMMY {0xf227e0ff, 0x48e7fffc, 0x426742e7, 0x4eb93232, 0x3232dffc, 0x69696969, 0x4e4f4e71} - -#define CALL_DUMMY_LENGTH 28 - -#define CALL_DUMMY_START_OFFSET 12 - -/* Insert the specified number of args and function address - into a call sequence of the above form stored at DUMMYNAME. */ - -#define FIX_CALL_DUMMY(dummyname, fun, nargs) \ -{ *(int *)((char *) dummyname + 20) = nargs * 4; \ - *(int *)((char *) dummyname + 14) = fun; } - -/* Interface definitions for kernel debugger KDB. */ - -/* Map machine fault codes into signal numbers. - First subtract 0, divide by 4, then index in a table. - Faults for which the entry in this table is 0 - are not handled by KDB; the program's own trap handler - gets to handle then. */ - -#define FAULT_CODE_ORIGIN 0 -#define FAULT_CODE_UNITS 4 -#define FAULT_TABLE \ -{ 0, 0, 0, 0, SIGTRAP, 0, 0, 0, \ - 0, SIGTRAP, 0, 0, 0, 0, 0, SIGKILL, \ - 0, 0, 0, 0, 0, 0, 0, 0, \ - SIGILL } - -/* Start running with a stack stretching from BEG to END. - BEG and END should be symbols meaningful to the assembler. - This is used only for kdb. */ - -#define INIT_STACK(beg, end) \ -{ asm (".globl end"); \ - asm ("movel #end, sp"); \ - asm ("movel #0,a6"); } - -/* Push the frame pointer register on the stack. */ -#define PUSH_FRAME_PTR \ - asm ("movel a6,sp@@-"); - -/* Copy the top-of-stack to the frame pointer register. */ -#define POP_FRAME_PTR \ - asm ("movl sp@@,a6"); - -/* After KDB is entered by a fault, push all registers - that GDB thinks about (all NUM_REGS of them), - so that they appear in order of ascending GDB register number. - The fault code will be on the stack beyond the last register. */ - -#define PUSH_REGISTERS \ -{ asm ("clrw -(sp)"); \ - asm ("pea sp@@(10)"); \ - asm ("movem #0xfffe,sp@@-"); } - -/* Assuming the registers (including processor status) have been - pushed on the stack in order of ascending GDB register number, - restore them and return to the address in the saved PC register. */ - -#define POP_REGISTERS \ -{ asm ("subil #8,sp@@(28)"); \ - asm ("movem sp@@,#0xffff"); \ - asm ("rte"); } -@ - - -1.1 -log -@Initial revision -@ -text -@d1 485 -@ diff --git a/gdb/RCS/m-mac-auxinit.h,v b/gdb/RCS/m-mac-auxinit.h,v deleted file mode 100644 index 796bc8d..0000000 --- a/gdb/RCS/m-mac-auxinit.h,v +++ /dev/null @@ -1,43 +0,0 @@ -head 1.2; -access ; -symbols RMS-has:1.2; -locks ; strict; -comment @ * @; - - -1.2 -date 88.01.26.05.19.09; author gnu; state Exp; -branches ; -next 1.1; - -1.1 -date 88.01.26.05.18.45; author gnu; state Exp; -branches ; -next ; - - -desc -@Originally nonexistent. -@ - - -1.2 -log -@Created by John Gilmore for Mac A/UX -@ -text -@ -/* This is how the size of an individual .o file's text segment - is rounded on a mac under a/ux. */ - -#define FILEADDR_ROUND(addr) (addr) -@ - - -1.1 -log -@Initial revision -@ -text -@d1 5 -@ diff --git a/gdb/RCS/m68k-pinsn.c,v b/gdb/RCS/m68k-pinsn.c,v deleted file mode 100644 index dedc0e7..0000000 --- a/gdb/RCS/m68k-pinsn.c,v +++ /dev/null @@ -1,828 +0,0 @@ -head 1.2; -access ; -symbols RMS-has:1.2; -locks ; strict; -comment @ * @; - - -1.2 -date 88.01.26.05.08.29; author gnu; state Exp; -branches ; -next 1.1; - -1.1 -date 88.01.21.22.04.55; author gnu; state Exp; -branches ; -next ; - - -desc -@From RMS's development sources on wheaties, 20Jan88 -@ - - -1.2 -log -@Avoid the so-called "portable" preassembled instructions; call a macro -to generate them, since a/ux assembler uses a different syntax (grumble) -@ -text -@/* Print m68k instructions for GDB, the GNU debugger. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - -GDB is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY. No author or distributor accepts responsibility to anyone -for the consequences of using it or for whether it serves any -particular purpose or works at all, unless he says so in writing. -Refer to the GDB General Public License for full details. - -Everyone is granted permission to copy, modify and redistribute GDB, -but only under the conditions described in the GDB General Public -License. A copy of this license is supposed to have been given to you -along with GDB so you can know your rights and responsibilities. It -should be in a file named COPYING. Among other things, the copyright -notice and this notice must be preserved on all copies. - -In other words, go ahead and share GDB, but don't try to stop -anyone else from sharing it farther. Help stamp out software hoarding! -*/ - -#include <stdio.h> - -#include "defs.h" -#include "param.h" -#include "symtab.h" -#include "m68k-opcode.h" - -/* 68k instructions are never longer than this many bytes. */ -#define MAXLEN 22 - -/* Number of elements in the opcode table. */ -#define NOPCODES (sizeof m68k_opcodes / sizeof m68k_opcodes[0]) - -extern char *reg_names[]; -char *fpcr_names[] = { "", "fpiar", "fpsr", "fpiar/fpsr", "fpcr", - "fpiar/fpcr", "fpsr/fpcr", "fpiar-fpcr"}; - -static unsigned char *print_insn_arg (); -static unsigned char *print_indexed (); -static void print_base (); -static int fetch_arg (); - -#define NEXTBYTE(p) (p += 2, ((char *)p)[-1]) - -#define NEXTWORD(p) \ - (p += 2, ((((char *)p)[-2]) << 8) + p[-1]) - -#define NEXTLONG(p) \ - (p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]) - -#define NEXTSINGLE(p) \ - (p += 4, *((float *)(p - 4))) - -#define NEXTDOUBLE(p) \ - (p += 8, *((double *)(p - 8))) - -#define NEXTEXTEND(p) \ - (p += 12, 0.0) /* Need a function to convert from extended to double - precision... */ - -#define NEXTPACKED(p) \ - (p += 12, 0.0) /* Need a function to convert from packed to double - precision. Actually, it's easier to print a - packed number than a double anyway, so maybe - there should be a special case to handle this... */ - -/* Print the m68k instruction at address MEMADDR in debugged memory, - on STREAM. Returns length of the instruction, in bytes. */ - -int -print_insn (memaddr, stream) - CORE_ADDR memaddr; - FILE *stream; -{ - unsigned char buffer[MAXLEN]; - register int i; - register unsigned char *p; - register char *d; - register int bestmask; - int best; - - read_memory (memaddr, buffer, MAXLEN); - - bestmask = 0; - best = -1; - for (i = 0; i < NOPCODES; i++) - { - register unsigned int opcode = m68k_opcodes[i].opcode; - register unsigned int match = m68k_opcodes[i].match; - if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24))) - && ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16))) - && ((0xff & buffer[2] & (match >> 8)) == (0xff & (opcode >> 8))) - && ((0xff & buffer[3] & match) == (0xff & opcode))) - { - /* Don't use for printout the variants of divul and divsl - that have the same register number in two places. - The more general variants will match instead. */ - for (d = m68k_opcodes[i].args; *d; d += 2) - if (d[1] == 'D') - break; - - /* Don't use for printout the variants of most floating - point coprocessor instructions which use the same - register number in two places, as above. */ - if (*d == 0) - for (d = m68k_opcodes[i].args; *d; d += 2) - if (d[1] == 't') - break; - - if (*d == 0 && match > bestmask) - { - best = i; - bestmask = match; - } - } - } - - /* Handle undefined instructions. */ - if (best < 0) - { - fprintf (stream, "0%o", (buffer[0] << 8) + buffer[1]); - return 2; - } - - fprintf (stream, "%s", m68k_opcodes[best].name); - - /* Point at first word of argument data, - and at descriptor for first argument. */ - p = buffer + 2; - - /* Why do this this way? -MelloN */ - for (d = m68k_opcodes[best].args; *d; d += 2) - { - if (d[0] == '#') - { - if (d[1] == 'l' && p - buffer < 6) - p = buffer + 6; - else if (p - buffer < 4 && d[1] != 'C' && d[1] != '8' ) - p = buffer + 4; - } - if (d[1] >= '1' && d[1] <= '3' && p - buffer < 4) - p = buffer + 4; - if (d[1] >= '4' && d[1] <= '6' && p - buffer < 6) - p = buffer + 6; - } - - d = m68k_opcodes[best].args; - - if (*d) - fputc (' ', stream); - - while (*d) - { - p = print_insn_arg (d, buffer, p, memaddr + p - buffer, stream); - d += 2; - if (*d && *(d - 2) != 'I' && *d != 'k') - fprintf (stream, ","); - } - return p - buffer; -} - -static unsigned char * -print_insn_arg (d, buffer, p, addr, stream) - char *d; - unsigned char *buffer; - register unsigned char *p; - CORE_ADDR addr; /* PC for this arg to be relative to */ - FILE *stream; -{ - register int val; - register int place = d[1]; - int regno; - register char *regname; - register unsigned char *p1; - register double flval; - int flt_p; - - switch (*d) - { - case 'C': - fprintf (stream, "ccr"); - break; - - case 'S': - fprintf (stream, "sr"); - break; - - case 'U': - fprintf (stream, "usp"); - break; - - case 'J': - { - static struct { char *name; int value; } names[] - = {{"sfc", 0x000}, {"dfc", 0x001}, {"cacr", 0x002}, - {"usp", 0x800}, {"vbr", 0x801}, {"caar", 0x802}, - {"msp", 0x803}, {"isp", 0x804}}; - - val = fetch_arg (buffer, place, 12); - for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--) - if (names[regno].value == val) - { - fprintf (stream, names[regno].name); - break; - } - if (regno < 0) - fprintf (stream, "%d", val); - } - break; - - case 'Q': - val = fetch_arg (buffer, place, 3); - if (val == 0) val = 8; - fprintf (stream, "#%d", val); - break; - - case 'M': - val = fetch_arg (buffer, place, 8); - if (val & 0x80) - val = val - 0x100; - fprintf (stream, "#%d", val); - break; - - case 'T': - val = fetch_arg (buffer, place, 4); - fprintf (stream, "#%d", val); - break; - - case 'D': - fprintf (stream, "%s", reg_names[fetch_arg (buffer, place, 3)]); - break; - - case 'A': - fprintf (stream, "%s", reg_names[fetch_arg (buffer, place, 3) + 010]); - break; - - case 'R': - fprintf (stream, "%s", reg_names[fetch_arg (buffer, place, 4)]); - break; - - case 'F': - fprintf (stream, "fp%d", fetch_arg (buffer, place, 3)); - break; - - case 'O': - val = fetch_arg (buffer, place, 6); - if (val & 0x20) - fprintf (stream, "%s", reg_names [val & 7]); - else - fprintf (stream, "%d", val); - break; - - case '+': - fprintf (stream, "(%s)+", reg_names[fetch_arg (buffer, place, 3) + 8]); - break; - - case '-': - fprintf (stream, "-(%s)", reg_names[fetch_arg (buffer, place, 3) + 8]); - break; - - case 'k': - if (place == 'k') - fprintf (stream, "{%s}", reg_names[fetch_arg (buffer, place, 3)]); - else if (place == 'C') - { - val = fetch_arg (buffer, place, 7); - if ( val > 63 ) /* This is a signed constant. */ - val -= 128; - fprintf (stream, "{#%d}", val); - } - else - error ("Invalid arg format in opcode table: \"%c%c\".", - *d, place); - break; - - case '#': - p1 = buffer + 2; - if (place == 's') - val = fetch_arg (buffer, place, 4); - else if (place == 'C') - val = fetch_arg (buffer, place, 7); - else if (place == '8') - val = fetch_arg (buffer, place, 3); - else if (place == '3') - val = fetch_arg (buffer, place, 8); - else if (place == 'b') - val = NEXTBYTE (p1); - else if (place == 'w') - val = NEXTWORD (p1); - else if (place == 'l') - val = NEXTLONG (p1); - else - error ("Invalid arg format in opcode table: \"%c%c\".", - *d, place); - fprintf (stream, "#%d", val); - break; - - case '^': - if (place == 's') - val = fetch_arg (buffer, place, 4); - else if (place == 'C') - val = fetch_arg (buffer, place, 7); - else if (place == '8') - val = fetch_arg (buffer, place, 3); - else if (place == 'b') - val = NEXTBYTE (p); - else if (place == 'w') - val = NEXTWORD (p); - else if (place == 'l') - val = NEXTLONG (p); - else - error ("Invalid arg format in opcode table: \"%c%c\".", - *d, place); - fprintf (stream, "#%d", val); - break; - - case 'B': - if (place == 'b') - val = NEXTBYTE (p); - else if (place == 'w') - val = NEXTWORD (p); - else if (place == 'l') - val = NEXTLONG (p); - else if (place == 'g') - { - val = ((char *)buffer)[1]; - if (val == 0) - val = NEXTWORD (p); - else if (val == -1) - val = NEXTLONG (p); - } - else if (place == 'c') - { - if (buffer[1] & 0x40) /* If bit six is one, long offset */ - val = NEXTLONG (p); - else - val = NEXTWORD (p); - } - else - error ("Invalid arg format in opcode table: \"%c%c\".", - *d, place); - - print_address (addr + val, stream); - break; - - case 'd': - val = NEXTWORD (p); - fprintf (stream, "%d(%s)", val, fetch_arg (buffer, place, 3)); - break; - - case 's': - fprintf (stream, "%s", fpcr_names[fetch_arg (buffer, place, 3)]); - break; - - case 'I': - val = fetch_arg (buffer, 'd', 3); /* Get coprocessor ID... */ - if (val != 1) /* Unusual coprocessor ID? */ - fprintf (stream, "(cpid=%d) ", val); - if (place == 'i') - p += 2; /* Skip coprocessor extended operands */ - break; - - case '*': - case '~': - case '%': - case ';': - case '@@': - case '!': - case '$': - case '?': - case '/': - case '&': - - if (place == 'd') - { - val = fetch_arg (buffer, 'x', 6); - val = ((val & 7) << 3) + ((val >> 3) & 7); - } - else - val = fetch_arg (buffer, 's', 6); - - /* Get register number assuming address register. */ - regno = (val & 7) + 8; - regname = reg_names[regno]; - switch (val >> 3) - { - case 0: - fprintf (stream, "%s", reg_names[val]); - break; - - case 1: - fprintf (stream, "%s", regname); - break; - - case 2: - fprintf (stream, "(%s)", regname); - break; - - case 3: - fprintf (stream, "(%s)+", regname); - break; - - case 4: - fprintf (stream, "-(%s)", regname); - break; - - case 5: - val = NEXTWORD (p); - fprintf (stream, "%d(%s)", val, regname); - break; - - case 6: - p = print_indexed (regno, p, addr, stream); - break; - - case 7: - switch (val & 7) - { - case 0: - val = NEXTWORD (p); - fprintf (stream, "@@#"); - print_address (val, stream); - break; - - case 1: - val = NEXTLONG (p); - fprintf (stream, "@@#"); - print_address (val, stream); - break; - - case 2: - val = NEXTWORD (p); - print_address (addr + val, stream); - break; - - case 3: - p = print_indexed (-1, p, addr, stream); - break; - - case 4: - flt_p = 1; /* Assume it's a float... */ - switch( place ) - { - case 'b': - val = NEXTBYTE (p); - flt_p = 0; - break; - - case 'w': - val = NEXTWORD (p); - flt_p = 0; - break; - - case 'l': - val = NEXTLONG (p); - flt_p = 0; - break; - - case 'f': - flval = NEXTSINGLE(p); - break; - - case 'F': - flval = NEXTDOUBLE(p); - break; - - case 'x': - flval = NEXTEXTEND(p); - break; - - case 'p': - flval = NEXTPACKED(p); - break; - - default: - error ("Invalid arg format in opcode table: \"%c%c\".", - *d, place); - } - if ( flt_p ) /* Print a float? */ - fprintf (stream, "#%g", flval); - else - fprintf (stream, "#%d", val); - break; - - default: - fprintf (stream, "<invalid address mode 0%o>", val); - } - } - break; - - default: - error ("Invalid arg format in opcode table: \"%c\".", *d); - } - - return (unsigned char *) p; -} - -/* Fetch BITS bits from a position in the instruction specified by CODE. - CODE is a "place to put an argument", or 'x' for a destination - that is a general address (mode and register). - BUFFER contains the instruction. */ - -static int -fetch_arg (buffer, code, bits) - unsigned char *buffer; - char code; - int bits; -{ - register int val; - switch (code) - { - case 's': - val = buffer[1]; - break; - - case 'd': /* Destination, for register or quick. */ - val = (buffer[0] << 8) + buffer[1]; - val >>= 9; - break; - - case 'x': /* Destination, for general arg */ - val = (buffer[0] << 8) + buffer[1]; - val >>= 6; - break; - - case 'k': - val = (buffer[3] >> 4); - break; - - case 'C': - val = buffer[3]; - break; - - case '1': - val = (buffer[2] << 8) + buffer[3]; - val >>= 12; - break; - - case '2': - val = (buffer[2] << 8) + buffer[3]; - val >>= 6; - break; - - case '3': - case 'j': - val = (buffer[2] << 8) + buffer[3]; - break; - - case '4': - val = (buffer[4] << 8) + buffer[5]; - val >>= 12; - break; - - case '5': - val = (buffer[4] << 8) + buffer[5]; - val >>= 6; - break; - - case '6': - val = (buffer[4] << 8) + buffer[5]; - break; - - case '7': - val = (buffer[2] << 8) + buffer[3]; - val >>= 7; - break; - - case '8': - val = (buffer[2] << 8) + buffer[3]; - val >>= 10; - break; - - default: - abort (); - } - - switch (bits) - { - case 3: - return val & 7; - case 4: - return val & 017; - case 5: - return val & 037; - case 6: - return val & 077; - case 7: - return val & 0177; - case 8: - return val & 0377; - case 12: - return val & 07777; - default: - abort (); - } -} - -/* Print an indexed argument. The base register is BASEREG (-1 for pc). - P points to extension word, in buffer. - ADDR is the nominal core address of that extension word. */ - -static unsigned char * -print_indexed (basereg, p, addr, stream) - int basereg; - unsigned char *p; - FILE *stream; - CORE_ADDR addr; -{ - register int word; - static char *scales[] = {"", "*2", "*4", "*8"}; - register int base_disp; - register int outer_disp; - char buf[40]; - - word = NEXTWORD (p); - - /* Generate the text for the index register. - Where this will be output is not yet determined. */ - sprintf (buf, "[%s.%c%s]", - reg_names[(word >> 12) & 0xf], - (word & 0x800) ? 'l' : 'w', - scales[(word >> 9) & 3]); - - /* Handle the 68000 style of indexing. */ - - if ((word & 0x100) == 0) - { - print_base (basereg, - ((word & 0x80) ? word | 0xff00 : word & 0xff) - + ((basereg == -1) ? addr : 0), - stream); - fprintf (stream, "%s", buf); - return p; - } - - /* Handle the generalized kind. */ - /* First, compute the displacement to add to the base register. */ - - if (word & 0200) - basereg = -2; - if (word & 0100) - buf[0] = 0; - base_disp = 0; - switch ((word >> 4) & 3) - { - case 2: - base_disp = NEXTWORD (p); - break; - case 3: - base_disp = NEXTLONG (p); - } - if (basereg == -1) - base_disp += addr; - - /* Handle single-level case (not indirect) */ - - if ((word & 7) == 0) - { - print_base (basereg, base_disp, stream); - fprintf (stream, "%s", buf); - return p; - } - - /* Two level. Compute displacement to add after indirection. */ - - outer_disp = 0; - switch (word & 3) - { - case 2: - outer_disp = NEXTWORD (p); - break; - case 3: - outer_disp = NEXTLONG (p); - } - - fprintf (stream, "%d(", outer_disp); - print_base (basereg, base_disp, stream); - - /* If postindexed, print the closeparen before the index. */ - if (word & 4) - fprintf (stream, ")%s", buf); - /* If preindexed, print the closeparen after the index. */ - else - fprintf (stream, "%s)", buf); - - return p; -} - -/* Print a base register REGNO and displacement DISP, on STREAM. - REGNO = -1 for pc, -2 for none (suppressed). */ - -static void -print_base (regno, disp, stream) - int regno; - int disp; - FILE *stream; -{ - if (regno == -2) - fprintf (stream, "%d", disp); - else if (regno == -1) - fprintf (stream, "0x%x", disp); - else - fprintf (stream, "%d(%s)", disp, reg_names[regno]); -} - -/* This is not part of insn printing, but it is machine-specific, - so this is a convenient place to put it. - - Convert a 68881 extended float to a double. - FROM is the address of the extended float. - Store the double in *TO. */ - -#ifdef mac_aux -#ifdef __STDC__ -#define asm16(str) asm ("short " str#) -#else -#define asm16(str) asm ("short str") -#endif -#else -#ifdef __STDC__ -#define asm16(str) asm (".word " str#) -#else -#define asm16(str) asm (".word str") -#endif -#endif - -convert_from_68881 (from, to) - char *from; - double *to; -{ -#if 0 - asm ("movl a6@@(8),a0"); - asm ("movl a6@@(12),a1"); - asm ("fmovex a0@@,fp0"); - asm ("fmoved fp0,a1@@"); -#else - /* Hand-assemble those insns since some assemblers lose - and some have different syntax. */ - asm16 (020156); - asm16 (8); - asm16 (021156); - asm16 (12); - asm16 (0xf210); - asm16 (0x4800); - asm16 (0xf211); - asm16 (0x7400); -#endif -} - -/* The converse: convert the double *FROM to an extended float - and store where TO points. */ - -convert_to_68881 (from, to) - double *from; - char *to; -{ -#if 0 - asm ("movl a6@@(8),a0"); - asm ("movl a6@@(12),a1"); - asm ("fmoved a0@@,fp0"); - asm ("fmovex fp0,a1@@"); -#else - /* Hand-assemble those insns since some assemblers lose. */ - asm16 (020156); - asm16 (8); - asm16 (021156); - asm16 (12); - asm16 (0xf210); - asm16 (0x5400); - asm16 (0xf211); - asm16 (0x6800); -#endif -} -@ - - -1.1 -log -@Initial revision -@ -text -@d713 14 -d739 8 -a746 6 - asm (".word 020156"); - asm (".word 8"); - asm (".word 021156"); - asm (".word 12"); - asm (".long 0xf2104800"); - asm (".long 0xf2117400"); -d764 8 -a771 6 - asm (".word 020156"); - asm (".word 8"); - asm (".word 021156"); - asm (".word 12"); - asm (".long 0xf2105400"); - asm (".long 0xf2116800"); -@ diff --git a/gdb/RCS/main.c,v b/gdb/RCS/main.c,v deleted file mode 100644 index ae6615f..0000000 --- a/gdb/RCS/main.c,v +++ /dev/null @@ -1,1110 +0,0 @@ -head 1.2; -access ; -symbols RMS-has:1.2; -locks ; strict; -comment @ * @; - - -1.2 -date 88.01.26.05.09.12; author gnu; state Exp; -branches ; -next 1.1; - -1.1 -date 88.01.21.04.23.16; author gnu; state Exp; -branches ; -next ; - - -desc -@Original from RMS development on wheaties, 20Jan88 -@ - - -1.2 -log -@Add <sys/types.h> -@ -text -@/* Top level for GDB, the GNU debugger. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - -GDB is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY. No author or distributor accepts responsibility to anyone -for the consequences of using it or for whether it serves any -particular purpose or works at all, unless he says so in writing. -Refer to the GDB General Public License for full details. - -Everyone is granted permission to copy, modify and redistribute GDB, -but only under the conditions described in the GDB General Public -License. A copy of this license is supposed to have been given to you -along with GDB so you can know your rights and responsibilities. It -should be in a file named COPYING. Among other things, the copyright -notice and this notice must be preserved on all copies. - -In other words, go ahead and share GDB, but don't try to stop -anyone else from sharing it farther. Help stamp out software hoarding! -*/ - -#include <sys/types.h> -#include <sys/file.h> -#include <stdio.h> -#include <setjmp.h> -#include <signal.h> -#include <sys/param.h> -#include "defs.h" -#include "command.h" -#include "param.h" - -#ifdef SET_STACK_LIMIT_HUGE -#include <sys/time.h> -#include <sys/resource.h> -#endif - -/* Version number of GDB, as a string. */ - -extern char *version; - -/* Chain containing all defined commands. */ - -struct cmd_list_element *cmdlist; - -/* Chain containing all defined info subcommands. */ - -struct cmd_list_element *infolist; - -/* stdio stream that command input is being read from. */ - -FILE *instream; - -/* Nonzero if we should refrain from using an X window. */ - -int inhibit_windows = 0; - -/* Function to call before reading a command, if nonzero. - The function receives two args: an input stream, - and a prompt string. */ - -void (*window_hook) (); - -void free_command_lines (); -char *read_line (); -static void initialize_main (); -void command_loop (); -static void source_command (); -void print_gdb_version (); - -/* gdb prints this when reading a command interactively */ -static char *prompt; - -/* Buffer used for reading command lines, and the size - allocated for it so far. */ - -char *line; -int linesize; - -/* This is how `error' returns to command level. */ - -jmp_buf to_top_level; - -return_to_top_level () -{ - quit_flag = 0; - immediate_quit = 0; - clear_breakpoint_commands (); - clear_momentary_breakpoints (); - do_cleanups (0); - longjmp (to_top_level, 1); -} - -main (argc, argv, envp) - int argc; - char **argv; - char **envp; -{ - extern void request_quit (); - int count; - int inhibit_gdbinit = 0; - int quiet = 0; - int batch = 0; - register int i; - - quit_flag = 0; - linesize = 100; - line = (char *) xmalloc (linesize); - instream = stdin; - -#ifdef SET_STACK_LIMIT_HUGE - { - struct rlimit rlim; - - /* Set the stack limit huge so that alloca (particularly stringtab - * in dbxread.c) does not fail. */ - getrlimit (RLIMIT_STACK, &rlim); - rlim.rlim_cur = rlim.rlim_max; - setrlimit (RLIMIT_STACK, &rlim); - } -#endif /* SET_STACK_LIMIT_HUGE */ - - /* Look for flag arguments. */ - - for (i = 1; i < argc; i++) - { - if (!strcmp (argv[i], "-q") || !strcmp (argv[i], "-quiet")) - quiet = 1; - else if (!strcmp (argv[i], "-nx")) - inhibit_gdbinit = 1; - else if (!strcmp (argv[i], "-nw")) - inhibit_windows = 1; - else if (!strcmp (argv[i], "-batch")) - batch = 1, quiet = 1; - else if (argv[i][0] == '-') - i++; - } - - /* Run the init function of each source file */ - - initialize_all_files (); - initialize_main (); /* But that omits this file! Do it now */ - - signal (SIGINT, request_quit); - signal (SIGQUIT, SIG_IGN); - - if (!quiet) - print_gdb_version (); - - /* Process the command line arguments. */ - - count = 0; - for (i = 1; i < argc; i++) - { - register char *arg = argv[i]; - /* Args starting with - say what to do with the following arg - as a filename. */ - if (arg[0] == '-') - { - extern void exec_file_command (), symbol_file_command (); - extern void core_file_command (), directory_command (); - extern void tty_command (); - - if (!strcmp (arg, "-q") || !strcmp (arg, "-nx") - || !strcmp (arg, "quiet") || !strcmp (arg, "-batch")) - /* Already processed above */ - continue; - - if (++i == argc) - fprintf (stderr, "No argument follows \"%s\".\n", arg); - if (!setjmp (to_top_level)) - { - /* -s foo: get syms from foo. -e foo: execute foo. - -se foo: do both with foo. -c foo: use foo as core dump. */ - if (!strcmp (arg, "-se")) - { - exec_file_command (argv[i], !batch); - symbol_file_command (argv[i], !batch); - } - else if (!strcmp (arg, "-s") || !strcmp (arg, "-symbols")) - symbol_file_command (argv[i], !batch); - else if (!strcmp (arg, "-e") || !strcmp (arg, "-exec")) - exec_file_command (argv[i], !batch); - else if (!strcmp (arg, "-c") || !strcmp (arg, "-core")) - core_file_command (argv[i], !batch); - /* -x foo: execute commands from foo. */ - else if (!strcmp (arg, "-x") || !strcmp (arg, "-command") - || !strcmp (arg, "-commands")) - source_command (argv[i]); - /* -d foo: add directory `foo' to source-file directory - search-list */ - else if (!strcmp (arg, "-d") || !strcmp (arg, "-dir") - || !strcmp (arg, "-directory")) - directory_command (argv[i], 0); - /* -t /def/ttyp1: use /dev/ttyp1 for inferior I/O. */ - else if (!strcmp (arg, "-t") || !strcmp (arg, "-tty")) - tty_command (argv[i], 0); - else - error ("Unknown command-line switch: \"%s\"\n", arg); - } - } - else - { - /* Args not thus accounted for - are treated as, first, the symbol/executable file - and, second, the core dump file. */ - count++; - if (!setjmp (to_top_level)) - switch (count) - { - case 1: - exec_file_command (arg, !batch); - symbol_file_command (arg, !batch); - break; - - case 2: - core_file_command (arg, !batch); - break; - - case 3: - fprintf (stderr, "Excess command line args ignored. (%s%s)\n", - arg, (i == argc - 1) ? "" : " ..."); - } - } - } - - /* Read init file, if it exists in home directory */ - if (getenv ("HOME")) - { - char *s; - s = (char *) xmalloc (strlen (getenv ("HOME")) + 10); - strcpy (s, getenv ("HOME")); - strcat (s, "/.gdbinit"); - if (!inhibit_gdbinit && access (s, R_OK) == 0) - if (!setjmp (to_top_level)) - source_command (s); - } - - /* Read init file, if it exists in current directory. */ - if (!inhibit_gdbinit && access (".gdbinit", R_OK) == 0) - if (!setjmp (to_top_level)) - source_command (".gdbinit"); - - if (batch) - fatal ("Attempt to read commands from stdin in batch mode."); - - if (!quiet) - printf ("Type \"help\" for a list of commands.\n"); - - /* The command loop. */ - - while (1) - { - if (!setjmp (to_top_level)) - command_loop (); - clearerr (stdin); /* Don't get hung if C-d is typed. */ - } -} - -/* Execute the line P as a command. - Pass FROM_TTY as second argument to the defining function. */ - -void -execute_command (p, from_tty) - char *p; - int from_tty; -{ - register struct cmd_list_element *c; - register struct command_line *cmdlines; - - free_all_values (); - while (*p == ' ' || *p == '\t') p++; - if (*p) - { - c = lookup_cmd (&p, cmdlist, "", 0); - if (c->function == 0) - error ("That is not a command, just a help topic."); - else if (c->class == (int) class_user) - { - if (*p) - error ("User-defined commands cannot take command-line arguments: \"%s\"", - p); - cmdlines = (struct command_line *) c->function; - if (cmdlines == (struct command_line *) 0) - /* Null command */ - return; - while (cmdlines) - { - execute_command (cmdlines->line, 0); - cmdlines = cmdlines->next; - } - } - else - /* Pass null arg rather than an empty one. */ - (*c->function) (*p ? p : 0, from_tty); - } -} - -static void -do_nothing () -{ -} - -/* Read commands from `instream' and execute them - until end of file. */ -void -command_loop () -{ - struct cleanup *old_chain; - while (!feof (instream)) - { - if (instream == stdin) - printf ("%s", prompt); - fflush (stdout); - - if (window_hook && instream == stdin) - (*window_hook) (instream, prompt); - - quit_flag = 0; - old_chain = make_cleanup (do_nothing, 0); - execute_command (read_line (instream == stdin), instream == stdin); - /* Do any commands attached to breakpoint we stopped at. */ - do_breakpoint_commands (); - do_cleanups (old_chain); - } -} - -static void -stop_sig () -{ - signal (SIGTSTP, SIG_DFL); - sigsetmask (0); - kill (getpid (), SIGTSTP); - signal (SIGTSTP, stop_sig); - printf ("%s", prompt); - fflush (stdout); - - /* Forget about any previous command -- null line now will do nothing. */ - *line = 0; -} - -/* Commands call this if they do not want to be repeated by null lines. */ - -void -dont_repeat () -{ - *line = 0; -} - -/* Read one line from the command input stream `instream' - into the buffer `line' (whose current length is `linesize'). - The buffer is made bigger as necessary. - Returns the address of the start of the line. */ - -char * -read_line (repeat) - int repeat; -{ - register char *p = line; - register char *p1; - register int c; - char *nline; - - /* Control-C quits instantly if typed while in this loop - since it should not wait until the user types a newline. */ - immediate_quit++; - signal (SIGTSTP, stop_sig); - - while (1) - { - c = fgetc (instream); - if (c == -1 || c == '\n') - break; - if (p - line == linesize - 1) - { - linesize *= 2; - nline = (char *) xrealloc (line, linesize); - p += nline - line; - line = nline; - } - *p++ = c; - } - - signal (SIGTSTP, SIG_DFL); - immediate_quit--; - - /* If we just got an empty line, and that is supposed - to repeat the previous command, leave the last input unchanged. */ - if (p == line && repeat) - return line; - - /* If line is a comment, clear it out. */ - p1 = line; - while ((c = *p1) == ' ' || c == '\t') p1++; - if (c == '#') - p = line; - - *p = 0; - - return line; -} - -/* Read lines from the input stream - and accumulate them in a chain of struct command_line's - which is then returned. */ - -struct command_line * -read_command_lines () -{ - struct command_line *first = 0; - register struct command_line *next, *tail = 0; - register char *p, *p1; - struct cleanup *old_chain = 0; - - while (1) - { - dont_repeat (); - p = read_line (1); - /* Remove leading and trailing blanks. */ - while (*p == ' ' || *p == '\t') p++; - p1 = p + strlen (p); - while (p1 != p && (p1[-1] == ' ' || p1[-1] == '\t')) p1--; - - /* Is this "end"? */ - if (p1 - p == 3 && !strncmp (p, "end", 3)) - break; - - /* No => add this line to the chain of command lines. */ - next = (struct command_line *) xmalloc (sizeof (struct command_line)); - next->line = savestring (p, p1 - p); - next->next = 0; - if (tail) - { - tail->next = next; - } - else - { - /* We just read the first line. - From now on, arrange to throw away the lines we have - if we quit or get an error while inside this function. */ - first = next; - old_chain = make_cleanup (free_command_lines, &first); - } - tail = next; - } - - dont_repeat (); - - /* Now we are about to return the chain to our caller, - so freeing it becomes his responsibility. */ - if (first) - discard_cleanups (old_chain); - return first; -} - -/* Free a chain of struct command_line's. */ - -void -free_command_lines (lptr) - struct command_line **lptr; -{ - register struct command_line *l = *lptr; - register struct command_line *next; - - while (l) - { - next = l->next; - free (l->line); - free (l); - l = next; - } -} - -/* Add an element to the list of info subcommands. */ - -void -add_info (name, fun, doc) - char *name; - void (*fun) (); - char *doc; -{ - add_cmd (name, 0, fun, doc, &infolist); -} - -/* Add an alias to the list of info subcommands. */ - -void -add_info_alias (name, oldname, abbrev_flag) - char *name; - char *oldname; - int abbrev_flag; -{ - add_alias_cmd (name, oldname, 0, abbrev_flag, &infolist); -} - -/* The "info" command is defined as a prefix, with allow_unknown = 0. - Therefore, its own definition is called only for "info" with no args. */ - -static void -info_command () -{ - printf ("\"info\" must be followed by the name of an info command.\n"); - help_cmd (0, infolist, "info ", -1, stdout); -} - -/* Add an element to the list of commands. */ - -void -add_com (name, class, fun, doc) - char *name; - int class; - void (*fun) (); - char *doc; -{ - add_cmd (name, class, fun, doc, &cmdlist); -} - -/* Add an alias or abbreviation command to the list of commands. */ - -void -add_com_alias (name, oldname, class, abbrev_flag) - char *name; - char *oldname; - int class; - int abbrev_flag; -{ - add_alias_cmd (name, oldname, class, abbrev_flag, &cmdlist); -} - -void -error_no_arg (why) - char *why; -{ - error ("Argument required (%s).", why); -} - -static void -help_command (command, from_tty) - char *command; - int from_tty; /* Ignored */ -{ - help_cmd (command, cmdlist, "", -2, stdout); -} - -static void -validate_comname (comname) - char *comname; -{ - register char *p; - - if (comname == 0) - error_no_arg ("name of command to define"); - - p = comname; - while (*p) - { - if (!(*p >= 'A' && *p <= 'Z') - && !(*p >= 'a' && *p <= 'z') - && !(*p >= '1' && *p <= '9') - && *p != '-') - error ("Junk in argument list: \"%s\"", p); - p++; - } -} - -static void -define_command (comname, from_tty) - char *comname; - int from_tty; -{ - register struct command_line *cmds; - register struct cmd_list_element *c; - char *tem = comname; - - validate_comname (comname); - - c = lookup_cmd (&tem, cmdlist, "", -1); - if (c) - { - if (c->class == (int) class_user || c->class == (int) class_alias) - tem = "Redefine command \"%s\"? "; - else - tem = "Really redefine built-in command \"%s\"? "; - if (!query (tem, comname)) - error ("Command \"%s\" not redefined.", comname); - } - - if (from_tty) - printf ("Type commands for definition of \"%s\".\n\ -End with a line saying just \"end\".\n", comname); - - comname = savestring (comname, strlen (comname)); - - cmds = read_command_lines (); - - if (c && c->class == (int) class_user) - free_command_lines (&c->function); - - add_com (comname, class_user, cmds, - (c && c->class == (int) class_user) - ? c->doc : savestring ("User-defined.", 13)); -} - -static void -document_command (comname, from_tty) - char *comname; - int from_tty; -{ - struct command_line *doclines; - register struct cmd_list_element *c; - char *tem = comname; - - validate_comname (comname); - - c = lookup_cmd (&tem, cmdlist, "", 0); - - if (c->class != (int) class_user) - error ("Command \"%s\" is built-in.", comname); - - if (from_tty) - printf ("Type documentation for \"%s\".\n\ -End with a line saying just \"end\".\n", comname); - - doclines = read_command_lines (); - - if (c->doc) free (c->doc); - - { - register struct command_line *cl1; - register int len = 0; - - for (cl1 = doclines; cl1; cl1 = cl1->next) - len += strlen (cl1->line) + 1; - - c->doc = (char *) xmalloc (len + 1); - *c->doc = 0; - - for (cl1 = doclines; cl1; cl1 = cl1->next) - { - strcat (c->doc, cl1->line); - if (cl1->next) - strcat (c->doc, "\n"); - } - } - - free_command_lines (&doclines); -} - -static void -copying_info () -{ - immediate_quit++; - printf (" GDB GENERAL PUBLIC LICENSE\n\ -\n\ - Copyright (C) 1986 Richard M. Stallman\n\ - Everyone is permitted to copy and distribute verbatim copies\n\ - of this license, but changing it is not allowed.\n\ -\n\ - The license agreements of most software companies keep you at the\n\ -mercy of those companies. By contrast, our general public license is\n\ -intended to give everyone the right to share GDB. To make sure that\n\ -you get the rights we want you to have, we need to make restrictions\n\ -that forbid anyone to deny you these rights or to ask you to surrender\n\ -the rights. Hence this license agreement.\n\ -\n\ - Specifically, we want to make sure that you have the right to give\n\ -away copies of GDB, that you receive source code or else can get it\n\ -if you want it, that you can change GDB or use pieces of it in new\n\ -free programs, and that you know you can do these things.\n\ ---Type Return to print more--"); - fflush (stdout); - read_line (); - - printf ("\ - To make sure that everyone has such rights, we have to forbid you to\n\ -deprive anyone else of these rights. For example, if you distribute\n\ -copies of GDB, you must give the recipients all the rights that you\n\ -have. You must make sure that they, too, receive or can get the\n\ -source code. And you must tell them their rights.\n\ -\n\ - Also, for our own protection, we must make certain that everyone\n\ -finds out that there is no warranty for GDB. If GDB is modified by\n\ -someone else and passed on, we want its recipients to know that what\n\ -they have is not what we distributed, so that any problems introduced\n\ -by others will not reflect on our reputation.\n\ -\n\ - Therefore we (Richard Stallman and the Free Software Foundation,\n\ -Inc.) make the following terms which say what you must do to be\n\ -allowed to distribute or change GDB.\n\ ---Type Return to print more--"); - fflush (stdout); - read_line (); - - printf ("\ - COPYING POLICIES\n\ -\n\ - 1. You may copy and distribute verbatim copies of GDB source code as\n\ -you receive it, in any medium, provided that you conspicuously and\n\ -appropriately publish on each copy a valid copyright notice \"Copyright\n\ -\(C) 1987 Free Software Foundation, Inc.\" (or with the year updated if\n\ -that is appropriate); keep intact the notices on all files that refer\n\ -to this License Agreement and to the absence of any warranty; and give\n\ -any other recipients of the GDB program a copy of this License\n\ -Agreement along with the program. You may charge a distribution fee\n\ -for the physical act of transferring a copy.\n\ -\n\ - 2. You may modify your copy or copies of GDB or any portion of it,\n\ -and copy and distribute such modifications under the terms of\n\ -Paragraph 1 above, provided that you also do the following:\n\ -\n\ - a) cause the modified files to carry prominent notices stating\n\ - that you changed the files and the date of any change; and\n\ ---Type Return to print more--"); - fflush (stdout); - read_line (); - - printf ("\ - b) cause the whole of any work that you distribute or publish,\n\ - that in whole or in part contains or is a derivative of GDB\n\ - or any part thereof, to be licensed to all third parties on terms\n\ - identical to those contained in this License Agreement (except that\n\ - you may choose to grant more extensive warranty protection to third\n\ - parties, at your option).\n\ -\n"); - printf ("\ - c) if the modified program serves as a debugger, cause it\n\ - when started running in the simplest and usual way, to print\n\ - an announcement including a valid copyright notice\n\ - \"Copyright (C) 1987 Free Software Foundation, Inc.\" (or with\n\ - the year updated if appropriate), saying that there\n\ - is no warranty (or else, saying that you provide\n\ - a warranty) and that users may redistribute the program under\n\ - these conditions, and telling the user how to view a copy of\n\ - this License Agreement.\n\ -\n\ - d) You may charge a distribution fee for the physical act of\n\ - transferring a copy, and you may at your option offer warranty\n\ - protection in exchange for a fee.\n\ ---Type Return to print more--"); - fflush (stdout); - read_line (); - - printf ("\ - 3. You may copy and distribute GDB or any portion of it in\n\ -compiled, executable or object code form under the terms of Paragraphs\n\ -1 and 2 above provided that you do the following:\n\ -\n\ - a) cause each such copy to be accompanied by the\n\ - corresponding machine-readable source code, which must\n\ - be distributed under the terms of Paragraphs 1 and 2 above; or,\n\ -\n\ - b) cause each such copy to be accompanied by a\n\ - written offer, with no time limit, to give any third party\n\ - free (except for a nominal shipping charge) a machine readable\n\ - copy of the corresponding source code, to be distributed\n\ - under the terms of Paragraphs 1 and 2 above; or,\n\n"); - - printf ("\ - c) in the case of a recipient of GDB in compiled, executable\n\ - or object code form (without the corresponding source code) you\n\ - shall cause copies you distribute to be accompanied by a copy\n\ - of the written offer of source code which you received along\n\ - with the copy you received.\n\ ---Type Return to print more--"); - fflush (stdout); - read_line (); - - printf ("\ - 4. You may not copy, sublicense, distribute or transfer GDB\n\ -except as expressly provided under this License Agreement. Any attempt\n\ -otherwise to copy, sublicense, distribute or transfer GDB is void and\n\ -your rights to use the program under this License agreement shall be\n\ -automatically terminated. However, parties who have received computer\n\ -software programs from you with this License Agreement will not have\n\ -their licenses terminated so long as such parties remain in full compliance.\n\ -\n\ - 5. If you wish to incorporate parts of GDB into other free\n\ -programs whose distribution conditions are different, write to the Free\n\ -Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet\n\ -worked out a simple rule that can be stated here, but we will often permit\n\ -this. We will be guided by the two goals of preserving the free status of\n\ -all derivatives of our free software and of promoting the sharing and reuse\n\ -of software.\n\ -\n\ -In other words, go ahead and share GDB, but don't try to stop\n\ -anyone else from sharing it farther. Help stamp out software hoarding!\n\ -"); - immediate_quit--; -} - -static void -warranty_info () -{ - immediate_quit++; - printf (" NO WARRANTY\n\ -\n\ - BECAUSE GDB IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY NO\n\ -WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT\n\ -WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,\n\ -RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE GDB \"AS IS\" WITHOUT\n\ -WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT\n\ -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\n\ -A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND\n\ -PERFORMANCE OF GDB IS WITH YOU. SHOULD GDB PROVE DEFECTIVE, YOU\n\ -ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n"); - - printf ("\ - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.\n\ -STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY\n\ -WHO MAY MODIFY AND REDISTRIBUTE GDB, BE LIABLE TO\n\ -YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER\n\ -SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR\n\ -INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA\n\ -BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A\n\ -FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GDB, EVEN\n\ -IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR\n\ -ANY CLAIM BY ANY OTHER PARTY.\n"); - immediate_quit--; -} - -static void -print_gdb_version () -{ - printf ("GDB %s, Copyright (C) 1987 Free Software Foundation, Inc.\n\ -There is ABSOLUTELY NO WARRANTY for GDB; type \"info warranty\" for details.\n\ -GDB is free software and you are welcome to distribute copies of it\n\ - under certain conditions; type \"info copying\" to see the conditions.\n", - version); -} - -static void -version_info () -{ - immediate_quit++; - print_gdb_version (); - immediate_quit--; -} - -static void -set_prompt_command (text) - char *text; -{ - char *p, *q; - register int c; - char *new; - - if (text == 0) - error_no_arg ("string to which to set prompt"); - - new = (char *) xmalloc (strlen (text) + 2); - p = text; q = new; - while (c = *p++) - { - if (c == '\\') - { - /* \ at end of argument is used after spaces - so they won't be lost. */ - if (*p == 0) - break; - c = parse_escape (&p); - if (c == 0) - break; /* C loses */ - else if (c > 0) - *q++ = c; - } - else - *q++ = c; - } - if (*(p - 1) != '\\') - *q++ = ' '; - *q++ = '\0'; - new = (char *) xrealloc (new, q - new); - free (prompt); - prompt = new; -} - -static void -quit_command () -{ - if (have_inferior_p ()) - { - if (query ("The program is running. Quit anyway? ")) - { - /* Prevent any warning message from reopen_exec_file, in case - we have a core file that's inconsistent with the exec file. */ - exec_file_command (0, 0); - kill_inferior (); - } - else - error ("Not confirmed."); - } - exit (0); -} - -int -input_from_terminal_p () -{ - return instream == stdin; -} - -static void -pwd_command (arg, from_tty) - char *arg; - int from_tty; -{ - char buf[MAXPATHLEN]; - if (arg) error ("The \"pwd\" command does not take an argument: %s", arg); - printf ("Working directory %s.\n", getwd (buf)); -} - -static void -cd_command (dir, from_tty) - char *dir; - int from_tty; -{ - if (dir == 0) - error_no_arg ("new working directory"); - - if (chdir (dir) < 0) - perror_with_name (dir); - if (from_tty) - pwd_command ((char *) 0, 1); -} - - -/* Clean up on error during a "source" command. - Close the file opened by the command - and restore the previous input stream. */ - -static void -source_cleanup (stream) - FILE *stream; -{ - fclose (instream); - instream = stream; -} - -static void -source_command (file) - char *file; -{ - FILE *stream; - struct cleanup *cleanups; - - if (file == 0) - error_no_arg ("file to read commands from"); - - stream = fopen (file, "r"); - if (stream == 0) - perror_with_name (file); - - cleanups = make_cleanup (source_cleanup, instream); - - instream = stream; - - command_loop (); - - do_cleanups (cleanups); -} - -static void -echo_command (text) - char *text; -{ - char *p = text; - register int c; - - if (text) - while (c = *p++) - { - if (c == '\\') - { - /* \ at end of argument is used after spaces - so they won't be lost. */ - if (*p == 0) - return; - - c = parse_escape (&p); - if (c >= 0) - fputc (c, stdout); - } - else - fputc (c, stdout); - } -} - -static void -dump_me_command () -{ - if (query ("Should GDB dump core? ")) - { - signal (SIGQUIT, SIG_DFL); - kill (getpid (), SIGQUIT); - } -} - - -static void -initialize_main () -{ - prompt = savestring ("(gdb) ", 6); - - /* Define the classes of commands. - They will appear in the help list in the reverse of this order. */ - - add_cmd ("obscure", class_obscure, 0, "Obscure features.", &cmdlist); - add_cmd ("alias", class_alias, 0, "Aliases of other commands.", &cmdlist); - add_cmd ("user", class_user, 0, "User-defined commands.\n\ -The commands in this class are those defined by the user.\n\ -Use the \"define\" command to define a command.", &cmdlist); - add_cmd ("support", class_support, 0, "Support facilities.", &cmdlist); - add_cmd ("status", class_info, 0, "Status inquiries.", &cmdlist); - add_cmd ("files", class_files, 0, "Specifying and examining files.", &cmdlist); - add_cmd ("breakpoints", class_breakpoint, 0, "Making program stop at certain points.", &cmdlist); - add_cmd ("data", class_vars, 0, "Examining data.", &cmdlist); - add_cmd ("stack", class_stack, 0, "Examining the stack.\n\ -The stack is made up of stack frames. Gdb assigns numbers to stack frames\n\ -counting from zero for the innermost (currently executing) frame.\n\n\ -At any time gdb identifies one frame as the \"selected\" frame.\n\ -Variable lookups are done with respect to the selected frame.\n\ -When the program being debugged stops, gdb selects the innermost frame.\n\ -The commands below can be used to select other frames by number or address.", - &cmdlist); - add_cmd ("running", class_run, 0, "Running the program.", &cmdlist); - - add_com ("pwd", class_files, pwd_command, - "Print working directory. This is used for your program as well."); - add_com ("cd", class_files, cd_command, - "Set working directory to DIR for debugger and program being debugged.\n\ -The change does not take effect for the program being debugged\n\ -until the next time it is started."); - - add_com ("set-prompt", class_support, set_prompt_command, - "Change gdb's prompt from the default of \"(gdb)\""); - add_com ("echo", class_support, echo_command, - "Print a constant string. Give string as argument.\n\ -C escape sequences may be used in the argument.\n\ -No newline is added at the end of the argument;\n\ -use \"\\n\" if you want a newline to be printed.\n\ -Since leading and trailing whitespace are ignored in command arguments,\n\ -if you want to print some you must use \"\\\" before leading whitespace\n\ -to be printed or after trailing whitespace."); - add_com ("document", class_support, document_command, - "Document a user-defined command.\n\ -Give command name as argument. Give documentation on following lines.\n\ -End with a line of just \"end\"."); - add_com ("define", class_support, define_command, - "Define a new command name. Command name is argument.\n\ -Definition appears on following lines, one command per line.\n\ -End with a line of just \"end\".\n\ -Use the \"document\" command to give documentation for the new command.\n\ -Commands defined in this way do not take arguments."); - - add_com ("source", class_support, source_command, - "Read commands from a file named FILE.\n\ -Note that the file \".gdbinit\" is read automatically in this way\n\ -when gdb is started."); - add_com ("quit", class_support, quit_command, "Exit gdb."); - add_com ("help", class_support, help_command, "Print list of commands."); - add_com_alias ("q", "quit", class_support, 1); - add_com_alias ("h", "help", class_support, 1); - - add_com ("dump-me", class_obscure, dump_me_command, - "Get fatal error; make debugger dump its core."); - - add_prefix_cmd ("info", class_info, info_command, - "Generic command for printing status.", - &infolist, "info ", 0, &cmdlist); - add_com_alias ("i", "info", class_info, 1); - - add_info ("copying", copying_info, "Conditions for redistributing copies of GDB."); - add_info ("warranty", warranty_info, "Various kinds of warranty you do not have."); - add_info ("version", version_info, "Report what version of GDB this is."); -} -@ - - -1.1 -log -@Initial revision -@ -text -@d21 1 -@ diff --git a/gdb/RCS/source.c,v b/gdb/RCS/source.c,v deleted file mode 100644 index bd3218b..0000000 --- a/gdb/RCS/source.c,v +++ /dev/null @@ -1,705 +0,0 @@ -head 1.2; -access ; -symbols RMS-has:1.2; -locks ; strict; -comment @ * @; - - -1.2 -date 88.01.26.05.09.34; author gnu; state Exp; -branches ; -next 1.1; - -1.1 -date 88.01.21.04.30.11; author gnu; state Exp; -branches ; -next ; - - -desc -@Original from RMS development sources on wheaties, 20Jan88 -@ - - -1.2 -log -@Add <sys/types.h> -@ -text -@/* List lines of source files for GDB, the GNU debugger. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - -GDB is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY. No author or distributor accepts responsibility to anyone -for the consequences of using it or for whether it serves any -particular purpose or works at all, unless he says so in writing. -Refer to the GDB General Public License for full details. - -Everyone is granted permission to copy, modify and redistribute GDB, -but only under the conditions described in the GDB General Public -License. A copy of this license is supposed to have been given to you -along with GDB so you can know your rights and responsibilities. It -should be in a file named COPYING. Among other things, the copyright -notice and this notice must be preserved on all copies. - -In other words, go ahead and share GDB, but don't try to stop -anyone else from sharing it farther. Help stamp out software hoarding! -*/ - -#include <stdio.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/file.h> -#include "defs.h" -#include "initialize.h" -#include "symtab.h" - -/* Path of directories to search for source files. - Same format as the PATH environment variable's value. */ - -static char *source_path; - -/* Symtab of default file for listing lines of. */ - -struct symtab *current_source_symtab; - -/* Default next line to list. */ - -int current_source_line; - -/* Line for "info line" to work on if no line specified. */ - -static int line_info_default_line; - -/* First line number listed by last listing command. */ - -static int first_line_listed; - -START_FILE - -/* Set the source file default for the "list" command, - specifying a symtab. */ - -void -select_source_symtab (s) - register struct symtab *s; -{ - if (s) - { - struct symtab_and_line sal; - - /* Make the default place to list be the function `main' - if one exists. */ - if (lookup_symbol ("main", 0, VAR_NAMESPACE)) - { - sal = decode_line_spec ("main", 1); - current_source_symtab = sal.symtab; - current_source_line = sal.line - 9; - return; - } - - /* If there is no `main', use the last symtab in the list, - which is actually the first found in the file's symbol table. - But ignore .h files. */ - do - { - char *name = s->filename; - int len = strlen (name); - if (! (len > 2 && !strcmp (&name[len - 2], ".h"))) - current_source_symtab = s; - s = s->next; - } - while (s); - current_source_line = 1; - } -} - -static void -directories_info () -{ - printf ("Source directories searched: %s\n", source_path); -} - -static void -init_source_path () -{ - register struct symtab *s; - char wd[MAXPATHLEN]; - if (getwd (wd) == NULL) - perror_with_name ("getwd"); - - source_path = savestring (wd, strlen (wd)); - - /* Forget what we learned about line positions in source files; - must check again now since files may be found in - a different directory now. */ - for (s = symtab_list; s; s = s->next) - if (s->line_charpos != 0) - { - free (s->line_charpos); - s->line_charpos = 0; - } -} - -void -directory_command (dirname, from_tty) - char *dirname; - int from_tty; -{ - char *old = source_path; - - char wd[MAXPATHLEN]; - if (getwd (wd) == NULL) - perror_with_name ("getwd"); - - if (dirname == 0) - { - if (query ("Reinitialize source path to %s? ", wd)) - { - init_source_path (); - free (old); - } - } - else - { - struct stat st; - register int len = strlen (dirname); - register char *tem; - extern char *index (); - - if (index (dirname, ':')) - error ("Please add one directory at a time to the source path."); - if (dirname[len - 1] == '/') - /* Sigh. "foo/" => "foo" */ - dirname[--len] == '\0'; - - while (dirname[len - 1] == '.') - { - if (len == 1) - { - /* "." => getwd () */ - dirname = wd; - goto append; - } - else if (dirname[len - 2] == '/') - { - if (len == 2) - { - /* "/." => "/" */ - dirname[--len] = '\0'; - goto append; - } - else - { - /* "...foo/." => "...foo" */ - dirname[len -= 2] = '\0'; - continue; - } - } - break; - } - - if (dirname[0] != '/') - dirname = concat (wd, "/", dirname); - else - dirname = savestring (dirname, len); - make_cleanup (free, dirname); - - if (stat (dirname, &st) < 0) - perror_with_name (dirname); - if ((st.st_mode & S_IFMT) != S_IFDIR) - error ("%s is not a directory.", dirname); - - append: - len = strlen (dirname); - tem = source_path; - while (1) - { - if (!strncmp (tem, dirname, len) - && (tem[len] == '\0' || tem[len] == ':')) - { - printf ("\"%s\" is already in the source path.\n", - dirname); - break; - } - tem = index (tem, ':'); - if (tem) - tem++; - else - { - source_path = concat (old, ":", dirname); - free (old); - break; - } - } - if (from_tty) - directories_info (); - } -} - -/* Open a file named STRING, searching path PATH (dir names sep by colons) - using mode MODE and protection bits PROT in the calls to open. - If TRY_CWD_FIRST, try to open ./STRING before searching PATH. - (ie pretend the first element of PATH is ".") - If FILENAMED_OPENED is non-null, set it to a newly allocated string naming - the actual file opened (this string will always start with a "/" - - If a file is found, return the descriptor. - Otherwise, return -1, with errno set for the last name we tried to open. */ - -/* >>>> This should only allow files of certain types, - >>>> eg executable, non-directory */ -int -openp (path, try_cwd_first, string, mode, prot, filename_opened) - char *path; - int try_cwd_first; - char *string; - int mode; - int prot; - char **filename_opened; -{ - register int fd; - register char *filename; - register char *p, *p1; - register int len; - - /* ./foo => foo */ - while (string[0] == '.' && string[1] == '/') - string += 2; - - if (try_cwd_first || string[0] == '/') - { - filename = string; - fd = open (filename, mode, prot); - if (fd >= 0 || string[0] == '/') - goto done; - } - - filename = (char *) alloca (strlen (path) + strlen (string) + 2); - fd = -1; - for (p = path; p; p = p1 ? p1 + 1 : 0) - { - p1 = (char *) index (p, ':'); - if (p1) - len = p1 - p; - else - len = strlen (p); - - strncpy (filename, p, len); - filename[len] = 0; - strcat (filename, "/"); - strcat (filename, string); - - fd = open (filename, mode, prot); - if (fd >= 0) break; - } - - done: - if (filename_opened) - if (fd < 0) - *filename_opened = (char *) 0; - else if (filename[0] == '/') - *filename_opened = savestring (filename, strlen (filename)); - else - { - char dirname[MAXPATHLEN]; - if (getwd (dirname) == NULL) - perror_with_name ("getwd"); - *filename_opened = concat (dirname, "/", filename); - } - - return fd; -} - -/* Create and initialize the table S->line_charpos that records - the positions of the lines in the source file, which is assumed - to be open on descriptor DESC. - All set S->nlines to the number of such lines. */ - -static void -find_source_lines (s, desc) - struct symtab *s; - int desc; -{ - struct stat st; - register char *data, *p, *end; - int nlines = 0; - int lines_allocated = 1000; - int *line_charpos = (int *) xmalloc (lines_allocated * sizeof (int)); - extern int exec_mtime; - - fstat (desc, &st); - if (get_exec_file () != 0 && exec_mtime < st.st_mtime) - printf ("Source file is more recent than executable.\n"); - - data = (char *) alloca (st.st_size); - myread (desc, data, st.st_size); - end = data + st.st_size; - p = data; - line_charpos[0] = 0; - nlines = 1; - while (p != end) - { - if (*p++ == '\n') - { - if (nlines == lines_allocated) - line_charpos = (int *) xrealloc (line_charpos, - sizeof (int) * (lines_allocated *= 2)); - line_charpos[nlines++] = p - data; - } - } - s->nlines = nlines; - s->line_charpos = (int *) xrealloc (line_charpos, nlines * sizeof (int)); -} - -/* Return the character position of a line LINE in symtab S. - Return 0 if anything is invalid. */ - -int -source_line_charpos (s, line) - struct symtab *s; - int line; -{ - if (!s) return 0; - if (!s->line_charpos || line <= 0) return 0; - if (line > s->nlines) - line = s->nlines; - return s->line_charpos[line - 1]; -} - -/* Return the line number of character position POS in symtab S. */ - -int -source_charpos_line (s, chr) - register struct symtab *s; - register int chr; -{ - register int line = 0; - register int *lnp; - - if (s == 0 || s->line_charpos == 0) return 0; - lnp = s->line_charpos; - /* Files are usually short, so sequential search is Ok */ - while (line < s->nlines && *lnp <= chr) - { - line++; - lnp++; - } - if (line >= s->nlines) - line = s->nlines; - return line; -} - -/* Get full pathname and line number positions for a symtab. - Return nonzero if line numbers may have changed. - Set *FULLNAME to actual name of the file as found by `openp', - or to 0 if the file is not found. */ - -int -get_filename_and_charpos (s, line, fullname) - struct symtab *s; - int line; - char **fullname; -{ - register int desc, linenums_changed = 0; - - desc = openp (source_path, 0, s->filename, O_RDONLY, 0, fullname); - if (desc < 0) - { - *fullname = NULL; - return 0; - } - if (s->line_charpos == 0) linenums_changed = 1; - if (linenums_changed) find_source_lines (s, desc); - close (desc); - return linenums_changed; -} - -/* Print source lines from the file of symtab S, - starting with line number LINE and stopping before line number STOPLINE. */ - -void -print_source_lines (s, line, stopline) - struct symtab *s; - int line, stopline; -{ - register int c; - register int desc; - register FILE *stream; - int nlines = stopline - line; - - desc = openp (source_path, 0, s->filename, O_RDONLY, 0, (char **) 0); - if (desc < 0) - perror_with_name (s->filename); - - if (s->line_charpos == 0) - find_source_lines (s, desc); - - if (line < 1 || line >= s->nlines) - { - close (desc); - error ("Line number out of range; %s has %d lines.", - s->filename, s->nlines); - } - - if (lseek (desc, s->line_charpos[line - 1], 0) < 0) - { - close (desc); - perror_with_name (s->filename); - } - - current_source_symtab = s; - current_source_line = line; - first_line_listed = line; - - stream = fdopen (desc, "r"); - clearerr (stream); - - while (nlines-- > 0) - { - c = fgetc (stream); - if (c == EOF) break; - line_info_default_line = current_source_line; - printf ("%d\t", current_source_line++); - do - { - if (c < 040 && c != '\t' && c != '\n') - { - fputc ('^', stdout); - fputc (c + 0100, stdout); - } - else if (c == 0177) - printf ("^?"); - else - fputc (c, stdout); - } while (c != '\n' && (c = fgetc (stream)) >= 0); - } - - fclose (stream); -} - -static void -list_command (arg, from_tty) - char *arg; - int from_tty; -{ - struct symtab_and_line sal, sal_end; - struct symbol *sym; - char *arg1; - int no_end = 1; - int dummy_end = 0; - int dummy_beg = 0; - int linenum_beg = 0; - char *p; - - if (symtab_list == 0) - error ("Listing source lines requires symbols."); - - /* "l" or "l +" lists next ten lines. */ - - if (arg == 0 || !strcmp (arg, "+")) - { - if (current_source_symtab == 0) - error ("No default source file yet. Do \"help list\"."); - print_source_lines (current_source_symtab, current_source_line, - current_source_line + 10); - return; - } - - /* "l -" lists previous ten lines, the ones before the ten just listed. */ - if (!strcmp (arg, "-")) - { - if (current_source_symtab == 0) - error ("No default source file yet. Do \"help list\"."); - print_source_lines (current_source_symtab, - max (first_line_listed - 10, 1), - first_line_listed); - return; - } - - /* Now if there is only one argument, decode it in SAL - and set NO_END. - If there are two arguments, decode them in SAL and SAL_END - and clear NO_END; however, if one of the arguments is blank, - set DUMMY_BEG or DUMMY_END to record that fact. */ - - arg1 = arg; - if (*arg1 == ',') - dummy_beg = 1; - else - sal = decode_line_1 (&arg1, 0, 0, 0); - - /* Record whether the BEG arg is all digits. */ - - for (p = arg; p != arg1 && *p >= '0' && *p <= '9'; p++); - linenum_beg = (p == arg1); - - while (*arg1 == ' ' || *arg1 == '\t') - arg1++; - if (*arg1 == ',') - { - no_end = 0; - arg1++; - while (*arg1 == ' ' || *arg1 == '\t') - arg1++; - if (*arg1 == 0) - dummy_end = 1; - else if (dummy_beg) - sal_end = decode_line_1 (&arg1, 0, 0, 0); - else - sal_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line); - } - - if (*arg1) - error ("Junk at end of line specification."); - - if (!no_end && !dummy_beg && !dummy_end - && sal.symtab != sal_end.symtab) - error ("Specified start and end are in different files."); - if (dummy_beg && dummy_end) - error ("Two empty args do not say what lines to list."); - - /* if line was specified by address, - first print exactly which line, and which file. - In this case, sal.symtab == 0 means address is outside - of all known source files, not that user failed to give a filename. */ - if (*arg == '*') - { - if (sal.symtab == 0) - error ("No source file for address 0x%x.", sal.pc); - sym = find_pc_function (sal.pc); - if (sym) - printf ("0x%x is in %s (%s, line %d).\n", - sal.pc, SYMBOL_NAME (sym), sal.symtab->filename, sal.line); - else - printf ("0x%x is in %s, line %d.\n", - sal.pc, sal.symtab->filename, sal.line); - } - - /* If line was not specified by just a line number, - and it does not imply a symtab, it must be an undebuggable symbol - which means no source code. */ - - if (! linenum_beg && sal.symtab == 0) - error ("No line number known for %s.", arg); - - /* If this command is repeated with RET, - turn it into the no-arg variant. */ - - if (from_tty) - *arg = 0; - - if (dummy_beg && sal_end.symtab == 0) - error ("No default source file yet. Do \"help list\"."); - if (dummy_beg) - print_source_lines (sal_end.symtab, max (sal_end.line - 9, 1), - sal_end.line + 1); - else if (sal.symtab == 0) - error ("No default source file yet. Do \"help list\"."); - else if (no_end) - print_source_lines (sal.symtab, max (sal.line - 5, 1), sal.line + 5); - else - print_source_lines (sal.symtab, sal.line, - dummy_end ? sal.line + 10 : sal_end.line + 1); -} - -/* Print info on range of pc's in a specified line. */ - -static void -line_info (arg, from_tty) - char *arg; - int from_tty; -{ - struct symtab_and_line sal; - int start_pc, end_pc; - - if (arg == 0) - { - sal.symtab = current_source_symtab; - sal.line = line_info_default_line; - } - else - { - sal = decode_line_spec (arg); - - /* If this command is repeated with RET, - turn it into the no-arg variant. */ - - if (from_tty) - *arg = 0; - } - - if (sal.symtab == 0) - error ("No source file specified."); - if (sal.line > 0 - && find_line_pc_range (sal.symtab, sal.line, &start_pc, &end_pc)) - { - if (start_pc == end_pc) - printf ("Line %d of \"%s\" is at pc 0x%x but contains no code.\n", - sal.line, sal.symtab->filename, start_pc); - else - printf ("Line %d of \"%s\" starts at pc 0x%x and ends at 0x%x.\n", - sal.line, sal.symtab->filename, start_pc, end_pc); - /* x/i should display this line's code. */ - set_next_address (start_pc); - /* Repeating "info line" should do the following line. */ - line_info_default_line = sal.line + 1; - } - else - printf ("Line number %d is out of range for \"%s\".\n", - sal.line, sal.symtab->filename); -} - -static -initialize () -{ - current_source_symtab = 0; - init_source_path (); - - add_com ("directory", class_files, directory_command, - "Add directory DIR to end of search path for source files.\n\ -With no argument, reset the search path to just the working directory\n\ -and forget cached info on line positions in source files."); - - add_info ("directories", directories_info, - "Current search path for finding source files."); - - add_info ("line", line_info, - "Core addresses of the code for a source line.\n\ -Line can be specified as\n\ - LINENUM, to list around that line in current file,\n\ - FILE:LINENUM, to list around that line in that file,\n\ - FUNCTION, to list around beginning of that function,\n\ - FILE:FUNCTION, to distinguish among like-named static functions.\n\ -Default is to describe the last source line that was listed.\n\n\ -This sets the default address for \"x\" to the line's first instruction\n\ -so that \"x/i\" suffices to start examining the machine code.\n\ -The address is also stored as the value of \"$_\"."); - - add_com ("list", class_files, list_command, - "List specified function or line.\n\ -With no argument, lists ten more lines after or around previous listing.\n\ -\"list -\" lists the ten lines before a previous ten-line listing.\n\ -One argument specifies a line, and ten lines are listed around that line.\n\ -Two arguments with comma between specify starting and ending lines to list.\n\ -Lines can be specified in these ways:\n\ - LINENUM, to list around that line in current file,\n\ - FILE:LINENUM, to list around that line in that file,\n\ - FUNCTION, to list around beginning of that function,\n\ - FILE:FUNCTION, to distinguish among like-named static functions.\n\ - *ADDRESS, to list around the line containing that address.\n\ -With two args if one is empty it stands for ten lines away from the other arg."); -} - -END_FILE -@ - - -1.1 -log -@Initial revision -@ -text -@d22 1 -@ diff --git a/gdb/RCS/symmisc.c,v b/gdb/RCS/symmisc.c,v deleted file mode 100644 index 42653dfb..0000000 --- a/gdb/RCS/symmisc.c,v +++ /dev/null @@ -1,575 +0,0 @@ -head 1.2; -access ; -symbols RMS-has:1.2; -locks ; strict; -comment @ * @; - - -1.2 -date 88.01.26.05.09.53; author gnu; state Exp; -branches ; -next 1.1; - -1.1 -date 88.01.26.04.25.22; author gnu; state Exp; -branches ; -next ; - - -desc -@Original from RMS's devl sources on wheaties -@ - - -1.2 -log -@Check for null pointer passed to free()... -@ -text -@/* Do various things to symbol tables (other than lookup)), for GDB. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - -GDB is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY. No author or distributor accepts responsibility to anyone -for the consequences of using it or for whether it serves any -particular purpose or works at all, unless he says so in writing. -Refer to the GDB General Public License for full details. - -Everyone is granted permission to copy, modify and redistribute GDB, -but only under the conditions described in the GDB General Public -License. A copy of this license is supposed to have been given to you -along with GDB so you can know your rights and responsibilities. It -should be in a file named COPYING. Among other things, the copyright -notice and this notice must be preserved on all copies. - -In other words, go ahead and share GDB, but don't try to stop -anyone else from sharing it farther. Help stamp out software hoarding! -*/ - - -#include "defs.h" -#include "initialize.h" -#include "symtab.h" - -#include <stdio.h> -#include <obstack.h> - -static void free_symtab (); - -START_FILE - -/* Free all the symtabs that are currently installed, - and all storage associated with them. - Leaves us in a consistent state with no symtabs installed. */ - -void -free_all_symtabs () -{ - register struct symtab *s, *snext; - - /* All values will be invalid because their types will be! */ - - clear_value_history (); - clear_displays (); - clear_internalvars (); - clear_breakpoints (); - set_default_breakpoint (0, 0, 0, 0); - - current_source_symtab = 0; - - for (s = symtab_list; s; s = snext) - { - snext = s->next; - free_symtab (s); - } - symtab_list = 0; - obstack_free (symbol_obstack, 0); - obstack_init (symbol_obstack); - - if (misc_function_vector) - free (misc_function_vector); - misc_function_count = 0; - misc_function_vector = 0; -} - -/* Free a struct block <- B and all the symbols defined in that block. */ - -static void -free_symtab_block (b) - struct block *b; -{ - register int i, n; - n = BLOCK_NSYMS (b); - for (i = 0; i < n; i++) - { - free (SYMBOL_NAME (BLOCK_SYM (b, i))); - free (BLOCK_SYM (b, i)); - } - free (b); -} - -/* Free all the storage associated with the struct symtab <- S. - Note that some symtabs have contents malloc'ed structure by structure, - while some have contents that all live inside one big block of memory, - and some share the contents of another symbol table and so you should - not free the contents on their behalf (except sometimes the linetable, - which maybe per symtab even when the rest is not). - It is s->free_code that says which alternative to use. */ - -static void -free_symtab (s) - register struct symtab *s; -{ - register int i, n; - register struct blockvector *bv; - register struct type *type; - register struct typevector *tv; - - switch (s->free_code) - { - case free_nothing: - /* All the contents are part of a big block of memory - and some other symtab is in charge of freeing that block. - Therefore, do nothing. */ - break; - - case free_explicit: - /* All the contents are part of a big block of memory - and that is our `free_ptr' and will be freed below. */ - break; - - case free_contents: - /* Here all the contents were malloc'ed structure by structure - and must be freed that way. */ - /* First free the blocks (and their symbols. */ - bv = BLOCKVECTOR (s); - n = BLOCKVECTOR_NBLOCKS (bv); - for (i = 0; i < n; i++) - free_symtab_block (BLOCKVECTOR_BLOCK (bv, i)); - /* Free the blockvector itself. */ - free (bv); - /* Free the type vector. */ - tv = TYPEVECTOR (s); - if (tv) /* FIXME, should this happen? It does... */ - free (tv); - /* Also free the linetable. */ - - case free_linetable: - /* Everything will be freed either by our `free_ptr' - or by some other symbatb, except for our linetable. - Free that now. */ - free (LINETABLE (s)); - break; - } - - /* If there is a single block of memory to free, free it. */ - if (s->free_ptr) - free (s->free_ptr); - - if (s->line_charpos) - free (s->line_charpos); - free (s->filename); - free (s); -} - -/* Convert a raw symbol-segment to a struct symtab, - and relocate its internal pointers so that it is valid. */ - -/* This is how to relocate one pointer, given a name for it. - Works independent of the type of object pointed to. */ -#define RELOCATE(slot) (slot ? (* (char **) &slot += relocation) : 0) - -/* This is the inverse of RELOCATE. We use it when storing - a core address into a slot that has yet to be relocated. */ -#define UNRELOCATE(slot) (slot ? (* (char **) &slot -= relocation) : 0) - -/* During the process of relocation, this holds the amount to relocate by - (the address of the file's symtab data, in core in the debugger). */ -static int relocation; - -#define CORE_RELOCATE(slot) \ - ((slot) += (((slot) < data_start) ? text_relocation \ - : ((slot) < bss_start) ? data_relocation : bss_relocation)) - -#define TEXT_RELOCATE(slot) ((slot) += text_relocation) - -/* Relocation amounts for addresses in the program's core image. */ -static int text_relocation, data_relocation, bss_relocation; - -/* Boundaries that divide program core addresses into text, data and bss; - used to determine which relocation amount to use. */ -static int data_start, bss_start; - -static void relocate_typevector (); -static void relocate_blockvector (); -static void relocate_type (); -static void relocate_block (); -static void relocate_symbol (); - -/* Relocate a file symbol table so that all the pointers - are valid C pointers. Pass the struct symtab for the file - and the amount to relocate by. */ - -static struct symtab * -relocate_symtab (root) - struct symbol_root *root; -{ - struct symtab *sp = (struct symtab *) xmalloc (sizeof (struct symtab)); - bzero (sp, sizeof (struct symtab)); - - relocation = (int) root; - text_relocation = root->textrel; - data_relocation = root->datarel; - bss_relocation = root->bssrel; - data_start = root->databeg; - bss_start = root->bssbeg; - - sp->filename = root->filename; - sp->ldsymoff = root->ldsymoff; - sp->language = root->language; - sp->compilation = root->compilation; - sp->version = root->version; - sp->blockvector = root->blockvector; - sp->typevector = root->typevector; - sp->free_code = free_explicit; - sp->free_ptr = (char *) root; - - RELOCATE (TYPEVECTOR (sp)); - RELOCATE (BLOCKVECTOR (sp)); - RELOCATE (sp->version); - RELOCATE (sp->compilation); - RELOCATE (sp->filename); - - relocate_typevector (TYPEVECTOR (sp)); - relocate_blockvector (BLOCKVECTOR (sp)); - - return sp; -} - -static void -relocate_typevector (tv) - struct typevector *tv; -{ - register int ntypes = TYPEVECTOR_NTYPES (tv); - register int i; - - for (i = 0; i < ntypes; i++) - RELOCATE (TYPEVECTOR_TYPE (tv, i)); - for (i = 0; i < ntypes; i++) - relocate_type (TYPEVECTOR_TYPE (tv, i)); -} - -static void -relocate_blockvector (blp) - register struct blockvector *blp; -{ - register int nblocks = BLOCKVECTOR_NBLOCKS (blp); - register int i; - for (i = 0; i < nblocks; i++) - RELOCATE (BLOCKVECTOR_BLOCK (blp, i)); - for (i = 0; i < nblocks; i++) - relocate_block (BLOCKVECTOR_BLOCK (blp, i)); -} - -static void -relocate_block (bp) - register struct block *bp; -{ - register int nsyms = BLOCK_NSYMS (bp); - register int i; - - TEXT_RELOCATE (BLOCK_START (bp)); - TEXT_RELOCATE (BLOCK_END (bp)); - - /* These two should not be recursively processed. - The superblock need not be because all blocks are - processed from relocate_blockvector. - The function need not be because it will be processed - under the block which is its scope. */ - RELOCATE (BLOCK_SUPERBLOCK (bp)); - RELOCATE (BLOCK_FUNCTION (bp)); - - for (i = 0; i < nsyms; i++) - RELOCATE (BLOCK_SYM (bp, i)); - - for (i = 0; i < nsyms; i++) - relocate_symbol (BLOCK_SYM (bp, i)); -} - -static void -relocate_symbol (sp) - register struct symbol *sp; -{ - RELOCATE (SYMBOL_NAME (sp)); - if (SYMBOL_CLASS (sp) == LOC_BLOCK) - { - RELOCATE (SYMBOL_BLOCK_VALUE (sp)); - /* We can assume the block that belongs to this symbol - is not relocated yet, since it comes after - the block that contains this symbol. */ - BLOCK_FUNCTION (SYMBOL_BLOCK_VALUE (sp)) = sp; - UNRELOCATE (BLOCK_FUNCTION (SYMBOL_BLOCK_VALUE (sp))); - } - else if (SYMBOL_CLASS (sp) == LOC_STATIC) - CORE_RELOCATE (SYMBOL_VALUE (sp)); - else if (SYMBOL_CLASS (sp) == LOC_LABEL) - TEXT_RELOCATE (SYMBOL_VALUE (sp)); - RELOCATE (SYMBOL_TYPE (sp)); -} - -/* We cannot come up with an a priori spanning tree - for the network of types, since types can be used - for many symbols and also as components of other types. - Therefore, we need to be able to mark types that we - already have relocated (or are already in the middle of relocating) - as in a garbage collector. */ - -static void -relocate_type (tp) - register struct type *tp; -{ - register int nfields = TYPE_NFIELDS (tp); - register int i; - - RELOCATE (TYPE_NAME (tp)); - RELOCATE (TYPE_TARGET_TYPE (tp)); - RELOCATE (TYPE_FIELDS (tp)); - RELOCATE (TYPE_POINTER_TYPE (tp)); - - for (i = 0; i < nfields; i++) - { - RELOCATE (TYPE_FIELD_TYPE (tp, i)); - RELOCATE (TYPE_FIELD_NAME (tp, i)); - } -} - -/* Read symsegs from file named NAME open on DESC, - make symtabs from them, and return a chain of them. - Assumes DESC is prepositioned at the end of the string table, - just before the symsegs if there are any. */ - -struct symtab * -read_symsegs (desc, name) - int desc; - char *name; -{ - struct symbol_root root; - register char *data; - register struct symtab *sp, *chain = 0; - register int len; - - while (1) - { - len = myread (desc, &root, sizeof root); - if (len == 0 || root.format == 0) - break; - if (root.format != 1 || - root.length < sizeof root) - error ("Invalid symbol segment format code"); - data = (char *) xmalloc (root.length); - bcopy (&root, data, sizeof root); - len = myread (desc, data + sizeof root, - root.length - sizeof root); - sp = relocate_symtab (data); - sp->next = chain; - chain = sp; - } - - return chain; -} - -static int block_depth (); -static void print_spaces (); -static void print_symbol (); - -print_symtabs (filename) - char *filename; -{ - FILE *outfile; - register struct symtab *s; - register int i, j; - int len, line, blen; - register struct linetable *l; - struct blockvector *bv; - register struct block *b; - int depth; - struct cleanup *cleanups; - extern int fclose(); - - if (filename == 0) - error_no_arg ("file to write symbol data in"); - outfile = fopen (filename, "w"); - - cleanups = make_cleanup (fclose, outfile); - immediate_quit++; - - for (s = symtab_list; s; s = s->next) - { - /* First print the line table. */ - fprintf (outfile, "Symtab for file %s\n\n", s->filename); - fprintf (outfile, "Line table:\n\n"); - l = LINETABLE (s); - len = l->nitems; - for (i = 0; i < len; i++) - { - if (l->item[i] < 0) - line = - l->item[i] - 1; - else - fprintf (outfile, " line %d at %x\n", ++line, l->item[i]); - } - /* Now print the block info. */ - fprintf (outfile, "\nBlockvector:\n\n"); - bv = BLOCKVECTOR (s); - len = BLOCKVECTOR_NBLOCKS (bv); - for (i = 0; i < len; i++) - { - b = BLOCKVECTOR_BLOCK (bv, i); - depth = block_depth (b) * 2; - print_spaces (depth, outfile); - fprintf (outfile, "block #%03d (object 0x%x) ", i, b); - fprintf (outfile, "[0x%x..0x%x]", BLOCK_START (b), BLOCK_END (b)); - if (BLOCK_SUPERBLOCK (b)) - fprintf (outfile, " (under 0x%x)", BLOCK_SUPERBLOCK (b)); - if (BLOCK_FUNCTION (b)) - fprintf (outfile, " %s", SYMBOL_NAME (BLOCK_FUNCTION (b))); - fputc ('\n', outfile); - blen = BLOCK_NSYMS (b); - for (j = 0; j < blen; j++) - { - print_symbol (BLOCK_SYM (b, j), depth + 1, outfile); - } - } - - fprintf (outfile, "\n\n"); - } - - immediate_quit--; - do_cleanups (cleanups); -} - -static void -print_symbol (symbol, depth, outfile) - struct symbol *symbol; - int depth; - FILE *outfile; -{ - print_spaces (depth, outfile); - if (SYMBOL_NAMESPACE (symbol) == LABEL_NAMESPACE) - { - fprintf (outfile, "label %s at 0x%x", SYMBOL_NAME (symbol), - SYMBOL_VALUE (symbol)); - return; - } - if (SYMBOL_NAMESPACE (symbol) == STRUCT_NAMESPACE) - { - if (TYPE_NAME (SYMBOL_TYPE (symbol))) - { - type_print_1 (SYMBOL_TYPE (symbol), "", outfile, 1, depth); - } - else - { - fprintf (outfile, "%s %s = ", - (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_ENUM - ? "enum" - : (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_STRUCT - ? "struct" : "union")), - SYMBOL_NAME (symbol)); - type_print_1 (SYMBOL_TYPE (symbol), "", outfile, 1, depth); - } - fprintf (outfile, ";\n"); - } - else - { - if (SYMBOL_CLASS (symbol) == LOC_TYPEDEF) - fprintf (outfile, "typedef "); - if (SYMBOL_TYPE (symbol)) - { - type_print_1 (SYMBOL_TYPE (symbol), SYMBOL_NAME (symbol), - outfile, 1, depth); - fprintf (outfile, "; "); - } - else - fprintf (outfile, "%s ", SYMBOL_NAME (symbol)); - - switch (SYMBOL_CLASS (symbol)) - { - case LOC_CONST: - fprintf (outfile, "const %d (0x%x),", - SYMBOL_VALUE (symbol), SYMBOL_VALUE (symbol)); - break; - - case LOC_CONST_BYTES: - fprintf (outfile, "const %d hex bytes:", - TYPE_LENGTH (SYMBOL_TYPE (symbol))); - { - int i; - for (i = 0; i < TYPE_LENGTH (SYMBOL_TYPE (symbol)); i++) - fprintf (outfile, " %2x", SYMBOL_VALUE_BYTES (symbol) [i]); - fprintf (outfile, ","); - } - break; - - case LOC_STATIC: - fprintf (outfile, "static at 0x%x,", SYMBOL_VALUE (symbol)); - break; - - case LOC_REGISTER: - fprintf (outfile, "register %d,", SYMBOL_VALUE (symbol)); - break; - - case LOC_ARG: - fprintf (outfile, "arg at 0x%x,", SYMBOL_VALUE (symbol)); - break; - - case LOC_LOCAL: - fprintf (outfile, "local at 0x%x,", SYMBOL_VALUE (symbol)); - break; - - case LOC_TYPEDEF: - break; - - case LOC_LABEL: - fprintf (outfile, "label at 0x%x", SYMBOL_VALUE (symbol)); - break; - - case LOC_BLOCK: - fprintf (outfile, "block (object 0x%x) starting at 0x%x,", - SYMBOL_VALUE (symbol), - BLOCK_START (SYMBOL_BLOCK_VALUE (symbol))); - break; - } - } - fprintf (outfile, "\n"); -} - -/* Return the nexting depth of a block within other blocks in its symtab. */ - -static int -block_depth (block) - struct block *block; -{ - register int i = 0; - while (block = BLOCK_SUPERBLOCK (block)) i++; - return i; -} - -static -initialize () -{ - add_com ("printsyms", class_obscure, print_symtabs, - "Print dump of current symbol definitions to file OUTFILE."); -} - -END_FILE -@ - - -1.1 -log -@Initial revision -@ -text -@d125 2 -a126 1 - free (tv); -@ diff --git a/gdb/RCS/symtab.c,v b/gdb/RCS/symtab.c,v deleted file mode 100644 index 7ccdaac..0000000 --- a/gdb/RCS/symtab.c,v +++ /dev/null @@ -1,1153 +0,0 @@ -head 1.2; -access ; -symbols RMS-has:1.2; -locks ; strict; -comment @ * @; - - -1.2 -date 88.01.26.05.10.33; author gnu; state Exp; -branches ; -next 1.1; - -1.1 -date 88.01.26.02.18.56; author gnu; state Exp; -branches ; -next ; - - -desc -@Original from RMS's wheaties devel sources -@ - - -1.2 -log -@Permit SYS V regular expression library as well as real Unix one. -@ -text -@/* Symbol table lookup for the GNU debugger, GDB. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - -GDB is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY. No author or distributor accepts responsibility to anyone -for the consequences of using it or for whether it serves any -particular purpose or works at all, unless he says so in writing. -Refer to the GDB General Public License for full details. - -Everyone is granted permission to copy, modify and redistribute GDB, -but only under the conditions described in the GDB General Public -License. A copy of this license is supposed to have been given to you -along with GDB so you can know your rights and responsibilities. It -should be in a file named COPYING. Among other things, the copyright -notice and this notice must be preserved on all copies. - -In other words, go ahead and share GDB, but don't try to stop -anyone else from sharing it farther. Help stamp out software hoarding! -*/ - -#include "defs.h" -#include "initialize.h" -#include "symtab.h" -#include "param.h" - -#include <stdio.h> -#include <obstack.h> - -#ifdef mac_aux -#define REGCMP -#endif - -START_FILE - -/* Allocate an obstack to hold objects that should be freed - when we load a new symbol table. - This includes the symbols made by dbxread - and the types that are not permanent. */ - -struct obstack obstack1; - -struct obstack *symbol_obstack = &obstack1; - -/* These variables point to the objects - representing the predefined C data types. */ - -struct type *builtin_type_void; -struct type *builtin_type_char; -struct type *builtin_type_short; -struct type *builtin_type_int; -struct type *builtin_type_long; -struct type *builtin_type_unsigned_char; -struct type *builtin_type_unsigned_short; -struct type *builtin_type_unsigned_int; -struct type *builtin_type_unsigned_long; -struct type *builtin_type_float; -struct type *builtin_type_double; - -/* Lookup the symbol table of a source file named NAME. */ - -struct symtab * -lookup_symtab (name) - char *name; -{ - register struct symtab *s; - register char *copy; - - for (s = symtab_list; s; s = s->next) - if (!strcmp (name, s->filename)) - return s; - - /* If name not found as specified, see if adding ".c" helps. */ - - copy = (char *) alloca (strlen (name) + 3); - strcpy (copy, name); - strcat (copy, ".c"); - for (s = symtab_list; s; s = s->next) - if (!strcmp (copy, s->filename)) - return s; - - return 0; -} - -/* Lookup a typedef or primitive type named NAME, - visible in lexical block BLOCK. - If NOERR is nonzero, return zero if NAME is not suitably defined. */ - -struct type * -lookup_typename (name, block, noerr) - char *name; - struct block *block; - int noerr; -{ - register struct symbol *sym = lookup_symbol (name, block, VAR_NAMESPACE); - if (sym == 0 || SYMBOL_CLASS (sym) != LOC_TYPEDEF) - { - if (!strcmp (name, "int")) - return builtin_type_int; - if (!strcmp (name, "long")) - return builtin_type_long; - if (!strcmp (name, "short")) - return builtin_type_short; - if (!strcmp (name, "char")) - return builtin_type_char; - if (!strcmp (name, "float")) - return builtin_type_float; - if (!strcmp (name, "double")) - return builtin_type_double; - if (!strcmp (name, "void")) - return builtin_type_void; - - if (noerr) - return 0; - error ("No type named %s.", name); - } - return SYMBOL_TYPE (sym); -} - -struct type * -lookup_unsigned_typename (name) - char *name; -{ - if (!strcmp (name, "int")) - return builtin_type_unsigned_int; - if (!strcmp (name, "long")) - return builtin_type_unsigned_long; - if (!strcmp (name, "short")) - return builtin_type_unsigned_short; - if (!strcmp (name, "char")) - return builtin_type_unsigned_char; - error ("No type named unsigned %s.", name); -} - -/* Lookup a structure type named "struct NAME", - visible in lexical block BLOCK. */ - -struct type * -lookup_struct (name, block) - char *name; - struct block *block; -{ - register struct symbol *sym = lookup_symbol (name, block, STRUCT_NAMESPACE); - if (sym == 0) - error ("No struct type named %s.", name); - if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT) - error ("This context has union or enum %s, not a struct.", name); - return SYMBOL_TYPE (sym); -} - -/* Lookup a union type named "union NAME", - visible in lexical block BLOCK. */ - -struct type * -lookup_union (name, block) - char *name; - struct block *block; -{ - register struct symbol *sym = lookup_symbol (name, block, STRUCT_NAMESPACE); - if (sym == 0) - error ("No union type named %s.", name); - if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_UNION) - error ("This context has struct or enum %s, not a union.", name); - return SYMBOL_TYPE (sym); -} - -/* Lookup an enum type named "enum NAME", - visible in lexical block BLOCK. */ - -struct type * -lookup_enum (name, block) - char *name; - struct block *block; -{ - register struct symbol *sym = lookup_symbol (name, block, STRUCT_NAMESPACE); - if (sym == 0) - error ("No enum type named %s.", name); - if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_ENUM) - error ("This context has struct or union %s, not an enum.", name); - return SYMBOL_TYPE (sym); -} - -/* Given a type TYPE, return a type of pointers to that type. - May need to construct such a type if this is the first use. */ - -struct type * -lookup_pointer_type (type) - struct type *type; -{ - register struct type *ptype = TYPE_POINTER_TYPE (type); - if (ptype) return ptype; - - /* This is the first time anyone wanted a pointer to a TYPE. */ - if (TYPE_FLAGS (type) & TYPE_FLAG_PERM) - ptype = (struct type *) xmalloc (sizeof (struct type)); - else - ptype = (struct type *) obstack_alloc (symbol_obstack, - sizeof (struct type)); - - bzero (ptype, sizeof (struct type)); - TYPE_TARGET_TYPE (ptype) = type; - TYPE_POINTER_TYPE (type) = ptype; - /* New type is permanent if type pointed to is permanent. */ - if (TYPE_FLAGS (type) & TYPE_FLAG_PERM) - TYPE_FLAGS (ptype) |= TYPE_FLAG_PERM; - /* We assume the machine has only one representation for pointers! */ - TYPE_LENGTH (ptype) = sizeof (char *); - TYPE_CODE (ptype) = TYPE_CODE_PTR; - return ptype; -} - -/* Given a type TYPE, return a type of functions that return that type. - May need to construct such a type if this is the first use. */ - -struct type * -lookup_function_type (type) - struct type *type; -{ - register struct type *ptype = TYPE_FUNCTION_TYPE (type); - if (ptype) return ptype; - - /* This is the first time anyone wanted a function returning a TYPE. */ - if (TYPE_FLAGS (type) & TYPE_FLAG_PERM) - ptype = (struct type *) xmalloc (sizeof (struct type)); - else - ptype = (struct type *) obstack_alloc (symbol_obstack, - sizeof (struct type)); - - bzero (ptype, sizeof (struct type)); - TYPE_TARGET_TYPE (ptype) = type; - TYPE_FUNCTION_TYPE (type) = ptype; - /* New type is permanent if type returned is permanent. */ - if (TYPE_FLAGS (type) & TYPE_FLAG_PERM) - TYPE_FLAGS (ptype) |= TYPE_FLAG_PERM; - TYPE_LENGTH (ptype) = 1; - TYPE_CODE (ptype) = TYPE_CODE_FUNC; - TYPE_NFIELDS (ptype) = 0; - return ptype; -} - -/* Smash TYPE to be a type of pointers to TO_TYPE. - If TO_TYPE is not permanent and has no pointer-type yet, - record TYPE as its pointer-type. */ - -void -smash_to_pointer_type (type, to_type) - struct type *type, *to_type; -{ - bzero (type, sizeof (struct type)); - TYPE_TARGET_TYPE (type) = to_type; - /* We assume the machine has only one representation for pointers! */ - TYPE_LENGTH (type) = sizeof (char *); - TYPE_CODE (type) = TYPE_CODE_PTR; - - if (TYPE_POINTER_TYPE (to_type) == 0 - && !(TYPE_FLAGS (type) & TYPE_FLAG_PERM)) - { - TYPE_POINTER_TYPE (to_type) = type; - } -} - -/* Smash TYPE to be a type of functions returning TO_TYPE. - If TO_TYPE is not permanent and has no function-type yet, - record TYPE as its function-type. */ - -void -smash_to_function_type (type, to_type) - struct type *type, *to_type; -{ - bzero (type, sizeof (struct type)); - TYPE_TARGET_TYPE (type) = to_type; - TYPE_LENGTH (type) = 1; - TYPE_CODE (type) = TYPE_CODE_FUNC; - TYPE_NFIELDS (type) = 0; - - if (TYPE_FUNCTION_TYPE (to_type) == 0 - && !(TYPE_FLAGS (type) & TYPE_FLAG_PERM)) - { - TYPE_FUNCTION_TYPE (to_type) = type; - } -} - -static struct symbol *lookup_block_symbol (); - -/* Find the definition for a specified symbol name NAME - in namespace NAMESPACE, visible from lexical block BLOCK. - Returns the struct symbol pointer, or zero if no symbol is found. */ - -struct symbol * -lookup_symbol (name, block, namespace) - char *name; - register struct block *block; - enum namespace namespace; -{ - register int i, n; - register struct symbol *sym; - register struct symtab *s; - struct blockvector *bv; - - /* Search specified block and its superiors. */ - - while (block != 0) - { - sym = lookup_block_symbol (block, name, namespace); - if (sym) return sym; - block = BLOCK_SUPERBLOCK (block); - } - - /* Now search all symtabs' global blocks. */ - - for (s = symtab_list; s; s = s->next) - { - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, 0); - sym = lookup_block_symbol (block, name, namespace); - if (sym) return sym; - } - - /* Now search all symtabs' per-file blocks. - Not strictly correct, but more useful than an error. */ - - for (s = symtab_list; s; s = s->next) - { - bv = BLOCKVECTOR (s); - block = BLOCKVECTOR_BLOCK (bv, 1); - sym = lookup_block_symbol (block, name, namespace); - if (sym) return sym; - } - return 0; -} - -/* Look for a symbol in block BLOCK using binary search. */ - -static struct symbol * -lookup_block_symbol (block, name, namespace) - register struct block *block; - char *name; - enum namespace namespace; -{ - register int bot, top, inc; - register struct symbol *sym; - - top = BLOCK_NSYMS (block); - bot = 0; - - /* First, advance BOT to not far before - the first symbol whose name is NAME. */ - - while (1) - { - inc = (top - bot + 1); - /* No need to keep binary searching for the last few bits worth. */ - if (inc < 7) - break; - inc >>= 1; - sym = BLOCK_SYM (block, bot + inc); - if (strcmp (SYMBOL_NAME (sym), name) < 0) - bot += inc; - else - top = bot + inc; - } - - /* Now scan forward until we run out of symbols, - find one whose name is greater than NAME, - or find one we want. - If there is more than one symbol with the right name and namespace, - we return the first one. dbxread.c is careful to make sure - that if one is a register then it comes first. */ - - top = BLOCK_NSYMS (block); - while (bot < top) - { - sym = BLOCK_SYM (block, bot); - inc = strcmp (SYMBOL_NAME (sym), name); - if (inc == 0 && SYMBOL_NAMESPACE (sym) == namespace) - return sym; - if (inc > 0) - return 0; - bot++; - } - return 0; -} - -/* Return the symbol for the function which contains a specified - lexical block, described by a struct block BL. */ - -struct symbol * -block_function (bl) - struct block *bl; -{ - while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0) - bl = BLOCK_SUPERBLOCK (bl); - - return BLOCK_FUNCTION (bl); -} - -/* Subroutine of find_pc_line */ - -static struct symtab * -find_pc_symtab (pc) - register CORE_ADDR pc; -{ - register struct block *b; - struct blockvector *bv; - register struct symtab *s; - - /* Search all symtabs for one whose file contains our pc */ - - for (s = symtab_list; s; s = s->next) - { - bv = BLOCKVECTOR (s); - b = BLOCKVECTOR_BLOCK (bv, 0); - if (BLOCK_START (b) <= pc - && BLOCK_END (b) > pc) - break; - } - - return s; -} - -/* Find the source file and line number for a given PC value. - Return a structure containing a symtab pointer, a line number, - and a pc range for the entire source line. - The value's .pc field is NOT the specified pc. - NOTCURRENT nonzero means, if specified pc is on a line boundary, - use the line that ends there. Otherwise, in that case, the line - that begins there is used. */ - -struct symtab_and_line -find_pc_line (pc, notcurrent) - CORE_ADDR pc; - int notcurrent; -{ - struct symtab *s; - register struct linetable *l; - register int len; - register int i, item; - int line; - struct symtab_and_line value; - struct blockvector *bv; - - /* Info on best line seen so far, and where it starts, and its file. */ - - int best_line = 0; - CORE_ADDR best_pc = 0; - CORE_ADDR best_end = 0; - struct symtab *best_symtab = 0; - - /* Store here the first line number - of a file which contains the line at the smallest pc after PC. - If we don't find a line whose range contains PC, - we will use a line one less than this, - with a range from the start of that file to the first line's pc. */ - int alt_line = 0; - CORE_ADDR alt_pc = 0; - struct symtab *alt_symtab = 0; - - /* Info on best line seen in this file. */ - - int prev_line; - CORE_ADDR prev_pc; - - /* Info on first line of this file. */ - - int first_line; - CORE_ADDR first_pc; - - /* If this pc is not from the current frame, - it is the address of the end of a call instruction. - Quite likely that is the start of the following statement. - But what we want is the statement containing the instruction. - Fudge the pc to make sure we get that. */ - - if (notcurrent) pc -= 1; - - s = find_pc_symtab (pc); - if (s == 0) - { - value.symtab = 0; - value.line = 0; - value.pc = pc; - return value; - } - - bv = BLOCKVECTOR (s); - - /* Look at all the symtabs that share this blockvector. - They all have the same apriori range, that we found was right; - but they have different line tables. */ - - for (; s && BLOCKVECTOR (s) == bv; s = s->next) - { - /* Find the best line in this symtab. */ - l = LINETABLE (s); - len = l->nitems; - prev_line = -1; - first_line = -1; - for (i = 0; i < len; i++) - { - item = l->item[i]; - if (item < 0) - line = - item - 1; - else - { - line++; - if (first_line < 0) - { - first_line = line; - first_pc = item; - } - /* Return the last line that did not start after PC. */ - if (pc >= item) - { - prev_line = line; - prev_pc = item; - } - else - break; - } - } - - /* Is this file's best line closer than the best in the other files? - If so, record this file, and its best line, as best so far. */ - if (prev_line >= 0 && prev_pc > best_pc) - { - best_pc = prev_pc; - best_line = prev_line; - best_symtab = s; - if (i < len) - best_end = item; - else - best_end = 0; - } - /* Is this file's first line closer than the first lines of other files? - If so, record this file, and its first line, as best alternate. */ - if (first_line >= 0 && first_pc > pc - && (alt_pc == 0 || first_pc < alt_pc)) - { - alt_pc = first_pc; - alt_line = first_line; - alt_symtab = s; - } - } - if (best_symtab == 0) - { - value.symtab = alt_symtab; - value.line = alt_line - 1; - value.pc = BLOCK_END (BLOCKVECTOR_BLOCK (bv, 0)); - value.end = alt_pc; - } - else - { - value.symtab = best_symtab; - value.line = best_line; - value.pc = best_pc; - value.end = (best_end ? best_end - : (alt_pc ? alt_pc - : BLOCK_END (BLOCKVECTOR_BLOCK (bv, 0)))); - } - return value; -} - -/* Find the range of pc values in a line. - Store the starting pc of the line into *STARTPTR - and the ending pc (start of next line) into *ENDPTR. - Returns 1 to indicate success. - Returns 0 if could not find the specified line. */ - -int -find_line_pc_range (symtab, thisline, startptr, endptr) - struct symtab *symtab; - int thisline; - CORE_ADDR *startptr, *endptr; -{ - register struct linetable *l; - register int i, line, item; - int len; - register CORE_ADDR prev_pc; - CORE_ADDR last_pc; - - if (symtab == 0) - return 0; - - l = LINETABLE (symtab); - len = l->nitems; - prev_pc = -1; - for (i = 0; i < len; i++) - { - item = l->item[i]; - if (item < 0) - line = - item - 1; - else - { - line++; - /* As soon as we find a line following the specified one - we know the end pc and can return. */ - if (line > thisline) - { - /* If we have not seen an entry for the specified line, - assume that means the specified line has zero bytes. */ - *startptr = prev_pc == -1 ? item : prev_pc; - *endptr = item; - return 1; - } - /* If we see an entry for the specified line, - it gives the beginning. */ - if (line == thisline) - prev_pc = item; - last_pc = item; - } - } - if (prev_pc != -1) - { - /* If we found the specified line but no later line, it's file's last. - Its range is from line's pc to file's end pc. */ - *startptr = last_pc; - *endptr = BLOCK_END (BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), 0)); - return 1; - } - - return 0; -} - -/* Find the PC value for a given source file and line number. - Returns zero for invalid line number. - The source file is specified with a struct symtab. */ - -CORE_ADDR -find_line_pc (symtab, line) - struct symtab *symtab; - int line; -{ - register struct linetable *l; - register int len; - register int i; - register int item; - register int nextline = -1; - - if (line <= 0) - return 0; - - l = LINETABLE (symtab); - len = l->nitems; - for (i = 0; i < len; i++) - { - item = l->item[i]; - if (item < 0) - nextline = - item - 1; - else - { - nextline++; - if (line <= nextline) - return item; - } - } - return 0; -} - -int -find_pc_line_pc_range (pc, startptr, endptr) - CORE_ADDR pc; - CORE_ADDR *startptr, *endptr; -{ - struct symtab_and_line sal; - sal = find_pc_line (pc, 0); - *startptr = sal.pc; - *endptr = sal.end; - return sal.symtab != 0; -} - -/* Parse a string that specifies a line number. - Pass the address of a char * variable; that variable will be - advanced over the characters actually parsed. - - The string can be: - - LINENUM -- that line number in current file. PC returned is 0. - FILE:LINENUM -- that line in that file. PC returned is 0. - FUNCTION -- line number of openbrace of that function. - PC returned is the start of the function. - FILE:FUNCTION -- likewise, but prefer functions in that file. - *EXPR -- line in which address EXPR appears. - - FUNCTION may be an undebuggable function found in misc_function_vector. - - If the argument FUNFIRSTLINE is nonzero, we want the first line - of real code inside a function when a function is specified. - - DEFAULT_SYMTAB specifies the file to use if none is specified. - It defaults to current_source_symtab. - DEFAULT_LINE specifies the line number to use for relative - line numbers (that start with signs). Defaults to current_source_line. - - Note that it is possible to return zero for the symtab - if no file is validly specified. Callers must check that. - Also, the line number returned may be invalid. */ - -struct symtab_and_line -decode_line_1 (argptr, funfirstline, default_symtab, default_line) - char **argptr; - int funfirstline; - struct symtab *default_symtab; - int default_line; -{ - struct symtab_and_line value; - register char *p, *p1; - register struct symtab *s; - register struct symbol *sym; - register CORE_ADDR pc; - register int i; - char *copy; - - /* Defaults have defaults. */ - - if (default_symtab == 0) - { - default_symtab = current_source_symtab; - default_line = current_source_line; - } - - /* See if arg is *PC */ - - if (**argptr == '*') - { - (*argptr)++; - pc = parse_and_eval_address_1 (argptr); - value = find_pc_line (pc, 0); - value.pc = pc; - return value; - } - - /* Maybe arg is FILE : LINENUM or FILE : FUNCTION */ - - s = 0; - - for (p = *argptr; *p; p++) - { - if (p[0] == ':' || p[0] == ' ' || p[0] == '\t') - break; - } - while (p[0] == ' ' || p[0] == '\t') p++; - - if (p[0] == ':') - { - /* Extract the file name. */ - p1 = p; - while (p != *argptr && p[-1] == ' ') --p; - copy = (char *) alloca (p - *argptr + 1); - bcopy (*argptr, copy, p - *argptr); - copy[p - *argptr] = 0; - - /* Find that file's data. */ - s = lookup_symtab (copy); - if (s == 0) - { - if (symtab_list == 0) - error ("No symbol table is loaded. Use the \"symbol-file\" command."); - error ("No source file named %s.", copy); - } - - /* Discard the file name from the arg. */ - p = p1 + 1; - while (*p == ' ' || *p == '\t') p++; - *argptr = p; - } - - /* S is specified file's symtab, or 0 if no file specified. - arg no longer contains the file name. */ - - /* Check whether arg is all digits (and sign) */ - - p = *argptr; - if (*p == '-' || *p == '+') p++; - while (*p >= '0' && *p <= '9') - p++; - - if (p != *argptr && (*p == 0 || *p == ' ' || *p == '\t' || *p == ',')) - { - /* We found a token consisting of all digits -- at least one digit. */ - enum sign {none, plus, minus} sign = none; - - if (**argptr == '+') - sign = plus, (*argptr)++; - else if (**argptr == '-') - sign = minus, (*argptr)++; - value.line = atoi (*argptr); - switch (sign) - { - case plus: - if (p == *argptr) - value.line = 5; - if (s == 0) - value.line = default_line + value.line; - break; - case minus: - if (p == *argptr) - value.line = 15; - if (s == 0) - value.line = default_line - value.line; - else - value.line = 1; - break; - } - - while (*p == ' ' || *p == '\t') p++; - *argptr = p; - if (s == 0) - s = default_symtab; - value.symtab = s; - value.pc = 0; - return value; - } - - /* Arg token is not digits => try it as a function name - Find the next token (everything up to end or next whitespace). */ - p = *argptr; - while (*p && *p != ' ' && *p != '\t' && *p != ',') p++; - copy = (char *) alloca (p - *argptr + 1); - bcopy (*argptr, copy, p - *argptr); - copy[p - *argptr] = 0; - while (*p == ' ' || *p == '\t') p++; - *argptr = p; - - /* Look up that token as a function. - If file specified, use that file's per-file block to start with. */ - - sym = lookup_symbol (copy, s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), 1) : 0, - VAR_NAMESPACE); - - if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) - { - /* Arg is the name of a function */ - pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) + FUNCTION_START_OFFSET; - if (funfirstline) - SKIP_PROLOGUE (pc); - value = find_pc_line (pc, 0); - value.pc = (value.end && value.pc != pc) ? value.end : pc; - return value; - } - - if (sym) - error ("%s is not a function.", copy); - - for (i = 0; i < misc_function_count; i++) - if (!strcmp (misc_function_vector[i].name, copy)) - { - value.symtab = 0; - value.line = 0; - value.pc = misc_function_vector[i].address + FUNCTION_START_OFFSET; - if (funfirstline) - SKIP_PROLOGUE (value.pc); - return value; - } - - if (symtab_list == 0) - error ("No symbol table is loaded. Use the \"symbol-file\" command."); - error ("Function %s not defined.", copy); -} - -struct symtab_and_line -decode_line_spec (string, funfirstline) - char *string; - int funfirstline; -{ - struct symtab_and_line sal; - if (string == 0) - error ("Empty line specification."); - sal = decode_line_1 (&string, funfirstline, - current_source_symtab, current_source_line); - if (*string) - error ("Junk at end of line specification: %s", string); - return sal; -} - -static void -sources_info () -{ - register struct symtab *s; - register int column = 0; - - if (symtab_list == 0) - { - printf ("No symbol table is loaded.\n"); - return; - } - printf ("Source files for which symbol table is known:\n"); - for (s = symtab_list; s; s = s->next) - { - if (column != 0 && column + strlen (s->filename) >= 70) - { - printf ("\n"); - column = 0; - } - else if (column != 0) - { - printf (" "); - column++; - } - printf ("%s", s->filename); - column += strlen (s->filename); - if (s->next) - { - printf (","); - column++; - } - } - printf ("\n"); -} - -/* List all symbols (if REGEXP is 0) or all symbols matching REGEXP. - If CLASS is zero, list all symbols except functions and type names. - If CLASS is 1, list only functions. - If CLASS is 2, list only type names. */ - -#define MORE \ -{ print_count++; \ - if (print_count >= 21) \ - { printf ("--Type Return to print more--"); \ - print_count = 0; \ - fflush (stdout); \ - read_line (); } } - -static void -list_symbols (regexp, class) - char *regexp; - int class; -{ - register struct symtab *s; - register struct blockvector *bv; - struct blockvector *prev_bv = 0; - register struct block *b; - register int i, j; - register struct symbol *sym; - char *val = 0; - int found_in_file; - static char *classnames[] - = {"variable", "function", "type"}; - int print_count = 0; -#ifdef REGCMP - extern char *regcmp(), *regex(), *loc1; -#endif - - if (regexp) { -#ifdef REGCMP - val = regcmp(regexp, (char *)0); - if (val == 0) - error ("Invalid regexp: %s", regexp); -#else - if (val = (char *) re_comp (regexp)) - error ("Invalid regexp: %s", val); -#endif - } - - printf (regexp - ? "All %ss matching regular expression \"%s\":\n" - : "All defined %ss:\n", - classnames[class], - regexp); - - for (s = symtab_list; s; s = s->next) - { - found_in_file = 0; - bv = BLOCKVECTOR (s); - /* Often many files share a blockvector. - Scan each blockvector only once so that - we don't get every symbol many times. - It happens that the first symtab in the list - for any given blockvector is the main file. */ - if (bv != prev_bv) - for (i = 0; i < 2; i++) - { - b = BLOCKVECTOR_BLOCK (bv, i); - for (j = 0; j < BLOCK_NSYMS (b); j++) - { - QUIT; - sym = BLOCK_SYM (b, j); - if (regexp) { -#ifdef REGCMP - if (!regex(val, SYMBOL_NAME (sym))) - continue; -#else - if (!re_exec (SYMBOL_NAME (sym))) - continue; -#endif - } - if ((class == 0 && SYMBOL_CLASS (sym) != LOC_TYPEDEF - && SYMBOL_CLASS (sym) != LOC_BLOCK) - || (class == 1 && SYMBOL_CLASS (sym) == LOC_BLOCK) - || (class == 2 && SYMBOL_CLASS (sym) == LOC_TYPEDEF)) - { - if (!found_in_file) - { - printf ("\nFile %s:\n", s->filename); - print_count += 2; - } - found_in_file = 1; - MORE; - if (class != 2 && i == 1) - printf ("static "); - if (class == 2 - && SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE) - printf ("typedef "); - - type_print (SYMBOL_TYPE (sym), - (SYMBOL_CLASS (sym) == LOC_TYPEDEF - ? "" : SYMBOL_NAME (sym)), - stdout, 0); - if (class == 2 - && SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE - && (TYPE_NAME ((SYMBOL_TYPE (sym))) == 0 - || 0 != strcmp (TYPE_NAME ((SYMBOL_TYPE (sym))), - SYMBOL_NAME (sym)))) - printf (" %s", SYMBOL_NAME (sym)); - printf (";\n"); - } - } - } - prev_bv = bv; - } -#ifdef REGCMP - if (val) - (void)free(val); -#endif -} - -static void -variables_info (regexp) - char *regexp; -{ - list_symbols (regexp, 0); -} - -static void -functions_info (regexp) - char *regexp; -{ - list_symbols (regexp, 1); -} - -static void -types_info (regexp) - char *regexp; -{ - list_symbols (regexp, 2); -} - -/* Initialize the standard C scalar types. */ - -static -struct type * -init_type (code, length, uns, name) - enum type_code code; - int length, uns; - char *name; -{ - register struct type *type; - - type = (struct type *) xmalloc (sizeof (struct type)); - bzero (type, sizeof *type); - TYPE_CODE (type) = code; - TYPE_LENGTH (type) = length; - TYPE_FLAGS (type) = uns ? TYPE_FLAG_UNSIGNED : 0; - TYPE_FLAGS (type) |= TYPE_FLAG_PERM; - TYPE_NFIELDS (type) = 0; - TYPE_NAME (type) = name; - - return type; -} - -static -initialize () -{ - add_info ("variables", variables_info, - "All global and static variable names, or those matching REGEXP."); - add_info ("functions", functions_info, - "All function names, or those matching REGEXP."); - add_info ("types", types_info, - "All types names, or those matching REGEXP."); - add_info ("sources", sources_info, - "Source files in the program."); - - obstack_init (symbol_obstack); - - builtin_type_void = init_type (TYPE_CODE_VOID, 0, 0, "void"); - - builtin_type_float = init_type (TYPE_CODE_FLT, sizeof (float), 0, "float"); - builtin_type_double = init_type (TYPE_CODE_FLT, sizeof (double), 0, "double"); - - builtin_type_char = init_type (TYPE_CODE_INT, sizeof (char), 0, "char"); - builtin_type_short = init_type (TYPE_CODE_INT, sizeof (short), 0, "short"); - builtin_type_long = init_type (TYPE_CODE_INT, sizeof (long), 0, "long"); - builtin_type_int = init_type (TYPE_CODE_INT, sizeof (int), 0, "int"); - - builtin_type_unsigned_char = init_type (TYPE_CODE_INT, sizeof (char), 1, "unsigned char"); - builtin_type_unsigned_short = init_type (TYPE_CODE_INT, sizeof (short), 1, "unsigned short"); - builtin_type_unsigned_long = init_type (TYPE_CODE_INT, sizeof (long), 1, "unsigned long"); - builtin_type_unsigned_int = init_type (TYPE_CODE_INT, sizeof (int), 1, "unsigned int"); -} - -END_FILE -@ - - -1.1 -log -@Initial revision -@ -text -@d29 4 -d933 1 -a933 1 - char *val; -d938 3 -d942 6 -a947 1 - if (regexp) -d950 2 -d976 10 -a985 2 - if ((regexp == 0 || re_exec (SYMBOL_NAME (sym))) - && ((class == 0 && SYMBOL_CLASS (sym) != LOC_TYPEDEF -d988 1 -a988 1 - || (class == 2 && SYMBOL_CLASS (sym) == LOC_TYPEDEF))) -d1019 4 -@ diff --git a/gdb/RCS/utils.c,v b/gdb/RCS/utils.c,v deleted file mode 100644 index 3f7a836..0000000 --- a/gdb/RCS/utils.c,v +++ /dev/null @@ -1,461 +0,0 @@ -head 1.2; -access ; -symbols RMS-has:1.2; -locks ; strict; -comment @ * @; - - -1.2 -date 88.01.26.05.11.12; author gnu; state Exp; -branches ; -next 1.1; - -1.1 -date 88.01.21.05.11.11; author gnu; state Exp; -branches ; -next ; - - -desc -@From RMS's development sources on wheaties, 20Jan88 -@ - - -1.2 -log -@Avoid using TIOCFLUSH if it is not defined. -@ -text -@/* General utility routines for GDB, the GNU debugger. - Copyright (C) 1986 Free Software Foundation, Inc. - -GDB is distributed in the hope that it will be useful, but WITHOUT ANY -WARRANTY. No author or distributor accepts responsibility to anyone -for the consequences of using it or for whether it serves any -particular purpose or works at all, unless he says so in writing. -Refer to the GDB General Public License for full details. - -Everyone is granted permission to copy, modify and redistribute GDB, -but only under the conditions described in the GDB General Public -License. A copy of this license is supposed to have been given to you -along with GDB so you can know your rights and responsibilities. It -should be in a file named COPYING. Among other things, the copyright -notice and this notice must be preserved on all copies. - -In other words, go ahead and share GDB, but don't try to stop -anyone else from sharing it farther. Help stamp out software hoarding! -*/ - -#include <stdio.h> -#include <sys/ioctl.h> -#include "defs.h" - -void error (); -void fatal (); - -/* Chain of cleanup actions established with make_cleanup, - to be executed if an error happens. */ - -static struct cleanup *cleanup_chain; - -/* Nonzero means a quit has been requested. */ - -int quit_flag; - -/* Nonzero means quit immediately if Control-C is typed now, - rather than waiting until QUIT is executed. */ - -int immediate_quit; - -/* Add a new cleanup to the cleanup_chain, - and return the previous chain pointer - to be passed later to do_cleanups or discard_cleanups. - Args are FUNCTION to clean up with, and ARG to pass to it. */ - -struct cleanup * -make_cleanup (function, arg) - void (*function) (); - int arg; -{ - register struct cleanup *new - = (struct cleanup *) xmalloc (sizeof (struct cleanup)); - register struct cleanup *old_chain = cleanup_chain; - - new->next = cleanup_chain; - new->function = function; - new->arg = arg; - cleanup_chain = new; - - return old_chain; -} - -/* Discard cleanups and do the actions they describe - until we get back to the point OLD_CHAIN in the cleanup_chain. */ - -void -do_cleanups (old_chain) - register struct cleanup *old_chain; -{ - register struct cleanup *ptr; - while ((ptr = cleanup_chain) != old_chain) - { - (*ptr->function) (ptr->arg); - cleanup_chain = ptr->next; - free (ptr); - } -} - -/* Discard cleanups, not doing the actions they describe, - until we get back to the point OLD_CHAIN in the cleanup_chain. */ - -void -discard_cleanups (old_chain) - register struct cleanup *old_chain; -{ - register struct cleanup *ptr; - while ((ptr = cleanup_chain) != old_chain) - { - cleanup_chain = ptr->next; - free (ptr); - } -} - -/* This function is useful for cleanups. - Do - - foo = xmalloc (...); - old_chain = make_cleanup (free_current_contents, &foo); - - to arrange to free the object thus allocated. */ - -void -free_current_contents (location) - char **location; -{ - free (*location); -} - -/* Generally useful subroutines used throughout the program. */ - -/* Like malloc but get error if no storage available. */ - -char * -xmalloc (size) - long size; -{ - register char *val = (char *) malloc (size); - if (!val) - fatal ("virtual memory exhausted.", 0); - return val; -} - -/* Like realloc but get error if no storage available. */ - -char * -xrealloc (ptr, size) - char *ptr; - long size; -{ - register char *val = (char *) realloc (ptr, size); - if (!val) - fatal ("virtual memory exhausted.", 0); - return val; -} - -/* Print the system error message for errno, and also mention STRING - as the file name for which the error was encountered. - Then return to command level. */ - -void -perror_with_name (string) - char *string; -{ - extern int sys_nerr; - extern char *sys_errlist[]; - extern int errno; - char *err; - char *combined; - - if (errno < sys_nerr) - err = sys_errlist[errno]; - else - err = "unknown error"; - - combined = (char *) alloca (strlen (err) + strlen (string) + 3); - strcpy (combined, string); - strcat (combined, ": "); - strcat (combined, err); - - error ("%s.", combined); -} - -/* Print the system error message for ERRCODE, and also mention STRING - as the file name for which the error was encountered. */ - -void -print_sys_errmsg (string, errcode) - char *string; - int errcode; -{ - extern int sys_nerr; - extern char *sys_errlist[]; - char *err; - char *combined; - - if (errcode < sys_nerr) - err = sys_errlist[errcode]; - else - err = "unknown error"; - - combined = (char *) alloca (strlen (err) + strlen (string) + 3); - strcpy (combined, string); - strcat (combined, ": "); - strcat (combined, err); - - printf ("%s.\n", combined); -} - -void -quit () -{ - fflush (stdout); -#ifdef TIOCFLUSH - ioctl (fileno (stdout), TIOCFLUSH, 0); -#endif - error ("Quit"); -} - -/* Control C comes here */ - -void -request_quit () -{ - quit_flag = 1; - if (immediate_quit) - quit (); -} - -/* Print an error message and return to command level. - STRING is the error message, used as a fprintf string, - and ARG is passed as an argument to it. */ - -void -error (string, arg1, arg2, arg3) - char *string; - int arg1, arg2, arg3; -{ - fflush (stdout); - fprintf (stderr, string, arg1, arg2, arg3); - fprintf (stderr, "\n"); - return_to_top_level (); -} - -/* Print an error message and exit reporting failure. - This is for a error that we cannot continue from. - STRING and ARG are passed to fprintf. */ - -void -fatal (string, arg) - char *string; - int arg; -{ - fprintf (stderr, "gdb: "); - fprintf (stderr, string, arg); - fprintf (stderr, "\n"); - exit (1); -} - -/* Make a copy of the string at PTR with SIZE characters - (and add a null character at the end in the copy). - Uses malloc to get the space. Returns the address of the copy. */ - -char * -savestring (ptr, size) - char *ptr; - int size; -{ - register char *p = (char *) xmalloc (size + 1); - bcopy (ptr, p, size); - p[size] = 0; - return p; -} - -char * -concat (s1, s2, s3) - char *s1, *s2, *s3; -{ - register int len = strlen (s1) + strlen (s2) + strlen (s3) + 1; - register char *val = (char *) xmalloc (len); - strcpy (val, s1); - strcat (val, s2); - strcat (val, s3); - return val; -} - -void -print_spaces (n, file) - register int n; - register FILE *file; -{ - while (n-- > 0) - fputc (' ', file); -} - -/* Ask user a y-or-n question and return 1 iff answer is yes. - Takes three args which are given to printf to print the question. - The first, a control string, should end in "? ". - It should not say how to answer, because we do that. */ - -int -query (ctlstr, arg1, arg2) - char *ctlstr; -{ - register int answer; - - /* Automatically answer "yes" if input is not from a terminal. */ - if (!input_from_terminal_p ()) - return 1; - - while (1) - { - printf (ctlstr, arg1, arg2); - printf ("(y or n) "); - fflush (stdout); - answer = fgetc (stdin); - clearerr (stdin); /* in case of C-d */ - if (answer != '\n') - while (fgetc (stdin) != '\n') clearerr (stdin); - if (answer >= 'a') - answer -= 040; - if (answer == 'Y') - return 1; - if (answer == 'N') - return 0; - printf ("Please answer y or n.\n"); - } -} - -/* Parse a C escape sequence. STRING_PTR points to a variable - containing a pointer to the string to parse. That pointer - is updated past the characters we use. The value of the - escape sequence is returned. - - A negative value means the sequence \ newline was seen, - which is supposed to be equivalent to nothing at all. - - If \ is followed by a null character, we return a negative - value and leave the string pointer pointing at the null character. - - If \ is followed by 000, we return 0 and leave the string pointer - after the zeros. A value of 0 does not mean end of string. */ - -int -parse_escape (string_ptr) - char **string_ptr; -{ - register int c = *(*string_ptr)++; - switch (c) - { - case 'a': - return '\a'; - case 'b': - return '\b'; - case 'e': - return 033; - case 'f': - return '\f'; - case 'n': - return '\n'; - case 'r': - return '\r'; - case 't': - return '\t'; - case 'v': - return '\v'; - case '\n': - return -2; - case 0: - (*string_ptr)--; - return 0; - case '^': - c = *(*string_ptr)++; - if (c == '\\') - c = parse_escape (string_ptr); - if (c == '?') - return 0177; - return (c & 0200) | (c & 037); - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - { - register int i = c - '0'; - register int count = 0; - while (++count < 3) - { - if ((c = *(*string_ptr)++) >= '0' && c <= '7') - { - i *= 8; - i += c - '0'; - } - else - { - (*string_ptr)--; - break; - } - } - return i; - } - default: - return c; - } -} - -void -printchar (ch, stream) - unsigned char ch; - FILE *stream; -{ - register int c = ch; - if (c < 040 || c >= 0177) - { - if (c == '\n') - fprintf (stream, "\\n"); - else if (c == '\b') - fprintf (stream, "\\b"); - else if (c == '\t') - fprintf (stream, "\\t"); - else if (c == '\f') - fprintf (stream, "\\f"); - else if (c == '\r') - fprintf (stream, "\\r"); - else if (c == 033) - fprintf (stream, "\\e"); - else if (c == '\a') - fprintf (stream, "\\a"); - else - fprintf (stream, "\\%03o", c); - } - else - { - if (c == '\\' || c == '"' || c == '\'') - fputc ('\\', stream); - fputc (c, stream); - } -} -@ - - -1.1 -log -@Initial revision -@ -text -@d194 1 -d196 1 -@ |