diff options
author | gdb-2.5.1 <gdb@fsf.org> | 1988-05-02 01:00:00 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2012-06-03 15:36:30 +0100 |
commit | 632ea0ccc5c4c3f9fc06881bfedfc4b075873941 (patch) | |
tree | 96f152433c41c5f51fe57307b287eb85865a43e2 | |
parent | 7b4ac7e1ed2c4616bce56d1760807798be87ac9e (diff) | |
download | gdb-632ea0ccc5c4c3f9fc06881bfedfc4b075873941.zip gdb-632ea0ccc5c4c3f9fc06881bfedfc4b075873941.tar.gz gdb-632ea0ccc5c4c3f9fc06881bfedfc4b075873941.tar.bz2 |
gdb-2.5.1
-rw-r--r-- | gdb/=emacs | 108 | ||||
-rw-r--r-- | gdb/=news | 136 | ||||
-rw-r--r-- | gdb/=ns32k.msg | 1182 | ||||
-rw-r--r-- | gdb/=rt-ans2 | 103 | ||||
-rw-r--r-- | gdb/=rt-answers | 147 | ||||
-rw-r--r-- | gdb/=rt-changes | 3338 | ||||
-rw-r--r-- | gdb/=rt-extra | 84 | ||||
-rw-r--r-- | gdb/=xgdb.msg | 997 | ||||
-rw-r--r-- | gdb/COPYING | 138 | ||||
-rw-r--r-- | gdb/ChangeLog | 1025 | ||||
-rw-r--r-- | gdb/Makefile | 28 | ||||
-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 | ||||
-rw-r--r-- | gdb/README | 29 | ||||
-rw-r--r-- | gdb/TAGS | 852 | ||||
-rw-r--r-- | gdb/alloca.c | 191 | ||||
-rw-r--r-- | gdb/bar.c | 13 | ||||
-rw-r--r-- | gdb/bar.nm | 65 | ||||
-rw-r--r-- | gdb/bar.s | 93 | ||||
-rw-r--r-- | gdb/bar.sym | 51 | ||||
-rw-r--r-- | gdb/blockframe.c | 34 | ||||
-rw-r--r-- | gdb/breakpoint.c | 187 | ||||
-rw-r--r-- | gdb/coffread.c | 59 | ||||
-rw-r--r-- | gdb/command.c | 50 | ||||
-rw-r--r-- | gdb/command.h | 50 | ||||
-rw-r--r-- | gdb/core.c | 55 | ||||
-rw-r--r-- | gdb/dbxread.c | 817 | ||||
-rw-r--r-- | gdb/defs.h | 4 | ||||
-rw-r--r-- | gdb/environ.c | 50 | ||||
-rw-r--r-- | gdb/eval.c | 234 | ||||
-rw-r--r-- | gdb/expprint.c | 16 | ||||
-rw-r--r-- | gdb/expread.tab.c | 2114 | ||||
-rw-r--r-- | gdb/expread.y | 235 | ||||
-rw-r--r-- | gdb/expression.h | 23 | ||||
-rw-r--r-- | gdb/findvar.c | 4 | ||||
-rw-r--r-- | gdb/firstfile.c | 50 | ||||
-rw-r--r-- | gdb/foo.c | 13 | ||||
-rw-r--r-- | gdb/foo.nm | 39 | ||||
-rw-r--r-- | gdb/foo.od | 213 | ||||
-rw-r--r-- | gdb/foo.s | 65 | ||||
-rw-r--r-- | gdb/foo.sym | 114 | ||||
-rw-r--r-- | gdb/gdb+.texinfo | 2788 | ||||
-rw-r--r-- | gdb/gdb.1 | 91 | ||||
-rw-r--r-- | gdb/gdb.ideas | 694 | ||||
-rw-r--r-- | gdb/infcmd.c | 112 | ||||
-rw-r--r-- | gdb/inferior.h | 4 | ||||
-rw-r--r-- | gdb/inflow.c | 196 | ||||
-rw-r--r-- | gdb/infrun.c | 50 | ||||
-rw-r--r-- | gdb/initialize.h | 50 | ||||
-rw-r--r-- | gdb/m-mac-aux.h | 485 | ||||
-rw-r--r-- | gdb/m-mac-auxinit.h | 5 | ||||
-rw-r--r-- | gdb/m-merlin.h | 437 | ||||
-rw-r--r-- | gdb/m-news800.h | 566 | ||||
-rw-r--r-- | gdb/m-newsinit.h | 4 | ||||
-rw-r--r-- | gdb/m-sun3.h | 2 | ||||
-rw-r--r-- | gdb/m-suninit.h | 2 | ||||
-rw-r--r-- | gdb/m-umax.h | 425 | ||||
-rw-r--r-- | gdb/m68k-pinsn.c | 44 | ||||
-rw-r--r-- | gdb/main.c | 96 | ||||
-rw-r--r-- | gdb/ns32k-opcode.h | 307 | ||||
-rw-r--r-- | gdb/ns32k-pinsn.c | 437 | ||||
-rw-r--r--[l---------] | gdb/obstack.c | 325 | ||||
-rw-r--r--[l---------] | gdb/obstack.h | 444 | ||||
-rw-r--r-- | gdb/param.h | 2 | ||||
-rw-r--r-- | gdb/parent.c | 126 | ||||
-rw-r--r-- | gdb/printcmd.c | 388 | ||||
-rw-r--r-- | gdb/remote.c | 607 | ||||
-rw-r--r-- | gdb/song | 44 | ||||
-rw-r--r-- | gdb/source.c | 247 | ||||
-rw-r--r-- | gdb/stack.c | 11 | ||||
-rw-r--r-- | gdb/symmisc.c | 80 | ||||
-rw-r--r-- | gdb/symseg.h | 126 | ||||
-rw-r--r-- | gdb/symtab.c | 711 | ||||
-rw-r--r-- | gdb/symtab.h | 99 | ||||
-rw-r--r-- | gdb/test2.c | 13 | ||||
-rw-r--r-- | gdb/test3.c | 25 | ||||
-rw-r--r-- | gdb/testattach.c | 10 | ||||
-rw-r--r-- | gdb/testbf.c | 13 | ||||
-rw-r--r-- | gdb/testenum.c | 25 | ||||
-rw-r--r-- | gdb/testfb.c | 12 | ||||
-rw-r--r-- | gdb/testshort.c | 16 | ||||
-rw-r--r-- | gdb/testsig.c | 17 | ||||
-rw-r--r-- | gdb/utils.c (renamed from gdb/utils.c.OK) | 2 | ||||
-rw-r--r-- | gdb/valops.c | 452 | ||||
-rw-r--r-- | gdb/valprint.c | 324 | ||||
-rw-r--r-- | gdb/value.h | 7 | ||||
-rw-r--r-- | gdb/values.c | 108 | ||||
-rw-r--r-- | gdb/version.c | 2 |
99 files changed, 10552 insertions, 21807 deletions
diff --git a/gdb/=emacs b/gdb/=emacs deleted file mode 100644 index 74097b7..0000000 --- a/gdb/=emacs +++ /dev/null @@ -1,108 +0,0 @@ -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; gdb code changes -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -/* - * Core Problem: when gdb says something like (../src/file.c 1234), the - * real file might be in any of the active dirs in use by gdb and thus - * emacs can not always find the file at "../src". Emacs cannot just - * scan for GDB dir commands because these might be given in the .gdbinit - * file or other scripts. The only solution is to have gdb be a bit more - * specific when it prints file names. - * - * Remaining defects: - * - * 1. Do I really have to open the file to find out if it exists? - * There should be a faster way. - * - * 2. Should there be a bdb command to toggle between short and absolute - * forms of the file name? - */ - - -/* Add this to ~emacs/gdb/source.c after the openp function */ - -char * -get_absolute_filename(table) -/* Added by Lynn Slater, Silvar-Lisco 10/6/87 - returns the address of the best possible name to use for the file - in the passed symtab. Returns the filename if the path cannot be - resolved. - Please remember to free the absolute name after use.*/ -struct symtab *table; -{ - register int desc; - char *absolute_name; - - desc = openp (source_path, 0, table->filename, O_RDONLY, 0, &absolute_name); - if (desc < 0) - return( savestring(table->filename, strlen(table->filename))); - - close (desc); - return(absolute_name); -} - -/* Replace this fcn in ~emacs/gdb/stack.c */ -void -print_frame_info (fi, level, source, args) - struct frame_info *fi; - register int level; - int source; - int args; -{ - register FRAME frame = fi->frame; - struct symtab_and_line sal; - struct symbol *func; - register char *funname = 0; - int numargs; - - sal = find_pc_line (fi->pc, fi->next_frame); - func = get_frame_function (frame); - if (func) - funname = SYMBOL_NAME (func); - else - { - register int misc_index = find_pc_misc_function (fi->pc); - if (misc_index >= 0) - funname = misc_function_vector[misc_index].name; - } - - if (source >= 0 || !sal.symtab) - { - /* This avoids a bug in cc on the sun. */ - struct frame_info tem; - tem = *fi; - - if (level >= 0) - printf ("#%-2d ", level); - if (fi->pc != sal.pc || !sal.symtab) - printf ("0x%x in ", fi->pc); - printf ("%s (", funname ? funname : "??"); - if (args) - { - FRAME_NUM_ARGS (numargs, tem); - print_frame_args (func, FRAME_ARGS_ADDRESS (tem), numargs, stdout); - } - printf (")"); - if (sal.symtab) - { - char * absolute_filename; - absolute_filename = (char *) get_absolute_filename(sal.symtab); - printf (" (%s line %d)", absolute_filename, sal.line); - free(absolute_filename); - } - printf ("\n"); - } - - if (source != 0 && sal.symtab) - { - if (source < 0 && fi->pc != sal.pc) - printf ("0x%x\t", fi->pc); - print_source_lines (sal.symtab, sal.line, sal.line + 1); - current_source_line = max (sal.line - 5, 1); - } - if (source != 0) - set_default_breakpoint (1, fi->pc, sal.symtab, sal.line); - - fflush (stdout); -} - diff --git a/gdb/=news b/gdb/=news deleted file mode 100644 index 43de9bc..0000000 --- a/gdb/=news +++ /dev/null @@ -1,136 +0,0 @@ -=================================================================== -RCS file: RCS/printcmd.c,v -retrieving revision 1.1 -diff -c3 -r1.1 printcmd.c -*** /tmp/,RCSt1011248 Tue Jan 12 14:06:06 1988 ---- printcmd.c Mon Sep 21 21:33:39 1987 -*************** -*** 174,179 - VALUE_TYPE (val) = builtin_type_float; - if (TYPE_LENGTH (VALUE_TYPE (val)) == sizeof (double)) - VALUE_TYPE (val) = builtin_type_double; - printf ("%g", value_as_double (val)); - break; - - ---- 174,185 ----- - VALUE_TYPE (val) = builtin_type_float; - if (TYPE_LENGTH (VALUE_TYPE (val)) == sizeof (double)) - VALUE_TYPE (val) = builtin_type_double; -+ #ifdef PRINTF_BUG -+ if (is_nan(value_as_double (val))) -+ printf ("Nan"); -+ else -+ printf ("%g", value_as_double (val)); -+ #else - printf ("%g", value_as_double (val)); - #endif - break; -*************** -*** 175,180 - if (TYPE_LENGTH (VALUE_TYPE (val)) == sizeof (double)) - VALUE_TYPE (val) = builtin_type_double; - printf ("%g", value_as_double (val)); - break; - - case 0: - ---- 181,187 ----- - printf ("%g", value_as_double (val)); - #else - printf ("%g", value_as_double (val)); -+ #endif - break; - - case 0: -=================================================================== -RCS file: RCS/valprint.c,v -retrieving revision 1.1 -diff -c3 -r1.1 valprint.c -*** /tmp/,RCSt1011248 Tue Jan 12 14:06:09 1988 ---- valprint.c Mon Sep 21 21:35:45 1987 -*************** -*** 21,26 - #include <stdio.h> - #include "defs.h" - #include "initialize.h" - #include "symtab.h" - #include "value.h" - - ---- 21,27 ----- - #include <stdio.h> - #include "defs.h" - #include "initialize.h" -+ #include "param.h" - #include "symtab.h" - #include "value.h" - -*************** -*** 249,255 - break; - - case TYPE_CODE_FLT: -! fprintf (stream, "%g", unpack_double (type, valaddr)); - break; - - case TYPE_CODE_VOID: - ---- 250,265 ----- - break; - - case TYPE_CODE_FLT: -! { double d = unpack_double (type, valaddr); -! #ifdef PRINTF_BUG -! if (is_nan(d)) -! fprintf (stream, "Nan"); -! else -! fprintf (stream, "%g", d); -! #else -! fprintf (stream, "%g", d); -! #endif -! } - break; - - case TYPE_CODE_VOID: -*************** -*** 559,563 - float_type_table[sizeof (float)] = "float"; - float_type_table[sizeof (double)] = "double"; - } - - END_FILE - ---- 569,599 ----- - float_type_table[sizeof (float)] = "float"; - float_type_table[sizeof (double)] = "double"; - } -+ -+ -+ #ifdef PRINTF_BUG -+ -+ struct ieee { /* IEEE floating format */ -+ unsigned int s:1; -+ unsigned int e:11; -+ unsigned int f1:20; -+ unsigned int f2; -+ }; -+ -+ #define ZERO_F(x) ((x.f1 == 0) && (x.f2 == 0)) /* zero fraction ? */ -+ #define ZERO_E(x) (x.e == 0) /* zero exponential ? */ -+ #define MAX_E(x) (x.e == 0x7ff) /* max exponential ? */ -+ #define MINUS_S(x) (x.s == 1) /* minus ? */ -+ -+ int -+ is_nan(arg) /* Not a Number ? */ -+ struct ieee arg; -+ { -+ if (MAX_E(arg) && !ZERO_F(arg)) -+ return (1); -+ else -+ return (0); -+ } -+ #endif - - END_FILE - diff --git a/gdb/=ns32k.msg b/gdb/=ns32k.msg deleted file mode 100644 index 5268fc7..0000000 --- a/gdb/=ns32k.msg +++ /dev/null @@ -1,1182 +0,0 @@ -From uwvax!sequent!ogcvax!reed!keith@RUTGERS.EDU Thu Jul 23 21:46:44 1987 -Received: by PREP.AI.MIT.EDU; Thu, 23 Jul 87 21:44:35 EDT -Received: by RUTGERS.EDU (5.54/1.14) with UUCP - id AA04584; Thu, 23 Jul 87 21:42:33 EDT -Received: from sequent.UUCP by spool.WISC.EDU; Thu, 23 Jul 87 20:36:20 CDT -Received: from reed.UUCP by ogcvax.OGC.EDU (5.51/OGC_4.6+) - id AA05332; Thu, 23 Jul 87 13:31:52 PDT -Received: by reed.UUCP (5.51/5.17) - id AA23265; Thu, 23 Jul 87 11:19:20 PDT -From: uwvax!sequent!ogcvax!reed!keith@RUTGERS.EDU (Keith Packard) -Message-Id: <8707231819.AA23265@reed.UUCP> -To: phr@prep.ai.mit.edu (Paul Rubin) -Subject: Re: gdb -In-Reply-To: Your message of Thu, 23 Jul 87 02:06:52 EDT. - <8707230603.AA11722@EDDIE.MIT.EDU> -Date: Thu, 23 Jul 87 11:19:13 PDT -Status: R - - -Thanks much for the address -- the 2.1 sources that I have do not contain -any bug reporting address. The only real bug that I found was in -write_register_bytes in findvar.c: - -was: - - bcopy (myaddr, ®isters[regbyte], len); - if (have_inferior_p ()) - store_inferior_registers (0); - -should be: - - bcopy (myaddr, ®isters[regbyte], len); - if (have_inferior_p ()) - store_inferior_registers (-1); - -Other than that, most of the porting effort to the 32k was in removing -references to alloca - the 32k is adamant about not using alloca -- in fact -someone at tektronix wrote a replacement which accepted another argument -pointing to the function entry instruction so that the stack could be maimed -mercilessly... I just replaced them all with malloc and used free at -judicious times. It's not perfect but it worked fine. - -I would upload gdb 2.3 if I could, however I am not on the arpa net. I'll -probably end up sending GNU a tape. - -It's a great debugger, thanks! - - keith packard - tektronix!reed!keith - -Here are the param files and instruction printer for the 32032: - -#!/bin/sh -# shar: Shell Archiver -# Run the following text with /bin/sh to create: -# m-merlin.h -# n32k-opcode.h -# n32k-pinsn.c -sed 's/^X//' << 'SHAR_EOF' > m-merlin.h -X/* Definitions to make GDB run on a merlin under utek 2.1 -X Copyright (C) 1986, 1987 Free Software Foundation, Inc. -X -XGDB is distributed in the hope that it will be useful, but WITHOUT ANY -XWARRANTY. No author or distributor accepts responsibility to anyone -Xfor the consequences of using it or for whether it serves any -Xparticular purpose or works at all, unless he says so in writing. -XRefer to the GDB General Public License for full details. -X -XEveryone is granted permission to copy, modify and redistribute GDB, -Xbut only under the conditions described in the GDB General Public -XLicense. A copy of this license is supposed to have been given to you -Xalong with GDB so you can know your rights and responsibilities. It -Xshould be in a file named COPYING. Among other things, the copyright -Xnotice and this notice must be preserved on all copies. -X -XIn other words, go ahead and share GDB, but don't try to stop -Xanyone else from sharing it farther. Help stamp out software hoarding! -X*/ -X -X#ifndef ns16000 -X#define ns16000 -X#endif -X -X# include <machine/reg.h> -X -X/* Define this if the C compiler puts an underscore at the front -X of external names before giving them to the linker. */ -X -X#define NAMES_HAVE_UNDERSCORE -X -X/* Offset from address of function to start of its code. -X Zero on most machines. */ -X -X#define FUNCTION_START_OFFSET 0 -X -X/* Advance PC across any function entry prologue instructions -X to reach some "real" code. */ -X -X#define SKIP_PROLOGUE(pc) \ -X{ register int op = read_memory_integer (pc, 1); \ -X if (op == 0x82) { op = read_memory_integer (pc+2,1); \ -X if ((op & 0x80) == 0) pc += 3; \ -X else if ((op & 0xc0) == 0x80) pc += 4; \ -X else pc += 6; \ -X } \ -X} -X -X/* Immediately after a function call, return the saved pc. -X Can't always go through the frames for this because on some machines -X the new frame is not set up until the new function executes -X some instructions. */ -X -X#define SAVED_PC_AFTER_CALL(frame) \ -X read_memory_integer (read_register (SP_REGNUM), 4) -X -X/* This is the amount to subtract from u.u_ar0 -X to get the offset in the core file of the register values. */ -X -X#define KERNEL_U_ADDR (0xfef000) -X -X/* Address of end of stack space. */ -X -X#define STACK_END_ADDR (0x800000) -X -X/* Stack grows downward. */ -X -X#define INNER_THAN < -X -X/* Sequence of bytes for breakpoint instruction. */ -X -X#define BREAKPOINT {0xf2} -X -X/* Amount PC must be decremented by after a breakpoint. -X This is often the number of bytes in BREAKPOINT -X but not always. */ -X -X#define DECR_PC_AFTER_BREAK 0 -X -X/* Nonzero if instruction at PC is a return instruction. */ -X -X#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0x12) -X -X/* Return 1 if P points to an invalid floating point value. */ -X -X#define INVALID_FLOAT(p) (0) -X -X/* Say how long (ordinary) registers are. */ -X -X#define REGISTER_TYPE long -X -X/* Number of machine registers */ -X -X#define NUM_REGS 25 -X -X#define NUM_GENERAL_REGS 8 -X -X/* Initializer for an array of names of registers. -X There should be NUM_REGS strings in this initializer. */ -X -X#define REGISTER_NAMES {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ -X "pc", "sp", "fp", "ps", \ -X "fsr", \ -X "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ -X "l0", "l1", "l2", "l3", "l4", \ -X } -X -X/* Register numbers of various important registers. -X Note that some of these values are "real" register numbers, -X and correspond to the general registers of the machine, -X and some are "phony" register numbers which are too large -X to be actual register numbers as far as the user is concerned -X but do serve to get the desired values when passed to read_register. */ -X -X#define AP_REGNUM FP_REGNUM -X#define FP_REGNUM 10 /* Contains address of executing stack frame */ -X#define SP_REGNUM 9 /* Contains address of top of stack */ -X#define PC_REGNUM 8 /* Contains program counter */ -X#define PS_REGNUM 11 /* Contains processor status */ -X#define FPS_REGNUM 12 /* Floating point status register */ -X#define FP0_REGNUM 13 /* Floating point register 0 */ -X#define LP0_REGNUM 21 /* Double register 0 (same as FP0) */ -X -X#define REGISTER_U_ADDR(addr, blockend, regno) \ -X{ \ -X switch (regno) { \ -X case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: \ -X addr = blockend + (R0 - regno) * sizeof (int); break; \ -X case PC_REGNUM: \ -X addr = blockend + PC * sizeof (int); break; \ -X case SP_REGNUM: \ -X addr = blockend + SP * sizeof (int); break; \ -X case FP_REGNUM: \ -X addr = blockend + FP * sizeof (int); break; \ -X case PS_REGNUM: \ -X addr = blockend + 12 * sizeof (int); break; \ -X case FPS_REGNUM: \ -X addr = 108; break; \ -X case FP0_REGNUM + 0: case FP0_REGNUM + 1: \ -X case FP0_REGNUM + 2: case FP0_REGNUM + 3: \ -X case FP0_REGNUM + 4: case FP0_REGNUM + 5: \ -X case FP0_REGNUM + 6: case FP0_REGNUM + 7: \ -X addr = 76 + (regno - FP0_REGNUM) * sizeof (float); break; \ -X case LP0_REGNUM + 0: case LP0_REGNUM + 1: \ -X case LP0_REGNUM + 2: case LP0_REGNUM + 3: \ -X addr = 76 + (regno - LP0_REGNUM) * sizeof (double); break; \ -X default: \ -X printf ("bad argument to REGISTER_U_ADDR %d\n", regno); \ -X abort (); \ -X } \ -X} -X -X/* Total amount of space needed to store our copies of the machine's -X register state, the array `registers'. */ -X#define REGISTER_BYTES ((NUM_REGS - 4) * sizeof (int) + 4 * sizeof (double)) -X -X/* Index within `registers' of the first byte of the space for -X register N. */ -X -X#define REGISTER_BYTE(N) ((N) >= LP0_REGNUM ? \ -X LP0_REGNUM * 4 + ((N) - LP0_REGNUM) * 8 : (N) * 4) -X -X/* Number of bytes of storage in the actual machine representation -X for register N. On the 32000, all regs are 4 bytes -X except for the doubled floating registers. */ -X -X#define REGISTER_RAW_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4) -X -X/* Number of bytes of storage in the program's representation -X for register N. On the 32000, all regs are 4 bytes -X except for the doubled floating registers. */ -X -X#define REGISTER_VIRTUAL_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4) -X -X/* Largest value REGISTER_RAW_SIZE can have. */ -X -X#define MAX_REGISTER_RAW_SIZE 8 -X -X/* Largest value REGISTER_VIRTUAL_SIZE can have. */ -X -X#define MAX_REGISTER_VIRTUAL_SIZE 8 -X -X/* Nonzero if register N requires conversion -X from raw format to virtual format. */ -X -X#define REGISTER_CONVERTIBLE(N) 0 -X -X/* Convert data from raw format for register REGNUM -X to virtual format for register REGNUM. */ -X -X#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \ -X bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM)); -X -X/* Convert data from virtual format for register REGNUM -X to raw format for register REGNUM. */ -X -X#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \ -X bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM)); -X -X/* Return the GDB type object for the "standard" data type -X of data in register N. */ -X -X#define REGISTER_VIRTUAL_TYPE(N) \ -X ((N) >= FP0_REGNUM ? \ -X (N) >= LP0_REGNUM ? \ -X builtin_type_double \ -X : builtin_type_float \ -X : builtin_type_int) -X -X/* Describe the pointer in each stack frame to the previous stack frame -X (its caller). */ -X -X/* FRAME_CHAIN takes a frame's nominal address -X and produces the frame's chain-pointer. -X -X FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address -X and produces the nominal address of the caller frame. -X -X However, if FRAME_CHAIN_VALID returns zero, -X it means the given frame is the outermost one and has no caller. -X In that case, FRAME_CHAIN_COMBINE is not used. */ -X -X/* In the case of the Merlin, the frame's nominal address is the FP value, -X and at that address is saved previous FP value as a 4-byte word. */ -X -X#define FRAME_CHAIN(thisframe) (read_memory_integer (thisframe, 4)) -X -X#define FRAME_CHAIN_VALID(chain, thisframe) \ -X (chain != 0 && (FRAME_SAVED_PC (thisframe) >= first_object_file_end)) -X -X#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain) -X -X/* Define other aspects of the stack frame. */ -X -X#define FRAME_SAVED_PC(frame) (read_memory_integer (frame + 4, 4)) -X -X/* compute base of arguments */ -X#define FRAME_ARGS_ADDRESS(fi) ((fi).frame) -X -X#define FRAME_LOCALS_ADDRESS(fi) ((fi).frame) -X -X/* Return number of args passed to a frame. -X Can return -1, meaning no way to tell. */ -X -X#define FRAME_NUM_ARGS(numargs, fi) \ -X{ CORE_ADDR pc; \ -X int insn; \ -X int addr_mode; \ -X int width; \ -X \ -X pc = FRAME_SAVED_PC (fi.frame); \ -X insn = read_memory_integer (pc,2); \ -X addr_mode = (insn >> 11) & 0x1f; \ -X insn = insn & 0x7ff; \ -X if ((insn & 0x7fc) == 0x57c && \ -X addr_mode == 0x14) { /* immediate */ \ -X if (insn == 0x57c) /* adjspb */ \ -X width = 1; \ -X else if (insn == 0x57d) /* adjspw */ \ -X width = 2; \ -X else if (insn == 0x57f) /* adjspd */ \ -X width = 4; \ -X numargs = read_memory_integer (pc+2,width); \ -X if (width > 1) \ -X flip_bytes (&numargs, width); \ -X numargs = - sign_extend (numargs, width*8) / 4; \ -X } else { \ -X numargs = -1; \ -X } \ -X} -X -X/* Return number of bytes at start of arglist that are not really args. */ -X -X#define FRAME_ARGS_SKIP 8 -X -X/* Put here the code to store, into a struct frame_saved_regs, -X the addresses of the saved registers of frame described by FRAME_INFO. -X This includes special registers such as pc and fp saved in special -X ways in the stack frame. sp is even more special: -X the address we return for it IS the sp for the next frame. */ -X -X#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \ -X{ \ -X int regmask,regnum; \ -X int localcount; \ -X CORE_ADDR enter_addr; \ -X CORE_ADDR next_addr; \ -X \ -X enter_addr = get_pc_function_start ((frame_info).pc); \ -X regmask = read_memory_integer (enter_addr+1, 1); \ -X localcount = n32k_localcount (enter_addr); \ -X next_addr = (frame_info).frame + localcount; \ -X for (regnum = 0; regnum < 8; regnum++, regmask >>= 1) \ -X (frame_saved_regs).regs[regnum] = (regmask & 1) ? \ -X (next_addr -= 4) : 0; \ -X (frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 4; \ -X (frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4; \ -X (frame_saved_regs).regs[FP_REGNUM] = (read_memory_integer \ -X ((frame_info).frame, 4)); \ -X} -X -X/* Things needed for making the inferior call functions. */ -X -X/* Push an empty stack frame, to record the current PC, etc. */ -X -X#define PUSH_DUMMY_FRAME \ -X{ register CORE_ADDR sp = read_register (SP_REGNUM);\ -X register int regnum; \ -X sp = push_word (sp, read_register (PC_REGNUM)); \ -X sp = push_word (sp, read_register (FP_REGNUM)); \ -X write_register (FP_REGNUM, sp); \ -X for (regnum = 0; regnum < 8; regnum++) \ -X sp = push_word (sp, read_register (regnum)); \ -X write_register (SP_REGNUM, sp); \ -X} -X -X/* Discard from the stack the innermost frame, restoring all registers. */ -X -X#define POP_FRAME \ -X{ register CORE_ADDR fp = read_register (FP_REGNUM); \ -X register int regnum; \ -X struct frame_saved_regs fsr; \ -X struct frame_info fi; \ -X fi = get_frame_info (fp); \ -X get_frame_saved_regs (&fi, &fsr); \ -X for (regnum = 0; regnum < 8; regnum++) \ -X if (fsr.regs[regnum]) \ -X write_register (regnum, read_memory_integer (fsr.regs[regnum], 4)); \ -X write_register (FP_REGNUM, read_memory_integer (fp, 4)); \ -X write_register (PC_REGNUM, read_memory_integer (fp + 4, 4)); \ -X write_register (SP_REGNUM, fp + 8); \ -X} -X -X/* This sequence of words is the instructions -X enter 0xff,0 82 ff 00 -X jsr @0x00010203 7f ae c0 01 02 03 -X adjspd 0x69696969 7f a5 01 02 03 04 -X bpt f2 -X Note this is 16 bytes. */ -X -X#define CALL_DUMMY { 0x7f00ff82, 0x0201c0ae, 0x01a57f03, 0xf2040302 } -X -X#define CALL_DUMMY_START_OFFSET 3 -X#define CALL_DUMMY_LENGTH 16 -X#define CALL_DUMMY_ADDR 5 -X#define CALL_DUMMY_NARGS 11 -X -X/* Insert the specified number of args and function address -X into a call sequence of the above form stored at DUMMYNAME. */ -X -X#define FIX_CALL_DUMMY(dummyname, fun, nargs) \ -X{ \ -X int flipped; \ -X flipped = fun | 0xc0000000; \ -X flip_bytes (&flipped, 4); \ -X *((int *) (((char *) dummyname)+CALL_DUMMY_ADDR)) = flipped; \ -X flipped = - nargs * 4; \ -X flip_bytes (&flipped, 4); \ -X *((int *) (((char *) dummyname)+CALL_DUMMY_NARGS)) = flipped; \ -X} -X -X#ifdef notdef -X/* Interface definitions for kernel debugger KDB. */ -X -X/* Map machine fault codes into signal numbers. -X First subtract 0, divide by 4, then index in a table. -X Faults for which the entry in this table is 0 -X are not handled by KDB; the program's own trap handler -X gets to handle then. */ -X -X#define FAULT_CODE_ORIGIN 0 -X#define FAULT_CODE_UNITS 4 -X#define FAULT_TABLE \ -X{ 0, SIGKILL, SIGSEGV, 0, 0, 0, 0, 0, \ -X 0, 0, SIGTRAP, SIGTRAP, 0, 0, 0, 0, \ -X 0, 0, 0, 0, 0, 0, 0, 0} -X -X/* Start running with a stack stretching from BEG to END. -X BEG and END should be symbols meaningful to the assembler. -X This is used only for kdb. */ -X -X#define INIT_STACK(beg, end) \ -X{ asm (".globl end"); \ -X asm ("movl $ end, sp"); \ -X asm ("clrl fp"); } -X -X/* Push the frame pointer register on the stack. */ -X#define PUSH_FRAME_PTR \ -X asm ("pushl fp"); -X -X/* Copy the top-of-stack to the frame pointer register. */ -X#define POP_FRAME_PTR \ -X asm ("movl (sp), fp"); -X -X/* After KDB is entered by a fault, push all registers -X that GDB thinks about (all NUM_REGS of them), -X so that they appear in order of ascending GDB register number. -X The fault code will be on the stack beyond the last register. */ -X -X#define PUSH_REGISTERS \ -X{ asm ("pushl 8(sp)"); \ -X asm ("pushl 8(sp)"); \ -X asm ("pushal 0x14(sp)"); \ -X asm ("pushr $037777"); } -X -X/* Assuming the registers (including processor status) have been -X pushed on the stack in order of ascending GDB register number, -X restore them and return to the address in the saved PC register. */ -X -X#define POP_REGISTERS \ -X{ asm ("popr $037777"); \ -X asm ("subl2 $8,(sp)"); \ -X asm ("movl (sp),sp"); \ -X asm ("rei"); } -X#endif -SHAR_EOF -sed 's/^X//' << 'SHAR_EOF' > n32k-opcode.h -X/* n32k-opcode.h */ -X -X#ifndef n32k_opcodeT -X#define n32k_opcodeT int -X#endif /* no n32k_opcodeT */ -X -Xstruct not_wot /* n32k opcode table: wot to do with this */ -X /* particular opcode */ -X{ -X int obits; /* number of opcode bits */ -X int ibits; /* number of instruction bits */ -X n32k_opcodeT code; /* op-code (may be > 8 bits!) */ -X char *args; /* how to compile said opcode */ -X}; -X -Xstruct not /* n32k opcode text */ -X{ -X char * name; /* opcode name: lowercase string [key] */ -X struct not_wot detail; /* rest of opcode table [datum] */ -X}; -X -X/* F : 32 bit float -X * L : 64 bit float -X * B : byte -X * W : word -X * D : double-word -X * Q : quad-word -X * d : displacement -X * q : quick -X * i : immediate (8 bits) -X * r : register number (3 bits) -X * p : displacement - pc relative addressing -X*/ -Xstatic struct not -Xnotstrs[] = -X{ -X{ "absf", 14,24, 0x35be, "1F2F" }, -X{ "absl", 14,24, 0x34be, "1L2L" }, -X{ "absb", 14,24, 0x304e, "1B2B" }, -X{ "absw", 14,24, 0x314e, "1W2W" }, -X{ "absd", 14,24, 0x334e, "1D2D" }, -X{ "acbb", 7,16, 0x4c, "2B1q3p" }, -X{ "addf", 14,24, 0x01be, "1F2F" }, -X{ "addl", 14,24, 0x00be, "1L2L" }, -X{ "addb", 6,16, 0x00, "1B2B" }, -X{ "addw", 6,16, 0x01, "1W2W" }, -X{ "addd", 6,16, 0x03, "1D2D" }, -X{ "addcb", 6,16, 0x10, "1B2B" }, -X{ "addcw", 6,16, 0x11, "1W2W" }, -X{ "addcd", 6,16, 0x13, "1D2D" }, -X{ "addpb", 14,24, 0x3c4e, "1B2B" }, -X{ "addpw", 14,24, 0x3d4e, "1W2W" }, -X{ "addpd", 14,24, 0x3f4e, "1D2D" }, -X{ "addqb", 7,16, 0x0c, "2B1q" }, -X{ "addqw", 7,16, 0x0d, "2W1q" }, -X{ "addqd", 7,16, 0x0f, "2D1q" }, -X{ "addr", 6,16, 0x27, "1D2D" }, -X{ "adjspb", 11,16, 0x057c, "1B" }, -X{ "adjspw", 11,16, 0x057d, "1W" }, -X{ "adjspd", 11,16, 0x057f, "1D" }, -X{ "andb", 6,16, 0x28, "1B2B" }, -X{ "andw", 6,16, 0x29, "1W2W" }, -X{ "andd", 6,16, 0x2b, "1D2D" }, -X{ "ashb", 14,24, 0x044e, "1B2B" }, -X{ "ashw", 14,24, 0x054e, "1B2W" }, -X{ "ashd", 14,24, 0x074e, "1B2D" }, -X{ "beq", 8,8, 0x0a, "1p" }, -X{ "bne", 8,8, 0x1a, "1p" }, -X{ "bcs", 8,8, 0x2a, "1p" }, -X{ "bcc", 8,8, 0x3a, "1p" }, -X{ "bhi", 8,8, 0x4a, "1p" }, -X{ "bls", 8,8, 0x5a, "1p" }, -X{ "bgt", 8,8, 0x6a, "1p" }, -X{ "ble", 8,8, 0x7a, "1p" }, -X{ "bfs", 8,8, 0x8a, "1p" }, -X{ "bfc", 8,8, 0x9a, "1p" }, -X{ "blo", 8,8, 0xaa, "1p" }, -X{ "bhs", 8,8, 0xba, "1p" }, -X{ "blt", 8,8, 0xca, "1p" }, -X{ "bge", 8,8, 0xda, "1p" }, -X{ "bicb", 6,16, 0x08, "1B2B" }, -X{ "bicw", 6,16, 0x09, "1W2W" }, -X{ "bicd", 6,16, 0x0b, "1D2D" }, -X{ "bicpsrb", 11,16, 0x17c, "1B" }, -X{ "bicpsrw", 11,16, 0x17d, "1W" }, -X{ "bispsrb", 11,16, 0x37c, "1B" }, -X{ "bispsrw", 11,16, 0x37d, "1W" }, -X{ "bpt", 8,8, 0xf2, "" }, -X{ "br", 8,8, 0xea, "1p" }, -X{ "bsr", 8,8, 0x02, "1p" }, -X{ "caseb", 11,16, 0x77c, "1B" }, -X{ "casew", 11,16, 0x77d, "1W" }, -X{ "cased", 11,16, 0x77f, "1D" }, -X{ "cbitb", 14,24, 0x084e, "1B2D" }, -X{ "cbitw", 14,24, 0x094e, "1W2D" }, -X{ "cbitd", 14,24, 0x0b4e, "1D2D" }, -X{ "cbitib", 14,24, 0x0c4e, "1B2D" }, -X{ "cbitiw", 14,24, 0x0d4e, "1W2D" }, -X{ "cbitid", 14,24, 0x0f4e, "1D2D" }, -X{ "checkb", 11,24, 0x0ee, "2A3B1r" }, -X{ "checkw", 11,24, 0x1ee, "2A3B1r" }, -X{ "checkd", 11,24, 0x3ee, "2A3D1r" }, -X{ "cmpf", 14,24, 0x09be, "1F2F" }, -X{ "cmpl", 14,24, 0x08be, "1L2L" }, -X{ "cmpb", 6,16, 0x04, "1B2B" }, -X{ "cmpw", 6,16, 0x05, "1W2W" }, -X{ "cmpd", 6,16, 0x07, "1D2D" }, -X{ "cmpmb", 14,24, 0x04ce, "1D2D3d" }, -X{ "cmpmw", 14,24, 0x05ce, "1D2D3d" }, -X{ "cmpmd", 14,24, 0x07ce, "1D2D3d" }, -X{ "cmpqb", 7,16, 0x1c, "2B1q" }, -X{ "cmpqw", 7,16, 0x1d, "2W1q" }, -X{ "cmpqd", 7,16, 0x1f, "2D1q" }, -X{ "cmpsb", 16,16, 0x040e, "i" }, -X{ "cmpsw", 16,16, 0x050e, "i" }, -X{ "cmpsd", 16,16, 0x070e, "i" }, -X{ "cmpst", 16,16, 0x840e, "i" }, -X{ "comb", 14,24, 0x344e, "1B2B" }, -X{ "comw", 14,24, 0x354e, "1W2W" }, -X{ "comd", 14,24, 0x374e, "1D2D" }, -X{ "cvtp", 11,24, 0x036e, "2D3D1r" }, -X{ "cxp", 8,8, 0x22, "1p" }, -X{ "cxpd", 11,16, 0x07f, "1D" }, -X{ "deib", 14,24, 0x2cce, "1B2W" }, -X{ "deiw", 14,24, 0x2cce, "1W2D" }, -X{ "deid", 14,24, 0x2cce, "1D2Q" }, -X{ "dia", 8,8, 0xc2, "" }, -X{ "divf", 14,24, 0x21be, "1F2F" }, -X{ "divl", 14,24, 0x20be, "1L2L" }, -X{ "divb", 14,24, 0x3cce, "1B2B" }, -X{ "divw", 14,24, 0x3dce, "1W2W" }, -X{ "divd", 14,24, 0x3fce, "1D2D" }, -X{ "enter", 8,8, 0x82, "1i2d" }, -X{ "exit", 8,8, 0x92, "1i" }, -X{ "extb", 11,24, 0x02e, "2D3B1r4d" }, -X{ "extw", 11,24, 0x12e, "2D3W1r4d" }, -X{ "extd", 11,24, 0x32e, "2D3D1r4d" }, -X{ "extsb", 14,24, 0x0cce, "1D2B3i" }, -X{ "extsw", 14,24, 0x0dce, "1D2W3i" }, -X{ "extsd", 14,24, 0x0fce, "1D2D3i" }, -X{ "ffsb", 14,24, 0x046e, "1B2B" }, -X{ "ffsw", 14,24, 0x056e, "1W2B" }, -X{ "ffsd", 14,24, 0x076e, "1D2B" }, -X{ "flag", 8,8, 0xd2, "" }, -X{ "floorfb", 14,24, 0x3c3e, "1F2B" }, -X{ "floorfw", 14,24, 0x3d3e, "1F2W" }, -X{ "floorfd", 14,24, 0x3f3e, "1F2D" }, -X{ "floorlb", 14,24, 0x383e, "1L2B" }, -X{ "floorlw", 14,24, 0x393e, "1L2W" }, -X{ "floorld", 14,24, 0x3b3e, "1L2D" }, -X{ "ibitb", 14,24, 0x384e, "1B2D" }, -X{ "ibitw", 14,24, 0x394e, "1W2D" }, -X{ "ibitd", 14,24, 0x3b4e, "1D2D" }, -X{ "indexb", 11,24, 0x42e, "2B3B1r" }, -X{ "indexw", 11,24, 0x52e, "2W3W1r" }, -X{ "indexd", 11,24, 0x72e, "2D3D1r" }, -X{ "insb", 11,24, 0x0ae, "2B3B1r4d" }, -X{ "insw", 11,24, 0x1ae, "2W3W1r4d" }, -X{ "insd", 11,24, 0x3ae, "2D3D1r4d" }, -X{ "inssb", 14,24, 0x08ce, "1B2D3i" }, -X{ "inssw", 14,24, 0x09ce, "1W2D3i" }, -X{ "inssd", 14,24, 0x0bce, "1D2D3i" }, -X{ "jsr", 11,16, 0x67f, "1A" }, -X{ "jump", 11,16, 0x27f, "1A" }, -X{ "lfsr", 19,24, 0x00f3e,"1D" }, -X{ "lmr", 15,24, 0x0b1e, "2D1q" }, -X{ "lprb", 7,16, 0x6c, "2B1q" }, -X{ "lprw", 7,16, 0x6d, "2W1q" }, -X{ "lprd", 7,16, 0x6f, "2D1q" }, -X{ "lshb", 14,24, 0x144e, "1B2B" }, -X{ "lshw", 14,24, 0x154e, "1B2W" }, -X{ "lshd", 14,24, 0x174e, "1B2D" }, -X{ "meib", 14,24, 0x24ce, "1B2W" }, -X{ "meiw", 14,24, 0x25ce, "1W2D" }, -X{ "meid", 14,24, 0x27ce, "1D2Q" }, -X{ "modb", 14,24, 0x38ce, "1B2B" }, -X{ "modw", 14,24, 0x39ce, "1W2W" }, -X{ "modd", 14,24, 0x3bce, "1D2D" }, -X{ "movf", 14,24, 0x05be, "1F2F" }, -X{ "movl", 14,24, 0x04be, "1L2L" }, -X{ "movb", 6,16, 0x14, "1B2B" }, -X{ "movw", 6,16, 0x15, "1W2W" }, -X{ "movd", 6,16, 0x17, "1D2D" }, -X{ "movbf", 14,24, 0x043e, "1B2F" }, -X{ "movwf", 14,24, 0x053e, "1W2F" }, -X{ "movdf", 14,24, 0x073e, "1D2F" }, -X{ "movbl", 14,24, 0x003e, "1B2L" }, -X{ "movwl", 14,24, 0x013e, "1W2L" }, -X{ "movdl", 14,24, 0x033e, "1D2L" }, -X{ "movfl", 14,24, 0x1b3e, "1F2L" }, -X{ "movlf", 14,24, 0x163e, "1L2F" }, -X{ "movmb", 14,24, 0x00ce, "1D2D3d" }, -X{ "movmw", 14,24, 0x00de, "1D2D3d" }, -X{ "movmd", 14,24, 0x00fe, "1D2D3d" }, -X{ "movqb", 7,16, 0x5c, "2B1q" }, -X{ "movqw", 7,16, 0x5d, "2B1q" }, -X{ "movqd", 7,16, 0x5f, "2B1q" }, -X{ "movsb", 16,16, 0x000e, "i" }, -X{ "movsw", 16,16, 0x010e, "i" }, -X{ "movsd", 16,16, 0x030e, "i" }, -X{ "movst", 16,16, 0x800e, "i" }, -X{ "movsub", 14,24, 0x0cae, "1A1A" }, -X{ "movsuw", 14,24, 0x0dae, "1A1A" }, -X{ "movsud", 14,24, 0x0fae, "1A1A" }, -X{ "movusb", 14,24, 0x1cae, "1A1A" }, -X{ "movusw", 14,24, 0x1dae, "1A1A" }, -X{ "movusd", 14,24, 0x1fae, "1A1A" }, -X{ "movxbd", 14,24, 0x1cce, "1B2D" }, -X{ "movxwd", 14,24, 0x1dce, "1W2D" }, -X{ "movxbw", 14,24, 0x10ce, "1B2W" }, -X{ "movzbd", 14,24, 0x18ce, "1B2D" }, -X{ "movzwd", 14,24, 0x19ce, "1W2D" }, -X{ "movzbw", 14,24, 0x14ce, "1B2W" }, -X{ "mulf", 14,24, 0x31be, "1F2F" }, -X{ "mull", 14,24, 0x30be, "1L2L" }, -X{ "mulb", 14,24, 0x20ce, "1B2B" }, -X{ "mulw", 14,24, 0x21ce, "1W2W" }, -X{ "muld", 14,24, 0x23ce, "1D2D" }, -X{ "negf", 14,24, 0x15be, "1F2F" }, -X{ "negl", 14,24, 0x14be, "1L2L" }, -X{ "negb", 14,24, 0x204e, "1B2B" }, -X{ "negw", 14,24, 0x214e, "1W2W" }, -X{ "negd", 14,24, 0x234e, "1D2D" }, -X{ "nop", 8,8, 0xa2, "" }, -X{ "notb", 14,24, 0x244e, "1B2B" }, -X{ "notw", 14,24, 0x254e, "1W2W" }, -X{ "notd", 14,24, 0x274e, "1D2D" }, -X{ "orb", 6,16, 0x18, "1B1B" }, -X{ "orw", 6,16, 0x19, "1W1W" }, -X{ "ord", 6,16, 0x1b, "1D1D" }, -X{ "quob", 14,24, 0x30ce, "1B2B" }, -X{ "quow", 14,24, 0x31ce, "1W2W" }, -X{ "quod", 14,24, 0x33ce, "1D2D" }, -X{ "rdval", 19,24, 0x0031e,"1A" }, -X{ "remb", 14,24, 0x34ce, "1B2B" }, -X{ "remw", 14,24, 0x35ce, "1W2W" }, -X{ "remd", 14,24, 0x37ce, "1D2D" }, -X{ "restore", 8,8, 0x72, "1i" }, -X{ "ret", 8,8, 0x12, "1d" }, -X{ "reti", 8,8, 0x52, "" }, -X{ "rett", 8,8, 0x42, "" }, -X{ "rotb", 14,24, 0x004e, "1B2B" }, -X{ "rotw", 14,24, 0x014e, "1B2W" }, -X{ "rotd", 14,24, 0x034e, "1B2D" }, -X{ "roundfb", 14,24, 0x243e, "1F2B" }, -X{ "roundfw", 14,24, 0x253e, "1F2W" }, -X{ "roundfd", 14,24, 0x273e, "1F2D" }, -X{ "roundlb", 14,24, 0x203e, "1L2B" }, -X{ "roundlw", 14,24, 0x213e, "1L2W" }, -X{ "roundld", 14,24, 0x233e, "1L2D" }, -X{ "rxp", 8,8, 0x32, "1d" }, -X{ "sCONDb", 7,16, 0x3c, "2B1q" }, -X{ "sCONDw", 7,16, 0x3d, "2D1q" }, -X{ "sCONDd", 7,16, 0x3f, "2D1q" }, -X{ "save", 8,8, 0x62, "1i" }, -X{ "sbitb", 14,24, 0x184e, "1B2A" }, -X{ "sbitw", 14,24, 0x194e, "1W2A" }, -X{ "sbitd", 14,24, 0x1b4e, "1D2A" }, -X{ "sbitib", 14,24, 0x1c4e, "1B2A" }, -X{ "sbitiw", 14,24, 0x1d4e, "1W2A" }, -X{ "sbitid", 14,24, 0x1f4e, "1D2A" }, -X{ "setcfg", 15,24, 0x0b0e, "5D1q" }, -X{ "sfsr", 14,24, 0x673e, "5D1D" }, -X{ "skpsb", 16,16, 0x0c0e, "i" }, -X{ "skpsw", 16,16, 0x0d0e, "i" }, -X{ "skpsd", 16,16, 0x0f0e, "i" }, -X{ "skpst", 16,16, 0x8c0e, "i" }, -X{ "smr", 15,24, 0x0f1e, "2D1q" }, -X{ "sprb", 7,16, 0x2c, "2B1q" }, -X{ "sprw", 7,16, 0x2d, "2W1q" }, -X{ "sprd", 7,16, 0x2f, "2D1q" }, -X{ "subf", 14,24, 0x11be, "1F2F" }, -X{ "subl", 14,24, 0x10be, "1L2L" }, -X{ "subb", 6,16, 0x20, "1B2B" }, -X{ "subw", 6,16, 0x21, "1W2W" }, -X{ "subd", 6,16, 0x23, "1D2D" }, -X{ "subcb", 6,16, 0x30, "1B2B" }, -X{ "subcw", 6,16, 0x31, "1W2W" }, -X{ "subcd", 6,16, 0x33, "1D2D" }, -X{ "subpb", 14,24, 0x2c4e, "1B2B" }, -X{ "subpw", 14,24, 0x2d4e, "1W2W" }, -X{ "subpd", 14,24, 0x2f4e, "1D2D" }, -X{ "svc", 8,8, 0xe2, "2i1i" }, /* not really, but unix uses it */ -X{ "tbitb", 6,16, 0x34, "1B2A" }, -X{ "tbitw", 6,16, 0x35, "1W2A" }, -X{ "tbitd", 6,16, 0x37, "1D2A" }, -X{ "truncfb", 14,24, 0x2c3e, "1F2B" }, -X{ "truncfw", 14,24, 0x2d3e, "1F2W" }, -X{ "truncfd", 14,24, 0x2f3e, "1F2D" }, -X{ "trunclb", 14,24, 0x283e, "1L2B" }, -X{ "trunclw", 14,24, 0x293e, "1L2W" }, -X{ "truncld", 14,24, 0x2b3e, "1L2D" }, -X{ "wait", 8,8, 0xb2, "" }, -X{ "wrval", 19,24, 0x0071e,"1A" }, -X{ "xorb", 6,16, 0x38, "1B2B" }, -X{ "xorw", 6,16, 0x39, "1W2W" }, -X{ "xord", 6,16, 0x3b, "1D2D" }, -X}; /* notstrs */ -X -X/* end: n32k.opcode.h */ -X -X# define MAX_ARGS 4 -X# define ARG_LEN 50 -SHAR_EOF -sed 's/^X//' << 'SHAR_EOF' > n32k-pinsn.c -X/* Print 32000 instructions for GDB, the GNU debugger. -X Copyright (C) 1986 Free Software Foundation, Inc. -X -XGDB is distributed in the hope that it will be useful, but WITHOUT ANY -XWARRANTY. No author or distributor accepts responsibility to anyone -Xfor the consequences of using it or for whether it serves any -Xparticular purpose or works at all, unless he says so in writing. -XRefer to the GDB General Public License for full details. -X -XEveryone is granted permission to copy, modify and redistribute GDB, -Xbut only under the conditions described in the GDB General Public -XLicense. A copy of this license is supposed to have been given to you -Xalong with GDB so you can know your rights and responsibilities. It -Xshould be in a file named COPYING. Among other things, the copyright -Xnotice and this notice must be preserved on all copies. -X -XIn other words, go ahead and share GDB, but don't try to stop -Xanyone else from sharing it farther. Help stamp out software hoarding! -X*/ -X -X#include <stdio.h> -X -X#include "defs.h" -X#include "param.h" -X#include "symtab.h" -X#include "n32k-opcode.h" -X -X/* 32000 instructions are never longer than this. */ -X#define MAXLEN 62 -X -X/* Number of elements in the opcode table. */ -X#define NOPCODES (sizeof notstrs / sizeof notstrs[0]) -X -Xextern char *reg_names[]; -X -X#define NEXT_IS_ADDR '|' -X -X/* -X * extract "count" bits starting "offset" bits -X * into buffer -X */ -X -Xint -Xbit_extract (buffer, offset, count) -Xchar *buffer; -Xint offset; -Xint count; -X{ -X int result; -X int mask; -X int bit; -X -X buffer += offset >> 3; -X offset &= 7; -X bit = 1; -X result = 0; -X while (count--) { -X if ((*buffer & (1 << offset))) -X result |= bit; -X if (++offset == 8) { -X offset = 0; -X buffer++; -X } -X bit <<= 1; -X } -X return result; -X} -X -Xdouble -Xdbit_extract (buffer, offset, count) -X{ -X union { -X struct { -X int low, high; -X } ival; -X double dval; -X } foo; -X -X foo.ival.low = bit_extract (buffer, offset, 32); -X foo.ival.high = bit_extract (buffer, offset+32, 32); -X return foo.dval; -X} -X -Xsign_extend (value, bits) -X{ -X value = value & ((1 << bits) - 1); -X return (value & (1 << (bits-1))) ? -X (value | (~((1 << bits) - 1))) -X : value; -X} -X -Xflip_bytes (ptr, count) -Xchar *ptr; -Xint count; -X{ -X char tmp; -X -X while (count > 0) { -X tmp = *ptr; -X ptr[0] = ptr[count-1]; -X ptr[count-1] = tmp; -X ptr++; -X count -= 2; -X } -X} -X -X -X/* Print the 32000 instruction at address MEMADDR in debugged memory, -X on STREAM. Returns length of the instruction, in bytes. */ -X -Xint -Xprint_insn (memaddr, stream) -XCORE_ADDR memaddr; -XFILE *stream; -X{ -X unsigned char buffer[MAXLEN]; -X register int i; -X register unsigned char *p; -X register char *d; -X unsigned short first_word; -X int gen, disp; -X int ioffset; /* bits into instruction */ -X int aoffset; /* bits into arguments */ -X char arg_bufs[MAX_ARGS+1][ARG_LEN]; -X int argnum; -X int maxarg; -X -X read_memory (memaddr, buffer, MAXLEN); -X -X first_word = *(unsigned short *) buffer; -X for (i = 0; i < NOPCODES; i++) { -X if ((first_word & ((1 << notstrs[i].detail.obits) - 1)) == -X notstrs[i].detail.code) -X break; -X } -X -X /* Handle undefined instructions. */ -X if (i == NOPCODES) { -X fprintf (stream, "0%o", buffer[0]); -X return 1; -X } -X -X fprintf (stream, "%s", notstrs[i].name); -X -X ioffset = notstrs[i].detail.ibits; -X aoffset = notstrs[i].detail.ibits; -X d = notstrs[i].detail.args; -X -X if (*d) { -X fputc ('\t', stream); -X -X maxarg = 0; -X while (*d) -X { -X argnum = *d - '1'; -X d++; -X if (argnum > maxarg && argnum < MAX_ARGS) -X maxarg = argnum; -X ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer, -X memaddr, arg_bufs[argnum]); -X d++; -X } -X for (argnum = 0; argnum <= maxarg; argnum++) { -X CORE_ADDR addr; -X char *ch, *index (); -X for (ch = arg_bufs[argnum]; *ch;) { -X if (*ch == NEXT_IS_ADDR) { -X ++ch; -X addr = atoi (ch); -X print_address (addr, stream); -X while (*ch && *ch != NEXT_IS_ADDR) -X ++ch; -X if (*ch) -X ++ch; -X } else -X putc (*ch++, stream); -X } -X if (argnum < maxarg) -X fprintf (stream, ", "); -X } -X } -X return aoffset / 8; -X} -X -Xprint_insn_arg (d, ioffset, aoffsetp, buffer, addr, result) -Xchar d; -Xint ioffset, *aoffsetp; -Xchar *buffer; -XCORE_ADDR addr; -Xchar *result; -X{ -X int addr_mode; -X float Fvalue; -X double Lvalue; -X int Ivalue; -X int disp1, disp2; -X int index; -X -X switch (d) { -X case 'F': -X case 'L': -X case 'B': -X case 'W': -X case 'D': -X case 'A': -X addr_mode = bit_extract (buffer, ioffset-5, 5); -X ioffset -= 5; -X switch (addr_mode) { -X case 0x0: case 0x1: case 0x2: case 0x3: -X case 0x4: case 0x5: case 0x6: case 0x7: -X sprintf (result, "r%d", addr_mode); -X break; -X case 0x8: case 0x9: case 0xa: case 0xb: -X case 0xc: case 0xd: case 0xe: case 0xf: -X disp1 = get_displacement (buffer, aoffsetp); -X sprintf (result, "%d(r%d)", disp1, addr_mode & 7); -X break; -X case 0x10: -X case 0x11: -X case 0x12: -X disp1 = get_displacement (buffer, aoffsetp); -X disp2 = get_displacement (buffer, aoffsetp); -X sprintf (result, "%d(%d(%s))", disp2, disp1, -X addr_mode==0x10?"fp":addr_mode==0x11?"sp":"sb"); -X break; -X case 0x13: -X sprintf (result, "reserved"); -X break; -X case 0x14: -X switch (d) { -X case 'B': -X Ivalue = bit_extract (buffer, *aoffsetp, 8); -X Ivalue = sign_extend (Ivalue, 8); -X *aoffsetp += 8; -X sprintf (result, "$%d", Ivalue); -X break; -X case 'W': -X Ivalue = bit_extract (buffer, *aoffsetp, 16); -X flip_bytes (&Ivalue, 2); -X *aoffsetp += 16; -X Ivalue = sign_extend (Ivalue, 16); -X sprintf (result, "$%d", Ivalue); -X break; -X case 'D': -X Ivalue = bit_extract (buffer, *aoffsetp, 32); -X flip_bytes (&Ivalue, 4); -X *aoffsetp += 32; -X sprintf (result, "$%d", Ivalue); -X break; -X case 'A': -X Ivalue = bit_extract (buffer, *aoffsetp, 32); -X flip_bytes (&Ivalue, 4); -X *aoffsetp += 32; -X sprintf (result, "$|%d|", Ivalue); -X break; -X case 'F': -X Fvalue = (float) bit_extract -X (buffer, *aoffsetp, 32); -X flip_bytes (&Fvalue, 4); -X *aoffsetp += 32; -X sprintf (result, "$%g", Fvalue); -X break; -X case 'L': -X Lvalue = dbit_extract -X (buffer, *aoffsetp, 64); -X flip_bytes (&Lvalue, 8); -X *aoffsetp += 64; -X sprintf (result, "$%g", Lvalue); -X break; -X } -X break; -X case 0x15: -X disp1 = get_displacement (buffer, aoffsetp); -X sprintf (result, "@|%d|", disp1); -X break; -X case 0x16: -X disp1 = get_displacement (buffer, aoffsetp); -X disp2 = get_displacement (buffer, aoffsetp); -X sprintf (result, "EXT(%d) + %d", disp1, disp2); -X break; -X case 0x17: -X sprintf (result, "tos"); -X break; -X case 0x18: -X disp1 = get_displacement (buffer, aoffsetp); -X sprintf (result, "%d(fp)", disp1); -X break; -X case 0x19: -X disp1 = get_displacement (buffer, aoffsetp); -X sprintf (result, "%d(sp)", disp1); -X break; -X case 0x1a: -X disp1 = get_displacement (buffer, aoffsetp); -X sprintf (result, "%d(sb)", disp1); -X break; -X case 0x1b: -X disp1 = get_displacement (buffer, aoffsetp); -X sprintf (result, "|%d|", addr + disp1); -X break; -X case 0x1c: -X case 0x1d: -X case 0x1e: -X case 0x1f: -X index = bit_extract (buffer, *aoffsetp, 8); -X *aoffsetp += 8; -X print_insn_arg (d, *aoffsetp, aoffsetp, buffer, addr, -X result); -X { -X static char *ind[] = {"b", "w", "d", "q"}; -X char *off; -X -X off = result + strlen (result); -X sprintf (off, "[r%d:%s]", index & 7, -X ind[addr_mode & 3]); -X } -X break; -X } -X break; -X case 'q': -X Ivalue = bit_extract (buffer, ioffset-4, 4); -X Ivalue = sign_extend (Ivalue, 4); -X sprintf (result, "%d", Ivalue); -X ioffset -= 4; -X break; -X case 'r': -X Ivalue = bit_extract (buffer, ioffset-3, 3); -X sprintf (result, "r%d", Ivalue&7); -X ioffset -= 3; -X break; -X case 'd': -X sprintf (result, "%d", get_displacement (buffer, aoffsetp)); -X break; -X case 'p': -X sprintf (result, "%c%d%c", NEXT_IS_ADDR, addr + -X get_displacement (buffer, aoffsetp), -X NEXT_IS_ADDR); -X break; -X case 'i': -X Ivalue = bit_extract (buffer, *aoffsetp, 8); -X *aoffsetp += 8; -X sprintf (result, "0x%x", Ivalue); -X break; -X } -X return ioffset; -X} -X -Xget_displacement (buffer, aoffsetp) -Xchar *buffer; -Xint *aoffsetp; -X{ -X int Ivalue; -X -X Ivalue = bit_extract (buffer, *aoffsetp, 8); -X switch (Ivalue & 0xc0) { -X case 0x00: -X case 0x40: -X Ivalue = sign_extend (Ivalue, 7); -X *aoffsetp += 8; -X break; -X case 0x80: -X Ivalue = bit_extract (buffer, *aoffsetp, 16); -X flip_bytes (&Ivalue, 2); -X Ivalue = sign_extend (Ivalue, 14); -X *aoffsetp += 16; -X break; -X case 0xc0: -X Ivalue = bit_extract (buffer, *aoffsetp, 32); -X flip_bytes (&Ivalue, 4); -X Ivalue = sign_extend (Ivalue, 30); -X *aoffsetp += 32; -X break; -X } -X return Ivalue; -X} -X/* -X * return the number of locals in the current frame given a pc -X * pointing to the enter instruction -X */ -Xn32k_localcount (enter_pc) -XCORE_ADDR enter_pc; -X{ -X int localtype, localcount; -X -X localtype = read_memory_integer (enter_pc+2, 1); -X if ((localtype & 0x80) == 0) -X localcount = localtype; -X else if ((localtype & 0xc0) == 0x80) -X localcount = -X ((read_memory_integer (enter_pc+2, 1) & ~0xc0) << 8) | -X ((read_memory_integer (enter_pc+3, 1))); -X else -X localcount = -X ((read_memory_integer (enter_pc+2, 1) & ~0xc0) << 24) | -X ((read_memory_integer (enter_pc+3, 1)) << 16) | -X ((read_memory_integer (enter_pc+4, 1)) << 8 ) | -X ((read_memory_integer (enter_pc+5, 1))); -X return localcount; -X} -SHAR_EOF -exit - diff --git a/gdb/=rt-ans2 b/gdb/=rt-ans2 deleted file mode 100644 index cd5f9fa..0000000 --- a/gdb/=rt-ans2 +++ /dev/null @@ -1,103 +0,0 @@ -BABYL OPTIONS: -Version: 5 -Labels: -Note: This is the header of an rmail file. -Note: If you are seeing it in rmail, -Note: it means the file has no messages in it. - -1,answered,, -Received: by PREP.AI.MIT.EDU; Tue, 26 May 87 14:03:00 EDT -Received: by po2.andrew.cmu.edu (5.54/3.15) id <AA00274> for rms@PREP.AI.MIT.EDU; Tue, 26 May 87 13:12:52 EDT -Received: via switchmail; Tue, 26 May 87 13:12:49 edt -Received: FROM mooncrest VIA qmail - ID </cmu/common/mailqs/q004/QF.mooncrest.20b9cce3.d0134>; - Tue, 26 May 87 13:12:08 edt -Received: FROM mooncrest VIA qmail - ID </cmu/itc/kazar/.Outgoing/QF.mooncrest.20b9ccb0.1b570>; - Tue, 26 May 87 13:11:14 edt -Message-Id: <0UiQmky00UkA06w0Ci@andrew.cmu.edu> -X-Trace: MS Version 3.24 on ibm032 host mooncrest, by kazar (71). -Date: Tue, 26 May 87 13:11:12 edt -From: kazar#@andrew.cmu.edu (Mike Kazar) -To: rms@PREP.AI.MIT.EDU (Richard M. Stallman) -Subject: Re: Fwd: RT diffs for gdb version 2.1 -Cc: zs01#@andrew.cmu.edu (Zalman Stern) -In-Reply-To: <4UiN0ly00Vs8Njw0PC@andrew.cmu.edu> - -*** EOOH *** -X-Trace: MS Version 3.24 on ibm032 host mooncrest, by kazar (71). -Date: Tue, 26 May 87 13:11:12 edt -From: kazar#@andrew.cmu.edu (Mike Kazar) -To: rms@PREP.AI.MIT.EDU (Richard M. Stallman) -Subject: Re: Fwd: RT diffs for gdb version 2.1 -Cc: zs01#@andrew.cmu.edu (Zalman Stern) -In-Reply-To: <4UiN0ly00Vs8Njw0PC@andrew.cmu.edu> - -I'm afraid that neither of your proposed simplifications to the gdb RT port -actually work. - -First, the trace table problem. The fundamental problem is that gdb expects -to be able to pass in a frame pointer and get that frame's parent. This is -the purpose of FRAME_CHAIN, a macro whose one parameter is the frame whose -parent is desired. - -This is simply insufficient information with which to compute the preceding -frame's address. In order to truly appreciate how bad things are, let me -describe the procedure involved in going from a set of saved registers -(including the pc), say after a core dump occurs, to the address of the -preceding frame. I assure you that you'll be shocked by its complexity.... - -I start off knowing only one thing: the PC of the guy who pushed the last -stack frame. At the time of a core dump, this is in the saved PC, and for -other stack frames, it is in register R15 (the return address is put in R15 -by the procedure call sequence). My first goal is to compute the frame -register number! Not the contents of the frame register, but the register -number itself, because the RT calling convention lets you change frame -pointers from procedure to procedure! So, I scan for the trace table, based -on the PC, and obtain a structure that gives the frame register number (for -both of our C compilers, this is R13, but it doesn't have to be), the number -of arguments to the procedure, the space used by the locals and the number of -registers saved by the procedure prolog. This enables me to take the frame -pointer, compute the offset of the saved registers off of this frame pointer -and essentially restore the registers to the state they were at the time this -procedure was called. R15 now contains *its* callers PC, and I can redo this -procedure again to back up another frame. - -In essence, in order to compute the preceding frame's address, I need more -than just the current frame's address. I need the full machine state at the -time of the call, including all of the registers since I don't know which one -will even turn out to be the frame pointer for the preceding procedure. - -This is why I put in the frame caching code. Note that even were I to assume -that the frame pointer is always in R13 (and this is almost certainly a -mistake; IBM will surely eventually come up with a compiler where the frame -pointer is NOT r13), I still either need r15 or the PC (depending upon which -frame we're dealing with) in order to compute the preceding frame address. - -As for the _foo v.s. _.foo issue, there are two problems. First, we can not -simply ignore _foo symbols, since an _foo symbol is only "junk" if there is -(possibly later) an _.foo symbol. We might be able to have the processing -for the "_.foo" change the value in the symbol table placed under the name -_foo. I do not know if this will work, since I do not know what processing -is done when a symbol is first encountered, and how much can be done a second -time. The second problem is that sometimes we need to see what is in the -variable named _foo, and we can't if it actually refers to _.foo. I -personally might be willing to live with this loss of functionality, but -other people probably would not. - -As for initialize.h, we simply have no guarantees that IBM won't again change -the junk they stick in front of procedures in the text segment. Already, -depending upon which compiler (and we use both), pcc puts a funny string (and -maybe an integer, too) in front of every procedure, while the metaware hc -compiler puts a funny string in front of the first procedure in a file, but -nothing in front of the others. IBM has made it clear to us that they feel -free to change this at any time, so I feel quite strongly that it would be a -mistake to assume that they've finished playing around with junk at the start -of the text. BTW, for all I know, some of these magic text strings disappear -when you compile with -O. They certainly *should*. - - Mike - - - -
\ No newline at end of file diff --git a/gdb/=rt-answers b/gdb/=rt-answers deleted file mode 100644 index b23cfee..0000000 --- a/gdb/=rt-answers +++ /dev/null @@ -1,147 +0,0 @@ -X-Trace: MS Version 3.24 on ibm032 host dublin.itc.cmu.edu, by zs01 (623). -Date: Mon, 25 May 87 10:30:10 edt -From: zs01#@andrew.cmu.edu (Zalman Stern) -To: rms@PREP.AI.MIT.EDU (Richard M. Stallman) -Subject: Re: RT diffs for gdb version 2.1 -Cc: kazar#@andrew.cmu.edu (Mike Kazar), zs01#@andrew.cmu.edu (Zalman Stern) -In-Reply-To: <8705250107.AA13256@prep.ai.mit.edu> - -Richard, - -First I will cover the easy questions. - -Either of our fixes to environ.c (i.e. with respect to version 1.9 which was -broken) will work. As I understand it, the intent of init_environ is to fill -in the environment and leave a little extra space for later additions. I do -not understand why you would want to only leave the extra space when the -original size was within 10 elements of the final size. - -add_com returning something is probably left over from a fix I put in which -is superceeded by the "user" class to distinguish command lists from function -pointers. I should have removed it. - -We use csh instead of sh because I got tired of putting up with sh's crapping -out on large environments. - -The change to inferior_args involves putting an explicit initializer of NULL -on it, and testing it for NULL before freeing it. I guess most -implementations of free ignore NULL pointers. The one we have on our Sun-2's -does not. - -I can't remember why the alloca's were moved out of the variable -initializations. It may have been to avoid a compiler problem. In any event, -ignoring this modification shouldn't hurt. - -Now for the hard ones... - -The RT is a very different architecture from either a Sun or a VAX. It does -not use a self-describing stack frame and it does not use the same -conventions for symbols within object modules. There are also certain -subtleties to the way it lays out its address space that cause problems. Many -people at the ITC, including myself, are very impressed with the quality of -the port Mike did in spite of these obstacles. You may feel that these -problems are not worth effort. I have attempted to describe the differences -involved with the RT in case you choose to address them. If not, we are still -quite happy with the debugger we have and thank you for providing us with the -code... - -Both the 68k family and the VAX have a frame pointer and a stack pointer. -Using these to values and the information on the stack, one can do a complete -stack trace. The RT on the other hand has only a stack pointer and a very -loose concept of a frame pointer. The stack pointer will point just below a -section of the stack dedicated to the maximum number of outgoing parameters -minus 4 (the first 4 are in registers). The frame pointer will point -somewhere in the stack where the compiler has deemed it optimal for -addressing locals and parameters. There are variable length fields in the -stack frame, such as the register save areas. In all, the thing looks like -so: - - -Higher Address ------------------ - -a) Incoming args 5 through N <---- Previous sp was here - (part of previous function's stack frame) -b) Four words to save register passed arguments. -c) Four words of linkage area (reserved). -d) 1 word static link. -e) 1 - 16 words of register save area. - (Variable length, return address is at the top of this since it was in -r15) -f) 0 -8 words of floating point reg. save area. (Variable length) -g) Local variables (variable length) -h) Outgoing arguments, words 5 - N <---- Current sp points to bottom of this. - -Lower Address ----------------- - -These and the stack contents are not enough to get back to the previous stack -frame because you do not know how far back it is to the register save area. -The code works because each function has been compiled to know how to pop its -stack frame (i.e. it has embedded constants). In order to facilitate -debugging, there is a trace table at the end of each function containing all -the necessary information. (Namely the offset from the frame pointer to the -top of the stack frame b in the above diagram) The trace table is located by -starting at the beginning of the function and looking for the illegal -instruction sequence 0xdf07df. Since the RT does not have 32bit constants in -the instruction stream, this actually works. In general, the iar and the -stack pointer are needed to do frame manipulations. The cache is necessary -because finding the trace table is very expensive. In short, the machinery -present in gdb was not up to handling this system, so we added what we -thought would work. It is interesting to note that similar calling -conventions are used on other RISC machines, notably the MIPS R2000. If you -wish to take advantage of these high performance machines, you will have to -do something like what we have done. - -The POP_DUMMY_FRAME problem is related to this. The RT stores return address -in r15. We can not use this location to store the current iar since we must -store r15 for later restoration. This rules out using the same function for -popping both kinds of frames. There is also some hassle involved in getting -the stack and frame pointers correct, but I think this might be fixed by -generating an appropriate trace back table for the dummy function. - -The other problem we faced is the non-standard use of symbols within object -modules. The RT defines two symbols for a function foo. There is "_.foo" -which corresponds to the actual code in the text segment (just like "_foo" on -a Sun or VAX), and "_foo" which points to the data area for the function in -the data segment. The first word of the data area contains a pointer to the -code. A function pointer (i.e. int (*foo)()) points to the data area (_foo), -not the code (_.foo). This is what the TYPE_CODE_PTR modification in valops.c -is for. Since both of these symbols are used for certain things, we cannot -simply remove the dots. This is a bogus IBM feature and we do not like it any -better than you do. We have to live with it if we want a working debugger. - -The "fix" to find_pc_misc function handles a special case on the RT where -certain functions are in the high end of the address space. The RT uses the -top 4 bits of an address as a segment number. The text segment is seg. 0, the -data segment is seg. 1, and the kernel is mapped into seg. 14. Certain kernel -functions (i.e. floating point functions) are directly callable by user code -and so occur in the misc_function_vector. I realize this is bogus. - -The initialization code will not run because both the RT compilers (pcc and -hc) output ascii data in the text section preceding the first function. Pcc -outputs the name of each function before the function. Hc outputs the name of -the source file at the beginning of the object module. Coding around this may -be possible, but what is the point? I see no reason for this hackery. I have -had problems getting it to work not only on the RT, but on the Sun-3. It is -guaranteed to be a portability headache on many other machines as well. If -you intend for gdb to only work when compiled with gcc, I suppose you may be -able to use this method. - -I strongly agree with your statements that cleaner solutions are better in -every way. Unfortunately, we did not write gdb, nor is the system we are -working with particularly supportive of symbolic debugging. We were faced -with the task of both figuring out gdb, and hacking our way around a -contorted system (featuring among other things, a plethora of compiler bugs). -The fact that our version of gdb is the only working symbolic debugger on the -IBM RT (despite much effort by IBM) is proof that we have done something -right. I am willing to discuss what would make this port better. However, it -is not our intent to maintain or rewrite gdb. We merely wish to use it, and -if not a terrible hassle, let other people use it too. Mike and I would -prefer a copyright assignment. I would appreciate it if you would send me -info on what we need to do. - --Z- - - - diff --git a/gdb/=rt-changes b/gdb/=rt-changes deleted file mode 100644 index 1eda81c..0000000 --- a/gdb/=rt-changes +++ /dev/null @@ -1,3338 +0,0 @@ -From: zs01#@andrew.cmu.edu (Zalman Stern) -Date: Sun, 24 May 87 03:20:57 edt -To: rms@prep.ai.mit.edu -Subject: RT diffs for gdb version 2.1 - -Here are the new files, followed by the diffs to old files. The first file below -is ITCMODS which is my attempt to document some of our changes. Unfortunately, -it has not been maintained particularly well and notably does not include info -about our changes to support the HIGH-C compiler. One big change we put in was -to use a number of initialize routines instead of the "linked list of object -modules" that is used on other machines. The RT object file format appears to -have a variable size header before the code, making it very difficult -(impossible?) to get the initialization stuff to work. If you have any -questions, don't hesitate to send me mail. - --Z- - -Only in .: ITCMODS - -blockframe.c: - set_current_frame now takes an extra argument. - RT specific code for interpreting and caching of trace table entries. - Added initialize routine. - -breakpoint.c: - Added new_breakpoint_commands flag to prevent incorrect interpretation of command lists containing a continue statement. - Modified do_breakpoint_commands to know about new_breakpoint_commands. - Modified clear_breakpoint_commands to set new_breakpoint_commands. - Added initialize routine. - -core.c: - RT specific code to find the uarea. - RT specific code to indicate the start of the data segment. - set_current_frame now takes an extra argument. - Added initialize routine. - -dbxread.c: - Added support for the Camphor dynamic loading system. (All under #ifdef CAMPHOR). - Fix for multiple declarations of register variables (i.e. they are declared twice). The fix munges the incorrect declaration (i.e. the one which is not register). - set_rel_command to set relocation offset for camphor loaded files. (Under #ifdef CAMPHOR). - add_file_command to append a file's symbols to the current symbol table instead of replacing it. (Under #ifdef CAMPHOR). - RT specific code to deal with function names being _.foo instead of _foo. - Added initialize routine. - - Feb 8, 1987 Zalman Stern. - Added test in symbol_file_command to see if file was compiled with debugging. If not print an error message instead of dumping core. - Added same test in add_file_command and made it run through BZPATH, CLASSPATH, and PATH in that order (Under #ifdef CAMPHOR). - -environ.c: - Fixed error in calculating new size of a reallocated environment. - -eval.c: - Added initialize routine. - -expread.y: - Moved alloca call out of variable initializations. - -findvar.c: - Added initialize routine. - -firstfile.c: - Added main initialization driver routine. - -frame.h: - Added RT specific declarations to hold frame information, and to deal with trace table caching. - -ibm032-pinsn.c: - New file, contains RT disassembler. - -ibm032-opcode.h: - New file, contains RT opcode definitions. - -infcmd.c - Changed code to use csh instead of sh to avoid the anoyance of the environment bug. - Added initialize routine. - -inflow.c: - Added initialize routine. - -infrun.c: - set_current_frame now takes an extra argument. - Added some code to deal with stopping in the middle of a camphor link. (Under #ifdef CAMPHOR). - Added RT specific code to get the return values from the right registers. Replaces code that was there for RT. - RT specific code to do a "POP_DUMMY_FRAME." Dummy frames are to store more complete state than a normal frame. Makes calling a function in inferior more reliable. Perhaps this should be expanded to other machine types. - Added initialize routine. - - Feb 9, 1987 Zalman Stern. - Added call to select_frame after popping a stack dummy frame in normal_stop. This fixes the bug where you could not print variables without doing a "frame 0" after printing an expression with a function call in it. - -iniitialize.h: - Changed file to use #ifdef's for machine type. Allows one to use same sources for different machines. - -m-ibm032.h: - New file, contains RT specific macros and variables. - -param.h: - Changed file to use #ifdef's for machine type. Allows one to use same sources for different machines. - -pinsn.c: - Changed file to use #ifdef's for machine type. Allows one to use same sources for different machines. - -printcmd.c: - Moved alloca calls out of variable initialization. - Added initialize routine. - -source.c: - Added initialize routine. - -stack.c: - Added initialize routine. - -symmisc.c: - Added initialize routine. - -symtab.c: - RT specific code to deal with function names being _.foo instead of _foo. - Added initialize routine. - -utils.c: - Added comment. - -valarith.c: - Added initialize routine. - -valops.c: - Added initialize routine. - -valprint.c: - Added initialize routine. - -values.c: - Added initialize routine. - -Only in .: ibm032-opcode.h - -/* The opcode table consists of a 256 element array containing an - * instruction mnemonic and an instruction type field. This can be - * indexed directly by the first eight bits of an RT instruction. - * The instruction type consists of a type field and some flags. - * In addition to this, there is an ifdef'd out "instruction" table - * at the end of the file. This is an alphabetical listing of the instructions - * containing mnemonic, opcode, and type. This is useful for modification - * purposes. There is also some code in the ifdef to convert the - * instruction table into an opcode table. - */ - -/* Various useful bit masks. */ -#define ibm032_typeMask 0x0f /* Mask to get actual type info out of instruction type. */ -#define LOW4 0x0f -#define HIGH4 0xf0 -#define LOW16 0x0000ffff -#define HIGH16 0xffff0000 -#define LOW20 0x000fffff -#define LOW24 0x00ffffff - -/* Instruction types consist of a type id in the low 4 bits and flags above that. */ - -/* Flags. */ -#define ibm032_conditional 0x10 -#define ibm032_negative 0x20 - -/* Format types. */ -#define ibm032_JI 0x0 /* Jump immediate. */ -#define ibm032_X 0x1 /* ??? */ - -/* These next ones are in a special bit position. Do not change their defines. */ -#define ibm032_DS0 0x2 /* Data short with no shift for immediate value. */ -#define ibm032_DS1 0x3 /* Data short with 1 bit shift for immediate value. */ -#define ibm032_DS2 0x4 /* Data short with 2 bit shift for immediate value */ -#define ibm032_DSShiftOffset ibm032_DS0 /* Offset to get shift value from ibm032_DS? types. */ - -#define ibm032_RR 0x5 /* R format where second argument is a register */ -#define ibm032_RI 0x6 /* R format where second argument is 4 bit immediate. */ -#define ibm032_BI 0x7 /* Branch immediate. */ -#define ibm032_BA 0x8 /* Branch absolute. */ -#define ibm032_D 0x9 /* Data. */ - -/* What an instruction looks like. */ -struct ibm032_opcode { - char *mnemonic; /* the name. NULL indicates illegal instruction. */ - int type; /* See above. */ -}; - -#define MAXOPCODES 256 /* Pretty well hardwired. */ - -#ifndef BUILDTABLE -/* The actual data. */ -struct ibm032_opcode ibm032_opcodes[] = { - {"j%s", ibm032_JI | ibm032_conditional | ibm032_negative}, - {"j%s", ibm032_JI | ibm032_conditional | ibm032_negative}, - {"j%s", ibm032_JI | ibm032_conditional | ibm032_negative}, - {"j%s", ibm032_JI | ibm032_conditional | ibm032_negative}, - {"j%s", ibm032_JI | ibm032_conditional | ibm032_negative}, - {"j%s", ibm032_JI | ibm032_conditional | ibm032_negative}, - {"j%s", ibm032_JI | ibm032_conditional | ibm032_negative}, - {"j%s", ibm032_JI | ibm032_conditional | ibm032_negative}, - {"j%s", ibm032_JI | ibm032_conditional}, - {"j%s", ibm032_JI | ibm032_conditional}, - {"j%s", ibm032_JI | ibm032_conditional}, - {"j%s", ibm032_JI | ibm032_conditional}, - {"j%s", ibm032_JI | ibm032_conditional}, - {"j%s", ibm032_JI | ibm032_conditional}, - {"j%s", ibm032_JI | ibm032_conditional}, - {"j%s", ibm032_JI | ibm032_conditional}, - {"stcs", ibm032_DS0}, - {"stcs", ibm032_DS0}, - {"stcs", ibm032_DS0}, - {"stcs", ibm032_DS0}, - {"stcs", ibm032_DS0}, - {"stcs", ibm032_DS0}, - {"stcs", ibm032_DS0}, - {"stcs", ibm032_DS0}, - {"stcs", ibm032_DS0}, - {"stcs", ibm032_DS0}, - {"stcs", ibm032_DS0}, - {"stcs", ibm032_DS0}, - {"stcs", ibm032_DS0}, - {"stcs", ibm032_DS0}, - {"stcs", ibm032_DS0}, - {"stcs", ibm032_DS0}, - {"sths", ibm032_DS1}, - {"sths", ibm032_DS1}, - {"sths", ibm032_DS1}, - {"sths", ibm032_DS1}, - {"sths", ibm032_DS1}, - {"sths", ibm032_DS1}, - {"sths", ibm032_DS1}, - {"sths", ibm032_DS1}, - {"sths", ibm032_DS1}, - {"sths", ibm032_DS1}, - {"sths", ibm032_DS1}, - {"sths", ibm032_DS1}, - {"sths", ibm032_DS1}, - {"sths", ibm032_DS1}, - {"sths", ibm032_DS1}, - {"sths", ibm032_DS1}, - {"sts", ibm032_DS2}, - {"sts", ibm032_DS2}, - {"sts", ibm032_DS2}, - {"sts", ibm032_DS2}, - {"sts", ibm032_DS2}, - {"sts", ibm032_DS2}, - {"sts", ibm032_DS2}, - {"sts", ibm032_DS2}, - {"sts", ibm032_DS2}, - {"sts", ibm032_DS2}, - {"sts", ibm032_DS2}, - {"sts", ibm032_DS2}, - {"sts", ibm032_DS2}, - {"sts", ibm032_DS2}, - {"sts", ibm032_DS2}, - {"sts", ibm032_DS2}, - {"lcs", ibm032_DS0}, - {"lcs", ibm032_DS0}, - {"lcs", ibm032_DS0}, - {"lcs", ibm032_DS0}, - {"lcs", ibm032_DS0}, - {"lcs", ibm032_DS0}, - {"lcs", ibm032_DS0}, - {"lcs", ibm032_DS0}, - {"lcs", ibm032_DS0}, - {"lcs", ibm032_DS0}, - {"lcs", ibm032_DS0}, - {"lcs", ibm032_DS0}, - {"lcs", ibm032_DS0}, - {"lcs", ibm032_DS0}, - {"lcs", ibm032_DS0}, - {"lcs", ibm032_DS0}, - {"lhas", ibm032_DS1}, - {"lhas", ibm032_DS1}, - {"lhas", ibm032_DS1}, - {"lhas", ibm032_DS1}, - {"lhas", ibm032_DS1}, - {"lhas", ibm032_DS1}, - {"lhas", ibm032_DS1}, - {"lhas", ibm032_DS1}, - {"lhas", ibm032_DS1}, - {"lhas", ibm032_DS1}, - {"lhas", ibm032_DS1}, - {"lhas", ibm032_DS1}, - {"lhas", ibm032_DS1}, - {"lhas", ibm032_DS1}, - {"lhas", ibm032_DS1}, - {"lhas", ibm032_DS1}, - {"cas", ibm032_X}, - {"cas", ibm032_X}, - {"cas", ibm032_X}, - {"cas", ibm032_X}, - {"cas", ibm032_X}, - {"cas", ibm032_X}, - {"cas", ibm032_X}, - {"cas", ibm032_X}, - {"cas", ibm032_X}, - {"cas", ibm032_X}, - {"cas", ibm032_X}, - {"cas", ibm032_X}, - {"cas", ibm032_X}, - {"cas", ibm032_X}, - {"cas", ibm032_X}, - {"cas", ibm032_X}, - {"ls", ibm032_DS2}, - {"ls", ibm032_DS2}, - {"ls", ibm032_DS2}, - {"ls", ibm032_DS2}, - {"ls", ibm032_DS2}, - {"ls", ibm032_DS2}, - {"ls", ibm032_DS2}, - {"ls", ibm032_DS2}, - {"ls", ibm032_DS2}, - {"ls", ibm032_DS2}, - {"ls", ibm032_DS2}, - {"ls", ibm032_DS2}, - {"ls", ibm032_DS2}, - {"ls", ibm032_DS2}, - {"ls", ibm032_DS2}, - {"ls", ibm032_DS2}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {"b%s", ibm032_BI | ibm032_conditional | ibm032_negative}, - {"b%sx", ibm032_BI | ibm032_conditional | ibm032_negative}, - {"bala", ibm032_BA}, - {"balax", ibm032_BA}, - {"bali", ibm032_BI}, - {"balix", ibm032_BI}, - {"b%s", ibm032_BI | ibm032_conditional}, - {"b%sx", ibm032_BI | ibm032_conditional}, - {"ais", ibm032_RI}, - {"inc", ibm032_RI}, - {"sis", ibm032_RI}, - {"dec", ibm032_RI}, - {"cis", ibm032_RI}, - {"clrsb", ibm032_RI}, - {"mfs", ibm032_RR}, - {"setsb", ibm032_RI}, - {"clrbu", ibm032_RI}, - {"clrbl", ibm032_RI}, - {"setbu", ibm032_RI}, - {"setbl", ibm032_RI}, - {"mftbiu", ibm032_RI}, - {"mftbil", ibm032_RI}, - {"mttbiu", ibm032_RI}, - {"mttbil", ibm032_RI}, - {"sari", ibm032_RI}, - {"sari16", ibm032_RI}, - {0, 0}, - {0, 0}, - {"lis", ibm032_RI}, - {0, 0}, - {0, 0}, - {0, 0}, - {"sri", ibm032_RI}, - {"sri16", ibm032_RI}, - {"sli", ibm032_RI}, - {"sli16", ibm032_RI}, - {"srpi", ibm032_RI}, - {"srpi16", ibm032_RI}, - {"slpi", ibm032_RI}, - {"slpi16", ibm032_RI}, - {"sar", ibm032_RR}, - {"exts", ibm032_RR}, - {"sf", ibm032_RR}, - {"cl", ibm032_RR}, - {"c", ibm032_RR}, - {"mts", ibm032_RR}, - {"d", ibm032_RR}, - {0, 0}, - {"sr", ibm032_RR}, - {"srp", ibm032_RR}, - {"sl", ibm032_RR}, - {"slp", ibm032_RR}, - {"mftb", ibm032_RR}, - {"tgte", ibm032_RR}, - {"tlt", ibm032_RR}, - {"mttb", ibm032_RR}, - {"svc", ibm032_D}, - {"ai", ibm032_D}, - {"cal16", ibm032_D}, - {"oiu", ibm032_D}, - {"oil", ibm032_D}, - {"nilz", ibm032_D}, - {"nilo", ibm032_D}, - {"xil", ibm032_D}, - {"cal", ibm032_D}, - {"lm", ibm032_D}, - {"lha", ibm032_D}, - {"ior", ibm032_D}, - {"ti", ibm032_D}, - {"l", ibm032_D}, - {"lc", ibm032_D}, - {"tsh", ibm032_D}, - {"lps", ibm032_D}, - {"aei", ibm032_D}, - {"sfi", ibm032_D}, - {"cli", ibm032_D}, - {"ci", ibm032_D}, - {"niuz", ibm032_D}, - {"niuo", ibm032_D}, - {"xiu", ibm032_D}, - {"cau", ibm032_D}, - {"stm", ibm032_D}, - {"lh", ibm032_D}, - {"iow", ibm032_D}, - {"sth", ibm032_D}, - {"st", ibm032_D}, - {"stc", ibm032_D}, - {0, 0}, - {"abs", ibm032_RR}, - {"a", ibm032_RR}, - {"s", ibm032_RR}, - {"o", ibm032_RR}, - {"twoc", ibm032_RR}, - {"n", ibm032_RR}, - {"m", ibm032_RR}, - {"x", ibm032_RR}, - {"b%sr", ibm032_RR | ibm032_conditional | ibm032_negative}, - {"b%srx", ibm032_RR | ibm032_conditional | ibm032_negative}, - {0, 0}, - {"lhs", ibm032_RR}, - {"balr", ibm032_RR}, - {"balrx", ibm032_RR}, - {"b%sr", ibm032_RR | ibm032_conditional}, - {"b%srx", ibm032_RR | ibm032_conditional}, - {"wait", ibm032_RR}, - {"ae", ibm032_RR}, - {"se", ibm032_RR}, - {"ca16", ibm032_RR}, - {"onec", ibm032_RR}, - {"clz", ibm032_RR}, - {0, 0}, - {0, 0}, - {0, 0}, - {"mc03", ibm032_RR}, - {"mc13", ibm032_RR}, - {"mc23", ibm032_RR}, - {"mc33", ibm032_RR}, - {"mc30", ibm032_RR}, - {"mc31", ibm032_RR}, - {"mc32", ibm032_RR}, -}; - -#else -struct ibm032_opcode ibm032_opcodes[MAXOPCODES]; - -struct ibm032_instruction { - char *mnemonic; /* Mnemonic for this instruction */ - char opcode; /* Numerical value of opcode. */ - int type; /* This instructions format. */ -}; - -struct ibm032_instruction ibm032_instructions[] = -{ - {"a", 0xe1, ibm032_RR}, - {"abs", 0xe0, ibm032_RR}, - {"ae", 0xf1, ibm032_RR}, - {"aei", 0xd1, ibm032_D}, - {"ai", 0xc1, ibm032_D}, - {"ais", 0x90, ibm032_RI}, - {"bala", 0x8a, ibm032_BA}, - {"balax", 0x8b, ibm032_BA}, - {"bali", 0x8c, ibm032_BI}, - {"balix", 0x8d, ibm032_BI}, - {"balr", 0xec, ibm032_RR}, - {"balrx", 0xed, ibm032_RR}, - {"b%s", 0x8e, ibm032_BI | ibm032_conditional}, - {"b%sr", 0xee, ibm032_RR | ibm032_conditional}, - {"b%srx", 0xef, ibm032_RR | ibm032_conditional}, - {"b%sx", 0x8f, ibm032_BI | ibm032_conditional}, - {"b%s", 0x88, ibm032_BI | ibm032_conditional | ibm032_negative}, - {"b%sr", 0xe8, ibm032_RR | ibm032_conditional | ibm032_negative}, - {"b%srx", 0xe9, ibm032_RR | ibm032_conditional | ibm032_negative}, - {"b%sx", 0x89, ibm032_BI | ibm032_conditional | ibm032_negative}, - {"c", 0xb4, ibm032_RR}, - {"cal", 0xc8, ibm032_D}, - {"cal16", 0xc2, ibm032_D}, - {"cas", 0x60, ibm032_X}, - {"cau", 0xd8, ibm032_D}, - {"ca16", 0xf3, ibm032_RR}, - {"ci", 0xd4, ibm032_D}, - {"cis", 0x94, ibm032_RI}, - {"cl", 0xb3, ibm032_RR}, - {"cli", 0xd3, ibm032_D}, - {"clrbl", 0x99, ibm032_RI}, - {"clrbu", 0x98, ibm032_RI}, - {"clrsb", 0x95, ibm032_RI}, - {"clz", 0xf5, ibm032_RR}, - {"d", 0xb6, ibm032_RR}, - {"dec", 0x93, ibm032_RI}, - {"exts", 0xb1, ibm032_RR}, - {"inc", 0x91, ibm032_RI}, - {"ior", 0xcb, ibm032_D}, - {"iow", 0xdb, ibm032_D}, - - {"j%s", 0x08, ibm032_JI | ibm032_conditional}, - {"j%s", 0x00, ibm032_JI | ibm032_conditional | ibm032_negative}, - - {"l", 0xcd, ibm032_D}, - {"lc", 0xce, ibm032_D}, - {"lcs", 0x40, ibm032_DS0}, - {"lh", 0xda, ibm032_D}, - {"lha", 0xca, ibm032_D}, - {"lhas", 0x50, ibm032_DS1}, - {"lhs", 0xeb, ibm032_RR}, - {"lis", 0xa4, ibm032_RI}, - {"lm", 0xc9, ibm032_D}, - {"lps", 0xd0, ibm032_D}, - {"ls", 0x70, ibm032_DS2}, - {"m", 0xe6, ibm032_RR}, - {"mc03", 0xf9, ibm032_RR}, - {"mc13", 0xfa, ibm032_RR}, - {"mc23", 0xfb, ibm032_RR}, - {"mc33", 0xfc, ibm032_RR}, - {"mc30", 0xfd, ibm032_RR}, - {"mc31", 0xfe, ibm032_RR}, - {"mc32", 0xff, ibm032_RR}, - {"mfs", 0x96, ibm032_RR}, - {"mftb", 0xbc, ibm032_RR}, - {"mftbil", 0x9d, ibm032_RI}, - {"mftbiu", 0x9c, ibm032_RI}, - {"mts", 0xb5, ibm032_RR}, - {"mttb", 0xbf, ibm032_RR}, - {"mttbil", 0x9f, ibm032_RI}, - {"mttbiu", 0x9e, ibm032_RI}, - {"n", 0xe5, ibm032_RR}, - - {"nilo", 0xc6, ibm032_D}, - {"nilz", 0xc5, ibm032_D}, - {"niuo", 0xd6, ibm032_D}, - {"niuz", 0xd5, ibm032_D}, - {"o", 0xe3, ibm032_RR}, - {"oil", 0xc4, ibm032_D}, - {"oiu", 0xc3, ibm032_D}, - {"onec", 0xf4, ibm032_RR}, - {"s", 0xe2, ibm032_RR}, - {"sar", 0xb0, ibm032_RR}, - {"sari", 0xa0, ibm032_RI}, - {"sari16", 0xa1, ibm032_RI}, - {"se", 0xf2, ibm032_RR}, - {"setbl", 0x9b, ibm032_RI}, - {"setbu", 0x9a, ibm032_RI}, - {"setsb", 0x97, ibm032_RI}, - {"sf", 0xb2, ibm032_RR}, - - {"sfi", 0xd2, ibm032_D}, - - {"sis", 0x92, ibm032_RI}, - {"sl", 0xba, ibm032_RR}, - {"sli", 0xaa, ibm032_RI}, - {"sli16", 0xab, ibm032_RI}, - {"slp", 0xbb, ibm032_RR}, - {"slpi", 0xae, ibm032_RI}, - {"slpi16", 0xaf, ibm032_RI}, - {"sr", 0xb8, ibm032_RR}, - {"sri", 0xa8, ibm032_RI}, - {"sri16", 0xa9, ibm032_RI}, - {"srp", 0xb9, ibm032_RR}, - {"srpi", 0xac, ibm032_RI}, - {"srpi16", 0xad, ibm032_RI}, - - {"st", 0xdd, ibm032_D}, - - {"stc", 0xde, ibm032_D}, - {"stcs", 0x10, ibm032_DS0}, - {"sth", 0xdc, ibm032_D}, - {"sths", 0x20, ibm032_DS1}, - {"stm", 0xd9, ibm032_D}, - {"sts", 0x30, ibm032_DS2}, - {"svc", 0xc0, ibm032_D}, - {"tgte", 0xbd, ibm032_RR}, - {"ti", 0xcc, ibm032_D}, - {"tlt", 0xbe, ibm032_RR}, - {"tsh", 0xcf, ibm032_D}, - {"twoc", 0xe4, ibm032_RR}, - {"wait", 0xf0, ibm032_RR}, - {"x", 0xe7, ibm032_RR}, - {"xil", 0xc7, ibm032_D}, - {"xiu", 0xd7, ibm032_D} -}; - -/* Code to generate the packed opcode table from the instructions table. */ - -#include <stdio.h> - -char *typeNames[] = { - "ibm032_JI", - "ibm032_X", - "ibm032_DS0", - "ibm032_DS1", - "ibm032_DS2", - "ibm032_RR", - "ibm032_RI", - "ibm032_BI", - "ibm032_BA", - "ibm032_D" -}; - -main() -{ - - int i, j, opcode, type; - - for (j = (sizeof(ibm032_instructions) / sizeof(struct ibm032_instruction)); j >= 0; j--) { - opcode = ibm032_instructions[j].opcode; - switch (ibm032_instructions[j].type & ibm032_typeMask) { - case ibm032_JI: - i = 7; - break; - case ibm032_X: - case ibm032_DS0: - case ibm032_DS1: - case ibm032_DS2: - i = 15; - break; - case ibm032_RR: - case ibm032_RI: - default: - i = 0; - break; - } - for (;i >= 0; i--) { - ibm032_opcodes[opcode + i].mnemonic = ibm032_instructions[j].mnemonic; - ibm032_opcodes[opcode + i].type = ibm032_instructions[j].type; - } - } - - printf("struct ibm032_opcode ibm032_opcodes[] = {\n"); - for ( j = 0; j < 256; j++) { - type = ibm032_opcodes[j].type; - if (ibm032_opcodes[j].mnemonic != NULL) - printf(" {\"%s\",\t\t%s%s%s},\n", ibm032_opcodes[j].mnemonic, - typeNames[type & ibm032_typeMask], - (type & ibm032_conditional) ? " | ibm032_conditional" : "", - (type & ibm032_negative) ? " | ibm032_negative" : ""); - else - printf(" {0,\t\t\t0},\n"); - } - printf("};\n"); -} -#endif /* BUILDTABLE */ - -Only in .: ibm032-pinsn.c - -/* Print ibm032 instructions 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 "defs.h" -#include "param.h" -#include "symtab.h" -#include "ibm032-opcode.h" - -/* ibm032 instructions are never longer than this many bytes. */ -#define MAXLEN 4 - -extern char *reg_names[]; - -static char *mapCondition(); - - -/* Print the ibm032 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]; - int opcodeIndex, instructionBits, type; - char *mnemonic; - - read_memory (memaddr, buffer, MAXLEN); - instructionBits = (buffer[0] << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3]; /* Get it into an int for easy use. */ - - if ((mnemonic = ibm032_opcodes[opcodeIndex = buffer[0]].mnemonic) == NULL) - { - fprintf (stream, "0%o", (instructionBits & HIGH16) >> 16); - return 2; - } - type = ibm032_opcodes[opcodeIndex].type; - if (!(type & ibm032_conditional)) { - fprintf (stream, "%s", mnemonic); - - switch (type) { - - int displacement; /* Used for sign extensions. */ - char *sign; - - case ibm032_X: - fprintf(stream, "\t%s, %s(%s)", reg_names[buffer[0] & LOW4], (buffer[1] & HIGH4) ? (reg_names[(buffer[1] & HIGH4) >> 4]) : "", reg_names[buffer[1] & LOW4]); - return 2; - case ibm032_DS0: - case ibm032_DS1: - case ibm032_DS2: - fprintf(stream, "\t%s, %x", reg_names[(buffer[1] & HIGH4) >> 4], (buffer[0] & LOW4) << (ibm032_opcodes[opcodeIndex].type - ibm032_DSShiftOffset)); /* Hacked to shift imediate field. */ - if (buffer[1] & LOW4) - fprintf(stream, "(%s)", reg_names[buffer[1] & LOW4]); - return 2; - case ibm032_RR: - fprintf(stream, "\t%s, %s", reg_names[(buffer[1] & HIGH4) >> 4], reg_names[buffer[1] & 0x0f]); - return 2; - case ibm032_RI: - fprintf(stream, "\t%s, %x", reg_names[(buffer[1] & HIGH4) >> 4], buffer[1] & LOW4); - return 2; - case ibm032_BI: - fprintf(stream, "\t%s, ", reg_names[(buffer[1] & HIGH4) >> 4]); - displacement = (instructionBits & LOW20); - if ((displacement & (1 << 19)) != 0) /* Cover sign extension. */ - displacement |= 0xfff00000; - print_address(memaddr + (displacement * 2), stream); /* Need sign extension. */ - return 4; - case ibm032_BA: - print_address((instructionBits & LOW24) & ~1, stream); - return 4; - case ibm032_D: - displacement = (instructionBits & LOW16); - if ((displacement & (1 << 15)) != 0) { /* Cover sign extension. */ - displacement = - (displacement | 0xffff0000); - sign = "-"; - } - else - sign = ""; - fprintf(stream, "\t%s, %s, %s%x", reg_names[(buffer[1] & HIGH4) >> 4], reg_names[buffer[1] & LOW4], sign, displacement); - return 4; - } - } - else { /* Conditional branches are hacked. */ - switch (type & 0x0f) { - - int displacement; - - case ibm032_JI: - fprintf(stream, ibm032_opcodes[opcodeIndex].mnemonic, mapCondition(type & ibm032_negative, buffer[0] & LOW4)); - putc('\t', stream); - print_address((buffer[1] << 1) + memaddr, stream); - return 2; - case ibm032_BI: - fprintf(stream, ibm032_opcodes[opcodeIndex].mnemonic, mapCondition(type & ibm032_negative, (buffer[1] & HIGH4) >> 4)); - putc('\t', stream); - displacement = (instructionBits & LOW20); - if ((displacement & (1 << 19)) != 0) /* Cover sign extension. */ - displacement |= 0xfff00000; - print_address((displacement * 2) + memaddr, stream); - return 4; - case ibm032_RR: - fprintf(stream, ibm032_opcodes[opcodeIndex].mnemonic, mapCondition(type & ibm032_negative, (buffer[1] & HIGH4) >> 4)); - fprintf(stream, "\t%s", reg_names[buffer[1] & LOW4]); - return 2; - } - } -} - -/* Converts a 4 bit "conditional specifier" into a semi-meaningful name. */ -static char *mapCondition(negative, conditionBits) - int conditionBits; -{ - - char *condition; - - if (negative) - switch (conditionBits) { - case 0x8: - condition = ""; - break; - case 0x9: - condition = "ge"; - break; - case 0xa: - condition = "ne"; - break; - case 0xb: - condition = "le"; - break; - case 0xc: - condition = "nc"; - break; - case 0xd: /* Reserved. */ - condition = "notbogus"; - break; - case 0xe: - condition = "no"; - break; - case 0xf: - condition = "ntb"; - break; - default: - condition = "notbogus"; - break; - } - else - switch (conditionBits) { - case 0x8: - condition = "nop"; - break; - case 0x9: - condition = "lt"; - break; - case 0xa: - condition = "eq"; - break; - case 0xb: - condition = "gt"; - break; - case 0xc: - condition = "c"; - break; - case 0xd: /* Reserved. */ - condition = "bogus"; - break; - case 0xe: - condition = "o"; - break; - case 0xf: - condition = "tb"; - break; - default: - condition = "bogus"; - break; - } - return condition; -} - -Only in .: m-ibm032.h - -/* Parameters for execution on an IBM RT, 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! -*/ - -/* Define this if the C compiler puts an underscore at the front - of external names before giving them to the linker. */ - -#define NAMES_HAVE_UNDERSCORE - -/* 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, 1) & 0x00ff; \ - if (op == 0xd9) { \ - pc += 4; \ - op = read_memory_integer (pc, 2); \ - if ((op & 0xff00) == 0xc100) { /* pcc prolog add r1, number */ \ - pc += 4; \ - op = read_memory_integer (pc, 1) & 0x00ff; \ - if (op == 0x6e) { /* cas r14, 0 */ \ - pc += 2; \ - op = read_memory_integer (pc, 2) & 0xffff; \ - if (op == 0xc8d1) pc += 4; /* cal r13, junk(r1) */ \ - } \ - } \ - else if ((op & 0xffff) == 0x6e00) { /* hc prolog cas r14, 0 */ \ - pc += 4; \ - op = read_memory_integer(pc, 1) & 0xff; \ - if (op == 0x6d) { /* cas r13 junk, probably */ \ - pc += 2; \ - op = read_memory_integer(pc, 2) & 0xffff; \ - if (op == 0xc811) pc += 4; /* cal r1, foo(r1) */ \ - } \ - } \ - } \ - while (1) { \ - /* now watch for st, sth, stc, and short versions thereof, cas instructions and exts */ \ - /* which are all used to store the parameters from r2-r5 onto the stack or into reg vars */ \ - op = read_memory_integer (pc, 2); \ - if ((op & 0xff00) == 0x3000 && (op & 0xf0) >= 0x20 && (op & 0xf0) <= 0x50) pc += 2; \ - else if ((op & 0xff00) == 0x2300 && (op & 0xf0) >= 0x20 && (op & 0xf0) <= 0x50) pc += 2; \ - else if ((op & 0xff00) == 0x1b00 && (op & 0xf0) >= 0x20 && (op & 0xf0) <= 0x50) pc += 2; \ - else if ((op & 0xff00) == 0x6c00 && (op & 0xf0) >= 0x20 && (op & 0xf0) <= 0x50) pc += 2; \ - else if ((op & 0xff00) == 0xb100) pc += 2; /* extend sign */ \ - else if ((op & 0xff00) == 0xdd00 && (op & 0xf0) >= 0x20 && (op & 0xf0) <= 0x50) pc += 4; \ - else break; \ - } \ -} - -/* 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_register (15) - -/* This is the amount to subtract from u.u_ar0 - to get the offset in the core file of the register values. */ - -#define KERNEL_U_ADDR (0x20000000 - NBPG * (UPAGES)) - -/* Address of end of stack space. */ - -/* extra page is for the "red zone" */ -#define STACK_END_ADDR (0x20000000 - NBPG * (UPAGES+1)) - -/* Stack grows downward. */ - -#define INNER_THAN < - -/* Sequence of bytes for breakpoint instruction. */ - -#define BREAKPOINT {0xbd, 0x00} - -/* Amount PC must be decremented by after a breakpoint. - This is often the number of bytes in BREAKPOINT - but not always. */ - -#define DECR_PC_AFTER_BREAK 0 - -/* Nonzero if instruction at PC is a return instruction. */ - -#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) & 0x00ff == 0xc9) - -/* Return 1 if P points to an invalid floating point value. */ - -#define INVALID_FLOAT(p) 0 /* Just a first guess; not checked */ - -/* Say how long (ordinary) registers are. */ - -#define REGISTER_TYPE long - -/* Number of machine registers */ - -#define NUM_REGS 18 - -/* Initializer for an array of names of registers. - There should be NUM_REGS strings in this initializer. */ - -#define REGISTER_NAMES {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "iar", "mq"} - -/* 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 13 /* Contains address of executing stack frame */ -#define SP_REGNUM 1 /* Contains address of top of stack */ -#define PS_REGNUM 17 /* Contains processor status */ -#define PC_REGNUM 16 /* Contains program counter */ - -#define REGISTER_U_ADDR(addr, blockend, regno) \ -{ addr = blockend + regno * 4; } - -/* Total amount of space needed to store our copies of the machine's - register state, the array `registers'. */ -#define REGISTER_BYTES (NUM_REGS*4) - -/* Index within `registers' of the first byte of the space for - register N. */ - -#define REGISTER_BYTE(N) ((N) * 4) - -/* Number of bytes of storage in the actual machine representation - for register N. On the vax, all regs are 4 bytes. */ - -#define REGISTER_RAW_SIZE(N) 4 - -/* Number of bytes of storage in the program's representation - for register N. On the vax, all regs are 4 bytes. */ - -#define REGISTER_VIRTUAL_SIZE(N) 4 - -/* Largest value REGISTER_RAW_SIZE can have. */ - -#define MAX_REGISTER_RAW_SIZE 4 - -/* Largest value REGISTER_VIRTUAL_SIZE can have. */ - -#define MAX_REGISTER_VIRTUAL_SIZE 4 - -/* Nonzero if register N requires conversion - from raw format to virtual format. */ - -#define REGISTER_CONVERTIBLE(N) 0 - -/* Convert data from raw format for register REGNUM - to virtual format for register REGNUM. */ - -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \ - bcopy ((FROM), (TO), 4); - -/* Convert data from virtual format for register REGNUM - to raw format for register REGNUM. */ - -#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \ - bcopy ((FROM), (TO), 4); - -/* Return the GDB type object for the "standard" data type - of data in register N. */ - -#define REGISTER_VIRTUAL_TYPE(N) builtin_type_int - -/* 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) (rt_prev_frame(thisframe)) - -#define FRAME_CHAIN_VALID(chain, thisframe) \ - (chain >= 0x10000000 && chain < 0x20000000) - -#define FRAME_CHAIN_COMBINE(chain, thisframe) (chain) - -/* Define other aspects of the stack frame. */ - -#define FRAME_SAVED_PC(frame) (rt_frame_reg(frame, 15)) - -#define FRAME_ARGS_ADDRESS(fi) (rt_frame_args(fi.frame)) - -#define FRAME_LOCALS_ADDRESS(fi) (fi.frame) - -/* Return number of args passed to a frame. - Can return -1, meaning no way to tell. */ - -#define FRAME_NUM_ARGS(val, fi) \ -{register struct rt_frame *tf; \ - tf = get_cached_frame(fi.frame); \ - val = -1; \ - if (tf) val = tf->nParms;\ -} - -/* Return number of bytes at start of arglist that are not really args. */ - -#define FRAME_ARGS_SKIP 0 - -/* Put here the code to store, into a struct frame_saved_regs, - the addresses of the saved registers of frame described by FRAME_INFO. - This includes special registers such as pc and fp saved in special - ways in the stack frame. sp is even more special: - the address we return for it IS the sp for the next frame. */ - -#define FRAME_FIND_SAVED_REGS(frame_info, frame_saved_regs) \ -{ register int regnum; \ - register struct rt_frame *tf; \ - register CORE_ADDR next_addr; \ - bzero (&(frame_saved_regs), sizeof (frame_saved_regs)); \ - tf = get_cached_frame((frame_info).frame); \ - if (tf) { \ - for(regnum = tf->firstReg; regnum < 16; regnum++) { \ - (frame_saved_regs).regs[regnum] = tf->firstRLoc+ 4*(regnum - tf->firstReg); \ - } \ - } \ -} - - -/* 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; \ - sp = push_word (sp, read_register (PC_REGNUM)); \ - for (regnum = 15; regnum >= 0; regnum--) \ - sp = push_word (sp, read_register (regnum)); \ - write_register (FP_REGNUM, sp+64); \ - write_register (SP_REGNUM, sp); } - -/* discard special frame pushed by PUSH_DUMMY_FRAME */ -#define POP_DUMMY_FRAME \ - {register CORE_ADDR sp; \ - register int regnum; \ - sp = read_register(FP_REGNUM)-64; \ - for(regnum = 0; regnum < 16;regnum++) { \ - write_register(regnum, read_memory_integer(sp, 4)); \ - sp += 4; \ - } \ - /* now get the pc */ \ - write_register(PC_REGNUM, read_memory_integer(sp, 4)); \ - sp += 4; \ - } - -/* Discard from the stack the innermost frame, restoring all registers. */ -/* THIS ROUTINE DOES NOT SET R1 (SP_REGNUM) CORRECTLY */ -/* REALLY MUST CONSULT TRACE TBL TO FIND OUT FRAME SIZE */ -#define POP_FRAME \ -{ register CORE_ADDR fp = read_register (FP_REGNUM); \ - register int regnum; \ - register struct rt_frame *tf; \ - tf = (struct rt_frame *) get_cached_frame(fp); \ - if (tf) { \ - for(regnum = tf->firstReg; regnum < 16; regnum++) { \ - write_register(regnum, \ - read_memory_integer (tf->firstRLoc + 4*(regnum-tf->firstReg), 4) \ - ); \ - } \ - write_register(PC_REGNUM, read_register(15)); \ - write_register(SP_REGNUM, tf->firstRLoc + 4*(16-tf->firstReg) + 36); \ - } \ -} - -/* This sequence of words is the instructions - ls r2,0(r1) 2 bytes pick up args - ls r3,4(r1) 2 bytes pick up args - ls r4,8(r1) 2 bytes pick up args - ls r5,c(r1) 2 bytes pick up args - cal r1,16(r1) 4 bytes fix up ap (==sp) - cal16 r15,<low> 4 bytes do call - oiu r15,<high>(r15) 4 - lr r0,r15 2 - ls r15,0(r15) 2 - balr r15 2 - bpt 2 get back to gdb - <4 byte trace table> 4 - -This is 16 bytes. -*/ - -#define CALL_DUMMY {0x70217131, 0x72417351, 0xc8110010, 0xc2f06969, \ - 0xc3ff6969, 0x60f070ff, 0xecffbd00, 0xdf7fdf00} - -#define CALL_DUMMY_LENGTH 32 - -#define CALL_DUMMY_START_OFFSET 0 - -/* 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) \ -{ *((short *)(((char *)dummyname)+14)) = fun&0xffff; \ -*((short *)(((char *)dummyname)+18)) = (fun>>16)&0xffff; \ -} - -/* 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, which we do not support. */ - -#define INIT_STACK(beg, end) \ -{ } - -/* Push the frame pointer register on the stack. */ -#define PUSH_FRAME_PTR \ -{ } - -/* Copy the top-of-stack to the frame pointer register. */ -#define POP_FRAME_PTR \ -{ } - -/* 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 \ -{ } - -/* 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 \ -{ } - -Only in .: m-ibm032init.h - -/* This is how the size of an individual .o file's text segment - is rounded on a sun. */ - -#define FILEADDR_ROUND(addr) ((addr + 3) & -4) - -diff -c ../../gnu/gdb/blockframe.c ./blockframe.c -*** ../../gnu/gdb/blockframe.c Sat Apr 4 22:06:18 1987 ---- ./blockframe.c Mon Apr 27 01:06:06 1987 -*************** -*** 53,62 **** - } - - void -! set_current_frame (frame) - FRAME frame; - { - current_frame = frame; - } - - /* Return the frame that called FRAME. ---- 53,67 ---- - } - - void -! set_current_frame (frame, validp) - FRAME frame; -+ int validp; - { - current_frame = frame; -+ #ifdef ibm032 -+ if (validp) -+ recache_frames(); -+ #endif - } - - /* Return the frame that called FRAME. -*************** -*** 291,301 **** - CORE_ADDR pc; - { - register int i; - - /* Note that the last thing in the vector is always _etext. */ - for (i = 0; i < misc_function_count; i++) - { -! if (pc < misc_function_vector[i].address) - return i - 1; - } - return -1; ---- 296,309 ---- - CORE_ADDR pc; - { - register int i; -+ register long j; - - /* Note that the last thing in the vector is always _etext. */ - for (i = 0; i < misc_function_count; i++) - { -! if ((j = misc_function_vector[i].address) < 0) -! continue; -! if (pc < j) - return i - 1; - } - return -1; -*************** -*** 325,333 **** ---- 333,610 ---- - } - } - -+ #ifdef ibm032 -+ /* RT frame format: -+ arg 3 these are not really here, but are in regs -+ arg 2 -+ arg 1 -+ arg 0 -+ resvd 20 bytes -+ rn to r15 saved regs -+ floating regs (at first assume 0 bytes, fix later) -+ locals -+ -+ N.B. r13 points 64 bytes below the end of the locals. -+ */ -+ -+ /* -+ * Routine for ibm032 stack trace. Called after a new frame has been set. Do an entire stack -+ * trace, and squirrel away the information. We need to do this since the ibm032 (rt) does -+ * not have enough info in a known place off of the frame ptr (r13) to do anything useful. -+ * Instead, one also requires the pc, and can then perform various operations to find -+ * out how that procedure built its frame, and thus, to decode it. However, since this is -+ * fairly slow, we only do it after a set_current_frame operation has been performed. -+ */ -+ -+ #define rtTTSize 50 -+ static struct rtTTCache { -+ CORE_ADDR lbound; /* lowest address so far known as using this trace table */ -+ CORE_ADDR ttaddr; /* address of the last '0xdf' in the trace table */ -+ char ttype; /* type of the trace table -- 0 == unused */ -+ } ttcache[rtTTSize]; -+ short ttptr = 0; -+ -+ #define rtSize 50 -+ static struct rt_frame rtFrames[rtSize]; -+ static int rtCount; -+ static CORE_ADDR rt_next_frame, rt_next_pc; -+ -+ static struct rtTTCache *ttfind (addr) -+ CORE_ADDR addr; { -+ register int i; -+ register struct rtTTCache *tp; -+ for(i=0,tp=ttcache;i<rtTTSize;i++,tp++) { -+ if (addr >= tp->lbound && addr <= tp->ttaddr) return tp; -+ } -+ return 0; -+ } -+ -+ static ttadd(lowaddr, ttaddr, type) -+ register CORE_ADDR lowaddr, ttaddr; -+ char type; { -+ register struct rtTTCache *tp; -+ if (tp = ttfind(ttaddr)) { -+ /* possibly increase the bound on this cache element */ -+ if (lowaddr < tp->lbound) tp->lbound = lowaddr; -+ } -+ else { -+ /* add a new element */ -+ tp = &ttcache[ttptr++]; -+ tp->lbound = lowaddr; -+ tp->ttaddr = ttaddr; -+ tp->ttype = type; -+ if (ttptr >= rtTTSize) ttptr = 0; /* keep it in bounds */ -+ } -+ } -+ -+ /* this routine scans for a trace table, and returns 4 bytes: 0 0 <n params> <first saved reg> */ -+ rt_num_regs (pc, tf) -+ register struct rt_frame *tf; -+ CORE_ADDR pc; { -+ register state = 0; -+ register long newpc = pc; -+ register int tc; -+ short nparms, firstreg; -+ short ttype; -+ short optx; -+ long offset; -+ char offtype; -+ struct rtTTCache *tp; -+ CORE_ADDR frame; -+ -+ frame = tf->frame; -+ /* first see if it is in our ttcache */ -+ if (tp = ttfind(pc)) { -+ state = 3; -+ ttype = tp->ttype; -+ newpc = tp->ttaddr; -+ } -+ else { -+ /* state machine to look for 'df' 'xx' 'df' */ -+ while (1) { -+ tc = read_memory_integer(newpc, 2); -+ if (state == 0 && (tc&0xff00) == 0xdf00) { -+ state = 1; -+ ttype = tc & 0xff; -+ } -+ else if (state == 1 && (tc & 0xff00) == 0xdf00) { -+ state = 3; -+ break; -+ } -+ else state = 0; -+ if (newpc - pc > 20000) break; -+ newpc += 2; -+ } -+ if (state == 3) ttadd(pc, newpc, ttype); /* add to cache */ -+ } -+ if (state != 3) { -+ printf("No trace table for pc %x, making one up.\n", pc); -+ tf->nParms = 0; -+ tf->firstReg = 12; -+ tf->firstRLoc = frame+64; -+ rt_next_pc = read_memory_integer(frame+64+12, 4); -+ rt_next_frame = read_memory_integer(frame+64+4, 4); -+ return 0; -+ } -+ /* otherwise newpc is pointing at the last 'df' in the trace table */ -+ else if (ttype == 3) { -+ /* funny trace table found by OBSERVATION (not doc) to be in program prolog */ -+ return -1; /* special value checked by recache_frames */ -+ } -+ else if (ttype == 2) { -+ /* assembly: no registers were saved */ -+ tf->nParms = 0; -+ tf->firstReg = 16; -+ tf->firstRLoc = 0; -+ rt_next_pc = read_register(15); /* where we go back to */ -+ rt_next_frame = frame; -+ tf->frame -= 100; /* hack to eliminate duplicate tags */ -+ return 0; -+ } -+ else if (ttype == 0x7f) { -+ /* special machine state frame saved by STACK_DUMMY */ -+ tf->nParms = 0; -+ tf->firstReg = 16; -+ tf->firstRLoc = 0; -+ rt_next_pc = read_memory_integer(frame + 64 - 64, 4); -+ rt_next_frame = read_memory_integer(frame -64 + 13*4, 4); -+ return 0; -+ } -+ else { -+ /* C program, I hope */ -+ nparms = (read_memory_integer(newpc+2, 1) >> 4) & 0x0f; -+ firstreg = ((tc=read_memory_integer(newpc+1, 1)) >> 4) & 0x0f; -+ optx = ((tc&4)? 1 : 0); /* flags says if floating registers described */ -+ offtype = read_memory_integer(newpc+optx+3, 1) & 0xff; -+ if ((offtype & 0xc0) == 0) { -+ /* 6 bits of local offset */ -+ offset = offtype & 0x3f; -+ } -+ else if ((offtype & 0xc0) == 0x40) { -+ /* 14 bits of local offset */ -+ offset = (offtype & 0x3f) << 8; -+ offset += (read_memory_integer(newpc+optx+4, 1) & 0xff); -+ } -+ else if ((offtype & 0xc0) == 0x80) { -+ /* 22 bits of local offset */ -+ offset = (offtype & 0x3f) << 8; -+ offset += (read_memory_integer(newpc+optx+4, 1) & 0xff); -+ offset <<= 8; -+ offset += (read_memory_integer(newpc+optx+5, 1) & 0xff); -+ } -+ else if ((offtype & 0xc0) == 0xc0) { -+ /* 30 bits of local offset */ -+ offset = (offtype & 0x3f) << 8; -+ offset += (read_memory_integer(newpc+optx+4, 1) & 0xff); -+ offset <<= 8; -+ offset += (read_memory_integer(newpc+optx+5, 1) & 0xff); -+ offset <<= 8; -+ offset += (read_memory_integer(newpc+optx+6, 1) & 0xff); -+ } -+ offset <<= 2; -+ tf->nParms = nparms; -+ tf->firstReg = firstreg; -+ tf->firstRLoc = frame /* initial frame location */ -+ + offset /* to top of frame */ -+ - 36 /* pascal static link, incomings args and linkage */ -+ - (4*(16-firstreg)); /* space used by general regs */ -+ rt_next_pc = read_memory_integer(tf->firstRLoc + 4*(15-firstreg), 4); -+ rt_next_frame = read_memory_integer(tf->firstRLoc + 4*(13-firstreg), 4); -+ return 0; -+ } -+ } -+ -+ recache_frames() { -+ register long i, j; -+ long pc; -+ CORE_ADDR curfp; -+ struct rt_frame *tf; -+ -+ pc = read_pc(); -+ curfp = current_frame; -+ rtCount = 0; -+ /* these next special cases can only occur with frame #0; others can't make calls -+ in these intermediate states. -+ */ -+ /* if pc points at br or brx, we're doing a return, so set the pc to the target */ -+ i=read_memory_integer(pc, 2); -+ if ((i & 0xfe00) == 0xe800) { -+ /* we're looking at a br or brx instruction */ -+ pc = read_register(i&0x0f); -+ } -+ /* also, if pc points at d9xx or c111 we're in the middle of a frame push, and should -+ use r15 for the pc. -+ */ -+ if ((i & 0xff00) == 0xd900 || (i & 0xffff) == 0xc111) { -+ pc = read_register(15); -+ } -+ while (1) { -+ if (curfp <= 0x10000000 || curfp >= 0x20000000) break; -+ if (pc > 0x20000000) break; -+ /* otherwise try to add a new frame structure */ -+ if (rtCount >= rtTTSize) break; -+ tf = &rtFrames[rtCount++]; -+ tf->frame = curfp; -+ tf->pc = pc; -+ i = rt_num_regs(pc, tf); -+ if (i<0) { /* exceptional values */ -+ rtCount--; /* last frame was bogus */ -+ break; -+ } -+ /* now setup for next iteration */ -+ pc = rt_next_pc; -+ curfp = rt_next_frame; -+ } -+ } -+ -+ struct rt_frame *get_cached_frame(aframe) -+ CORE_ADDR aframe; { -+ register int i; -+ for(i=0;i<rtCount;i++) { -+ if (rtFrames[i].frame == aframe) return &rtFrames[i]; -+ } -+ return 0; -+ } -+ -+ long rt_prev_frame(frame) -+ register CORE_ADDR frame; { -+ register int i; -+ for(i=0;i<rtCount-1;i++) { -+ if (rtFrames[i].frame == frame) return rtFrames[i+1].frame; -+ } -+ return 0; -+ } -+ -+ long rt_frame_reg(frame, reg) -+ CORE_ADDR frame; -+ register long reg; { -+ register struct rt_frame *tf; -+ tf = get_cached_frame(frame); -+ if (tf == 0) return 0; -+ if (tf->firstReg > reg) return 0; /* didn't save this one! */ -+ return read_memory_integer(tf->firstRLoc + 4 * (reg - tf->firstReg), 4); -+ } -+ -+ long rt_frame_args(frame) -+ CORE_ADDR frame; { -+ register struct rt_frame *tf; -+ tf = get_cached_frame(frame); -+ if (!tf) return 0; -+ return tf->firstRLoc + 20 + 4*(16 - tf->firstReg); -+ } -+ #endif -+ -+ blockinitialize() {initialize();} -+ - static - initialize () - { -+ #ifdef ibm032 -+ #ifdef CAMPHOR -+ add_com ("recache-frames", class_stack, recache_frames, -+ "Tell debugger to recompute PC/RT stack frame cache\n"); -+ #endif -+ #endif - } - - END_FILE -diff -c ../../gnu/gdb/breakpoint.c ./breakpoint.c -*** ../../gnu/gdb/breakpoint.c Sat Apr 4 22:22:44 1987 ---- ./breakpoint.c Sun Apr 26 23:02:20 1987 -*************** -*** 94,99 **** ---- 94,100 ---- - of last breakpoint hit. */ - - struct command_line *breakpoint_commands; -+ char new_breakpoint_commands = 0; /* Zalman Stern, ITC 1/12/1987 */ - - START_FILE - -*************** -*** 203,210 **** - { - execute_command (breakpoint_commands->line, 0); - /* If command was "cont", breakpoint_commands is 0 now. */ -! if (breakpoint_commands) - breakpoint_commands = breakpoint_commands->next; - } - clear_momentary_breakpoints (); - } ---- 204,213 ---- - { - execute_command (breakpoint_commands->line, 0); - /* If command was "cont", breakpoint_commands is 0 now. */ -! if (breakpoint_commands && !new_breakpoint_commands) /* Zalman Stern, ITC 1/12/1987 */ - breakpoint_commands = breakpoint_commands->next; -+ else /* Zalman Stern, ITC 1/12/1987 */ -+ new_breakpoint_commands = 0; /* Zalman Stern, ITC 1/12/1987 */ - } - clear_momentary_breakpoints (); - } -*************** -*** 215,220 **** ---- 218,225 ---- - void - clear_breakpoint_commands () - { -+ if (breakpoint_commands != 0) /* Zalman Stern, ITC 1/12/1987 */ -+ new_breakpoint_commands = 1; /* Zalman Stern, ITC 1/12/1987 */ - breakpoint_commands = 0; - breakpoint_auto_delete (0); - } -*************** -*** 921,926 **** ---- 926,933 ---- - struct cmd_list_element *enablelist; - - extern struct cmd_list_element *cmdlist; -+ -+ breakinitialize() {initialize();} - - static - initialize () -diff -c ../../gnu/gdb/command.c ./command.c -*** ../../gnu/gdb/command.c Sat Apr 4 22:24:07 1987 ---- ./command.c Sat Apr 25 17:18:15 1987 -*************** -*** 94,100 **** - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! */ - -- - #include "command.h" - #include <stdio.h> - ---- 94,99 ---- -*************** -*** 388,394 **** - { - if (nfound > 1 && allow_unknown >= 0) - { -! *p = 0; - ambbuf[0] = 0; - for (c = list; c; c = c->next) - if (!strncmp (*line, c->name, p - *line)) ---- 387,393 ---- - { - if (nfound > 1 && allow_unknown >= 0) - { -! *p = 0; - ambbuf[0] = 0; - for (c = list; c; c = c->next) - if (!strncmp (*line, c->name, p - *line)) -diff -c ../../gnu/gdb/core.c ./core.c -*** ../../gnu/gdb/core.c Sat Apr 4 22:27:23 1987 ---- ./core.c Mon Apr 27 13:20:47 1987 -*************** -*** 163,172 **** - int reg_offset; - - /* 4.2bsd-style core dump */ - val = myread (corechan, &u, sizeof u); - if (val < 0) -! perror_with_name (filename); - data_start = exec_data_start; - data_end = data_start + NBPG * u.u_dsize; - stack_start = stack_end - NBPG * u.u_ssize; - data_offset = NBPG * UPAGES; ---- 163,180 ---- - int reg_offset; - - /* 4.2bsd-style core dump */ -+ #ifdef ibm032 -+ /* on ibm032, uarea is at the far end of the u pages */ -+ lseek(corechan, UPAGES*NBPG - sizeof(u), 0); -+ #endif - val = myread (corechan, &u, sizeof u); - if (val < 0) -! perror_with_name (execfile); -! #ifdef ibm032 -! data_start = 0x10000000; -! #else - data_start = exec_data_start; -+ #endif - data_end = data_start + NBPG * u.u_dsize; - stack_start = stack_end - NBPG * u.u_ssize; - data_offset = NBPG * UPAGES; -*************** -*** 208,214 **** - corefile = concat (dirname, "/", filename); - } - -! set_current_frame (read_register (FP_REGNUM)); - select_frame (get_current_frame (), 0); - validate_files (); - } ---- 216,222 ---- - corefile = concat (dirname, "/", filename); - } - -! set_current_frame (read_register (FP_REGNUM), 1); - select_frame (get_current_frame (), 0); - validate_files (); - } -*************** -*** 523,528 **** ---- 531,539 ---- - - #endif /* not NEW_SUN_CORE */ - -+ -+ coreinitialize() {initialize();} -+ - static - initialize () - { -diff -c ../../gnu/gdb/dbxread.c ./dbxread.c -*** ../../gnu/gdb/dbxread.c Sat Apr 4 22:29:54 1987 ---- ./dbxread.c Fri May 15 15:52:24 1987 -*************** -*** 28,33 **** ---- 28,36 ---- - #include "initialize.h" - #include "symtab.h" - #include "param.h" -+ #ifdef CAMPHOR -+ #include "value.h" -+ #endif - - static void add_symbol_to_list (); - static void read_dbx_symtab (); -*************** -*** 89,94 **** ---- 92,109 ---- - int prev_line_number; - }; - -+ /* When dealing with dynamically loaded objects, the symbol table in the sym file -+ does not match where we actually load the files. Thus, gdb has to relocate those -+ symbols during dbxread. This is only used by the camphor support code, and -+ probably should be under an ifdef camphor. */ -+ -+ struct dlreloc -+ { -+ long text; -+ long data; -+ long bss; -+ } dlreloc; -+ - static struct subfile *subfiles; - - static struct subfile *current_subfile; -*************** -*** 1015,1020 **** ---- 1030,1037 ---- - register int i, nbl; - register struct blockvector *bv; - register struct block *b; -+ int j; -+ struct symbol *ts1, *ts2; - - for (s = symtab_list; s; s = s->next) - { -*************** -*** 1025,1034 **** ---- 1042,1238 ---- - b = BLOCKVECTOR_BLOCK (bv, i); - qsort (&BLOCK_SYM (b, 0), BLOCK_NSYMS (b), - sizeof (struct symbol *), compare_symbols); -+ /* Register parms have two decls, but the register one is the only one of interest */ -+ /* So, trash the name of the bad one, since binary srch could get either. Yucko. */ -+ /* doing name this way enables symbol freeing code to keep working */ -+ for(j=1;j<BLOCK_NSYMS(b);j++) -+ { -+ ts1 = BLOCK_SYM(b,j-1); -+ ts2 = BLOCK_SYM(b, j); -+ if (SYMBOL_NAMESPACE(ts1) == VAR_NAMESPACE -+ && SYMBOL_NAMESPACE(ts2) == VAR_NAMESPACE -+ && strcmp(SYMBOL_NAME(ts1), SYMBOL_NAME(ts2)) == 0) -+ {if (SYMBOL_CLASS(ts1) == LOC_REGISTER) -+ {SYMBOL_CLASS(ts2) = LOC_REGISTER; -+ SYMBOL_TYPE(ts2) = SYMBOL_TYPE(ts1); -+ SYMBOL_VALUE(ts2) = SYMBOL_VALUE(ts1); -+ } -+ else if (SYMBOL_CLASS(ts2) == LOC_REGISTER ) -+ {SYMBOL_CLASS(ts1) = LOC_REGISTER; -+ SYMBOL_TYPE(ts1) = SYMBOL_TYPE(ts2); -+ SYMBOL_VALUE(ts1) = SYMBOL_VALUE(ts2); -+ } -+ #ifdef notdef -+ else printf("Check out def of symbol %s\n", SYMBOL_NAME(ts1)); -+ #endif -+ } -+ } - } - } - } - -+ -+ #ifdef CAMPHOR -+ set_rel_command(exp) -+ char *exp; -+ { -+ struct expression *expr = (struct expression *) parse_c_expression (exp); -+ register value val; -+ register long temp; -+ register struct cleanup *old_chain -+ = make_cleanup (free_current_contents, &expr); -+ val = evaluate_expression (expr); -+ temp = value_as_long (val); -+ dlreloc.text = dlreloc.data = dlreloc.bss = temp; -+ printf("Relocation for all segs set to %x.\n", temp); -+ do_cleanups (old_chain); -+ } -+ -+ void -+ add_file_command (name) -+ char *name; -+ { -+ register int desc; -+ struct exec hdr; -+ struct nlist *nlist; -+ char *stringtab; -+ long buffer; -+ register int val; -+ extern void close (); -+ struct cleanup *old_chain; -+ int in_this_dir = 1; -+ struct symtab *symtab_temp; -+ -+ dont_repeat (); -+ -+ if (name == 0) -+ error_no_arg ("file to add symbols from"); -+ -+ if (symtab_list && !query ("Add more symbols from \"%s\"? ", name)) -+ error ("Not confirmed."); -+ -+ if (symfile) -+ free (symfile); -+ symfile = 0; -+ -+ desc = open (name, 0); -+ if (desc < 0) -+ { -+ if ((desc = openp (getenv ("BZPATH"), name, 0, 0)) < 0) -+ if ((desc = openp (getenv ("CLASSPATH"), name, 0, 0)) < 0) -+ desc = openp (getenv ("PATH"), name, 0, 0); -+ -+ in_this_dir = 0; -+ } -+ if (desc < 0) -+ perror_with_name (name); -+ -+ old_chain = make_cleanup (close, desc); -+ -+ val = myread (desc, &hdr, sizeof hdr); -+ if (val < 0) -+ perror_with_name (name); -+ -+ if (N_BADMAG (hdr)) -+ error ("File \"%s\" not in executable format.", name); -+ -+ if (hdr.a_syms == 0) -+ { -+ free_all_symtabs (); /* check this */ -+ return; -+ } -+ -+ /* Now read the string table, all at once. */ -+ val = lseek (desc, N_SYMOFF (hdr) + hdr.a_syms, 0); -+ if (val < 0) -+ perror_with_name (name); -+ val = myread (desc, &buffer, sizeof buffer); -+ if (val < 0) -+ perror_with_name (name); -+ stringtab = (char *) alloca (buffer); -+ bcopy (&buffer, stringtab, sizeof buffer); -+ val = myread (desc, stringtab + sizeof buffer, buffer - sizeof buffer); -+ if (val < 0) -+ perror_with_name (name); -+ -+ #ifdef READ_GDB_SYMSEGS -+ /* That puts us at the symsegs. Read them. */ -+ symseg_chain = read_symsegs (desc, name); -+ hash_symsegs (); -+ #else -+ /* Where people are using the 4.2 ld program, must not check for -+ symsegs, because that ld puts randonm garbage at the end of -+ the output file and that would trigger an error message. */ -+ symseg_chain = 0; -+ #endif -+ -+ /* Position to read the symbol table. Do not read it all at once. */ -+ val = lseek (desc, N_SYMOFF (hdr), 0); -+ if (val < 0) -+ perror_with_name (name); -+ -+ printf ("Reading symbol data from %s...", name); -+ fflush (stdout); -+ -+ init_misc_functions (); -+ make_cleanup (discard_misc_bunches, 0); -+ init_header_files (); -+ make_cleanup (free_header_files, 0); -+ -+ /* Remember symtab_list to check if the added file had any dbx info in it. */ -+ symtab_temp = symtab_list; -+ -+ /* Now that the symbol table data of the executable file are all in core, -+ process them and define symbols accordingly. Closes desc. */ -+ -+ read_dbx_symtab (desc, stringtab, hdr.a_syms / sizeof (struct nlist)); -+ -+ if (symtab_list == symtab_temp) { -+ printf("\n%s not compiled with -g, debugging posibilities are limited.\n", name); -+ fflush(stdout); -+ } -+ else { -+ -+ /* Sort symbols alphabetically within each block. */ -+ -+ sort_syms (); -+ -+ /* Go over the misc functions and install them in vector. */ -+ -+ condense_misc_bunches (); -+ -+ /* Make a default for file to list. */ -+ -+ select_source_symtab (symtab_list); -+ } -+ -+ do_cleanups (old_chain); -+ -+ /* Free the symtabs made by read_symsegs, but not their contents, -+ which have been copied into symtabs on symtab_list. */ -+ while (symseg_chain) -+ { -+ register struct symtab *s = symseg_chain->next; -+ free (symseg_chain); -+ symseg_chain = s; -+ } -+ -+ if (in_this_dir && name[0] != '/') -+ { -+ char dirname[MAXPATHLEN]; -+ -+ getwd (dirname); -+ symfile = concat (dirname, "/", -+ savestring (name, strlen (name))); -+ } -+ else -+ symfile = savestring (name, strlen (name)); -+ -+ printf ("done.\n"); -+ fflush (stdout); -+ } -+ #endif -+ - /* This is the symbol-file command. Read the file, analyze its symbols, - and add a struct symtab to symtab_list. */ - -*************** -*** 1047,1052 **** ---- 1251,1263 ---- - - dont_repeat (); - -+ #ifdef CAMPHOR -+ /* this command does not deal with automatically relocated stuff */ -+ dlreloc.text = 0; -+ dlreloc.data = 0; -+ dlreloc.bss = 0; -+ #endif -+ - if (name == 0) - error_no_arg ("file to read symbols from"); - -*************** -*** 1130,1151 **** - - read_dbx_symtab (desc, stringtab, hdr.a_syms / sizeof (struct nlist)); - - /* Sort symbols alphabetically within each block. */ - -! sort_syms (); - - /* Go over the misc functions and install them in vector. */ - -! condense_misc_bunches (); - - /* Don't allow char * to have a typename (else would get caddr_t.) */ - -! TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0; - - /* Make a default for file to list. */ - -! select_source_symtab (symtab_list); - - symfile = savestring (name, strlen (name)); - - do_cleanups (old_chain); ---- 1341,1372 ---- - - read_dbx_symtab (desc, stringtab, hdr.a_syms / sizeof (struct nlist)); - -+ /* Check to make sure file was compiled with -g. */ -+ -+ if (symtab_list == NULL) { -+ printf("\n%s not compiled with -g, debugging posibilities are limited.\n", name); -+ fflush(stdout); -+ } -+ else { -+ - /* Sort symbols alphabetically within each block. */ - -! sort_syms (); - - /* Go over the misc functions and install them in vector. */ - -! condense_misc_bunches (); - - /* Don't allow char * to have a typename (else would get caddr_t.) */ - -! TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0; - - /* Make a default for file to list. */ - -! select_source_symtab (symtab_list); - -+ } -+ - symfile = savestring (name, strlen (name)); - - do_cleanups (old_chain); -*************** -*** 1204,1209 **** ---- 1425,1440 ---- - { - fread (&buf, sizeof buf, 1, stream); - namestring = buf.n_un.n_strx ? buf.n_un.n_strx + stringtab : 0; -+ #ifdef CAMPHOR -+ if ((buf.n_type & N_TYPE) == N_UNDF) { -+ /* don't screw around with undefined symbols */ -+ } -+ else { -+ if ((buf.n_type & N_TYPE) == N_TEXT) buf.n_value += dlreloc.text; -+ else if ((buf.n_type & N_TYPE) == N_DATA) buf.n_value += dlreloc.data; -+ else if ((buf.n_type & N_TYPE) == N_BSS) buf.n_value += dlreloc.bss; -+ } -+ #endif - if (buf.n_type & N_STAB) - process_one_symbol (buf.n_type, buf.n_desc, - buf.n_value, namestring); -*************** -*** 1356,1361 **** ---- 1587,1596 ---- - } - } - -+ #ifdef ibm032 -+ static char hcState; /* two different, incompatible compilers for the RT */ -+ #endif -+ - static void - process_one_symbol (type, desc, value, name) - int type, desc; -*************** -*** 1363,1369 **** - char *name; - { - register struct context_stack *new; -! - /* Something is wrong if we see real data before - seeing a source file name. */ - ---- 1598,1633 ---- - char *name; - { - register struct context_stack *new; -! char tname[256]; -! /* Now, there are two compilers for the RT, and they are seriously incompatible. -! pcc is just like normal c compilers: stabs for a block occur before the LBRAC -! stab for that same block. Thus this code squirrels them away in the context -! and when the RBRAC is hit, restores local_symbols as of the time the LBRAC -! was encountered, and adds these symbosl to the block that just ended. -! -! However, with the HC compiler, those symbols occur *after* the LBRAC symbol -! declaring the block's start. Totally incompatible, of course. One expects no -! less from IBM. For hc compiled programs, we use the symbols in local_symbols -! *before* the RBRAC command pops the context stack. -! -! Amazingly enough, when we complained to IBM/Palo Alto about this incompatibility, -! they claimed that Mark Linton (original author of dbx) liked the new way better, and -! that he didn't even know that pcc used a different order. Sorta explains some things -! about dbx, n'est-ce pas? Furthermore, of course, IBM doesn't want to change -! either pcc or hc. -! -! Anyway, hc and pcc compiled .o files often co-exist in programs. How do we -! tell which is which? Stupid heuristic which doesn't work with programs -! with no top-level locals or parameters: after seeing a function's start, if we see -! an LBRAC before seeing a variable, then we are using hc, otherwise it is pcc. -! Stupid heuristics are better than none, so we use it. -! -! The variable hcState is used to keep track of this crap. -! 0 ==> saw function symbol -! 1 ==> saw lbrac in state 0, this is hc. -! 2 ==> saw symbol in state 0, this is pcc. -! */ -! - /* Something is wrong if we see real data before - seeing a source file name. */ - -*************** -*** 1384,1389 **** ---- 1648,1656 ---- - also the end of the lexical context for the previous function. */ - new = context_stack; - within_function = 1; -+ #ifdef ibm032 -+ hcState = 0; -+ #endif - if (new) - { - /* Make a block for the local symbols within. */ -*************** -*** 1400,1406 **** ---- 1667,1679 ---- - new->locals = 0; - new->old_blocks = pending_blocks; - new->start_addr = value; -+ #ifdef ibm032 -+ strcpy(tname, "."); -+ strcat(tname, name); -+ new->name = define_symbol(value, tname); -+ #else - new->name = define_symbol (value, name); -+ #endif - local_symbols = 0; - break; - -*************** -*** 1407,1412 **** ---- 1680,1688 ---- - case N_LBRAC: - /* This "symbol" just indicates the start of an inner lexical - context within a function. */ -+ #ifdef ibm032 -+ if (hcState == 0) hcState = 1; -+ #endif - new = (struct context_stack *) xmalloc (sizeof (struct context_stack)); - new->depth = desc; - new->next = context_stack; -*************** -*** 1422,1430 **** - /* This "symbol" just indicates the end of an inner lexical - context that was started with N_RBRAC. */ - new = context_stack; - if (new == 0 || desc != new->depth) - error ("Invalid symbol data: N_LBRAC/N_RBRAC symbol mismatch, symtab pos %d.", symnum); -- local_symbols = new->locals; - context_stack = new->next; - /* If this is not the outermost LBRAC...RBRAC pair in the - function, its local symbols preceded it, and are the ones ---- 1698,1711 ---- - /* This "symbol" just indicates the end of an inner lexical - context that was started with N_RBRAC. */ - new = context_stack; -+ #ifdef ibm032 -+ if (hcState == 2) /* pcc */ -+ local_symbols = new->locals; -+ #else -+ local_symbols = new->locals; -+ #endif - if (new == 0 || desc != new->depth) - error ("Invalid symbol data: N_LBRAC/N_RBRAC symbol mismatch, symtab pos %d.", symnum); - context_stack = new->next; - /* If this is not the outermost LBRAC...RBRAC pair in the - function, its local symbols preceded it, and are the ones -*************** -*** 1443,1448 **** ---- 1724,1733 ---- - new->start_addr + last_source_start_addr, - value + last_source_start_addr); - } -+ #ifdef ibm032 -+ if (hcState == 1 && context_stack->next) /* hc */ -+ local_symbols = new->locals; /* now we get them */ -+ #endif - free (new); - break; - -*************** -*** 1493,1498 **** ---- 1778,1786 ---- - break; - - default: -+ #ifdef ibm032 -+ if (hcState == 0) hcState = 2; -+ #endif - if (name) - define_symbol (value, name); - } -*************** -*** 1553,1558 **** ---- 1841,1849 ---- - Dbx data never actually contains 'l'. */ - case 'l': - SYMBOL_CLASS (sym) = LOC_LOCAL; -+ #ifdef ibm032 -+ if (hcState == 1) value += 1000000; /* temporary hack until rel 3 pcc matches hc */ -+ #endif - SYMBOL_VALUE (sym) = value; - SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; - add_symbol_to_list (sym, &local_symbols); -*************** -*** 1572,1577 **** ---- 1863,1875 ---- - add_symbol_to_list (sym, &local_symbols); - break; - -+ case 'R': -+ SYMBOL_CLASS (sym) = LOC_REGISTER; -+ SYMBOL_VALUE (sym) = value; -+ SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; -+ add_symbol_to_list (sym, &local_symbols); -+ break; -+ - case 'S': - /* Static symbol at top level of file */ - SYMBOL_CLASS (sym) = LOC_STATIC; -*************** -*** 1616,1622 **** - break; - - default: -! error ("Invalid symbol data: unknown symbol-type code `%c' at symtab pos %d.", deftype, symnum); - } - return sym; - } ---- 1914,1928 ---- - break; - - default: -! printf ("Unknown symbol-type code '%c' in dbx symbol table, assuming local.\n", deftype); -! SYMBOL_CLASS (sym) = LOC_LOCAL; -! #ifdef ibm032 -! if (hcState == 1) value += 1000000; /* temporary hack until rel 3 pcc matches hc */ -! #endif -! SYMBOL_VALUE (sym) = value; -! SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE; -! add_symbol_to_list (sym, &local_symbols); -! break; - } - return sym; - } -*************** -*** 1741,1746 **** ---- 2047,2056 ---- - (*pp) += 5; - else if (!strncmp (*pp, "r(0,1);0;", 9)) - (*pp) += 9; -+ #if 1 -+ else if ((**pp == 'r') && (!strncmp(*pp + 2, ";0;", 3))) -+ (*pp) += 5; -+ #endif - else break; - - TYPE_CODE (type) = TYPE_CODE_ARRAY; -*************** -*** 1980,1986 **** - rather than -128 which is what I would like. - So use n1 != 0 to prevent char from being taken as unsigned. */ - -! else if (n2 == 0 && n1 == 1) - { - /* an unsigned type */ - if (n3 == (1 << (8 * sizeof (int)))) ---- 2290,2296 ---- - rather than -128 which is what I would like. - So use n1 != 0 to prevent char from being taken as unsigned. */ - -! if (n2 == 0) - { - /* an unsigned type */ - if (n3 == (1 << (8 * sizeof (int)))) -*************** -*** 1989,1994 **** ---- 2299,2306 ---- - return builtin_type_unsigned_short; - if (n3 == (1 << (8 * sizeof (char)))) - return builtin_type_unsigned_char; -+ if (n3 == (1 << (8 * sizeof (char) - 1))) -+ return builtin_type_char; - } - else - { -*************** -*** 2002,2007 **** ---- 2314,2321 ---- - if (n3 == (1 << (8 * sizeof (char) - 1))) - return builtin_type_char; - } -+ if (n2 == 0 && n3 == 1) -+ return builtin_type_void; - error ("Invalid symbol data: range type spec %s at symtab pos %d.", - errp - 1, symnum); - } -*************** -*** 2033,2040 **** ---- 2347,2364 ---- - - /* Read the digits, as far as they go. */ - -+ #if 0 /* Yet another "Compiler sucks" fix. */ - while ((c = *p++) >= '0' && c <= '9') -+ #else -+ while (((c = *p++) >= '0' && c <= '9') || ((end != '\n') && (c == '\n'))) -+ #endif - { -+ #if 1 -+ if (c == '\n') { -+ printf("Ignoring bogus newline in stabs entry. Your compiler should be fixed.\n"); -+ continue; -+ } -+ #endif - n *= 10; - n += c - '0'; - } -*************** -*** 2050,2060 **** ---- 2374,2392 ---- - return n * sign; - } - -+ dbxinitialize() {initialize();} -+ - static - initialize () - { - symfile = 0; - -+ #ifdef CAMPHOR -+ add_com ("add-file", class_files, add_file_command, -+ "Add a new symbol table (in dbx format) from file FILE."); -+ add_com("set-rel", class_files, set_rel_command, -+ "Set relocation for add-file command to NUMBER."); -+ #endif - add_com ("symbol-file", class_files, symbol_file_command, - "Load symbol table (in dbx format) from executable file FILE."); - } -diff -c ../../gnu/gdb/environ.c ./environ.c -*** ../../gnu/gdb/environ.c Sat Apr 4 22:31:16 1987 ---- ./environ.c Sun Apr 26 23:48:05 1987 -*************** -*** 129,135 **** - - if (e->allocated < i) - { -! e->allocated = max (i, e->allocated + 10); - e->vector = (char **) xrealloc (e->vector, - (e->allocated + 1) * sizeof (char *)); - } ---- 129,136 ---- - - if (e->allocated < i) - { -! e->allocated = i + 10; - e->vector = (char **) xrealloc (e->vector, - (e->allocated + 1) * sizeof (char *)); - } -diff -c ../../gnu/gdb/eval.c ./eval.c -*** ../../gnu/gdb/eval.c Sat Apr 4 22:32:36 1987 ---- ./eval.c Mon Apr 27 00:01:27 1987 -*************** -*** 546,551 **** ---- 546,553 ---- - } - } - -+ evalinitialize() {initialize();} -+ - static - initialize () - { } -diff -c ../../gnu/gdb/expread.y ./expread.y -*** ../../gnu/gdb/expread.y Sat Apr 4 22:35:27 1987 ---- ./expread.y Sun Apr 26 23:56:51 1987 -*************** -*** 650,655 **** ---- 650,656 ---- - ; - else - { -+ /*N.B. error does a longjmp, so we do not have to worry about storage */ - err_copy = (char *) alloca (olen + 1); - bcopy (lexptr, err_copy, olen); - err_copy[olen] = 0; -*************** -*** 945,953 **** - { - register int len = sizeof (struct expression) + - expr->nelts * sizeof (union exp_element); -! register struct expression *temp -! = (struct expression *) alloca (len); - register int inpos = expr->nelts, outpos = 0; - - /* Copy the original expression into temp. */ - bcopy (expr, temp, len); ---- 946,955 ---- - { - register int len = sizeof (struct expression) + - expr->nelts * sizeof (union exp_element); -! register struct expression *temp; - register int inpos = expr->nelts, outpos = 0; -+ -+ temp = (struct expression *) alloca(len); - - /* Copy the original expression into temp. */ - bcopy (expr, temp, len); -diff -c ../../gnu/gdb/findvar.c ./findvar.c -*** ../../gnu/gdb/findvar.c Sat Apr 4 22:36:38 1987 ---- ./findvar.c Mon Apr 27 00:01:44 1987 -*************** -*** 359,364 **** ---- 359,366 ---- - return value_cast (lookup_pointer_type (SYMBOL_TYPE (var)), - value_from_long (builtin_type_long, addr)); - } -+ -+ findinitialize() {initialize();} - - static - initialize () -diff -c ../../gnu/gdb/firstfile.c ./firstfile.c -*** ../../gnu/gdb/firstfile.c Sat Apr 4 22:37:06 1987 ---- ./firstfile.c Mon Apr 27 00:02:06 1987 -*************** -*** 125,130 **** ---- 125,152 ---- - static initialize_dummy_1 (); - static initialize_dummy_2 (); - -+ initialize_all_files() { -+ blockinitialize(); -+ breakinitialize(); -+ coreinitialize(); -+ dbxinitialize(); -+ evalinitialize(); -+ findinitialize(); -+ infcmdinitialize(); -+ inflowinitialize(); -+ infruninitialize(); -+ symmiscinitialize(); -+ symtabinitialize(); -+ valarithinitialize(); -+ valopsinitialize(); -+ valprintinitialize(); -+ valuesinitialize(); -+ printcmdinitialize(); -+ sourceinitialize(); -+ stackinitialize(); -+ } -+ -+ #if 0 - initialize_all_files () - { - initialize_next_file ((char *) initialize_dummy_2 -*************** -*** 148,153 **** ---- 170,176 ---- - initialize_dummy_2 () - { - } -+ #endif - - /* This makes the function initialize_next_file. */ - -diff -c ../../gnu/gdb/frame.h ./frame.h -*** ../../gnu/gdb/frame.h Sat Apr 4 22:37:22 1987 ---- ./frame.h Mon Apr 27 00:02:14 1987 -*************** -*** 20,25 **** ---- 20,35 ---- - - /* Note that frame.h requires param.h! */ - -+ #ifdef ibm032 -+ struct rt_frame { -+ CORE_ADDR frame; /* frame address */ -+ CORE_ADDR pc; /* pc we called from */ -+ CORE_ADDR firstRLoc; /* loc'n of first saved general reg */ -+ short nParms; /* number of parameters to this frame */ -+ short firstReg; /* the reg stored at 64(fp) */ -+ }; -+ #endif -+ - #define FRAME CORE_ADDR - - struct frame_info -*************** -*** 62,64 **** ---- 72,77 ---- - extern struct block *get_selected_block (); - extern struct symbol *get_frame_function (); - extern struct symbol *get_pc_function (); -+ #ifdef ibm032 -+ extern struct rt_frame *get_cached_frame(); -+ #endif -diff -c ../../gnu/gdb/infcmd.c ./infcmd.c -*** ../../gnu/gdb/infcmd.c Sat Apr 4 22:47:22 1987 ---- ./infcmd.c Mon Apr 27 00:07:53 1987 -*************** -*** 39,45 **** - /* 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; - - /* Pid of our debugged inferior, or 0 if no inferior now. */ - ---- 39,45 ---- - /* 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 = NULL; - - /* Pid of our debugged inferior, or 0 if no inferior now. */ - -*************** -*** 112,119 **** - set_args_command (args) - char *args; - { -! free (inferior_args); -! if (!args) args = ""; - inferior_args = concat (" ", args, ""); - } - ---- 112,121 ---- - set_args_command (args) - char *args; - { -! if (inferior_args != NULL) -! free (inferior_args); -! if (!args) -! args = ""; - inferior_args = concat (" ", args, ""); - } - -*************** -*** 171,177 **** - signal (SIGINT, SIG_DFL); */ - - ptrace (0); -! execle ("/bin/sh", "sh", "-c", allargs, 0, - environ_vector (inferior_environ)); - - fprintf (stderr, "Cannot exec /bin/sh: %s.\n", ---- 173,180 ---- - signal (SIGINT, SIG_DFL); */ - - ptrace (0); -! -! execle ("/bin/csh", "csh", "-f", "-c", allargs, 0, - environ_vector (inferior_environ)); - - fprintf (stderr, "Cannot exec /bin/sh: %s.\n", -*************** -*** 473,478 **** ---- 476,482 ---- - - retbuf[0] = stop_r0; - retbuf[1] = stop_r1; -+ - val = value_being_returned (value_type, retbuf); - printf ("Value returned is $%d = ", record_latest_value (val)); - value_print (val, stdout); -*************** -*** 705,710 **** ---- 709,716 ---- - printf ("Contents are relative to selected stack frame.\n"); - } - -+ infcmdinitialize() {initialize();} -+ - static - initialize () - { -diff -c ../../gnu/gdb/inflow.c ./inflow.c -*** ../../gnu/gdb/inflow.c Sat Apr 4 22:56:34 1987 ---- ./inflow.c Mon Apr 27 00:12:10 1987 -*************** -*** 188,194 **** - inferior_pid = 0; - mark_breakpoints_out (); - if (have_core_file_p ()) -! set_current_frame (read_register (FP_REGNUM)); - } - - /* Resume execution of the inferior process. ---- 188,194 ---- - inferior_pid = 0; - mark_breakpoints_out (); - if (have_core_file_p ()) -! set_current_frame (read_register (FP_REGNUM), 1); - } - - /* Resume execution of the inferior process. -*************** -*** 266,271 **** ---- 266,274 ---- - char buf[MAX_REGISTER_RAW_SIZE]; - register int i; - -+ #ifdef ibm032 -+ offset += UPAGES*NBPG - sizeof(u); /* ibm032: ustruct at end of uarea */ -+ #endif - offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; - for (regno = 0; regno < NUM_REGS; regno++) - { -*************** -*** 291,296 **** ---- 294,303 ---- - register unsigned int regaddr; - char buf[80]; - -+ #ifdef ibm032 -+ offset += UPAGES*NBPG - sizeof(u); /* ibm032: ustruct at end of uarea */ -+ #endif -+ - offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; - - if (regno >= 0) -*************** -*** 340,347 **** - 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); ---- 347,355 ---- - register int count - = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); - /* Allocate buffer of that many longwords. */ -! register int *buffer; - -+ 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); -*************** -*** 367,377 **** - 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] ---- 375,386 ---- - register int count - = (((memaddr + len) - addr) + sizeof (int) - 1) / sizeof (int); - /* Allocate buffer of that many longwords. */ -! register int *buffer; - extern int errno; - - /* Fill start and end extra bytes of buffer with existing memory data. */ - -+ buffer = (int *) alloca (count * sizeof (int)); - buffer[0] = ptrace (1, inferior_pid, addr, 0); - if (count > 1) - buffer[count - 1] -*************** -*** 388,397 **** - { - errno = 0; - ptrace (4, inferior_pid, addr, buffer[i]); -! if (errno) - return 1; - } -- - return 0; - } - ---- 397,406 ---- - { - errno = 0; - ptrace (4, inferior_pid, addr, buffer[i]); -! if (errno) { - return 1; -+ } - } - return 0; - } - -*************** -*** 421,426 **** ---- 430,437 ---- - } - } - -+ inflowinitialize() {initialize();} -+ - static - initialize () - { -diff -c ../../gnu/gdb/infrun.c ./infrun.c -*** ../../gnu/gdb/infrun.c Sat Apr 4 22:57:15 1987 ---- ./infrun.c Mon Apr 27 00:17:40 1987 -*************** -*** 257,263 **** - pc_changed = 0; - fetch_inferior_registers (); - stop_pc = read_pc (); -! set_current_frame (read_register (FP_REGNUM)); - stop_frame = get_current_frame (); - stop_sp = read_register (SP_REGNUM); - another_trap = 0; ---- 257,271 ---- - pc_changed = 0; - fetch_inferior_registers (); - stop_pc = read_pc (); -! #ifdef CAMPHOR -! /* if we're not going to stop, don't bother with a stack trace */ -! if (WIFSTOPPED(w) && !signal_stop[WSTOPSIG(w)]) -! set_current_frame(read_register(FP_REGNUM), 0); -! else -! set_current_frame(read_register(FP_REGNUM), 1); -! #else -! set_current_frame (read_register (FP_REGNUM), 1); -! #endif - stop_frame = get_current_frame (); - stop_sp = read_register (SP_REGNUM); - another_trap = 0; -*************** -*** 688,700 **** - - /* Save the function value return registers - We might be about to restore their previous contents. */ -! stop_r0 = read_register (0); -! stop_r1 = read_register (1); - - if (stop_stack_dummy) - { - /* Pop the empty frame that contains the stack dummy. */ - POP_FRAME; - select_frame (read_register (FP_REGNUM), 0); - } - } ---- 696,717 ---- - - /* Save the function value return registers - We might be about to restore their previous contents. */ -! #ifdef ibm032 -! stop_r0 = read_register (2); -! stop_r1 = read_register (3); -! #else -! stop_r0 = read_register (0); -! stop_r1 = read_register (1); -! #endif - - if (stop_stack_dummy) - { - /* Pop the empty frame that contains the stack dummy. */ -+ #ifdef ibm032 -+ POP_DUMMY_FRAME; -+ #else - POP_FRAME; -+ #endif - select_frame (read_register (FP_REGNUM), 0); - } - } -*************** -*** 841,846 **** ---- 858,865 ---- - printf ("\nUse the \"handle\" command to change these tables.\n"); - } - -+ infruninitialize() {initialize();} -+ - static - initialize () - { -diff -c ../../gnu/gdb/initialize.h ./initialize.h -*** ../../gnu/gdb/initialize.h Sat Apr 4 22:58:27 1987 ---- ./initialize.h Sun May 24 00:19:21 1987 -*************** -*** 103,109 **** ---- 103,120 ---- - of the end of one object file's text to the start of the next - object file's text. */ - -+ /* Changed to use ifdefs on the machine type. David Nichols, 11/28/86 */ -+ #ifdef ibm032 -+ #include "m-ibm032init.h" -+ #endif -+ -+ #ifdef vax - #include "m-vaxinit.h" -+ #endif -+ -+ #ifdef sun -+ #include "m-suninit.h" -+ #endif - - /* This is used to make a file's initialization function. - It calls another function named `initialize', which must -diff -c ../../gnu/gdb/main.c ./main.c -*** ../../gnu/gdb/main.c Sat Apr 4 23:11:59 1987 ---- ./main.c Mon Apr 27 00:27:21 1987 -*************** -*** 236,241 **** ---- 236,243 ---- - if (*p) - { - c = lookup_cmd (&p, cmdlist, "", 0); -+ if (c->function == 0) -+ error ("That is not a command, just a help topic."); - if (c->class == (int) class_user) - { - if (*p) -*************** -*** 457,463 **** - - /* Add an element to the list of commands. */ - -! void - add_com (name, class, fun, doc) - char *name; - int class; ---- 459,465 ---- - - /* Add an element to the list of commands. */ - -! struct cmd_list_element * - add_com (name, class, fun, doc) - char *name; - int class; -*************** -*** 464,470 **** - void (*fun) (); - char *doc; - { -! add_cmd (name, class, fun, doc, &cmdlist); - } - - /* Add an alias or abbreviation command to the list of commands. */ ---- 466,473 ---- - void (*fun) (); - char *doc; - { -! -! return add_cmd (name, class, fun, doc, &cmdlist); - } - - /* Add an alias or abbreviation command to the list of commands. */ -*************** -*** 547,552 **** ---- 550,556 ---- - - if (c && c->class == (int) class_user) - free_command_lines (&c->function); -+ - - add_com (comname, class_user, cmds, - (c && c->class == (int) class_user) -diff -c ../../gnu/gdb/param.h ./param.h -*** ../../gnu/gdb/param.h Sat Apr 4 23:15:44 1987 ---- ./param.h Mon Apr 27 00:28:17 1987 -*************** -*** 1 **** ---- 1,19 ---- -+ /* Changed to use ifdefs so we don't have to edit it all the time. -+ David Nichols -+ 28 November 1986 */ -+ -+ #ifdef vax - #include "m-vax.h" -+ #endif -+ -+ #ifdef ibm032 -+ #include "m-ibm032.h" -+ #endif -+ -+ #ifdef sun -+ #ifdef mc68020 -+ #include "m-sun3.h" -+ #else -+ #include "m-sun2.h" -+ #endif -+ #endif -diff -c ../../gnu/gdb/pinsn.c ./pinsn.c -*** ../../gnu/gdb/pinsn.c Sat Apr 4 23:15:58 1987 ---- ./pinsn.c Mon Apr 27 00:28:36 1987 -*************** -*** 1 **** ---- 1,15 ---- -+ /* Changed to use ifdefs so we don't have to edit this. -+ David Nichols -+ 28 Nov 1986 */ -+ -+ #ifdef ibm032 -+ #include "ibm032-pinsn.c" -+ #endif -+ -+ #ifdef vax - #include "vax-pinsn.c" -+ #endif -+ -+ #ifdef sun -+ #include "m68k-pinsn.c" -+ #endif -diff -c ../../gnu/gdb/printcmd.c ./printcmd.c -*** ../../gnu/gdb/printcmd.c Sat Apr 4 23:17:03 1987 ---- ./printcmd.c Mon Apr 27 00:30:52 1987 -*************** -*** 797,804 **** - CORE_ADDR frame; - FILE *stream; - { -! char *space = (char *) alloca (TYPE_LENGTH (SYMBOL_TYPE (var))); - value val = read_var_value (var, frame); - value_print (val, stream); - } - ---- 797,805 ---- - CORE_ADDR frame; - FILE *stream; - { -! char *space; - value val = read_var_value (var, frame); -+ space = (char *) alloca (TYPE_LENGTH (SYMBOL_TYPE (var))); - value_print (val, stream); - } - -*************** -*** 883,888 **** ---- 884,891 ---- - } - } - -+ printcmdinitialize() {initialize();} -+ - static - initialize () - { -diff -c ../../gnu/gdb/source.c ./source.c -*** ../../gnu/gdb/source.c Sat Apr 4 23:17:55 1987 ---- ./source.c Mon Apr 27 00:31:25 1987 -*************** -*** 276,282 **** - 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, s->filename); - end = data + st.st_size; - p = data; ---- 276,283 ---- - 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, s->filename); - end = data + st.st_size; - p = data; -*************** -*** 530,535 **** ---- 531,538 ---- - printf ("Line number %d is out of range for \"%s\".\n", - sal.line, sal.symtab->filename); - } -+ -+ sourceinitialize() {initialize();} - - static - initialize () -diff -c ../../gnu/gdb/stack.c ./stack.c -*** ../../gnu/gdb/stack.c Sun Apr 5 00:28:05 1987 ---- ./stack.c Mon Apr 27 00:31:50 1987 -*************** -*** 511,516 **** ---- 511,517 ---- - - print_stack_frame (selected_frame, selected_frame_level, 1); - } -+ - - static void - return_command (retval_exp) -*************** -*** 538,543 **** ---- 539,546 ---- - frame_command ("0", 1); - } - -+ stackinitialize() {initialize();} -+ - static - initialize () - { -diff -c ../../gnu/gdb/symmisc.c ./symmisc.c -*** ../../gnu/gdb/symmisc.c Sun Apr 5 00:33:16 1987 ---- ./symmisc.c Mon Apr 27 00:37:46 1987 -*************** -*** 504,509 **** ---- 504,511 ---- - return i; - } - -+ symmiscinitialize() {initialize();} -+ - static - initialize () - { -diff -c ../../gnu/gdb/symtab.c ./symtab.c -*** ../../gnu/gdb/symtab.c Sun Apr 5 00:35:45 1987 ---- ./symtab.c Mon Apr 27 00:38:19 1987 -*************** -*** 71,78 **** - strcpy (copy, name); - strcat (copy, ".c"); - for (s = symtab_list; s; s = s->next) -! if (!strcmp (copy, s->filename)) - return s; - - return 0; - } ---- 71,79 ---- - strcpy (copy, name); - strcat (copy, ".c"); - for (s = symtab_list; s; s = s->next) -! if (!strcmp (copy, s->filename)) { - return s; -+ } - - return 0; - } -*************** -*** 703,709 **** - register struct symbol *sym; - register CORE_ADDR pc; - register int i; -! char *copy; - - /* Defaults have defaults. */ - ---- 704,710 ---- - register struct symbol *sym; - register CORE_ADDR pc; - register int i; -! char *copy, *dotcopy; - - /* Defaults have defaults. */ - -*************** -*** 818,825 **** ---- 819,847 ---- - /* Look up that token as a function. - If file specified, use that file's per-file block to start with. */ - -+ #ifdef ibm032 -+ /* RT has stupid dots in front of function names (_.foo), and worse, has bogus _foo -+ symbol to confuse us, too. -+ */ -+ if (*copy != '.') { -+ dotcopy = (char *) alloca (strlen(copy)+2); /* one for the null and one for the dot */ -+ dotcopy[0] = '.'; -+ strcpy(dotcopy+1, copy); -+ sym = lookup_symbol (dotcopy, s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), 1) : 0, -+ VAR_NAMESPACE); -+ } -+ else { -+ sym = 0; -+ dotcopy = 0; -+ } -+ if (!sym || SYMBOL_CLASS(sym) != LOC_BLOCK) { -+ sym = lookup_symbol (copy, s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), 1) : 0, -+ VAR_NAMESPACE); -+ } -+ #else - sym = lookup_symbol (copy, s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), 1) : 0, - VAR_NAMESPACE); -+ #endif - - if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) - { -*************** -*** 835,840 **** ---- 857,875 ---- - if (sym) - error ("%s is not a function.", copy); - -+ #ifdef ibm032 -+ /* try the dot version first */ -+ if (dotcopy) for (i = 0; i < misc_function_count; i++) -+ if (!strcmp (misc_function_vector[i].name, dotcopy)) -+ { -+ value.symtab = 0; -+ value.line = 0; -+ value.pc = misc_function_vector[i].address + FUNCTION_START_OFFSET; -+ if (funfirstline) -+ SKIP_PROLOGUE (value.pc); -+ return value; -+ } -+ #endif - for (i = 0; i < misc_function_count; i++) - if (!strcmp (misc_function_vector[i].name, copy)) - { -*************** -*** 1027,1032 **** ---- 1062,1069 ---- - - return type; - } -+ -+ symtabinitialize() {initialize();} - - static - initialize () -diff -c ../../gnu/gdb/utils.c ./utils.c -*** ../../gnu/gdb/utils.c Sun Apr 5 00:40:01 1987 ---- ./utils.c Mon Apr 27 00:40:01 1987 -*************** -*** 151,156 **** ---- 151,157 ---- - else - err = "unknown error"; - -+ /* ibm032: no core leak or other problems 'cause we alway call error -> longjmps away */ - combined = (char *) alloca (strlen (err) + strlen (string) + 3); - strcpy (combined, string); - strcat (combined, ": "); -diff -c ../../gnu/gdb/valarith.c ./valarith.c -*** ../../gnu/gdb/valarith.c Sun Apr 5 00:40:44 1987 ---- ./valarith.c Fri May 22 20:18:46 1987 -*************** -*** 239,245 **** - COERCE_ARRAY (arg1); - - len = TYPE_LENGTH (VALUE_TYPE (arg1)); -! p = VALUE_CONTENTS (arg1); - - while (--len >= 0) - { ---- 239,245 ---- - COERCE_ARRAY (arg1); - - len = TYPE_LENGTH (VALUE_TYPE (arg1)); -! p = (char *) VALUE_CONTENTS (arg1); - - while (--len >= 0) - { -*************** -*** 281,288 **** - && ((len = TYPE_LENGTH (VALUE_TYPE (arg1))) - == TYPE_LENGTH (VALUE_TYPE (arg2)))) - { -! p1 = VALUE_CONTENTS (arg1); -! p2 = VALUE_CONTENTS (arg2); - while (--len >= 0) - { - if (*p1++ != *p2++) ---- 281,288 ---- - && ((len = TYPE_LENGTH (VALUE_TYPE (arg1))) - == TYPE_LENGTH (VALUE_TYPE (arg2)))) - { -! p1 = (char *) VALUE_CONTENTS (arg1); -! p2 = (char *) VALUE_CONTENTS (arg2); - while (--len >= 0) - { - if (*p1++ != *p2++) -*************** -*** 348,353 **** ---- 348,355 ---- - return value_from_long (VALUE_TYPE (arg1), ~ value_as_long (arg1)); - } - -+ valarithinitialize() {initialize();} -+ - static - initialize () - { -diff -c ../../gnu/gdb/valops.c ./valops.c -*** ../../gnu/gdb/valops.c Sun Apr 5 00:41:32 1987 ---- ./valops.c Fri May 22 20:13:02 1987 -*************** -*** 174,180 **** - /* Return a value just like TOVAL except with the contents of FROMVAL. */ - - val = allocate_value (type); -! bcopy (toval, val, VALUE_CONTENTS (val) - (char *) val); - bcopy (VALUE_CONTENTS (fromval), VALUE_CONTENTS (val), TYPE_LENGTH (type)); - - return val; ---- 174,180 ---- - /* Return a value just like TOVAL except with the contents of FROMVAL. */ - - val = allocate_value (type); -! bcopy (toval, val, (char *) VALUE_CONTENTS (val) - (char *) val); - bcopy (VALUE_CONTENTS (fromval), VALUE_CONTENTS (val), TYPE_LENGTH (type)); - - return val; -*************** -*** 413,419 **** ---- 413,427 ---- - } - else if (code == TYPE_CODE_PTR) - { -+ #ifdef ibm032 -+ /* apparently '_a' pseudoprocedure has lval_memory as its lval type */ -+ if (VALUE_LVAL(function) == lval_memory) -+ funaddr = VALUE_ADDRESS(function); -+ else -+ funaddr = value_as_long (function); -+ #else - funaddr = value_as_long (function); -+ #endif - if (TYPE_CODE (TYPE_TARGET_TYPE (ftype)) - == TYPE_CODE_FUNC) - value_type = TYPE_TARGET_TYPE (TYPE_TARGET_TYPE (ftype)); -*************** -*** 429,439 **** - else - /* Handle integer used as address of a function. */ - funaddr = value_as_long (function); -- - value_type = builtin_type_int; - } -! else - error ("Invalid data type for function to be called."); - - /* Create a call sequence customized for this function - and the number of arguments for it. */ ---- 437,447 ---- - else - /* Handle integer used as address of a function. */ - funaddr = value_as_long (function); - value_type = builtin_type_int; - } -! else { - error ("Invalid data type for function to be called."); -+ } - - /* Create a call sequence customized for this function - and the number of arguments for it. */ -*************** -*** 590,595 **** ---- 598,605 ---- - return value_field (arg1, i); - } - -+ valopsinitialize() {initialize();} -+ - static - initialize () - { } -diff -c ../../gnu/gdb/valprint.c ./valprint.c -*** ../../gnu/gdb/valprint.c Sun Apr 5 00:42:28 1987 ---- ./valprint.c Mon Apr 27 00:40:56 1987 -*************** -*** 529,534 **** ---- 529,536 ---- - print_max = atoi (arg); - } - -+ valprintinitialize() {initialize();} -+ - static - initialize () - { -diff -c ../../gnu/gdb/value.h ./value.h -*** ../../gnu/gdb/value.h Sun Apr 5 00:43:44 1987 ---- ./value.h Fri May 22 20:03:32 1987 -*************** -*** 37,43 **** - short repeated; - short repetitions; - short regno; -! char contents[1]; - }; - - typedef struct value *value; ---- 37,43 ---- - short repeated; - short repetitions; - short regno; -! long contents[1]; /* Forces alignment... */ - }; - - typedef struct value *value; -diff -c ../../gnu/gdb/values.c ./values.c -*** ../../gnu/gdb/values.c Sun Apr 5 00:45:14 1987 ---- ./values.c Fri May 22 20:12:40 1987 -*************** -*** 338,344 **** - int offset, bitpos, bitsize; - value newval; - { -! register char *addr = VALUE_CONTENTS (var->value) + offset; - if (bitsize) - modify_field (addr, value_as_long (newval), - bitpos, bitsize); ---- 338,344 ---- - int offset, bitpos, bitsize; - value newval; - { -! register char *addr = (char *) VALUE_CONTENTS (var->value) + offset; - if (bitsize) - modify_field (addr, value_as_long (newval), - bitpos, bitsize); -*************** -*** 733,738 **** ---- 733,740 ---- - write_register (1, retbuf[1]); - } - -+ valuesinitialize() {initialize();} -+ - static - initialize () - { - diff --git a/gdb/=rt-extra b/gdb/=rt-extra deleted file mode 100644 index 827e1a1..0000000 --- a/gdb/=rt-extra +++ /dev/null @@ -1,84 +0,0 @@ -BABYL OPTIONS: -Version: 5 -Labels: -Note: This is the header of an rmail file. -Note: If you are seeing it in rmail, -Note: it means the file has no messages in it. - -1,, -Received: by PREP.AI.MIT.EDU; Mon, 25 May 87 04:03:20 EDT -Message-Id: <8705250803.AA14993@prep.ai.mit.edu> -Received: by po2.andrew.cmu.edu (5.54/3.15) id <AA00199> for rms@prep.ai.mit.edu; Mon, 25 May 87 04:02:41 EDT -Received: via switchmail; Mon, 25 May 87 04:02:29 edt -Received: FROM z.itc.cmu.edu VIA qmail - ID </cmu/common/mailqs/q004/QF.z.itc.cmu.edu.20b7fa53.6bb39>; - Mon, 25 May 87 04:01:27 edt -Received: FROM z.itc.cmu.edu VIA qmail - ID </cmu/itc/zs01/.Outgoing/QF.z.itc.cmu.edu.20b7fa49.a49502>; - Mon, 25 May 87 04:01:15 edt -From: zs01#@andrew.cmu.edu (Zalman Stern) -Date: Mon, 25 May 87 04:01:13 edt -To: rms@prep.ai.mit.edu -Subject: Small diff to yesterdays gdb diffs. - -*** EOOH *** -From: zs01#@andrew.cmu.edu (Zalman Stern) -Date: Mon, 25 May 87 04:01:13 edt -To: rms@prep.ai.mit.edu -Subject: Small diff to yesterdays gdb diffs. - -Richard, - -Here is another minor diff to the diassembler to get certain conditional -branches instructions correct... - -Also, I noticed that gcc.tar.Z is out of date with respect to gcc.tar . -When I go to get these files, should I go ahead and replace the compressed -version with a newer one or should I leave it alone? Likewise, should I try and -make a split version on prep? - --Z- - -*** ibm032-pinsn.c.old Mon May 25 03:31:04 1987 ---- ibm032-pinsn.c Mon May 25 03:47:12 1987 -*************** -*** 101,112 **** - } - } - else { /* Conditional branches are hacked. */ -! switch (type & 0x0f) { - - int displacement; - - case ibm032_JI: -! fprintf(stream, ibm032_opcodes[opcodeIndex].mnemonic, mapCondition(type & ibm032_negative, buffer[0] & LOW4)); - putc('\t', stream); - print_address((buffer[1] << 1) + memaddr, stream); - return 2; ---- 101,112 ---- - } - } - else { /* Conditional branches are hacked. */ -! switch (type & LOW4) { - - int displacement; - - case ibm032_JI: -! fprintf(stream, ibm032_opcodes[opcodeIndex].mnemonic, mapCondition(type & ibm032_negative, (buffer[0] & LOW3) + 8)); - putc('\t', stream); - print_address((buffer[1] << 1) + memaddr, stream); - return 2; -*** ibm032-opcode.h.old Mon May 25 03:33:19 1987 ---- ibm032-opcode.h Mon May 25 03:33:24 1987 -*************** -*** 11,16 **** ---- 11,17 ---- - - /* Various useful bit masks. */ - #define ibm032_typeMask 0x0f /* Mask to get actual type info out of instruction type. */ -+ #define LOW3 0x07 - #define LOW4 0x0f - #define HIGH4 0xf0 - #define LOW16 0x0000ffff - -
\ No newline at end of file diff --git a/gdb/=xgdb.msg b/gdb/=xgdb.msg deleted file mode 100644 index ac32300..0000000 --- a/gdb/=xgdb.msg +++ /dev/null @@ -1,997 +0,0 @@ -From beatty@unh.cs.cmu.edu Sat Jul 4 12:04:01 1987 -Received: by PREP.AI.MIT.EDU; Sat, 4 Jul 87 12:03:37 EDT -Message-Id: <8707041603.AA08600@prep.ai.mit.edu> -To: phr@prep.ai.mit.edu (Paul Rubin) -Date: Sat, 4 Jul 87 12:03:01 EDT -From: Derek Beatty <beatty@unh.cs.cmu.edu> -Subject: Re: gdb and X (msg 1 of 3) -Status: R - -This is part 1 of 3 parts. It consists of the cursor I used, and a message -I sent to Zalman Stern at Andrew regarding what I did, and why. The -code and context diffs will follow in other messages. - -#define gdb_width 16 -#define gdb_height 16 -#define gdb_x_hot 7 -#define gdb_y_hot 0 -static short gdb_bits[] = { - 0x0000, 0x0140, 0x0220, 0x0220, - 0x23e2, 0x13e4, 0x09c8, 0x0ff8, - 0x0220, 0x3ffe, 0x0630, 0x03e0, - 0x0220, 0x1ffc, 0x2632, 0x01c0}; - -#define gdb_mask_width 16 -#define gdb_mask_height 16 -#define gdb_mask_x_hot 7 -#define gdb_mask_y_hot 0 -static short gdb_mask_bits[] = { - 0x0360, 0x07f0, 0x07f0, 0x77f7, - 0x7fff, 0x7fff, 0x1ffc, 0x1ffc, - 0x7fff, 0x7fff, 0x7fff, 0x0ff8, - 0x3ffe, 0x7fff, 0x7fff, 0x7fff}; - -> -> The X support I added is minimal; it was inspired by Suntools' dbxtool, -> together with the availability of the V10 implementation of the X V11 -> toolkit specification. Design was guided by simplicity and the facilities -> of the toolkit. The debugger window provides a view into the code -> corresponding to the current stack frame, and several buttons for the -> breakpoint, print, step, next, continue, finish, up, and down commands. -> The standard gdb command interface remains available in the tty window from -> which gdb was started. The breakpoint and print buttons make use of the -> current selection, so you can do simple things like click at text in the -> source window, then click the "Go 'til" button to continue until that -> point. -> -> Such an interface is simple to program ( ~ 20 hours, about 700 lines), -> but it has some drawbacks. First, I didn't take the time to understand -> the longjmp's in gdb, and I'm not exactly happy with the idea of them -> jumping out of my callback procedures that were invoked by toolkit routines. -> There's one core dump bug (it shows up when gdb can't find a source -> file) that I haven't tracked down, and it may be related to this. Second, -> selection in the text window is not particularly graceful: double-clicking -> highlights one word of text, as the toolkit defines a word. It would -> be much more graceful were double-clicking to highlight a C identifier. -> Finally, and most seriously, most buttons operate by building textual -> command lines and passing them to gdb's execute_command function. This -> means that all selected expressions are evaluated and printed in the -> lexical scope corresponding to the current stack frame, although the -> selected text may be in a different lexical scope. This serious bug would -> require work to fix. -> -> I wrote the X support out of frustration at not having dbxtool available -> when I work on a vax. The hope of portability to V11 via the toolkit -> also helped motivate me to write V10 code at this late date. Finally, -> I'd never written any nontrivial code that ran on a windowing system -> (although that turns out still to be the case). Were I to make a more -> serious effort at this project, I would probably add a general "define-button" -> command akin to gdb's "define" command. -> -> Look in /usr/beatty/gnu/gdb on vlsi.cs.cmu.edu. All files I have modified -> are marked, and also have associated backups (.B extensions). Bennet -> Yee has a copy of the toolkit library; see /usr/bsy/Xtlib on f.gp.cs.cmu.edu. -> -> -- Derek -> - - -- Derek Beatty - -From beatty@unh.cs.cmu.edu Sat Jul 4 12:12:47 1987 -Received: by PREP.AI.MIT.EDU; Sat, 4 Jul 87 12:09:20 EDT -Message-Id: <8707041609.AA08643@prep.ai.mit.edu> -To: phr@PREP.AI.MIT.EDU (Paul Rubin) -Date: Sat, 4 Jul 87 12:07:25 EDT -From: Derek Beatty <beatty@unh.cs.cmu.edu> -Subject: Re: gdb and X (msg 2 of 3) -In-Reply-To: Message from "Paul Rubin" of Jul 4, 87 at 1:22 am -Status: R - -The following is "tool.c". I hereby grant permission to do anything you -like with it. - - -- Derek Beatty - -[nosave] -/* - * gdb tool for X V10R4 (using V11-compatible toolkit). - * Derek Beatty 30 June 87. - */ -#include <X/Xlib.h> -#include <X/Xt/Xtlib.h> -#include <stdio.h> - -#include "defs.h" -#include "symtab.h" - -#include "gdb.cursor" -#include "gdb_mask.cursor" - - - -/* forward refs */ - -static Window createFileText(); -/* - * Windows manipulated by this package. - */ - -static Window - icon, - frame, - srcLabelStrip, - srcText, - ctlPanel, - execLabelStrip; - -static Cursor curse; - -/* - * Source text display. - */ - -static struct symtab *displayedSymtab= 0; - -extern struct symtab *current_source_symtab; -extern int current_source_line; - -toolDisplaySource() -{ - char *fullName; - static Arg labelArgs[1]; - int linenumbers_changed= 0; - static int newWidget= 1; - - struct symtab_and_line get_selected_frame_sal(); - struct symtab_and_line sal; - - /* we could be called before we are initialized */ - if (!frame) return; - - sal= get_selected_frame_sal(); - - /* strictly this is wrong, but better than a blank display */ - if (sal.symtab==NULL) { - sal.symtab= current_source_symtab; - /* current_source_line may be off by a small number like 4 */ - sal.line= current_source_line; - } - - /* - * Switch to a new file if necessary. - */ - - if (sal.symtab) - linenumbers_changed= get_filename_and_charpos(sal.symtab, - sal.line, - &fullName); - if (!fullName) sal.symtab= NULL; - /* if the display may be wrong, destroy it */ - if (linenumbers_changed || displayedSymtab != sal.symtab) { - XtVPanedWindowDeletePane( srcText); - XtSendDestroyNotify( srcText); - XDestroyWindow( srcText); - srcText= 0; - } - /* if there's no display, create one */ - if (!srcText) { - newWidget= 1; - /* if there's no valid display, create a dummy display */ - if (!sal.symtab ) { - displayedSymtab= NULL; - srcText= createFileText(frame, "/dev/null"); - XtVPanedWindowAddPane(frame, srcText, 1, 20, 1000, 1); - /* create /dev/null text widget */ - XtSetArg(labelArgs[0], XtNlabel, "No source displayed."); - XtLabelSetValues(srcLabelStrip, labelArgs, XtNumber(labelArgs)); - } else { - displayedSymtab= sal.symtab; - srcText= createFileText(frame, fullName); - XtVPanedWindowAddPane(frame, srcText, 1, 20, 1000, 1); - XtSetArg(labelArgs[0], XtNlabel, fullName); - XtLabelSetValues(srcLabelStrip, labelArgs, XtNumber(labelArgs)); - /* free filename (maybe: check gdb code!) */ - } - } - - /* - * Update display and cursor positions as necessary. - * Cursor should be placed on line sal.line. - */ - - { - static int prevTop= 0, highWaterMark= 0; - int currentTop; - Arg textArgs[1]; - - /* get positions of start of display, and caret */ - XtSetArg(textArgs[0], XtNdisplayPosition, NULL); - XtTextGetValues(srcText, textArgs, XtNumber(textArgs)); - currentTop= cvtCharToLine(displayedSymtab, - (int) textArgs[0].value); - - highWaterMark += currentTop - prevTop; - - if ( sal.line < currentTop - || sal.line > highWaterMark - || newWidget) { - - /* warp the display */ - - newWidget= 0; - - /* yes, these magic numbers are ugly, but I don't know how - * to get the height of a text widget in a V11-portable way - */ - currentTop= (sal.line > 15) ? sal.line - 15 : 0; - highWaterMark= currentTop + 35; - - XtSetArg(textArgs[0], XtNdisplayPosition, - cvtLineToChar(displayedSymtab, currentTop)); - XtTextSetValues(srcText, textArgs, XtNumber(textArgs)); - } - XtSetArg(textArgs[0], XtNinsertPosition, - cvtLineToChar(displayedSymtab, sal.line)); - XtTextSetValues(srcText, textArgs, XtNumber(textArgs)); - - prevTop= currentTop; - } -} - -/* return the character position of a line */ -int -cvtLineToChar( s, line) - struct symtab *s; - int line; -{ - if (!s) return 0; - if (!s->line_charpos) return 0; - if (line < 0) line= 0; - if (line > s->nlines) line= s->nlines; - return *(s->line_charpos + line-1); -} - -/* return the line position of a character */ -int -cvtCharToLine( s, chr) - register struct symtab *s; - register int chr; -{ - register int lineNumber= 0; - register int *lnp; - - if (!s) return 0; - lnp= s->line_charpos; - /* files are usually short, so sequential search is Ok */ - while ( lineNumber < s->nlines && *lnp <= chr) { - lineNumber++; - lnp++; - } - if (lineNumber >= s->nlines) - lineNumber= s->nlines; - return lineNumber; -} - -/* - * title bar at bottom - */ - -static char *execFileName; - -toolSetExecFile(s) - char *s; -{ - execFileName= s; - if (execLabelStrip) { - static Arg labelArgs[1]; - - XtSetArg(labelArgs[0], XtNlabel, execFileName); - XtLabelSetValues(execLabelStrip, labelArgs, XtNumber(labelArgs)); - } -} - -/* - * Command line into which command are placed for execution. - * There's some ugly interaction between this and readline in main.c. - */ -extern char *line; -extern int linesize; - -/* - * Do any necessary prompting, etc. - */ -static char *gdbPrompt; - -static void -printPrompt() -{ - if (gdbPrompt) { - printf("%s", gdbPrompt); - fflush(stdout); - } -} - -/* - * Callback procedures for control panel. - */ - -/* used by "print" and "print*" buttons */ -static void printButnProc_1( starflag) - int starflag; -{ - int selnLen; - char *seln; - - char *cmd= starflag ? "print * " : "print "; - register int cmdlen= strlen(cmd); - - seln= XFetchBytes(&selnLen); - if (selnLen) { - if (selnLen+cmdlen >= linesize-1) { - linesize= (selnLen+cmdlen > linesize*2-1) ? selnLen+cmdlen+1 : linesize*2; - line= (char *) xrealloc(line, linesize); - } - strcpy(line, cmd); - strncpy(line+cmdlen, seln, selnLen); - *(line+cmdlen+selnLen)= '\0'; - execute_command(line, 0); - free(seln); - } - printPrompt(); -} - -static void printButnProc() -{ - printButnProc_1( 0); -} - -static void printStarButnProc() -{ - printButnProc_1( 1); -} - -static void nextButnProc() -{ - strcpy(line, "next"); - execute_command(line, 0); - toolDisplaySource(); - printPrompt(); -} - -static void stepButnProc() -{ - strcpy(line, "step"); - execute_command(line, 0); - toolDisplaySource(); - printPrompt(); -} - -static void contButnProc() -{ - strcpy(line, "cont"); - execute_command(line, 0); - toolDisplaySource(); - printPrompt(); -} - -static void finButnProc() -{ - strcpy(line, "finish"); - execute_command(line, 0); - toolDisplaySource(); - printPrompt(); -} - -/* used by "stop at" and "go till" buttons */ -static void stopAtButnProc_1( gotillFlag) - int gotillFlag; -{ - XtTextPosition start, finish; - static int lineNumber; - - XtTextGetSelectionPos(srcText, &start, &finish); - if (!displayedSymtab) - printf("No source file displayed.\n"); - else { - break_command_for_tool( displayedSymtab, - cvtCharToLine(displayedSymtab, start), - gotillFlag); - if (gotillFlag) { - strcpy(line, "cont"); - execute_command(line, 0); - toolDisplaySource(); - } - } - printPrompt(); -} - -static void stopAtButnProc() -{ - stopAtButnProc_1( 0); -} - -static void untilButnProc() -{ - stopAtButnProc_1( 1); -} - -/* decide if a character is trash */ -static int -garbage(c) - char c; -{ - if ('a' <= c && c <= 'z') return 0; - if ('A' <= c && c <= 'Z') return 0; - if ('0' <= c && c <= '9') return 0; - if (c == '_') return 0; - return 1; -} - -static void stopInButnProc() -{ - static int selnLen; - static char *seln; - char *sp, *selnp; - - seln= XFetchBytes(&selnLen); - if (selnLen) { - if (selnLen+6 >= linesize-1) { - linesize= (selnLen+6 > linesize*2-1) ? selnLen+7 : linesize*2; - line= (char *) xrealloc(line, linesize); - } - strcpy(line, "break "); - /* copy selection but not garbage */ - selnp= seln; - sp= line+strlen(line); - while (garbage(*selnp) && selnLen) selnp++, selnLen--; - while (!garbage(*selnp) && selnLen) { - *sp++= *selnp++; - selnLen--; - } - *sp= '\0'; - execute_command(line, 0); - free(seln); - } - printPrompt(); -} - -static void deIconifyButnProc() -{ - XUnmapWindow(icon); - XMapWindow(frame); -} - -static void iconifyButnProc() -{ - static Arg iconArgs[1]; - XtSetArg(iconArgs[0], XtNlabel, gdbPrompt); - XtCommandSetValues(icon, iconArgs, XtNumber(iconArgs)); - XUnmapWindow(frame); - XMapWindow(icon); -} - -static void upButnProc() -{ - strcpy(line, "up"); - execute_command(line, 0); - toolDisplaySource(); - printPrompt(); -} - -static void downButnProc() -{ - strcpy(line, "down"); - execute_command(line, 0); - toolDisplaySource(); - printPrompt(); -} - -#define addbutton(w) XtSetArg(buttons[buttoncount], XtNwindow, w); \ - buttoncount++; -static Arg buttons[20]; -static int buttoncount= 0; - -/* - * Create control panel buttons. - */ -static createButtons(parent) - Window parent; -{ - static Window button; - static Arg commandArgs[2]; - -#define crButn(label,fn) \ - XtSetArg(commandArgs[0], XtNlabel, label);\ - XtSetArg(commandArgs[1], XtNfunction, fn);\ - button= XtCommandCreate(parent, commandArgs, XtNumber(commandArgs));\ - addbutton(button); - - crButn("Brk At", stopAtButnProc); - crButn("Brk In", stopInButnProc); - crButn("Go 'til", untilButnProc); - - crButn("Print", printButnProc); - crButn("Print*", printStarButnProc); - - crButn("Next", nextButnProc); - crButn("Step", stepButnProc); - crButn("Cont", contButnProc); - crButn("Finish", finButnProc); - - crButn("Up", upButnProc); - crButn("Down", downButnProc); - - crButn("Iconify", iconifyButnProc); -#undef crButn -} - -static Window createLabel(parent, name, label) - Window parent; - char *name, *label; -{ - static Arg labelArgs[2]; - - XtSetArg(labelArgs[0], XtNname, name); - XtSetArg(labelArgs[1], XtNlabel, label); - return XtLabelCreate(frame, labelArgs, XtNumber(labelArgs)); -} - -static Window createFileText( parent, filename) - Window parent; - char *filename; -{ - static Arg fileArgs[2]; - - XtSetArg(fileArgs[0], XtNfile, filename); - XtSetArg(fileArgs[1], XtNtextOptions, scrollVertical); - return XtTextDiskCreate(parent, fileArgs, XtNumber(fileArgs)); -} - -/***************** Externally referenced routine **************/ -int createTool() -{ - static Arg frameArgs[]= { - {XtNwidth, (XtArgVal) 600}, - {XtNheight, (XtArgVal) 700}, - }; - - ResourceDataBase db; - FILE *rdbFile; - - /* - * init and database stuff... this is wrong but what the heck - */ - if (XOpenDisplay("") == NULL) - return 0; - printf("Initializing tool..."); fflush(stdout); - XtInitialize(); - /* should be checking .Xdefaults in $HOME */ - if ((rdbFile= fopen(".Xresources", "r")) != NULL) { - XtGetDataBase(rdbFile, &db); - XtSetCurrentDataBase(db); - fclose(rdbFile); - } - - /* - * create the frame - */ - frame= XtVPanedWindowCreate(RootWindow, frameArgs, XtNumber(frameArgs)); - - /* create source label strip and add to frame */ - srcLabelStrip= createLabel(frame, "Source File", "No source file yet."); - XtVPanedWindowAddPane(frame, srcLabelStrip, 0, 15, 15, 0); - - /* create text widget and add to frame */ - srcText= createFileText(frame, "/dev/null"); - XtVPanedWindowAddPane(frame, srcText, 1, 20, 1000, 1); - - /* create button box */ - ctlPanel= XtButtonBoxCreate(frame, NULL, 0); - createButtons( ctlPanel); - XtButtonBoxAddButton(ctlPanel, buttons, buttoncount); - XtVPanedWindowAddPane(frame, ctlPanel, 2, 30, 30, 0); - - /* create exec label strip and add */ - execLabelStrip= createLabel(frame, "Executable", - execFileName ? execFileName : "No executable specified."); - XtVPanedWindowAddPane(frame, execLabelStrip, 3, 15, 15, 0); - - - /* create icon */ - { - static Arg iconArgs[2]; - XtSetArg(iconArgs[0], XtNlabel, "(gdb)"); - XtSetArg(iconArgs[1], XtNfunction, deIconifyButnProc); - icon= XtCommandCreate(RootWindow, iconArgs, XtNumber(iconArgs)); - XMoveWindow(icon, 100, 100); /* HACK */ - XSetIconWindow(frame, icon); - } - - /* throw it onto the display */ - curse= XCreateCursor(gdb_width, gdb_height, gdb_bits, gdb_mask_bits, - gdb_x_hot, gdb_y_hot, - BlackPixel, WhitePixel, GXcopy); - XDefineCursor(frame, curse); - XDefineCursor(icon, curse); - XMapWindow(frame); - XMapSubwindows(frame); - XFlush(); - printf("done\n"); - return 1; -} - -/**************** Externally referenced routine. ***********/ -/* toolDispatcher -- dispatch events until data is available on fp */ -toolDispatcher(fp, prompt) - FILE *fp; - char *prompt; -{ - int inMask= 1 << fileno(fp); - int xMask= 1 << dpyno(); - int rfds= 0; - int nfds; - XEvent ev; - int pend; - - gdbPrompt= prompt; - - while (! (rfds & inMask)) { - pend= XPending(); - if (!pend) { - rfds= inMask | xMask; - /* this isn't right for 4.3 but it works 'cuz of 4.2 compatibility */ - nfds= select( 32, &rfds, 0, 0, (struct timeval *) 0); - } - if (pend || rfds & xMask) { - XNextEvent(&ev); - XtDispatchEvent(&ev); - } - } -} - -From beatty@unh.cs.cmu.edu Sat Jul 4 12:17:44 1987 -Received: by PREP.AI.MIT.EDU; Sat, 4 Jul 87 12:15:18 EDT -Message-Id: <8707041615.AA08691@prep.ai.mit.edu> -To: phr@PREP.AI.MIT.EDU (Paul Rubin) -Date: Sat, 4 Jul 87 12:14:08 EDT -From: Derek Beatty <beatty@unh.cs.cmu.edu> -Subject: Re: gdb and X (msg 3 of 3) -In-Reply-To: Message from "Paul Rubin" of Jul 4, 87 at 1:22 am -Status: R - -Context diffs follow. The original files are from GDB 2.1 (emacs distribution -18.40). - - -- Derek Beatty -[nosave] -*** /usr/misc/.gdb/src/core.c Fri Mar 27 12:20:14 1987 ---- core.c Sat Jul 4 11:12:16 1987 -*************** -*** 1,3 - /* Work with core dump and executable files, for GDB. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - - ---- 1,5 ----- -+ /* modified by Beatty 1 Jul 87 for gdb tool. */ -+ - /* Work with core dump and executable files, for GDB. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - -*************** -*** 257,262 - } - else if (from_tty) - printf ("No exec file now.\n"); - } - - /* If we have both a core file and an exec file, - ---- 259,267 ----- - } - else if (from_tty) - printf ("No exec file now.\n"); -+ #ifdef TOOL -+ toolSetExecFile( filename ? filename : "No executable specified.\n"); -+ #endif /* def TOOL */ - } - - /* If we have both a core file and an exec file, -*** /usr/misc/.gdb/src/breakpoint.c Fri Mar 27 12:20:11 1987 ---- breakpoint.c Wed Jul 1 11:27:31 1987 -*************** -*** 1,3 - /* Everything about breakpoints, for GDB. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - - ---- 1,5 ----- -+ /* modified by Beatty 1 Jul 87 for gdbtool */ -+ - /* Everything about breakpoints, for GDB. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - -*************** -*** 513,518 - break; - } - } - - /* Set a breakpoint according to ARG (function, linenum or *address) - and make it temporary if TEMPFLAG is nonzero. */ - ---- 515,571 ----- - break; - } - } -+ -+ #ifdef TOOL -+ /* set a breakpoint from a symtab and line */ -+ void break_command_for_tool( s, line, tempflag) -+ struct symtab *s; -+ int line; -+ int tempflag; -+ { -+ register struct breakpoint *b; -+ struct symtab_and_line sal; -+ -+ sal.symtab= s; -+ sal.line= line; -+ sal.pc= find_line_pc( sal.symtab, sal.line); -+ if (sal.pc==0) { -+ error("No line %d in file \"%s\".\n", sal.line, sal.symtab->filename); -+ } else { -+ b= set_raw_breakpoint( sal); -+ b->number= ++breakpoint_count; -+ b->cond= 0; -+ if (tempflag) -+ b->enable= temporary; -+ -+ printf ("Breakpoint %d at 0x%x", b->number, b->address); -+ if (b->symtab) -+ printf (": file %s, line %d.", b->symtab->filename, b->line_number); -+ printf ("\n"); -+ -+ { -+ int others = 0; -+ ALL_BREAKPOINTS (b) -+ if (b->address == sal.pc && b->number != breakpoint_count) -+ others++; -+ if (others > 0) -+ { -+ printf ("Note: breakpoint%s ", (others > 1) ? "s" : ""); -+ ALL_BREAKPOINTS (b) -+ if (b->address == sal.pc && b->number != breakpoint_count) -+ { -+ others--; -+ printf ("%d%s%s ", -+ b->number, -+ (b->enable == disabled) ? " (disabled)" : "", -+ (others > 1) ? "," : ((others == 1) ? " and" : "")); -+ } -+ printf (" also set at pc 0x%x\n", sal.pc); -+ } -+ } -+ } -+ } -+ #endif /* def TOOL */ - - /* Set a breakpoint according to ARG (function, linenum or *address) - and make it temporary if TEMPFLAG is nonzero. */ -*** /usr/misc/.gdb/src/main.c Fri Mar 27 12:20:45 1987 ---- main.c Sat Jul 4 11:13:32 1987 -*************** -*** 1,3 - /* Top level for GDB, the GNU debugger. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - - ---- 1,5 ----- -+ /* modified by Beatty 30 june 87 for gdb tool */ -+ - /* Top level for GDB, the GNU debugger. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - -*************** -*** 42,47 - - FILE *instream; - - void free_command_lines (); - char *read_line (); - static void initialize_main (); - ---- 44,54 ----- - - FILE *instream; - -+ #ifdef TOOL -+ /* flag indicating whether we are running in a window system */ -+ int isaTool= 0; -+ #endif /* def TOOL */ -+ - void free_command_lines (); - char *read_line (); - static void initialize_main (); -*************** -*** 214,219 - - while (1) - { - if (!setjmp (to_top_level)) - command_loop (); - clearerr (stdin); /* Don't get hung if C-d is typed. */ - ---- 221,232 ----- - - while (1) - { -+ -+ #ifdef TOOL -+ if (!isaTool) -+ isaTool= createTool(); -+ #endif /* def TOOL */ -+ - if (!setjmp (to_top_level)) - command_loop (); - clearerr (stdin); /* Don't get hung if C-d is typed. */ -*************** -*** 270,275 - printf ("%s", prompt); - fflush (stdout); - - quit_flag = 0; - execute_command (read_line (instream == stdin), instream == stdin); - /* Do any commands attached to breakpoint we stopped at. */ - ---- 283,294 ----- - printf ("%s", prompt); - fflush (stdout); - -+ #ifdef TOOL -+ toolDisplaySource(); -+ if (isaTool) toolDispatcher(instream, -+ instream==stdin ? prompt : NULL); -+ #endif /* def TOOL */ -+ - quit_flag = 0; - execute_command (read_line (instream == stdin), instream == stdin); - /* Do any commands attached to breakpoint we stopped at. */ -*************** -*** 320,325 - - while (1) - { - c = fgetc (instream); - if (c == -1 || c == '\n') - break; - ---- 339,345 ----- - - while (1) - { -+ - c = fgetc (instream); - if (c == -1 || c == '\n') - break; -*************** -*** 765,770 - 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 - ---- 785,793 ----- - 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); -+ #ifdef TOOL -+ printf( "(CMU X support is available in this version.)\n"); -+ #endif - } - - static void -*** /usr/misc/.gdb/src/source.c Fri Mar 27 12:20:50 1987 ---- source.c Wed Jul 1 17:56:58 1987 -*************** -*** 1,3 - /* List lines of source files for GDB, the GNU debugger. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - - ---- 1,5 ----- -+ /* modified 1 July 87 by Beatty for gdbtool */ -+ - /* List lines of source files for GDB, the GNU debugger. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - -*************** -*** 295,300 - s->nlines = nlines; - s->line_charpos = (int *) xrealloc (line_charpos, nlines * sizeof (int)); - } - - /* Print source lines from the file of symtab S, - starting with line number LINE and stopping before line number STOPLINE. */ - ---- 297,328 ----- - s->nlines = nlines; - s->line_charpos = (int *) xrealloc (line_charpos, nlines * sizeof (int)); - } -+ -+ #ifdef TOOL -+ /* Get full pathname and line number positions for a symtab -+ * return nonzero if line numbers may have changed -+ * set full pathname to NULL if no file 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; -+ } -+ #endif /* def TOOL */ -+ - - /* Print source lines from the file of symtab S, - starting with line number LINE and stopping before line number STOPLINE. */ -*** /usr/misc/.gdb/src/stack.c Fri Mar 27 12:20:51 1987 ---- stack.c Wed Jul 1 17:27:34 1987 -*************** -*** 1,3 - /* Print and select stack frames for GDB, the GNU debugger. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - - ---- 1,5 ----- -+ /* modified by Beatty 1 Jul 87 for gdbtool */ -+ - /* Print and select stack frames for GDB, the GNU debugger. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. - -*************** -*** 42,47 - static void select_calling_frame (); - - void print_frame_info (); - - /* Print a stack frame briefly. FRAME should be the frame address - and LEVEL should be its level in the stack (or -1 for level not defined). - ---- 44,62 ----- - static void select_calling_frame (); - - void print_frame_info (); -+ -+ #ifdef TOOL -+ /* get symtab and line of selected frame, for tool display */ -+ struct symtab_and_line -+ get_selected_frame_sal() -+ { -+ struct frame_info fi; -+ -+ fi= get_frame_info( selected_frame); -+ return find_pc_line(fi.pc, fi.next_frame); -+ } -+ -+ #endif /* TOOL */ - - /* Print a stack frame briefly. FRAME should be the frame address - and LEVEL should be its level in the stack (or -1 for level not defined). -End of context diffs. The presence of this line verifies that this message -has not been truncated. - diff --git a/gdb/COPYING b/gdb/COPYING deleted file mode 100644 index 9f3a6dc..0000000 --- a/gdb/COPYING +++ /dev/null @@ -1,138 +0,0 @@ - - GDB GENERAL PUBLIC LICENSE - (Clarified 20 March 1987) - - Copyright (C) 1986 Richard M. Stallman - Everyone is permitted to copy and distribute verbatim copies - of this license, but changing it is not allowed. - - The license agreements of most software companies keep you at the -mercy of those companies. By contrast, our general public license is -intended to give everyone the right to share GDB. To make sure that -you get the rights we want you to have, we need to make restrictions -that forbid anyone to deny you these rights or to ask you to surrender -the rights. Hence this license agreement. - - Specifically, we want to make sure that you have the right to give -away copies of GDB, that you receive source code or else can get it -if you want it, that you can change GDB or use pieces of it in new -free programs, and that you know you can do these things. - - To make sure that everyone has such rights, we have to forbid you to -deprive anyone else of these rights. For example, if you distribute -copies of GDB, you must give the recipients all the rights that you -have. You must make sure that they, too, receive or can get the -source code. And you must tell them their rights. - - Also, for our own protection, we must make certain that everyone -finds out that there is no warranty for GDB. If GDB is modified by -someone else and passed on, we want its recipients to know that what -they have is not what we distributed, so that any problems introduced -by others will not reflect on our reputation. - - Therefore we (Richard Stallman and the Free Software Foundation, -Inc.) make the following terms which say what you must do to be -allowed to distribute or change GDB. - - - COPYING POLICIES - - 1. You may copy and distribute verbatim copies of GDB source code as -you receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy a valid copyright notice "Copyright -(C) 1986 Free Software Foundation, Inc." (or with the year updated if -that is appropriate); keep intact the notices on all files that refer -to this License Agreement and to the absence of any warranty; and give -any other recipients of the GDB program a copy of this License -Agreement along with the program. You may charge a distribution fee -for the physical act of transferring a copy. - - 2. You may modify your copy or copies of GDB or any portion of it, -and copy and distribute such modifications under the terms of -Paragraph 1 above, provided that you also do the following: - - a) cause the modified files to carry prominent notices stating - that you changed the files and the date of any change; and - - b) cause the whole of any work that you distribute or publish, - that in whole or in part contains or is a derivative of GDB or any - part thereof, to be licensed at no charge to all third parties on - terms identical to those contained in this License Agreement - (except that you may choose to grant more extensive warranty - protection to third parties, at your option). - - c) if the modified program serves as a debugger, cause it - when started running in the simplest and usual way, to print - an announcement including a valid copyright notice - "Copyright (C) 1986 Free Software Foundation, Inc." (or with - the year updated if appropriate), saying that there - is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of - this License Agreement. - - d) You may charge a distribution fee for the physical act of - transferring a copy, and you may at your option offer warranty - protection in exchange for a fee. - - 3. You may copy and distribute GDB or any portion of it in -compiled, executable or object code form under the terms of Paragraphs -1 and 2 above provided that you do the following: - - a) cause each such copy to be accompanied by the - corresponding machine-readable source code, which must - be distributed under the terms of Paragraphs 1 and 2 above; or, - - b) cause each such copy to be accompanied by a - written offer, with no time limit, to give any third party - free (except for a nominal shipping charge) a machine readable - copy of the corresponding source code, to be distributed - under the terms of Paragraphs 1 and 2 above; or, - - c) in the case of a recipient of GDB in compiled, executable - or object code form (without the corresponding source code) you - shall cause copies you distribute to be accompanied by a copy - of the written offer of source code which you received along - with the copy you received. - - 4. You may not copy, sublicense, distribute or transfer GDB -except as expressly provided under this License Agreement. Any attempt -otherwise to copy, sublicense, distribute or transfer GDB is void and -your rights to use the program under this License agreement shall be -automatically terminated. However, parties who have received computer -software programs from you with this License Agreement will not have -their licenses terminated so long as such parties remain in full compliance. - - 5. If you wish to incorporate parts of GDB into other free -programs whose distribution conditions are different, write to the Free -Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet -worked out a simple rule that can be stated here, but we will often permit -this. We will be guided by the two goals of preserving the free status of -all derivatives of our free software and of promoting the sharing and reuse -of software. - -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! - - NO WARRANTY - - BECAUSE GDB IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY NO -WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT -WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, -RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE GDB "AS IS" WITHOUT -WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND -PERFORMANCE OF GDB IS WITH YOU. SHOULD GDB PROVE DEFECTIVE, YOU -ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. -STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY -WHO MAY MODIFY AND REDISTRIBUTE GDB AS PERMITTED ABOVE, BE LIABLE TO -YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER -SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR -INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA -BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A -FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GDB, EVEN -IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR -ANY CLAIM BY ANY OTHER PARTY. diff --git a/gdb/ChangeLog b/gdb/ChangeLog deleted file mode 100644 index 301bdac..0000000 --- a/gdb/ChangeLog +++ /dev/null @@ -1,1025 +0,0 @@ -Fri Jan 15 05:09:18 1988 Richard Stallman (rms at frosted-flakes) - - * valprint.c [IEEE_FLOAT]: New function `is_nan' checks - whether a double is a nan. - - * printcmd.c (print_formatted) [IEEE_FLOAT]: - Detect nans and print specially. - * valprint.c (val_print) [IEEE_FLOAT]: Same thing. - - * m68k-pinsn.c (convert_{to,from}_68881): Hand-assemble - all the assembler code. - - * m-newsinit.h, m-news800.h: Two new files. - -Thu Jan 7 22:25:16 1988 Richard Stallman (rms at frosted-flakes) - - * valops.c (value_assign): Don't coerce the arg being stored in. - Coercion is not right either for an array or for an enum. - -Tue Jan 5 00:59:29 1988 Richard Stallman (rms at frosted-flakes) - - * symtab.c (decode_line_1): Don't complain about no symtabs loaded - until after trying the misc function table. - -Sat Jan 2 13:16:08 1988 Richard Stallman (rms at frosted-flakes) - - * stack.c (record_selected_frame): New fn to access - the selected frame and its level. - * infcmd.c (run_stack_dummy): Save and restore the selected - frame and its level. - -Wed Dec 30 18:44:41 1987 Richard Stallman (rms at frosted-flakes) - - * valprint.c (type_print_varspec_prefix): - Treat arrays just like functions. - * valprint.c (type_print_varspec_{prefix,suffix}): - When passed_a_ptr is handled, pass 0 for it in the recursive call. - -Fri Dec 18 10:24:14 1987 Richard Stallman (rms at frosted-flakes) - - * findvar.c (read_var_value): Share code between values really - in registers and values in saved registers. - Register short on a big-endian machine needs a VALUE_OFFSET. - - * findvar.c (locate_var_value): Offset the address of a - saved register variable that's shorter than the register. - -Thu Dec 17 08:26:31 1987 Richard Stallman (rms at lucky-charms) - - * valprint.c (type_print_base): Print nameless bit fields - to indicate gaps before bit fields. - - * source.c (select_source_symtab): Ignore .h files. - Also, if a function `main' exists, make the default listing line - the beginning of `main'. - - * breakpoint.c ({get,set}_breakpoint_commands): - Commands to examine or set the pending breakpoint-commands. - - * infcmd.c (run_stack_dummy): Save and restore the breakpoint - commands around the function call. - - * stack.c (return_command): Don't query or print if not interactive. - - * value.h (COERCE_ENUM): New macro: if arg is enum, convert to int. - * value.h (COERCE_ARRAY): Do that, as well as old job. - - * valarith.c (value_binop, value_neg, value_lognot): - Use COERCE_ENUM on the arguments. - * valops.c (value_arg_coerce): Likewise. - * valops.c (value_cast): AVOID coercing enums when arrays are. - - * eval.c (evaluate_subexp): In the BINOP_SUB case, - use evaluate_subexp_with_coercion. - - * inflow.c (terminal_ours_1, terminal_inferior): - Ignore inferior_thisrun_terminal since our terminal - is the inferior's controlling terminal regardless. - - * m-sun3.h: Fix assembler syntax for kdb macros. - - * infcmd.c ({attach,detach}_command): New functions from Dave Taylor. - * inflow.c (attach, detach): New functions from Dave Taylor. - * infrun.c (attach_process): New function, middle-level. - Does all the work of attaching a process, assuming there is no - inferior yet, except for printing and querying. - - * infrun.c (clear_proceed_status): Clear `stop_after_attach'. - * infrun.c (wait_for_inferior): Handle `stop_after_attach'. - -Sat Dec 12 04:36:39 1987 Richard Stallman (rms at corn-chex) - - * dbxread.c (end_symtab): The free_code for a symseg got - from a file should be free_linetable. - - * dbxread.c: Allocate blockvector, blocks, symbols and symbol names - from the symbol-obstack, and use free_linetable for all files. - The typevector is still malloc'd, so put it in the free_ptr - to get it freed. - - * symmisc.c (free_symtab): Always free the `free_ptr' if nonzero. - `free_explicit' therefore now the same as `free_nothing'. - - * dbxread.c (define_symbol): Handle defn code 'c', used by - fortran, which defines integer and real constant symbols. - - * symseg.h: Define LOC_CONST_BYTES for constants longer than a - word. New `bytes' alternative for the value of a symbol. - - * symtab.h (SYMBOL_VALUE_BYTES): Macro to access `bytes'. - - * findvar.c ({read,locate}_var_value): Handle LOC_CONST_BYTES. - * printcmd.c (address_info): Handle LOC_CONST_BYTES. - * symmisc.c (print_symbol): Handle LOC_CONST_BYTES. - -Tue Dec 8 20:26:37 1987 Richard Stallman (rms at frosted-flakes) - - * symtab.c (find_line_pc_range): Detection of last line in file - was erroneous. - -Fri Dec 4 21:52:52 1987 Richard Stallman (rms at frosted-flakes) - - * dbxread.c (read_range_type): Accept the typenums as argument. - Use read_type_number to read the subrange-of type. - A type defined as a subrange of itself is void. - -Thu Dec 3 12:45:10 1987 Richard Stallman (rms at frosted-flakes) - - * inflow.c ({fetch,store}_inferior_registers): Support UMAX_PTRACE. - - * m-umax.h: New file, for Encore machines. - - * core.c (exec_file_command, etc): Decode COFF files. - * core.c (core_file_command): Support UMAX_CORE format. - * core.c (validate_files, exec_file_command): - Set exec_mtime in exec_file_command so that COFF vs non-COFF - differences appear all in one place. - - * coffread.c: New file from Dave Johnson. - - * core.c (specify_exec_file_hook): New function to specify - a hook to be called by exec_file_command. Last #ifdef X_WINDOWS gone. - * xgdb.c (initialize): Specify a hook. - - * infrun.c, inferior.h: Replace stop_r0 and stop_r1 with an array - `stop_registers' that will hold ALL the registers. - * infcmd.c (run_stack_dummy): Get the value from `stop_registers' - and copy all of that into BUFFER. - * infcmd.c (finish_command): Specify `stop_registers' - to `value_being_returned'. - * values.c (value_being_returned): Use the new EXTRACT... macros. - * values.c (set_return_value): Use new STORE_RETURN_VALUE macro. - * valops.c (call_function): Allocate retbuf long enough for all regs. - * m-*.h: New macros EXTRACT_RETURN_VALUE, STORE_RETURN_VALUE and - EXTRACT_STRUCT_VALUE_ADDRESS that express machine-dependencies - in where return values are stored. - - * valops.c (call_function): Flush default for CALL_DUMMY_START_OFFSET. - Assume it is defined. - * m-vax.h: Define CALL_DUMMY_START_OFFSET. - - * ns32k-pinsn.c (ns32k-localcount): Fix decoding of `enter' insn. - * ns32k-pinsn.c (n32k_get_enter_addr): New fn used from m-umax.h. - - * m-*.h: Change INVALID_FLOAT to accept 2nd arg which is length - of the float. - * values.c (unpack_double): Pass the 2nd arg. - * vax-pinsn.c (print_insn_arg): Pass the 2nd arg. - * infcmd.c (registers_info): Pass the 2nd arg. - -Wed Nov 25 15:06:55 1987 Richard Stallman (rms at frosted-flakes) - - * Bug fixes by David Johnson (ddj%cs.brown.edu@relay.cs.net). - - * symtab.c (list_symbols): Print typedef names, and don't call - them `static'. - - * symmisc.c (print_symtabs): Allow immediate quit, and close the - output file if that happens. - - * stack.c (frame_command): Declare args `unsigned' so a negative - number is a frame address, not a level number. - - * source.c: Check for error-return from calls to `getwd'. - - * printcmd.c (address_info): Fix error in case of a function name. - - * inflow.c (create_inferior): Return the inferior pid properly. - - * inferior.h: Define `inferior_io_terminal'. - * infrun.c (tty_command): New command to specify inferior_io_terminal. - * inflow.c (new_tty): Open specified terminal for the inferior. - * inflow.c (terminal_{ours,inferior}): Do nothing if inferior was - started with its own terminal. - * main.c (main): -t switch calls `tty_command'. - - * expread.y (rule for `block'): `copy_name' was called in wrong - place and with wrong args. - - * dbxread.c: Entire file #ifdef READ_DBX_FORMAT. - * m-*.h: Define READ_DBX_FORMAT. - - * breakpoint.c (initialize): Error in doc string of `info breakpoints'. - -Wed Nov 11 12:57:28 1987 Richard Stallman (rms at frosted-flakes) - - * ns32k-opcode.h, ns32k-pinsn.c: Two new files. - * m-merlin.h: New file, for one 32000 box. - -Mon Nov 9 10:31:42 1987 Brian Fox (bfox at sugar-smacks) - - * eval.c (evaluate_subexp): Made the case of OP_FUNCALL use - evaluate_subexp_with_coercion, so that array references would - get converted into pointer references. - -Mon Nov 9 05:50:24 1987 Richard Stallman (rms at sugar-smacks) - - * breakpoint.c (ignore_command): Error if no arg. - -Sat Nov 7 13:57:40 1987 Richard Stallman (rms at frosted-flakes) - - * main.c (quit_command): Get rid of execfile before the kill_inferior. - - * xgdb.c: New file, interface to X windows. - - * main.c (main): Look for flag arguments before - calling the initialization functions. -nw switch sets - `inhibit_windows' which xgdb.c looks at. - * main.c (command_loop): Call the window hook function, if any. - - * source.c (get_filename_and_charpos): New function - that interfaces to find_source_lines. - * source.c (source_line_charpos, source_charpos_line): - New functions translate source line number to char pos and vice versa. - - * breakpoint.c (describe_other_breakpoints): New subroutine - to list all breakpoints at PC in a message about "other - breakpoints". - * breakpoint.c (break_command_1): Use describe_other_breakpoints. - * breakpoint.c (set_breakpoint): Like break_command_1 - but takes arg predecoded into symtab and line. - - * core.c (exec_file_command): Call xgdb_display_exec_file. - - * valprint.c (type_print_base): For struct bitfields, - print the bit size. - -Thu Aug 20 02:46:47 1987 Richard M. Stallman (rms at prep) - - * Version 2.4. - - * m68k-pinsn.c (print_insn_arg): Implement place = '3'. - - * findvar.c (write_register_bytes): Arg to - store_inferior_registers should be -1: write all registers. - - * dbxread.c (symbol_file_command): If no arg, - just discard all symbols. - - * core.c (myread): Flush the 4th arg (filename). - * source.c (find_source_lines): Don't pass 4th arg. - * symmisc.c (read_symsegs): Ditto. - - * dbxread.c (process_one_symbol): One call to `define_symbol' - lacked 3rd arg. - - * inflow.c (write_inferior_memory): On failure, return the errno value. - * core.c (write_memory): ditto. - * breakpoint.c ({insert,remove}_breakpoints): ditto. - * utils.c (print_sys_errmsg): Like perror_with_name but don't - signal an error; also, the error code is an arg instead of from - `errno'. - * infrun.c : Save the value from insert_breakpoints and pass it to - print_sys_errmsg. - - * main.c (input_from_terminal_p): Put in omitted `return'. - - * Makefile (expread.o): Use $(CC). - -Sun Jun 7 04:42:51 1987 Richard M. Stallman (rms at prep) - - * version.c: Version 2.3. - - * inflow.c (terminal_ours): Save fcntl flags correctly. - * inflow.c (term_status_command): - Print the tchars and ltchars structures, byte by byte. - -Mon May 25 14:37:14 1987 Richard M. Stallman (rms at prep) - - * version.c: Version 2.2. - - * breakpoint.c (do_breakpoint_commands): - Advance breakpoint_commands before executing the command, - in case command is `cont' and it hits another bpt with commands. - -Sun May 24 20:45:04 1987 Richard M. Stallman (rms at prep) - - * value.h: Declare `contents' long and cast its address to char *. - - * expread.y (prefixify_expression): Don't call alloca among the decls. - - * printcmd.c (print_variable_value): Flush unused local `space'. - - * main.c (execute_command): Barf on "user" like other class names. - -Fri May 22 01:34:37 1987 Richard M. Stallman (rms at prep) - - * m68k-pinsn.c (fetch_arg): New arg position 'j', for movec. - (print_insn_arg): New arg syntax 'J', for movec. - * m68k-opcode.h: movec uses 'Jj'. Everything reformatted. - bf... and cas... insns were corrected. - - * inflow.c (create_inferior): Fork and exec with given args and env. - Call close_exec_file. - (inferior_died): Record the fact that the inferior no longer exists. - Call reopen_exec_file. - - * core.c (close_exec_file): New fn: Close the execchan if it's open. - (reopen_exec_file): New fn: Reopen execchan if not currently open. - - * infrun.c (wait_for_inferior): Call inferior_died if it exits. - - * infcmd.c (run_command): Don't fork and exec; call create_inferior. - - * findvar.c (read_var_value): For reg var in a convertable reg, - fetch reg in its own virtual type and then cast to variable's type. - - * symtab.h: Declare xmalloc to return char *. - - * dbxread.c (read_dbx_symtab): Record static text syms as - misc-functions. But if an assembler symbol supplies the address - for a debugger symbol, don't record it as a misc-function. - - * utils.c (query): Do clearerr (stdin) frequently in case of C-d. - - * dbxread.c (process_one_symbol, define_symbol): - Pass the stab's DESC down to define_symbol. - DESC = 0 means GCC output: if type is "short", believe it. - - * dbxread.c (read_enum_type): Don't allocate the type here; - take it as an argument. (Like read_struct_type.) - (read_type)): Before call to read_enum_type, allocate the type - or get the one already allocated. - - * printcmd.c (print_frame_args): Print a comma before - every arg except the first. - -Wed May 13 00:36:00 1987 Richard M. Stallman (rms at prep) - - * m68k-pinsn.c (convert_{to,from}_68881): - Hand-assemble the fmoved and fmovex insns. - - * dbxread.c (define_symbol): For case 'p', a parameter, - if specified type is short or char, change it to int. - This is for how PCC handles arguments. - Define new case 'P' that does what 'p' used to do. - Maybe GCC will use this. - -Mon May 4 21:52:44 1987 Richard M. Stallman (rms at prep) - - * main.c (main): If SET_STACK_LIMIT_HUGE, set the - run-time stack limit as high as it can go. - * m-sun3.h, m-vax.h: define SET_STACK_LIMIT_HUGE. - -Sun May 3 08:46:23 1987 Richard Mlynarik (mly at prep) - - * command.c, expread.y, findvar.c, infcmd.c, inflow.c, utils.c, - values.c, defs.h: Various ANSI C compatibility changes - (fouts@wilbur.arpa <8705010117.AA13112@wilbur.arpa>) - - * core.c, inflow.c: Fix calls to supply_register. - * findvar.c (supply_register): Instead of register value as int, - pass address of buffer in core containing contents in raw form. - -Sat Apr 18 17:09:42 1987 Richard Mlynarik (mly at prep) - - * main.c (command_loop): - Do any cleanups made by a executing a command each time around. - - * source.c (directory_command): - make_cleanup (free, dirname), not - make_cleanup (free_current_contents, &dirname) - (rlk <8704180416.AA29572@PARIS.MIT.EDU>) - -Mon Apr 13 20:28:26 1987 Leonard H. Tower Jr. (tower at prep) - - * gdb.1: fixed typo and italicization errors. - (<kgk%cs.brown.edu@RELAY.CS.NET> id AA16470;Sun,12 Apr 87 14:30:07 EST) - -Sat Apr 11 15:41:01 1987 Richard Mlynarik (mly at prep) - - * dbxread.c (read_dbx_symtab): - No name for symbol => "" not 0 (avoid referencing memory 0) - (tower <8704081854.AA00135@buit3.bu.edu>) - -Mon Mar 30 22:24:07 1987 Leonard H. Tower Jr. (tower at prep) - - * gdb.1: Unix style manual page pointing at internal gdb - documentation, and info sub-system in GNU Emacs. - -Fri Mar 20 12:07:15 1987 Richard M. Stallman (rms at prep) - - * COPYING: Clarifications about distribution fees and mixing. - * main.c (copying_info): Same changes. - -Tue Mar 17 17:40:14 1987 Richard M. Stallman (rms at prep) - - * values.c (unpack_field_as_long): Avoid >>= operator - since ISI compiler has a bug. - -Sat Mar 7 12:19:35 1987 Richard M. Stallman (rms at prep) - - * GDB version 2.1. - - * values.c (unpack-field-as-long): Tests for endianness were broken. - * findvar.c (read_var_value): - Now we initialize the union as an int and test it as a char. - -Sun Mar 1 16:16:20 1987 Richard M. Stallman (rms at prep) - - * main.c (define_command): Command class symbols - must be cast to int. - -Mon Feb 23 02:47:44 1987 Richard M. Stallman (rms at prep) - - * source.c (list_command): Reword error messages. - New message for case of first arg not just a line-number - and no symtab specified by it. - -Sun Feb 22 21:15:19 1987 Richard M. Stallman (rms at prep) - - * dbxread.c (compare_misc_functions): - Compare the addresses as unsigned numbers. - -Sun Feb 22 13:11:45 1987 Richard Mlynarik (mly at prep) - - * main.c (define_command, document_command): - Stuff was being unnecessarily malloced (-and- not freed!) - - * main.c (execute_command): - User-defined commands don't take args. - Don't confuse empty user command with no command. - Replace bogus `etext' test with a comparison against - class_user. - - * main.c (define_command): - If the command of the specified name is built-in, note that when - asking whether to redefine it (this is suppressed for class_alias - -- should it not be?) - - * main.c (define_command): - If command was previously built-in, don't preserve its - documentation (otherwise could get error later when trying to free - the non-malloced text of built-in documentation strings) - -Tue Feb 17 16:23:57 1987 Richard Mlynarik (mly at prep) - - * main.c (echo_command): Don't die if not given any arg. - * main.c (cd_command): Echo new cwd if interactive. - -Thu Feb 12 11:22:56 1987 Richard M. Stallman (rms at prep) - - * stack.c (initialize): "bt" now appears in help aliases. - - * Version 2.0 released. - -Wed Feb 11 17:45:45 1987 Richard M. Stallman (rms at prep) - - * m68k-opcode.h: Errors corrected in several instructions - and reordering done for assembler's sake. - - * m-vax.h (POP_FRAME): End with call to set_current_frame. - -Tue Feb 10 15:06:07 1987 Richard M. Stallman (rms at prep) - - * infrun.c (wait_for_inferior): Set stop_print_frame to 1 - after checking breakpoint condition. - - * infcmd.c (run_stack_dummy): Save many flags. - -Thu Feb 5 07:12:20 1987 Richard Mlynarik (mly at prep) - - * source.c (directory_command): - Step over `:' - -Mon Feb 2 23:40:32 1987 Richard M. Stallman (rms at prep) - - * infcmd.c (set_environment_command): Fix stupid error - for case where no "=" appears in the string. - -Mon Jan 26 13:46:52 1987 Richard M. Stallman (rms at prep) - - * printcmd.c (print_frame_args): Round end-of-arg offset - up rather than down to multiple of int. - -Fri Jan 23 15:11:50 1987 Richard M. Stallman (rms at prep) - - * source.c (directory_command): If dir is not added cause already - present, print explanation. - - * infrun.c (proceed): Use read_pc (), not stop_pc, - to get current pc to think about. stop_pc could have been - clobbered by call_function. - -Fri Jan 23 15:00:55 1987 Richard Mlynarik (mly at prep) - - * source.c (directory_command): - If dir is already in source_path, don't append another copy of it. - -Thu Jan 22 00:31:03 1987 Richard M. Stallman (rms at prep) - - * Version 2.0. - - * blockframe.c (get_pc_function_start): - Understand misc functions. - - * core.c (core_file_command): - Copy all register contents into the array `registers' - Save a.out header of executable file in core_aouthdr. - Print name of executable file that was running, if we know - where to find it. - - * core.c (exec_file_command): - Save a.out header in exec_aouthdr and file's mtime - in exec_mtime. - - * core.c (validate_files): Check that core file's a.out hdr - matches exec file's. - - * New handling of registers: - Now all registers are fetched once when the program stops or - when a core file is selected. Their contents are kept in - `registers', an array of bytes. This is done by - `fetch_inferior_registers'. `read_register', etc., just look - there. Writing a register works through - `store_inferior_registers' which writes one or all registers - from `registers' back to the inferior. - - A register now can have a "raw" data format and a "virtual" - data format, which may require conversion or even be different sizes. - The conversion can be different for different registers. - For example, the 68000 cpu registers need no conversion - and both raw and virtual size is 4, but the 68881 floating point - registers have raw size 12 (for extended fmt) and virtual size 8 - (for double). Macros in the m- file such as REGISTER_BYTES, - REGISTER_BYTE, REGISTER_{RAW,VIRTUAL}_SIZE, and - REGISTER_CONVERT_TO_{RAW,VIRTUAL} control these things. - - `read_register' and `write_register' are usable only on registers - which hold an int and need no conversion (raw fmt = virtual fmt). - For other registers, `read_register_bytes' is used, or - `read_relative_register_raw_bytes'. - - * m-sun3.h: Define the 68881 fp registers. - Know how to recognize insns that save them. - Make dummy frames save them. - - * core.c (read_register, write_registers): Functions deleted. - * findvar.c (read_register, write_registers): New functions, - not the same as the old ones of the same name. - - * findvar.c (supply_register): Function used by - fetch_inferior_registers, etc., to install the register - values fetched from the inferior. - - * findvar.c (read_register_bytes, write_register_bytes): - Read spec'd number of bytes from the byte-array `registers'. - - * findvar.c (read_relative_register_raw_bytes): - Replaces old function `read_relative_register'; accepts - address of where to store the contents; # bytes stored is size - of the specified register in raw format. - - * findvar.c (value_of_register, read_var_value): - Convert register values and values of register variables - from raw format to virtual format. - - * findvar.c (locate_var_value): Like `read_var_value' but - returns value for variable's address. - - * value.h: Add new field VALUE_REGNO to each value. It holds - register number to control virtual-to-raw conversion - for assignments to the value. - - * valops.c (value_assign): Convert data from virtual to raw format - if value came from a register variable. - Use read_register_bytes and write_register_bytes. - - - * infcmd.c (continue_command): Subtract 1 from arg - before setting breakpoint's ignore-count. - - * infcmd.c (jump_command): Query if spec'd line is outside - of the current function. - - * infcmd.c (finish_command): Now finish the selected frame, - and no arg required. - - * infcmd.c (set_environment_command): Allow space to separate - varname and value. - - * infcmd.c (registers_info): Print both raw and virtual data - format if they differ. Allow register name as arg. - Ask for a Newline each 16 registers. - - * inflow.c (kill_inferior): call mark_breakpoints_out. - * inflow.c ({fetch,store}_inferior_registers for Sun): - Get the fp registers and store them in right places in - `registers'. - * inflow.c ({read,write}_inferior_register): Deleted. - - * infrun.c (wait_for_inferior): Single-stepping is not considered - to have hit a breakpoint unless the pc before the step matches the - address of the breakpoint. Necessary on machines where - breakpoints leave the pc incremented. - - If shell gets SIGSEGV, pass the signal silently to it. - - * m68k-pinsn.c, m68k-opcode.h: - Add the 68881 instructions. New operand codes `F', `I', `s' - and `k' are needed for them. New place codes `78tcik'. - NEXTBYTE now skips a word but fetches just a byte. - Explicit sign-extension removed from NEXTBYTE and NEXTWORD. - NEXTSINGLE, NEXTDOUBLE, NEXTEXTEND and NEXTPACKED defined. - Various changes to implement the new operand and place codes. - print_index changed because displacement-size codes for - word and long displacement were interchanged. - - * m68k-pinsn.c (convert_{from,to}_68881): Functions added - to support REGISTER_CONVERT_TO_{RAW,VIRTUAL} on 68000. - - * main.c (main): Move around calls to setjmp. - * main.c (define_command, document_command): - Accept a from_tty argument instead of calling input_from_terminal_p. - - * printcmd.c (address_info): Print info on class and address - of a specified symbol. For register symbols, gives name of register. - - * printcmd.c (print_command): Remember explicitly whether - `make_cleanup' was called. - - * printcmd.c (print_frame_args): Know how arg-addresses vary with - data type on big-endian machines. - - * source.c (directory_command): Detect `:' in arg and reject it. - Free the old directory-path. Simplify things like `/.' in - dirname. - - * source.c (openp): Simplify `./' in specified name. - - * source.c (find_source_lines): Compare source mtime against - `exec_mtime' and warn if source is newer. - - * source.c (line_info): No arg means use last line listed - or line following last one this command was used on. - If from tty, clear out argument so Return is like `i li' without - arg. - - * stack.c (frame_info): Print addresses registers are saved at. - - * stack.c (return_command): When asking for confirmation, give - name of function that will be made to return. - - * valops.c (call_function): If function type is - pointer-to-function, dereference it to compute return type. - If pointer-to-object, assume function returns int. - If char, assume that the value's address is the function address - (because it's a misc functon). If int, the value itself is the - function address. - - * dbxread.c (compare_symbols): Sort register symbols - before all others. - - * eval.c (evaluate_subexp_for_address): New function like - `evaluate_subexp' but returns a value for the address where - the subexpression's value would be located. - - * eval.c (evaluate_subexp_for_sizeof): New function like - `evaluate_subexp' but returns a value for the size of the subexp. - - * eval.c (evaluate_subexp_with_coercion): Like `evaluate_subexp' - but coerces arrays to pointers (without taking the time to - read the array contents). - - * eval.c (evaluate_subexp): Use the three new functions above - when appropriate instead of calling self recursively. - -Wed Jan 14 17:00:03 1987 Richard Mlynarik (mly at prep) - - * core.c (core_file_command): - Use correct file in calls to perror_with_name - -Mon Jan 12 03:34:35 1987 Richard Mlynarik (mly at prep) - - * breakpoint.c (map_breakpoint_numbers): - Err if no args not supplied, otherwise would get mpv. - - * main.c (main): - Command-line arg "-d dir" adds dir to source-file directory - search-list. - -Sun Jan 11 19:19:52 1987 Richard Mlynarik (mly at prep) - - * symmisc.c (free_all_symtabs): - Don't call free on 0. - - * core.c (exec_file_command): - Use correct name in call to perror_with_name. - Record absolute pathname. - Don't savestring an arg to concat. - - * dbxread.c (symbol_file_command): - Record absolute name of pathname opened. - Print a message if file doesn't have a symbol-table. - Don't savestring an arg to concat. - - * source.c (openp): - Add new arg filename_opened, which if non-zero will be set to a - malloced string of the absolute name of the actual filename opened. - - * breakpoint.c (clear_command): - If from_tty or cleared more than one breakpoint at location, - print which bpts were deleted. - - * breakpoint.c (break_command_1, break_command, tbreak_command): - If from_tty, mention any other breakpoints set at same location. - - * symtab.c (decode_line_1): - If no symtabs, err mentioning `symbol-file' command rather than - saying "function foo not defined" - -Fri Jan 9 01:25:19 1987 Richard Mlynarik (mly at prep) - - * main.c (set_prompt_command): - Add support command "set-prompt" - - * printcmd.c (undisplay_command): - Fix paren error to make "undisplay <number>" work. - -Wed Jan 7 12:06:09 1987 Richard Mlynarik (mly at prep) - - * main.c (print_gdb_version, gdb_version_info): - Add command "info version" to report the version - of gdb for use in bug reports. - - * infcmd.c: - Ensure inferior_args always points to string starting with a space - and is never 0. - - * printcmd.c: (clear_displays, undisplay_command): - Fix bug in clear_displays which led to looping. - Make undisplay_command call it instead of wrong-looking code which - looked at (display->number == 0) instead of (display == 0) to - determine if it were at the end of the chain. - -Mon Dec 15 20:57:06 1986 Richard M. Stallman (rms at prep) - - * utils.c (query): Don't ignore a second line if given a null line. - - * infrun.c (normal_stop): Print "bug in shell" message - only for a segmentation fault. - - * main.c (main): Read init file from home directory if any, - before init file from current directory. - -Thu Dec 4 09:05:35 1986 Richard M. Stallman (rms at prep) - - * source.c (select_source_symtab): Don't ref thru arg if null. - - * m68k.opcode.h: For trap instruction code, use type T. - * m68k-pinsn.c (print_insn_arg): Recognize new arg-code T - and print the trap vector properly. - - * m-sun[23].h (FRAME_FIND_SAVED_REGS): Recognize a movl REG,-(sp) - as a way to save one register. Recognize clrw -(sp); movw -(sp) - after saving regs as a way to save the PS register. Adjust the - way to find the starting pc of a stack dummy frame for the fact - that these frames now save the PS. - - * m-sun[23].h (POP_FRAME): Restore PS register if frame saved it. - - * m-sun[23].h (PUSH_DUMMY_FRAME): Push the old PS register. - - * m-sun[23].h (CALL_DUMMY, etc.): Fix erroneous binary code for - the addl #nnn,sp instruction. Insert clrw -(sp); movw -(sp) - to indicate that the PS has been saved. - - * infrun.c (wait_for_inferior): If inferior exits, call - mark_breakpoints_out so it works to delete breakpoints afterward. - - * infrun.c (normal_stop): After popping a stack dummy frame, - select the frame that we get to. - - * dbxread.c (process_one_symbol): Store new `depth' field - in all context_stack elements created. For N_RBRAC, test - that depth matches that in the context_stack; if not, error. - - * dbxread.c (all callers of error): Make all error messages - start "Invalid symbol data: " and end with value of symnum. - Also change a few aborts to errors. - -Mon Dec 1 20:20:37 1986 Richard M. Stallman (rms at prep) - - * version.c: Version 1.11. - - * breakpoint.c (condition_command): If no condition spec'd, - print "breakpoint N now unconditional". - - * breakpoint.c (commands_command): Give different error messages - for cases of args not containing a breakpoint number - and args containing anything after the breakpoint number. - - * commands.c (lookup_command): Don't store a zero in *p - if have an undefined subcommand that is not an error. - - * commands.c (lookup_command): For recursive call, - pass subcommand list properly. Was passing the address - of the word containing the list. - - * core.c ({core,exec}_file_name): If no arg, tell user - what the effect is. - - * dbxread.c (define_symbol): Accept class code 'v' - for static variable within a function. - - * dbxread.c (read_type): Now allow any plain number or - pair of numbers in parens, with no code letter. This means - define new type same as type with specified number, or define - it as void if specified number's type is not yet mentioned. - - * m68k-pinsn.c (print_insn_arg): Case of general operand - in byte insn that happened to be immediate used wrong arg-size. - - * printcmd.c (set_next_address): Set next_address from arg - and also set value of `$_' from it. - - * printcmd.c (do_examine): Save address in last_examine_address - and value fetched to examine in last_examine_value. - - * printcmd.c (x_command): Copy last_examine_{address,value} - into values of `$_' and `$__'. Change `x' documentation string. - - * source.c (directory_command): Query when no args now says - what new value it wants use for the path. - - * source.c (list_command): Don't die in cases like `list ,+30'. - - * source.c (line_info): Call `set_next_address' to make `x' - display the text of the line. Change `info list' doc string. - -Sat Nov 29 07:59:29 1986 Richard M. Stallman (rms at prep) - - * printcmd.c (undisplay_command): If get no arg, - rather than crashing, query and then delete undisplay everything. - -Fri Nov 28 15:43:52 1986 Richard M. Stallman (rms at prep) - - * dbxread.c (process_one_symbol): If N_LBRAC sym - has a greater value that N_RBRAC, ignore the - N_LBRAC value and give the block zero length. - -Tue Nov 25 03:10:12 1986 Richard M. Stallman (rms at prep) - - * dbxread.c (process_one_symbol): Ignore N_NSYMS symbols - that appear in Ultrix. - -Sat Nov 22 22:49:06 1986 Richard M. Stallman (rms at prep) - - * version.c: version 1.10. - - * valprint.c (type_print*): - SHOW < 0 now means abbreviate struct/union members - or enum values with `...'. SHOW now decremented on - each recursion in type_print_base. Several places - that used to check !show now check show <= 0. - - * valprint.c (val_print): Pass -1 for SHOW to type_print - when printing typename inside parens or braces. - - * printcmd.c (print_command): If no value specified to print, - print the value of $. - - * expression.h, expread.y, eval.c, expprint.c: - OP_MEMVAL renamed UNOP_MEMVAL - and now allows any expression, not just an integer address. - It now has same format as UNOP_CAST and works almost like it. - Each place that referred to it has been rewritten - starting with a copy of the code that handles UNOP_CAST. - Doc for `print' command changed for this. - - * source.c (init_source_path): - Free and zero out any line_charpos's saved in source symtabs. - - * breakpoint.c (condition_command): - Parse the condition in the environment of the code where the - breakpoint is set. This requires finding the breakpoint - before parsing, so code is rearranged. - - * dbxread.c (dbx_alloc_type): - New function given typenums returns the type for those typenums - or allocates a new, empty type for those typenums and returns it. - - * symtab.c (smash_type_to_{pointer,function}): - New functions modify an already-allocated type object - to be a pointer to or function returning some given type. - - * dbxread.c (read_type): Uses dbx_alloc_type in many cases. - Reading a pointer or function type now works by doing that, - then reading the value type or type pointed to, then smashing - it into the type already allocated. This makes some fwd refs win. - Likewise for structs and unions. - - * dbxread.c (read_struct_type): Now receives the type object - as args. Used to get typenums as args and look up the type - itself. - - * dbxread.c (symbol_file_command): - At very end, clear out any type name that `char *' has received. - -Thu Nov 20 16:43:53 1986 Richard M. Stallman (rms at prep) - - * m-sun2.h, m-sun3.h (FIND_FRAME_SAVED_REGS): - Was incrementing address even for regs not saved. - -Sun Nov 16 14:59:07 1986 Richard M. Stallman (rms at prep) - - * values.c (value_field): Was adding in byte offset - before calling unpack_field_as_long, which itself - adds in the offset. Now pass addr of start of structure. - - * infrun.c (normal_stop): Clean up inferior_pid conditionals: - just return early if no inferior. - -Thu Nov 13 15:45:50 1986 Richard M. Stallman (rms at prep) - - * dbxread.c (struct header_file): add new field .instance - to distinguish the various entries for one header file. - - * dbxread.c (process_one_symbol): Use the `value' of - a N_BINCL or N_EXCL as the instance code for the header file. - - * dbxread.c (add_{new,old}_header_file): - Accept an instance code as arg and treat it as if it were - part of the file name for distinguishing and finding entries. - - * dbxread.c (add_new_header_file, read_type): - Turn off the header_file_prev_index feature with #if 0. - - * values.c (unpack_field_as_long, modify_field): - Run-time test to distinguish big and little endian machines - and do shifting accordingly. - -Tue Nov 11 00:31:18 1986 Richard M. Stallman (rms at prep) - - * version.c: version 1.9. - - * breakpoint.c (delete_command): - Don't query if 2nd arg is zero. - - * breakpoint.c (clear_breakpoints): - Pass 2nd arg of zero to delete_command. - -Sat Nov 8 23:29:19 1986 Richard M. Stallman (rms at prep) - - * breakpoint.c (delete_command): - Ask for confirmation when used with no arg (delete all). - -Fri Nov 7 11:23:09 1986 Richard M. Stallman (rms at prep) - - * infrun.c (start_inferior, wait_for_inferior): - Eliminate `stop_in_shell' which was not being maintained right. - New variable `running_in_shell' is set to 1 or 0 when the - expected SIGTRAPs happen, and is simply examined at other times. - - * infrun.c (wait_for_inferior): - If get SIGSEGV with running_in_shell == 1, it is sh - allocating memory. Pass the signal silently to the shell. - - * core.c (exec_file_command): - data_{start,end} are adjusted unconditionally when an - exec file is opened, so closing counter-adjustment is - now unconditional as well. - - * printcmd.c (x_command): - Don't erase the expression from the calling args - if cllaed noninteractively (used to be clobbering - definitions of user-defined commands). - - * source.c (list_command): likewise. - -Wed Nov 5 09:41:00 1986 Richard M. Stallman (rms at prep) - - * Makefile: New variable OBSTACK1 that people can use - to make obstack.o a dependency of gdb. - - * breakpoint.c (initialize): - Define new aliases "br", "bre" and "brea" for "break". - -Sun Nov 2 21:16:06 1986 Richard Mlynarik (mly at prep) - - * symmisc.c (read_symsegs): - Add an extra protection against invalid symbol-file - - * m-vax.h: - Set KERNEL_U_ADDR and STACK_END_ADDR non-4.2-specifically - -Tue Oct 21 13:34:14 1986 Richard Mlynarik (mly at prep) - - * breakpoints.c (initialize): - Delet reference to non-existent command "tenable" from doc of "enable" - -Tue Oct 14 19:58:27 1986 Richard Mlynarik (mly at prep) - - * printcmd.c (display_command, undisplay_command): - * infcmd.c (run_command): - Call dont_repeat. - - -Local Variables: -mode: indented-text -eval: (auto-fill-mode 1) -left-margin: 8 -fill-column: 74 -version-control: never -End: diff --git a/gdb/Makefile b/gdb/Makefile index c1fd60c..070ee70 100644 --- a/gdb/Makefile +++ b/gdb/Makefile @@ -1,18 +1,20 @@ # -I. for "#include <obstack.h>" -CFLAGS = -g -I. -Dvfork=fork -DDEBUG +CFLAGS = -g -I. # NOTE!!! -O may FAIL TO WORK! See initialize.h for some weird hacks. +CC = cc +BISON = bison # 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 +OBSTACK = obstack.o +OBSTACK1 = obstack.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 + symtab.o symmisc.o coffread.o dbxread.o infcmd.o infrun.o remote.o TSOBS = core.o inflow.o @@ -25,20 +27,16 @@ TSSTART = /lib/crt0.o NTSSTART = kdb-start.o -gdb : $(STARTOBS) $(OBS) $(TSOBS) $(ENDOBS) $(OBSTACK1) - $(CC) -o gdb $(STARTOBS) $(OBS) $(TSOBS) $(ENDOBS) -lg $(OBSTACK) +gdb+: $(STARTOBS) $(OBS) $(TSOBS) $(ENDOBS) $(OBSTACK1) + $(CC) -o gdb+ $(STARTOBS) $(OBS) $(TSOBS) $(ENDOBS) -lc -lg $(OBSTACK) -xgdb : $(STARTOBS) $(OBS) xgdb.o $(TSOBS) $(ENDOBS) $(OBSTACK1) - $(CC) -o xgdb $(STARTOBS) $(OBS) xgdb.o $(TSOBS) $(ENDOBS) \ +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 @@ -48,9 +46,8 @@ 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 + @echo 'Expect 101 shift/reduce conflicts and 1 reduce/reduce conflict.' + $(BISON) -v expread.y 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 @@ -68,6 +65,7 @@ main.o : main.c defs.h command.h 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 +remote.o : remote.c defs.h initialize.h param.h frame.h inferior.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 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 -@ diff --git a/gdb/README b/gdb/README deleted file mode 100644 index 6e985de..0000000 --- a/gdb/README +++ /dev/null @@ -1,29 +0,0 @@ -This is GDB, a source-level debugger intended for GNU, -presently running under un*x. - -Before compiling GDB, you must set three files according to -the kind of machine you are running on. - -param.h must be set up to #include an m- file for the machine. -The m- files written so far are m-vax.h, m-sun2.h and m-sun3.h. -(I believe that it is the operating system version and not -the cpu type which determines which of the two is right on a Sun.) -This file contains macro definitions that express information -about the machine's registers, stack frame format and instructions. - -initialize.h must be set up to #include an m-...init.h file. -There are two of them written: m-vaxinit.h and m-suninit.h. -This file defines one macro, which says how to round up from the -address of the end of the text of one .o file to the beginning of -the text of the next .o file. - -pinsn.c must be set up to include the instruction printer for -your cpu type. The two printers that exist are vax-pinsn.c -and m68k-pinsn.c. - -`Makefile' must be changed to say `OBSTACK = obstack.o' instead of -`OBSTACK=-lobstack' (unless you want to install obstack.o as -/lib/libobstack.a). - -Once these files are set up, just `make' will do everything, -producing an executable `gdb' in this directory. diff --git a/gdb/TAGS b/gdb/TAGS deleted file mode 100644 index e01cba9..0000000 --- a/gdb/TAGS +++ /dev/null @@ -1,852 +0,0 @@ - -blockframe.c,436 -block_for_pc 221,5337 -block_innermost_frame 308,7200 -find_pc_function 276,6473 -find_pc_misc_function 290,6806 -get_current_block 182,4485 -get_current_frame 47,1553 -get_frame_block 172,4336 -get_frame_function 208,5053 -get_frame_info 90,2661 -get_frame_pc 150,3800 -get_frame_saved_regs 161,3986 -get_pc_function_start 188,4557 -get_prev_frame 66,1893 -get_prev_frame_info 128,3455 -initialize 329,7603 -set_current_frame 56,1705 - -breakpoint.c,1102 -#define ALL_BREAKPOINTS(71,2545 -break_command 604,14937 -break_command_1 528,13121 -breakpoint_1 360,9438 -breakpoint_auto_delete 687,16916 -breakpoint_here_p 288,7887 -breakpoint_stop_status 308,8410 -breakpoints_info 409,10520 -check_duplicates 443,11290 -clear_breakpoint_commands 218,6186 -clear_breakpoints 757,18298 -clear_command 620,15179 -clear_momentary_breakpoints 513,12821 -commands_command 154,4443 -condition_command 109,3533 -delete_breakpoint 704,17221 -delete_command 733,17741 -disable_breakpoint 873,20658 -disable_command 882,20791 -do_breakpoint_commands 200,5626 -enable_breakpoint 857,20419 -enable_command 866,20550 -enable_delete_breakpoint 910,21276 -enable_delete_command 919,21413 -enable_once_breakpoint 894,21020 -enable_once_command 903,21158 -ignore_command 797,19190 -initialize 933,21666 -insert_breakpoints 230,6503 -map_breakpoint_numbers 822,19738 -mark_breakpoints_out 275,7576 -remove_breakpoints 251,7042 -set_default_breakpoint 426,10820 -set_ignore_count 767,18523 -set_momentary_breakpoint 501,12597 -set_raw_breakpoint 464,11810 -tbreak_command 612,15057 - -command.c,151 -add_alias_cmd 141,6077 -add_cmd 116,5529 -add_prefix_cmd 177,7140 -delete_cmd 198,7681 -help_cmd 230,8515 -lookup_cmd 336,11651 -savestring 446,13891 - -core.c,397 -#define N_DATADDR(41,1348 -#define N_TXTADDR(37,1278 -close_exec_file 268,7417 -core_file_command 104,2838 -exec_file_command 221,6183 -files_info 330,8673 -get_exec_file 315,8446 -have_core_file_p 324,8612 -initialize 548,13957 -myread 505,13219 -read_memory 373,9666 -register_addr 531,13685 -reopen_exec_file 275,7501 -validate_files 291,7907 -write_memory 389,10073 -xfer_core_file 400,10338 - -dbxread.c,1108 -add_new_header_file 346,10622 -add_old_header_file 317,9604 -add_symbol_to_list 496,14905 -add_this_object_header_file 297,8977 -compare_misc_functions 931,26566 -compare_symbols 1000,28016 -condense_misc_bunches 957,27070 -dbx_alloc_type 454,13833 -dbx_lookup_type 404,12394 -define_symbol 1516,42011 -discard_misc_bunches 944,26878 -end_symtab 756,22240 -explicit_lookup_type 475,14373 -finish_block 512,15299 -free_header_files 273,8395 -get_sym_file 1174,32423 -hash_symsegs 1343,36983 -hashname 1318,36533 -init_header_files 260,8046 -init_misc_functions 903,25961 -initialize 2078,57588 -make_blockvector 590,17428 -new_object_header_files 286,8705 -next_symbol_text 1309,36368 -pop_subfile 861,25120 -process_one_symbol 1374,37801 -push_subfile 847,24770 -read_dbx_symtab 1186,32790 -read_enum_type 1892,52804 -read_number 2041,57023 -read_range_type 1962,54881 -read_struct_type 1809,50421 -read_type 1685,47313 -read_type_number 1658,46658 -record_line 627,18511 -record_misc_function 911,26075 -sort_syms 1012,28407 -start_subfile 699,20484 -start_symtab 662,19485 -symbol_file_command 1036,28951 - -environ.c,213 -environ_vector 164,6337 -free_environ 118,5334 -get_in_environ 173,6472 -init_environ 134,5661 -make_environ 103,5036 -#define max(96,4912 -#define min(95,4870 -set_in_environ 192,6807 -unset_in_environ 232,7561 - -eval.c,309 -evaluate_expression 95,2716 -evaluate_subexp 114,3104 -evaluate_subexp_for_address 440,13032 -evaluate_subexp_for_sizeof 509,14789 -evaluate_subexp_with_coercion 477,13979 -evaluate_type 106,2961 -initialize 550,15888 -parse_and_eval 64,1977 -parse_and_eval_address 33,1188 -parse_and_eval_address_1 50,1650 - -expprint.c,49 -print_expression 88,3265 -print_subexp 102,3660 - -expread.tab.c,358 -copy_name 538,12121 -end_arglist 125,2565 -free_funcalls 139,2867 -length_of_subexp 572,13025 -parse_c_1 751,17140 -parse_c_expression 790,18194 -parse_number 217,5038 -prefixify_expression 552,12457 -prefixify_subexp 644,14362 -start_arglist 111,2206 -write_exp_elt 156,3206 -write_exp_string 173,3660 -yyerror 529,11966 -yylex 315,7081 -yyparse(985,25972 - -findvar.c,309 -find_saved_register 38,1432 -initialize 386,10456 -locate_var_value 334,9235 -read_register 165,4621 -read_register_bytes 140,4050 -read_relative_register_raw_bytes 68,2095 -read_var_value 202,5600 -supply_register 190,5277 -value_of_register 102,2842 -write_register 175,4862 -write_register_bytes 151,4328 - -firstfile.c,89 -initialize_all_files 128,6009 -initialize_dummy_1 140,6338 -initialize_dummy_2 148,6497 - -infcmd.c,550 -cont_command 165,3979 -environment_info 479,11280 -finish_command 397,9291 -have_inferior_p 106,2907 -initialize 682,15823 -jump_command 269,6035 -next_command 202,4695 -nexti_command 216,4897 -program_info 457,10675 -read_memory_integer 542,12697 -read_pc 575,13293 -registers_info 589,13488 -run_command 121,3120 -run_stack_dummy 355,8179 -set_args_command 112,2972 -set_environment_command 499,11682 -signal_command 314,7007 -step_1 222,4974 -step_command 194,4543 -stepi_command 210,4820 -unset_environment_command 531,12458 -write_pc 580,13357 - -inflow.c,551 -create_inferior 187,5073 -fetch_inferior_registers 271,6793 -fetch_inferior_registers 317,8482 -inferior_died 244,6286 -initialize 483,13062 -kill_command 226,5974 -kill_inferior 235,6161 -read_inferior_memory 388,10475 -resume 258,6596 -store_inferior_registers 294,7707 -store_inferior_registers 343,9249 -term_status_command 165,4365 -terminal_inferior 87,2428 -terminal_init_inferior 71,2074 -terminal_ours 121,3326 -terminal_ours_1 127,3383 -terminal_ours_for_output 111,3126 -try_writing_regs_command 457,12556 -write_inferior_memory 416,11420 - -infrun.c,286 -clear_proceed_status 111,3347 -handle_command 728,21384 -initialize 848,24793 -insert_step_breakpoint 706,20807 -normal_stop 618,18254 -proceed 138,4172 -remove_step_breakpoint 718,21109 -signals_info 810,23832 -start_inferior 214,6079 -wait_for_inferior 242,7039 -writing_pc 202,5763 - -kdb-start.c,14 -start 10,140 - -lastfile.c,28 -initialize_last_file 4,144 - -m68k-pinsn.c,361 -#define NEXTBYTE(43,1554 -#define NEXTDOUBLE(54,1819 -#define NEXTEXTEND(57,1877 -#define NEXTLONG(48,1671 -#define NEXTPACKED(61,1995 -#define NEXTSINGLE(51,1762 -#define NEXTWORD(45,1602 -convert_from_68881 713,16392 -convert_to_68881 732,16806 -fetch_arg 504,12082 -print_base 693,15890 -print_indexed 603,13871 -print_insn 71,2389 -print_insn_arg 163,4738 - -main.c,841 -add_com 487,11896 -add_com_alias 499,12123 -add_info 455,11186 -add_info_alias 466,11372 -cd_command 885,24375 -command_loop 288,7462 -copying_info 628,14816 -define_command 545,12933 -do_nothing 281,7362 -document_command 583,13895 -dont_repeat 323,8255 -dump_me_command 961,25608 -echo_command 935,25224 -error_no_arg 509,12321 -execute_command 245,6496 -free_command_lines 437,10877 -help_command 516,12415 -info_command 478,11700 -initialize_main 972,25764 -input_from_terminal_p 869,24072 -main 81,2147 -print_gdb_version 800,22767 -pwd_command 875,24143 -quit_command 856,23880 -read_command_lines 386,9603 -read_line 334,8514 -return_to_top_level 71,1965 -set_prompt_command 818,23215 -source_cleanup 904,24752 -source_command 912,24854 -stop_sig 307,7915 -validate_comname 524,12566 -version_info 810,23117 -warranty_info 770,21356 - -obstack.c,77 -_obstack_begin 101,4993 -_obstack_free 148,6461 -_obstack_newchunk 121,5631 - -pinsn.c,0 - -printcmd.c,585 -address_info 385,9015 -clear_displays 661,15183 -decode_format 70,2061 -display_command 606,14214 -display_info 769,17310 -do_displays 731,16450 -do_examine 231,5522 -free_display 649,14965 -initialize 888,20497 -output_command 346,8219 -print_address 208,4990 -print_command 306,7398 -print_formatted 109,2860 -print_frame_args 810,18392 -print_frame_nameless_args 870,20125 -print_variable_value 795,17951 -ptype_command 525,12189 -set_command 374,8765 -set_next_address 193,4626 -undisplay_command 677,15445 -validate_format 291,6959 -whatis_command 500,11716 -x_command 452,10410 - -source.c,249 -directories_info 53,1637 -directory_command 79,2168 -find_source_lines 264,6263 -init_source_path 59,1735 -initialize 535,13376 -line_info 490,12220 -list_command 363,8569 -openp 186,4596 -print_source_lines 303,7291 -select_source_symtab 250,5960 - -stack.c,502 -args_info 350,8833 -backtrace_command 232,6280 -down_command 498,12939 -find_relative_frame 391,10010 -frame_command 444,11623 -frame_info 149,4137 -get_selected_block 371,9306 -initialize 542,13968 -locals_info 312,8132 -print_block_frame_locals 257,6820 -print_frame_arg_vars 318,8214 -print_frame_info 70,2167 -print_frame_local_vars 291,7614 -print_sel_frame 131,3689 -print_selected_frame 140,3894 -print_stack_frame 57,1964 -return_command 516,13439 -select_frame 359,9033 -up_command 477,12347 - -standalone.c,1165 -_exit 436,8533 -_flsbuf 326,6852 -access 76,1743 -chdir 62,1588 -close 164,4224 -core_file_command 340,7028 -exec_file_command 337,7003 -execle 433,8519 -exit 81,1771 -fault 514,9963 -fclose 189,4597 -fdopen 183,4539 -fflush 331,6910 -fgetc 247,5466 -fopen 175,4414 -fprintf 298,6263 -fputc 314,6593 -fread 229,5154 -fstat 195,4647 -fwrite 305,6422 -get_exec_file 344,7060 -getpid 54,1543 -getrlimit 474,9005 -getwd 66,1608 -have_core_file_p 350,7176 -initialize 585,11686 -ioctl 45,1478 -kill 51,1531 -kill_command 355,7213 -lseek 266,5714 -malloc_warning 441,8575 -myread 208,4831 -open 129,3606 -printf 291,6110 -ptrace 427,8490 -read_inferior_register 372,7361 -read_memory 375,7391 -read_register 397,7764 -restore_gdb 528,10282 -resume 490,9429 -save_frame_pointer 502,9633 -save_registers 540,10627 -sbrk 451,8691 -setpgrp 430,8504 -int (* signal 48,1506 -sigsetmask 59,1570 -int kdb_stack_beg[STACK_SIZE / sizeof 581,11613 -terminal_inferior 360,7254 -terminal_init_inferior 366,7300 -terminal_ours 363,7279 -ulimit 463,8913 -vfork 417,8200 -vlimit 469,8955 -wait 554,10975 -write_inferior_register 369,7330 -write_memory 385,7564 -write_register 406,7933 - -stuff.c,70 -err 162,5253 -find_symbol 141,4686 -get_offset 97,3038 -main 32,1184 - -symmisc.c,473 -#define CORE_RELOCATE(158,4817 -#define RELOCATE(148,4378 -#define TEXT_RELOCATE(162,4972 -#define UNRELOCATE(152,4573 -block_depth 499,13854 -free_all_symtabs 38,1310 -free_symtab 92,2701 -free_symtab_block 70,1994 -initialize 508,13995 -print_symbol 413,11786 -print_symtabs 353,10199 -read_symsegs 320,9451 -relocate_block 243,7195 -relocate_blockvector 231,6886 -relocate_symbol 268,7855 -relocate_symtab 182,5675 -relocate_type 296,8833 -relocate_typevector 218,6602 - -symtab.c,716 -block_function 383,10928 -decode_line_1 694,18782 -decode_line_spec 853,22739 -find_line_pc 624,16888 -find_line_pc_range 565,15457 -find_pc_line 425,11975 -find_pc_line_pc_range 655,17363 -find_pc_symtab 395,11161 -functions_info 995,26000 -init_type 1012,26230 -initialize 1032,26680 -list_symbols 916,24143 -lookup_block_symbol 330,9572 -lookup_enum 166,4758 -lookup_function_type 211,6260 -lookup_pointer_type 182,5269 -lookup_struct 134,3824 -lookup_symbol 285,8458 -lookup_symtab 58,1929 -lookup_typename 85,2559 -lookup_union 150,4293 -lookup_unsigned_typename 116,3346 -smash_to_function_type 262,7816 -smash_to_pointer_type 241,7206 -sources_info 868,23119 -types_info 1002,26088 -variables_info 988,25912 - -test2.c,11 -main 6,86 - -test3.c,25 -bar 12,123 -newfun 5,51 - -testbit.c,11 -main 7,58 - -testfun.c,44 -do_add 7,62 -do_float_add 13,104 -main 1,0 - -testkill.c,11 - main(2,1 - -testrec.c,20 -foo 6,24 -main 1,0 - -testreg.c,22 -foo 19,341 -main 1,0 - -testregs.c,23 -foo 2,11 -main 15,321 - -utils.c,382 -concat 254,5912 -discard_cleanups 84,2483 -do_cleanups 68,2104 -error 213,5038 -fatal 228,5397 -free_current_contents 104,2893 -make_cleanup 48,1636 -parse_escape 323,7736 -perror_with_name 142,3676 -print_spaces 266,6154 -print_sys_errmsg 168,4235 -printchar 390,8781 -query 280,6518 -quit 191,4675 -request_quit 201,4799 -savestring 243,5745 -xmalloc 115,3106 -xrealloc 127,3326 - -valarith.c,215 -initialize 352,8246 -value_add 31,1128 -value_binop 116,3276 -value_equal 257,5535 -value_less 301,6746 -value_lognot 342,7998 -value_neg 328,7619 -value_sub 70,2102 -value_subscript 105,2971 -value_zerop 233,5184 - -valops.c,395 -call_function 388,10791 -initialize 594,16295 -push_bytes 314,9135 -push_word 294,8769 -value_addr 247,7400 -value_arg_coerce 354,9928 -value_arg_push 373,10344 -value_assign 85,2697 -value_at 68,2289 -value_cast 34,1302 -value_coerce_array 219,6610 -value_ind 274,8155 -value_of_variable 209,6404 -value_push 333,9476 -value_repeat 186,5819 -value_string 485,13581 -value_struct_elt 555,15503 - -valprint.c,237 -initialize 533,13661 -set_maximum_command 525,13515 -type_print 272,7365 -type_print_1 283,7591 -type_print_base 403,10889 -type_print_varspec_prefix 316,8617 -type_print_varspec_suffix 352,9476 -val_print 113,3308 -value_print 46,1539 - -values.c,762 -access_value_history 212,5551 -allocate_repeat_value 83,2505 -allocate_value 59,1948 -clear_internalvars 371,9239 -clear_value_history 251,6511 -convenience_info 386,9475 -free_all_values 108,3143 -history_info 270,6920 -initialize 737,18259 -internalvar_name 361,9048 -lookup_internalvar 308,7852 -modify_field 602,14750 -record_latest_value 178,4634 -release_value 125,3410 -set_internalvar 351,8879 -set_internalvar_component 336,8485 -set_return_value 709,17666 -unpack_double 486,11851 -unpack_field_as_long 578,14176 -unpack_long 430,10615 -value_as_double 418,10252 -value_as_long 411,10132 -value_being_returned 688,17121 -value_copy 151,3834 -value_field 542,13135 -value_from_double 654,16089 -value_from_long 626,15329 -value_of_internalvar 327,8298 - -vax-pinsn.c,44 -print_insn 42,1456 -print_insn_arg 86,2396 - -version.c,0 - -command.h,0 - -defs.h,42 -#define max(24,1043 -#define min(23,1001 - -environ.h,0 - -expression.h,0 - -frame.h,0 - -inferior.h,0 - -initialize.h,0 - -m-isi-ov.h,852 -#define ABOUT_TO_RETURN(136,4974 -#define FIX_CALL_DUMMY(447,17543 -#define FRAME_ARGS_ADDRESS(275,9997 -#define FRAME_CHAIN(264,9636 -#define FRAME_CHAIN_COMBINE(269,9825 -#define FRAME_CHAIN_VALID(266,9706 -#define FRAME_FIND_SAVED_REGS(305,11191 -#define FRAME_LOCALS_ADDRESS(277,10040 -#define FRAME_NUM_ARGS(282,10176 -#define FRAME_SAVED_PC(273,9929 -#define INIT_STACK(471,18339 -#define INVALID_FLOAT(140,5108 -#define N_DATADDR(120,4437 -#define N_TXTADDR(125,4616 -#define REGISTER_BYTE(194,7220 -#define REGISTER_CONVERTIBLE(222,8151 -#define REGISTER_CONVERT_TO_RAW(236,8614 -#define REGISTER_CONVERT_TO_VIRTUAL(227,8318 -#define REGISTER_RAW_SIZE(203,7555 -#define REGISTER_U_ADDR(174,6379 -#define REGISTER_VIRTUAL_SIZE(209,7811 -#define REGISTER_VIRTUAL_TYPE(245,8895 -#define SAVED_PC_AFTER_CALL(97,3881 -#define SKIP_PROLOGUE(77,3210 - -m-sun2.h,824 -#define ABOUT_TO_RETURN(79,2505 -#define FIX_CALL_DUMMY(344,12862 -#define FRAME_ARGS_ADDRESS(196,6448 -#define FRAME_CHAIN(185,6087 -#define FRAME_CHAIN_COMBINE(190,6276 -#define FRAME_CHAIN_VALID(187,6157 -#define FRAME_FIND_SAVED_REGS(232,7817 -#define FRAME_LOCALS_ADDRESS(198,6491 -#define FRAME_NUM_ARGS(205,6746 -#define FRAME_NUM_ARGS(208,6795 -#define FRAME_SAVED_PC(194,6380 -#define INIT_STACK(368,13658 -#define INVALID_FLOAT(83,2639 -#define REGISTER_BYTE(121,3997 -#define REGISTER_CONVERTIBLE(144,4615 -#define REGISTER_CONVERT_TO_RAW(154,4927 -#define REGISTER_CONVERT_TO_VIRTUAL(149,4749 -#define REGISTER_RAW_SIZE(126,4162 -#define REGISTER_U_ADDR(166,5375 -#define REGISTER_VIRTUAL_SIZE(131,4317 -#define REGISTER_VIRTUAL_TYPE(159,5092 -#define SAVED_PC_AFTER_CALL(51,1836 -#define SKIP_PROLOGUE(38,1400 - -m-sun3.h,790 -#define ABOUT_TO_RETURN(78,2454 -#define FIX_CALL_DUMMY(392,15189 -#define FRAME_ARGS_ADDRESS(213,7102 -#define FRAME_CHAIN(202,6741 -#define FRAME_CHAIN_COMBINE(207,6930 -#define FRAME_CHAIN_VALID(204,6811 -#define FRAME_FIND_SAVED_REGS(249,8471 -#define FRAME_LOCALS_ADDRESS(215,7145 -#define FRAME_NUM_ARGS(222,7400 -#define FRAME_NUM_ARGS(225,7449 -#define FRAME_SAVED_PC(211,7034 -#define INIT_STACK(416,15985 -#define INVALID_FLOAT(82,2588 -#define REGISTER_BYTE(123,4130 -#define REGISTER_CONVERTIBLE(151,5061 -#define REGISTER_CONVERT_TO_RAW(165,5524 -#define REGISTER_CONVERT_TO_VIRTUAL(156,5228 -#define REGISTER_RAW_SIZE(132,4465 -#define REGISTER_VIRTUAL_SIZE(138,4721 -#define REGISTER_VIRTUAL_TYPE(174,5805 -#define SAVED_PC_AFTER_CALL(55,1929 -#define SKIP_PROLOGUE(42,1493 - -m-suninit.h,29 -#define FILEADDR_ROUND(5,94 - -m-vax.h,791 -#define ABOUT_TO_RETURN(80,2551 -#define FIX_CALL_DUMMY(294,10681 -#define FRAME_ARGS_ADDRESS(199,6661 -#define FRAME_CHAIN(185,6120 -#define FRAME_CHAIN_COMBINE(190,6314 -#define FRAME_CHAIN_VALID(187,6195 -#define FRAME_FIND_SAVED_REGS(222,7517 -#define FRAME_LOCALS_ADDRESS(204,6836 -#define FRAME_NUM_ARGS(209,6972 -#define FRAME_SAVED_PC(194,6418 -#define INIT_STACK(317,11455 -#define INVALID_FLOAT(84,2681 -#define REGISTER_BYTE(127,4329 -#define REGISTER_CONVERTIBLE(150,4942 -#define REGISTER_CONVERT_TO_RAW(161,5257 -#define REGISTER_CONVERT_TO_VIRTUAL(155,5076 -#define REGISTER_RAW_SIZE(132,4491 -#define REGISTER_U_ADDR(112,3753 -#define REGISTER_VIRTUAL_SIZE(137,4644 -#define REGISTER_VIRTUAL_TYPE(167,5425 -#define SAVED_PC_AFTER_CALL(53,1877 -#define SKIP_PROLOGUE(42,1480 - -m-vaxinit.h,29 -#define FILEADDR_ROUND(5,94 - -m68k-opcode.h,138 -#define one(130,5680 -int numopcodes=sizeof(1270,68164 -struct m68k_opcode *endop = m68k_opcodes+sizeof(1272,68226 -#define two(131,5707 - -obstack.h,618 -#define obstack_1grow(252,11387 -#define obstack_1grow_fast(275,12190 -#define obstack_alignment_mask(228,10489 -#define obstack_alloc(263,11796 -#define obstack_base(216,10145 -#define obstack_begin(232,10606 -#define obstack_blank(257,11569 -#define obstack_blank_fast(277,12257 -#define obstack_copy(266,11889 -#define obstack_copy0(269,11994 -#define obstack_finish(279,12314 -#define obstack_free(290,12730 -#define obstack_grow(237,10784 -#define obstack_grow0(244,11064 -#define obstack_init(230,10547 -#define obstack_next_free(220,10254 -#define obstack_object_size(224,10341 -#define obstack_room(272,12101 - -param.h,0 - -symseg.h,0 - -symtab.h,1291 -#define BLOCKLIST(108,3923 -#define BLOCKLIST_BLOCK(137,4911 -#define BLOCKLIST_NBLOCKS(136,4853 -#define BLOCKVECTOR(109,3971 -#define BLOCKVECTOR_BLOCK(139,5030 -#define BLOCKVECTOR_NBLOCKS(138,4970 -#define BLOCK_END(145,5244 -#define BLOCK_FUNCTION(148,5354 -#define BLOCK_NSYMS(146,5280 -#define BLOCK_START(144,5204 -#define BLOCK_SUPERBLOCK(149,5396 -#define BLOCK_SYM(147,5316 -#define LINELIST(113,4071 -#define LINETABLE(114,4116 -#define SYMBOL_BLOCK_VALUE(155,5635 -#define SYMBOL_CLASS(153,5539 -#define SYMBOL_NAME(151,5443 -#define SYMBOL_NAMESPACE(152,5486 -#define SYMBOL_TYPE(156,5692 -#define SYMBOL_VALUE(154,5584 -#define TYPEVECTOR(111,4022 -#define TYPEVECTOR_NTYPES(141,5092 -#define TYPEVECTOR_TYPE(142,5147 -#define TYPE_CODE(170,6307 -#define TYPE_FIELD(174,6453 -#define TYPE_FIELDS(172,6403 -#define TYPE_FIELD_BITPOS(178,6712 -#define TYPE_FIELD_BITSIZE(179,6780 -#define TYPE_FIELD_NAME(176,6571 -#define TYPE_FIELD_PACKED(180,6850 -#define TYPE_FIELD_TYPE(175,6507 -#define TYPE_FIELD_VALUE(177,6635 -#define TYPE_FLAGS(168,6187 -#define TYPE_FUNCTION_TYPE(166,6075 -#define TYPE_LENGTH(167,6138 -#define TYPE_NAME(163,5910 -#define TYPE_NFIELDS(171,6352 -#define TYPE_POINTER_TYPE(165,6014 -#define TYPE_TARGET_TYPE(164,5955 -#define TYPE_UNSIGNED(169,6234 - -value.h,399 -#define COERCE_ARRAY(58,1961 -#define VALUE_ADDRESS(48,1560 -#define VALUE_BITPOS(52,1752 -#define VALUE_BITSIZE(51,1710 -#define VALUE_CONTENTS(46,1469 -#define VALUE_INTERNALVAR(49,1611 -#define VALUE_LVAL(47,1524 -#define VALUE_NEXT(53,1792 -#define VALUE_OFFSET(50,1670 -#define VALUE_REGNO(56,1922 -#define VALUE_REPEATED(54,1828 -#define VALUE_REPETITIONS(55,1872 -#define VALUE_TYPE(45,1433 - -vax-opcode.h,0 - -wait.h,331 -#define WCOREDUMP(13,439 -#define WCOREDUMP(21,690 -#define WIFEXITED(10,338 -#define WIFSIGNALED(9,274 -#define WIFSTOPPED(8,231 -#define WRETCODE(11,377 -#define WRETCODE(19,622 -#define WSETSTOP(15,511 -#define WSETSTOP(23,760 -#define WSTOPSIG(12,408 -#define WSTOPSIG(20,656 -#define WTERMSIG(14,478 -#define WTERMSIG(22,726 - -expread.y,349 -copy_name 929,20955 -end_arglist 516,11399 -free_funcalls 530,11701 -length_of_subexp 963,21859 -parse_c_1 1142,25974 -parse_c_expression 1181,27028 -parse_number 608,13872 -prefixify_expression 943,21291 -prefixify_subexp 1035,23196 -start_arglist 502,11040 -write_exp_elt 547,12040 -write_exp_string 564,12494 -yyerror 920,20800 -yylex 706,15915 diff --git a/gdb/alloca.c b/gdb/alloca.c deleted file mode 100644 index cfe98f9..0000000 --- a/gdb/alloca.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - alloca -- (mostly) portable public-domain implementation -- D A Gwyn - - last edit: 86/05/30 rms - include config.h, since on VMS it renames some symbols. - Use xmalloc instead of malloc. - - This implementation of the PWB library alloca() function, - which is used to allocate space off the run-time stack so - that it is automatically reclaimed upon procedure exit, - was inspired by discussions with J. Q. Johnson of Cornell. - - It should work under any C implementation that uses an - actual procedure stack (as opposed to a linked list of - frames). There are some preprocessor constants that can - be defined when compiling for your specific system, for - improved efficiency; however, the defaults should be okay. - - The general concept of this implementation is to keep - track of all alloca()-allocated blocks, and reclaim any - that are found to be deeper in the stack than the current - invocation. This heuristic does not reclaim storage as - soon as it becomes invalid, but it will do so eventually. - - As a special case, alloca(0) reclaims storage without - allocating any. It is a good idea to use alloca(0) in - your main control loop, etc. to force garbage collection. -*/ -#ifndef lint -static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */ -#endif - -#ifdef emacs -#include "config.h" -#ifdef static -/* actually, only want this if static is defined as "" - -- this is for usg, in which emacs must undefine static - in order to make unexec workable - */ -#ifndef STACK_DIRECTION -you -lose --- must know STACK_DIRECTION at compile-time -#endif /* STACK_DIRECTION undefined */ -#endif static -#endif emacs - -#ifdef X3J11 -typedef void *pointer; /* generic pointer type */ -#else -typedef char *pointer; /* generic pointer type */ -#endif - -#define NULL 0 /* null pointer constant */ - -extern void free(); -extern pointer xmalloc(); - -/* - Define STACK_DIRECTION if you know the direction of stack - growth for your system; otherwise it will be automatically - deduced at run-time. - - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown -*/ - -#ifndef STACK_DIRECTION -#define STACK_DIRECTION 0 /* direction unknown */ -#endif - -#if STACK_DIRECTION != 0 - -#define STACK_DIR STACK_DIRECTION /* known at compile-time */ - -#else /* STACK_DIRECTION == 0; need run-time code */ - -static int stack_dir; /* 1 or -1 once known */ -#define STACK_DIR stack_dir - -static void -find_stack_direction (/* void */) -{ - static char *addr = NULL; /* address of first - `dummy', once known */ - auto char dummy; /* to get stack address */ - - if (addr == NULL) - { /* initial entry */ - addr = &dummy; - - find_stack_direction (); /* recurse once */ - } - else /* second entry */ - if (&dummy > addr) - stack_dir = 1; /* stack grew upward */ - else - stack_dir = -1; /* stack grew downward */ -} - -#endif /* STACK_DIRECTION == 0 */ - -/* - An "alloca header" is used to: - (a) chain together all alloca()ed blocks; - (b) keep track of stack depth. - - It is very important that sizeof(header) agree with malloc() - alignment chunk size. The following default should work okay. -*/ - -#ifndef ALIGN_SIZE -#define ALIGN_SIZE sizeof(double) -#endif - -typedef union hdr -{ - char align[ALIGN_SIZE]; /* to force sizeof(header) */ - struct - { - union hdr *next; /* for chaining headers */ - char *deep; /* for stack depth measure */ - } h; -} header; - -/* - alloca( size ) returns a pointer to at least `size' bytes of - storage which will be automatically reclaimed upon exit from - the procedure that called alloca(). Originally, this space - was supposed to be taken from the current stack frame of the - caller, but that method cannot be made to work for some - implementations of C, for example under Gould's UTX/32. -*/ - -static header *last_alloca_header = NULL; /* -> last alloca header */ - -pointer -alloca (size) /* returns pointer to storage */ - unsigned size; /* # bytes to allocate */ -{ - auto char probe; /* probes stack depth: */ - register char *depth = &probe; - -#if STACK_DIRECTION == 0 - if (STACK_DIR == 0) /* unknown growth direction */ - find_stack_direction (); -#endif - - /* Reclaim garbage, defined as all alloca()ed storage that - was allocated from deeper in the stack than currently. */ - - { - register header *hp; /* traverses linked list */ - - for (hp = last_alloca_header; hp != NULL;) - if (STACK_DIR > 0 && hp->h.deep > depth - || STACK_DIR < 0 && hp->h.deep < depth) - { - register header *np = hp->h.next; - - free ((pointer) hp); /* collect garbage */ - - hp = np; /* -> next header */ - } - else - break; /* rest are not deeper */ - - last_alloca_header = hp; /* -> last valid storage */ - } - - if (size == 0) - return NULL; /* no allocation required */ - - /* Allocate combined header + user data storage. */ - - { - register pointer new = xmalloc (sizeof (header) + size); - /* address of header */ - - ((header *)new)->h.next = last_alloca_header; - ((header *)new)->h.deep = depth; - - last_alloca_header = (header *)new; - - /* User storage begins just after header. */ - - return (pointer)((char *)new + sizeof(header)); - } -} - diff --git a/gdb/bar.c b/gdb/bar.c deleted file mode 100644 index 59e559f..0000000 --- a/gdb/bar.c +++ /dev/null @@ -1,13 +0,0 @@ -main() { - int i; - - for (i = 0; i >= 0; i++) - bar(); -} - -bar() -{ - int i; - - i = 10; -} diff --git a/gdb/bar.nm b/gdb/bar.nm deleted file mode 100644 index 6f2df5c..0000000 --- a/gdb/bar.nm +++ /dev/null @@ -1,65 +0,0 @@ -0000003e - 00 0002 RBRAC -000020de - 00 000d SLINE -000020d6 - 00 000c SLINE -000020c8 - 00 0009 SLINE -000020c4 - 00 0006 SLINE -00000024 - 00 0002 RBRAC -000020be - 00 0004 SLINE -000020b8 - 00 0005 SLINE -000020ae - 00 0004 SLINE -0000000e - 00 0002 LBRAC -000020d6 - 00 0009 SLINE -000020e4 - 00 ffff SLINE -000020ae - 00 0001 SLINE -000020a0 - 00 0001 SLINE -00000036 - 00 0002 LBRAC -000020e4 t -lg -00000000 - 00 0000 LSYM ???:t(0,12)=(0,1) -00002098 t Fcrt1.o -0002001c D _Fmode -00020020 D _Fstatus -0000215c T __cleanup -00002164 T __exit -00020052 D __exit_nhandlers -00020056 D __exit_tnames -00020018 D __skybase -000020c8 T _bar -00020000 D _environ -00020118 D _errno -00002110 T _exit -00002164 t _exit.o -000020e4 T _finitfp_ -00020010 D _fp_state_mc68881 -0002000c D _fp_state_skyffp -00020008 D _fp_state_software -00020014 D _fp_state_sunfpa -00020004 D _fp_switch -000020a0 T _main -000020a0 - 00 0000 SO bar.c -000020a0 t bar.o -000020c8 - 00 0004 FUN bar:F(0,1) -0000216c T cerror -0000216c t cerror.o -00000000 - 00 0000 LSYM char:t(0,2)=r(0,2);0;127; -00002020 t crt0.o -00000000 - 00 0000 LSYM double:t(0,10)=r(0,1);8;0; -00002110 t exit.o -0000215c t fakcu.o -000020e4 t finitfp.o -00000000 - 00 0000 LSYM float:t(0,9)=r(0,1);4;0; -00002110 t fp_globals.o -00002098 T fsoft_used -fffffffc - 00 0004 LSYM i:(0,1) -fffffffc - 00 0004 LSYM i:(0,1) -00000000 - 00 0000 LSYM int:t(0,1)=r(0,1);-2147483648;2147483647; -000020e4 - 00 0000 SO libg.s -00000000 - 00 0000 LSYM long:t(0,3)=r(0,1);-2147483648;2147483647; -000020a0 - 00 0004 FUN main:F(0,1) -00000000 - 00 0000 LSYM short:t(0,4)=r(0,1);-32768;32767; -00002020 T start -00002098 T start_float -00000000 - 00 0000 LSYM unsigned char:t(0,5)=r(0,1);0;255; -00000000 - 00 0000 LSYM unsigned int:t(0,8)=r(0,1);0;-1; -00000000 - 00 0000 LSYM unsigned long:t(0,7)=r(0,1);0;-1; -00000000 - 00 0000 LSYM unsigned short:t(0,6)=r(0,1);0;65535; -00000000 - 00 0000 LSYM void:t(0,11)=(0,11) diff --git a/gdb/bar.s b/gdb/bar.s deleted file mode 100644 index 96b4c07..0000000 --- a/gdb/bar.s +++ /dev/null @@ -1,93 +0,0 @@ - .stabs "bar.c",0144,0,0,LL0 -LL0: - .data - .stabs "int:t(0,1)=r(0,1);-2147483648;2147483647;",0x80,0,0,0 - .stabs "char:t(0,2)=r(0,2);0;127;",0x80,0,0,0 - .stabs "long:t(0,3)=r(0,1);-2147483648;2147483647;",0x80,0,0,0 - .stabs "short:t(0,4)=r(0,1);-32768;32767;",0x80,0,0,0 - .stabs "unsigned char:t(0,5)=r(0,1);0;255;",0x80,0,0,0 - .stabs "unsigned short:t(0,6)=r(0,1);0;65535;",0x80,0,0,0 - .stabs "unsigned long:t(0,7)=r(0,1);0;-1;",0x80,0,0,0 - .stabs "unsigned int:t(0,8)=r(0,1);0;-1;",0x80,0,0,0 - .stabs "float:t(0,9)=r(0,1);4;0;",0x80,0,0,0 - .stabs "double:t(0,10)=r(0,1);8;0;",0x80,0,0,0 - .stabs "void:t(0,11)=(0,11)",0x80,0,0,0 - .stabs "???:t(0,12)=(0,1)",0x80,0,0,0 - .stabs "main:F(0,1)",0x24,0,4,_main - .text - .stabn 0104,0,1,LL1 -LL1: -|#PROC# 04 - .globl _main -_main: -|#PROLOGUE# 0 - link a6,#0 - addl #-LF12,sp - moveml #LS12,sp@ -|#PROLOGUE# 1 - .stabn 0104,0,1,LL2 -LL2: - .stabs "i:(0,1)",0x80,0,4,-4 - .stabn 0300,0,2,LL3 -LL3: - .stabn 0104,0,4,LL4 -LL4: - clrl a6@(-0x4) -L16: - tstl a6@(-0x4) - jlt L15 - .stabn 0104,0,5,LL5 -LL5: - jbsr _bar -L14: - .stabn 0104,0,4,LL6 -LL6: - addql #0x1,a6@(-0x4) - jra L16 -L15: - .stabn 0340,0,2,LL7 -LL7: - .stabn 0104,0,6,LL8 -LL8: -LE12: - unlk a6 - rts - LF12 = 4 - LS12 = 0x0 - LFF12 = 4 - LSS12 = 0x0 - LP12 = 0x8 - .data - .stabs "bar:F(0,1)",0x24,0,4,_bar - .text - .stabn 0104,0,9,LL9 -LL9: -|#PROC# 04 - .globl _bar -_bar: -|#PROLOGUE# 0 - link a6,#0 - addl #-LF18,sp - moveml #LS18,sp@ -|#PROLOGUE# 1 - .stabn 0104,0,9,LL10 -LL10: - .stabs "i:(0,1)",0x80,0,4,-4 - .stabn 0300,0,2,LL11 -LL11: - .stabn 0104,0,12,LL12 -LL12: - movl #0xa,a6@(-0x4) - .stabn 0340,0,2,LL13 -LL13: - .stabn 0104,0,13,LL14 -LL14: -LE18: - unlk a6 - rts - LF18 = 4 - LS18 = 0x0 - LFF18 = 4 - LSS18 = 0x0 - LP18 = 0x8 - .data diff --git a/gdb/bar.sym b/gdb/bar.sym deleted file mode 100644 index a3f4131..0000000 --- a/gdb/bar.sym +++ /dev/null @@ -1,51 +0,0 @@ -Symtab for file libg.s - -Line table: - - line 2 at 20e4 - -Blockvector: - -block #000 (object 0x56f90) [0x20e4..0x20e4] - block #001 (object 0x56f7c) [0x20e4..0x20e4] (under 0x56f90) - - -Symtab for file bar.c - -Line table: - - line 1 at 20a0 - line 1 at 20ae - line 4 at 20ae - line 5 at 20b8 - line 4 at 20be - line 6 at 20c4 - line 9 at 20c8 - line 9 at 20d6 - line 12 at 20d6 - line 13 at 20de - -Blockvector: - -block #000 (object 0x56f4c) [0x20a0..0x20e4] - int bar; block (object 0x56ef0) starting at 0x20c8, - int main; block (object 0x56ea8) starting at 0x20a0, - block #001 (object 0x56f08) [0x20a0..0x20e4] (under 0x56f4c) - typedef int ???; - typedef char char; - typedef double double; - typedef float float; - typedef int int; - typedef int long; - typedef short short; - typedef unsigned char unsigned char; - typedef unsigned int unsigned int; - typedef unsigned int unsigned long; - typedef unsigned short unsigned short; - typedef void void; - block #002 (object 0x56ea8) [0x20a0..0x20c8] (under 0x56f08) main - int i; local at 0xfffffffc, - block #003 (object 0x56ef0) [0x20c8..0x20e4] (under 0x56f08) bar - int i; local at 0xfffffffc, - - diff --git a/gdb/blockframe.c b/gdb/blockframe.c index 5ed025c..b337900 100644 --- a/gdb/blockframe.c +++ b/gdb/blockframe.c @@ -1,6 +1,6 @@ /* Get info from stack frames; convert between frames, blocks, functions and pc values. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. + Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. GDB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone @@ -288,17 +288,33 @@ find_pc_function (pc) int find_pc_misc_function (pc) - CORE_ADDR pc; + register CORE_ADDR pc; { - register int i; + register int lo = 0; + register int hi = misc_function_count-1; + register int new; + register int distance; /* Note that the last thing in the vector is always _etext. */ - for (i = 0; i < misc_function_count; i++) - { - if (pc < misc_function_vector[i].address) - return i - 1; - } - return -1; + + /* trivial reject range test */ + if (pc < misc_function_vector[0].address || + pc > misc_function_vector[hi].address) + return -1; + + do { + new = (lo + hi) >> 1; + distance = misc_function_vector[new].address - pc; + if (distance == 0) + return new; /* an exact match */ + else if (distance > 0) + hi = new; + else + lo = new; + } while (hi-lo != 1); + + /* if here, we had no exact match, so return the lower choice */ + return lo; } /* Return the innermost stack frame executing inside of the specified block, diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index 82e4075..fc2155a 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -142,7 +142,9 @@ condition_command (arg, from_tty) while (*p == ' ' || *p == '\t') p++; arg = p; - b->cond = (struct expression *) parse_c_1 (&arg, block_for_pc (b->address)); + b->cond = (struct expression *) parse_c_1 (&arg, block_for_pc (b->address), 0); + if (*arg) + error ("Junk at end of expression"); } return; } @@ -605,63 +607,96 @@ set_breakpoint (s, line, tempflag) } /* Set a breakpoint according to ARG (function, linenum or *address) - and make it temporary if TEMPFLAG is nonzero. */ + and make it temporary if TEMPFLAG is nonzero. + + LINE_NUM is for C++. */ static void -break_command_1 (arg, tempflag, from_tty) +break_command_1 (arg, tempflag, from_tty, line_num) char *arg; - int tempflag, from_tty; + int tempflag, from_tty, line_num; { + struct symtabs_and_lines sals; struct symtab_and_line sal; register struct expression *cond = 0; register struct breakpoint *b; + char *save_arg; + int i; + + sals.sals = NULL; + sals.nelts = 0; - sal.pc = 0; + sal.line = sal.pc = sal.end = 0; + sal.symtab = 0; if (arg) { - sal = decode_line_1 (&arg, 1, 0, 0); + CORE_ADDR pc; + sals = decode_line_1 (&arg, 1, 0, 0); - if (sal.pc == 0 && sal.symtab != 0) + if (! sals.nelts) return; + save_arg = arg; + for (i = 0; i < sals.nelts; i++) { - sal.pc = find_line_pc (sal.symtab, sal.line); - if (sal.pc == 0) - error ("No line %d in file \"%s\".", - sal.line, sal.symtab->filename); - } + sal = sals.sals[i]; + if (sal.pc == 0 && sal.symtab != 0) + { + pc = find_line_pc (sal.symtab, sal.line); + if (pc == 0) + error ("No line %d in file \"%s\".", + sal.line, sal.symtab->filename); + } + else pc = sal.pc; - while (*arg) - { - if (arg[0] == 'i' && arg[1] == 'f' - && (arg[2] == ' ' || arg[2] == '\t')) - cond = (struct expression *) parse_c_1 ((arg += 2, &arg), - block_for_pc (sal.pc)); - else - error ("Junk at end of arguments."); + while (*arg) + { + if (arg[0] == 'i' && arg[1] == 'f' + && (arg[2] == ' ' || arg[2] == '\t')) + cond = (struct expression *) parse_c_1 ((arg += 2, &arg), + block_for_pc (pc), 0); + else + error ("Junk at end of arguments."); + } + arg = save_arg; + sals.sals[i].pc = pc; } } else if (default_breakpoint_valid) { + sals.sals = (struct symtab_and_line *) malloc (sizeof (struct symtab_and_line)); sal.pc = default_breakpoint_address; sal.line = default_breakpoint_line; sal.symtab = default_breakpoint_symtab; + sals.sals[0] = sal; + sals.nelts = 1; } else error ("No default breakpoint address now."); - if (from_tty) - describe_other_breakpoints (sal.pc); + for (i = 0; i < sals.nelts; i++) + { + sal = sals.sals[i]; + sal.line += line_num; /** C++ **/ + if (line_num != 0) + { /* get the pc for a particular line */ + sal.pc = find_line_pc (sal.symtab, sal.line); + } - b = set_raw_breakpoint (sal); - b->number = ++breakpoint_count; - b->cond = cond; - if (tempflag) - b->enable = temporary; - - printf ("Breakpoint %d at 0x%x", b->number, b->address); - if (b->symtab) - printf (": file %s, line %d.", b->symtab->filename, b->line_number); - printf ("\n"); + if (from_tty) + describe_other_breakpoints (sal.pc); + + b = set_raw_breakpoint (sal); + b->number = ++breakpoint_count; + b->cond = cond; + if (tempflag) + b->enable = temporary; + + printf ("Breakpoint %d at 0x%x", b->number, b->address); + if (b->symtab) + printf (": file %s, line %d.", b->symtab->filename, b->line_number); + printf ("\n"); + } + free (sals.sals); } static void @@ -669,7 +704,7 @@ break_command (arg, from_tty) char *arg; int from_tty; { - break_command_1 (arg, 0, from_tty); + break_command_1 (arg, 0, from_tty, 0); } static void @@ -677,7 +712,7 @@ tbreak_command (arg, from_tty) char *arg; int from_tty; { - break_command_1 (arg, 1, from_tty); + break_command_1 (arg, 1, from_tty, 0); } static void @@ -686,60 +721,72 @@ clear_command (arg, from_tty) int from_tty; { register struct breakpoint *b, *b1; + struct symtabs_and_lines sals; struct symtab_and_line sal; register struct breakpoint *found; + int i; if (arg) - sal = decode_line_spec (arg, 1); + { + sals = decode_line_spec (arg, 1); + } else { + sals.sals = (struct symtab_and_line *) malloc (sizeof (struct symtab_and_line)); sal.line = default_breakpoint_line; sal.symtab = default_breakpoint_symtab; sal.pc = 0; if (sal.symtab == 0) error ("No source file specified."); - } - /* If exact pc given, clear bpts at that pc. - But if sal.pc is zero, clear all bpts on specified line. */ + sals.sals[0] = sal; + sals.nelts = 1; + } - found = (struct breakpoint *) 0; - while (breakpoint_chain - && (sal.pc ? breakpoint_chain->address == sal.pc - : (breakpoint_chain->symtab == sal.symtab - && breakpoint_chain->line_number == sal.line))) + for (i = 0; i < sals.nelts; i++) { - b1 = breakpoint_chain; - breakpoint_chain = b1->next; - b1->next = found; - found = b1; - } + /* If exact pc given, clear bpts at that pc. + But if sal.pc is zero, clear all bpts on specified line. */ + sal = sals.sals[i]; + found = (struct breakpoint *) 0; + while (breakpoint_chain + && (sal.pc ? breakpoint_chain->address == sal.pc + : (breakpoint_chain->symtab == sal.symtab + && breakpoint_chain->line_number == sal.line))) + { + b1 = breakpoint_chain; + breakpoint_chain = b1->next; + b1->next = found; + found = b1; + } - ALL_BREAKPOINTS (b) - while (b->next - && (sal.pc ? b->next->address == sal.pc - : (b->next->symtab == sal.symtab - && b->next->line_number == sal.line))) - { - b1 = b->next; - b->next = b1->next; - b1->next = found; - found = b1; - } + ALL_BREAKPOINTS (b) + while (b->next + && (sal.pc ? b->next->address == sal.pc + : (b->next->symtab == sal.symtab + && b->next->line_number == sal.line))) + { + b1 = b->next; + b->next = b1->next; + b1->next = found; + found = b1; + } - if (found == 0) - error ("No breakpoint at %s.", arg); + if (found == 0) + error ("No breakpoint at %s.", arg); - if (found->next) from_tty = 1; /* Alwats report if deleted more than one */ - if (from_tty) printf ("Deleted breakpoint%s ", found->next ? "s" : ""); - while (found) - { - if (from_tty) printf ("%d ", found->number); - b1 = found->next; - delete_breakpoint (found); - found = b1; + if (found->next) from_tty = 1; /* Always report if deleted more than one */ + if (from_tty) printf ("Deleted breakpoint%s ", found->next ? "s" : ""); + while (found) + { + if (from_tty) printf ("%d ", found->number); + b1 = found->next; + delete_breakpoint (found); + found = b1; + } + if (from_tty) putchar ('\n'); } - if (from_tty) putchar ('\n'); + free (sals.sals); } /* Delete breakpoint number BNUM if it is a `delete' breakpoint. diff --git a/gdb/coffread.c b/gdb/coffread.c index 626b16f..50005fd 100644 --- a/gdb/coffread.c +++ b/gdb/coffread.c @@ -30,7 +30,6 @@ anyone else from sharing it farther. Help stamp out software hoarding! #include <a.out.h> #include <stdio.h> #include <obstack.h> -#include <sys/types.h> #include <sys/param.h> #include <sys/file.h> @@ -169,9 +168,6 @@ 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. @@ -785,7 +781,7 @@ read_coff_symtab (desc, nsyms) static AUXENT main_aux; int num_object_files = 0; - int next_file_symnum = 0; + int next_file_symnum; char *filestring; int depth; int fcn_first_line; @@ -810,10 +806,6 @@ read_coff_symtab (desc, nsyms) { read_one_sym (cs, &main_sym, &main_aux); - /* - * If we are finished with the previous file's symbols, and the - * next thing is not a C_FILE, then we have hit the global symbols. - */ if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE) { CORE_ADDR last_file_end = cur_src_end_addr; @@ -826,6 +818,10 @@ read_coff_symtab (desc, nsyms) /* done with all files, everything from here on out is globals */ } + /* Special case for file with type declarations only, no text. */ + if (!last_source_file && cs->c_type != T_NULL && cs->c_secnum == N_DEBUG) + complete_symtab (filestring, 0, 0); + if (ISFCN (cs->c_type)) { /* @@ -877,7 +873,6 @@ read_coff_symtab (desc, nsyms) end_symtab (); start_symtab (); } - complete_symtab (filestring, 0, 0); /* FIXME, 0 0 is wrong */ num_object_files++; break; @@ -902,12 +897,8 @@ read_coff_symtab (desc, nsyms) case C_STAT: if (cs->c_type == T_NULL && cs->c_secnum > N_UNDEF) { - /* These ".text", ".data", ".bss" entries don't seem to - * appear in A/UX COFF output. -- gnu@toad.com 4Apr88 - */ if (strcmp (cs->c_name, _TEXT) == 0) { - /* We have a ".text" symbol */ if (num_object_files == 1) { /* Record end address of first file, crt0.s */ @@ -1020,9 +1011,15 @@ read_file_hdr (chan, file_hdr) if (myread (chan, (char *)file_hdr, FILHSZ) < 0) return -1; - if (BADMAG(file_hdr)) - return -1; /* Non understood file */ - return file_hdr->f_nsyms; /* OK magic number, return # syms */ + switch (file_hdr->f_magic) + { + case NS32GMAGIC: + case NS32SMAGIC: + return file_hdr->f_nsyms; + + default: + return -1; + } } read_aout_hdr (chan, aout_hdr, size) @@ -1081,17 +1078,6 @@ read_one_sym (cs, sym, aux) cs->c_secnum = sym->n_scnum; cs->c_type = (unsigned) sym->n_type; -#ifdef DEBUG - if (debug) { - fprintf(stderr, "sym %3x: %2x %s %x %x %x", cs->c_symnum, - cs->c_sclass, cs->c_name, cs->c_value, cs->c_secnum, cs->c_type); - if (cs->c_nsyms > 1) - fprintf(stderr, " +aux %s\n", (char *)aux); - else - fprintf(stderr, "\n"); - } -#endif - symnum += cs->c_nsyms; } @@ -1111,13 +1097,6 @@ init_stringtab (chan, offset) return -1; val = myread (chan, (char *)&buffer, sizeof buffer); - - /* If no string table, we get 0 bytes back from the read. That's OK. */ - if (val == 0) { - free_stringtab(); - return 0; - } - if (val != sizeof buffer) return -1; @@ -1150,8 +1129,6 @@ getsymname (symbol_entry) if (symbol_entry->n_zeroes == 0) { - if (!stringtab) - error("Symbol entry references nonexistent string table"); result = stringtab + symbol_entry->n_offset; } else @@ -1172,11 +1149,9 @@ getfilename (aux_entry) char *result; extern char *rindex (); -#ifndef mac_aux if (aux_entry->x_file.x_foff != 0) strcpy (buffer, stringtab + aux_entry->x_file.x_foff); else -#endif { strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN); buffer[FILNMLEN] = '\0'; @@ -1578,8 +1553,7 @@ decode_base_type (cs, c_type, aux) switch (c_type) { case T_NULL: - /* NULL seems to be used as the basic type of void functions */ - return builtin_type_void; + /* shouldn't show up here */ break; case T_ARG: @@ -1663,8 +1637,7 @@ decode_base_type (cs, c_type, aux) case T_ULONG: return builtin_type_unsigned_long; } - printf ("unexpected type %d at symnum %d, name %s\n", c_type, cs->c_symnum, - cs->c_name); + printf ("unexpected type %d at symnum %d\n", c_type, cs->c_symnum); return builtin_type_void; } diff --git a/gdb/command.c b/gdb/command.c index fed5ff9..ec5bfc0 100644 --- a/gdb/command.c +++ b/gdb/command.c @@ -46,32 +46,40 @@ the terms of Paragraph 1 above, provided that you also do the following: that in whole or in part contains or is a derivative of this program or any part thereof, to be licensed at no charge to all third parties on terms identical to those contained in this - License Agreement (except that you may choose to grant more - extensive warranty protection to third parties, at your option). + License Agreement (except that you may choose to grant more extensive + warranty protection to some or all third parties, at your option). c) You may charge a distribution fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. - 3. You may copy and distribute this program or any portion of it in -compiled, executable or object code form under the terms of Paragraphs -1 and 2 above provided that you do the following: - - a) cause each such copy to be accompanied by the - corresponding machine-readable source code, which must - be distributed under the terms of Paragraphs 1 and 2 above; or, - - b) cause each such copy to be accompanied by a - written offer, with no time limit, to give any third party - free (except for a nominal shipping charge) a machine readable - copy of the corresponding source code, to be distributed - under the terms of Paragraphs 1 and 2 above; or, - - c) in the case of a recipient of this program in compiled, executable - or object code form (without the corresponding source code) you - shall cause copies you distribute to be accompanied by a copy - of the written offer of source code which you received along - with the copy you received. +Mere aggregation of another unrelated program with this program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other program under the scope of these terms. + + 3. You may copy and distribute this program (or a portion or derivative +of it, under Paragraph 2) in object code or executable form under the terms +of Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal + shipping charge) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +For an executable file, complete source code means all the source code for +all modules it contains; but, as a special exception, it need not include +source code for modules which are standard libraries that accompany the +operating system on which the executable file runs. 4. You may not copy, sublicense, distribute or transfer this program except as expressly provided under this License Agreement. Any attempt diff --git a/gdb/command.h b/gdb/command.h index 687741c..bf7891a 100644 --- a/gdb/command.h +++ b/gdb/command.h @@ -46,32 +46,40 @@ the terms of Paragraph 1 above, provided that you also do the following: that in whole or in part contains or is a derivative of this program or any part thereof, to be licensed at no charge to all third parties on terms identical to those contained in this - License Agreement (except that you may choose to grant more - extensive warranty protection to third parties, at your option). + License Agreement (except that you may choose to grant more extensive + warranty protection to some or all third parties, at your option). c) You may charge a distribution fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. - 3. You may copy and distribute this program or any portion of it in -compiled, executable or object code form under the terms of Paragraphs -1 and 2 above provided that you do the following: - - a) cause each such copy to be accompanied by the - corresponding machine-readable source code, which must - be distributed under the terms of Paragraphs 1 and 2 above; or, - - b) cause each such copy to be accompanied by a - written offer, with no time limit, to give any third party - free (except for a nominal shipping charge) a machine readable - copy of the corresponding source code, to be distributed - under the terms of Paragraphs 1 and 2 above; or, - - c) in the case of a recipient of this program in compiled, executable - or object code form (without the corresponding source code) you - shall cause copies you distribute to be accompanied by a copy - of the written offer of source code which you received along - with the copy you received. +Mere aggregation of another unrelated program with this program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other program under the scope of these terms. + + 3. You may copy and distribute this program (or a portion or derivative +of it, under Paragraph 2) in object code or executable form under the terms +of Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal + shipping charge) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +For an executable file, complete source code means all the source code for +all modules it contains; but, as a special exception, it need not include +source code for modules which are standard libraries that accompany the +operating system on which the executable file runs. 4. You may not copy, sublicense, distribute or transfer this program except as expressly provided under this License Agreement. Any attempt @@ -24,7 +24,7 @@ anyone else from sharing it farther. Help stamp out software hoarding! #include <a.out.h> #include <stdio.h> -#include <sys/types.h> +#include <signal.h> #include <sys/param.h> #include <sys/dir.h> #include <sys/file.h> @@ -41,16 +41,8 @@ anyone else from sharing it farther. Help stamp out software hoarding! #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 #endif /* NEW_SUN_CORE */ #ifndef N_TXTADDR @@ -72,6 +64,8 @@ anyone else from sharing it farther. Help stamp out software hoarding! #define AOUTHDR struct exec #endif +extern char *sys_siglist[]; + START_FILE /* Hook for `exec_file_command' command to call. */ @@ -105,8 +99,9 @@ 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; +CORE_ADDR text_start; +CORE_ADDR text_end; + static CORE_ADDR exec_data_start; static CORE_ADDR exec_data_end; @@ -211,6 +206,12 @@ core_file_command (filename, from_tty) bcopy (&corestr.c_aouthdr, &core_aouthdr, sizeof (struct exec)); printf ("Core file is from \"%s\".\n", corestr.c_cmdname); + if (corestr.c_signo > 0) + printf ("Program terminated with signal %d, %s.\n", + corestr.c_signo, + corestr.c_signo < NSIG + ? sys_siglist[corestr.c_signo] + : "(undocumented)"); } #else /* not NEW_SUN_CORE */ /* 4.2-style (and perhaps also sysV-style) core dump file. */ @@ -235,18 +236,14 @@ core_file_command (filename, from_tty) reg_offset = 0; bcopy (&u.pt_aouthdr, &core_aouthdr, sizeof (AOUTHDR)); - + printf ("Core file is from \"%s\".\n", u.pt_comm); + if (u.pt_signal > 0) + printf ("Program terminated with signal %d, %s.\n", + u.pt_signal, + u.pt_signal < NSIG + ? sys_siglist[u.pt_signal] + : "(undocumented)"); #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; @@ -256,7 +253,6 @@ core_file_command (filename, from_tty) /* 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 @@ -285,10 +281,7 @@ core_file_command (filename, from_tty) corefile = savestring (filename, strlen (filename)); else { - char dirname[MAXPATHLEN]; - - getwd (dirname); - corefile = concat (dirname, "/", filename); + corefile = concat (current_directory, "/", filename); } set_current_frame (read_register (FP_REGNUM)); @@ -672,12 +665,6 @@ register_addr (regno, blockend) 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; diff --git a/gdb/dbxread.c b/gdb/dbxread.c index 007e768..c1c4acc 100644 --- a/gdb/dbxread.c +++ b/gdb/dbxread.c @@ -1,5 +1,6 @@ /* Read dbx symbol tables and convert to internal format, for GDB. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. + Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. + Hacked by Michael Tiemann (tiemann@mcc.com) GDB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone @@ -46,7 +47,12 @@ static struct symbol *define_symbol (); static void start_subfile (); static int hashname (); static void hash_symsegs (); + extern struct symtab *read_symsegs (); +extern void free_all_symtabs (); + +/* C++ */ +static struct type **read_args (); START_FILE @@ -468,6 +474,7 @@ dbx_alloc_type (typenums) type = (struct type *) obstack_alloc (symbol_obstack, sizeof (struct type)); bzero (type, sizeof (struct type)); + TYPE_VPTR_FIELDNO (type) = -1; *type_addr = type; } return type; @@ -682,6 +689,8 @@ start_symtab (name, start_addr) if (s->ldsymoff == symnum * sizeof (struct nlist)) break; current_symseg = s; + if (s != 0) + return; type_vector_length = 160; type_vector = (struct typevector *) xmalloc (sizeof (struct typevector) + type_vector_length * sizeof (struct type *)); @@ -767,6 +776,13 @@ end_symtab (end_addr) register struct linetable *lv; struct subfile *nextsub; + if (current_symseg != 0) + { + last_source_file = 0; + current_symseg = 0; + return; + } + /* Finish the lexical context of the last function in the file. */ if (context_stack) @@ -779,12 +795,10 @@ end_symtab (end_addr) } /* Finish defining all the blocks of this symtab. */ - if (current_symseg == 0) - { - finish_block (0, &file_symbols, 0, last_source_start_addr, end_addr); - finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr); - blockvector = make_blockvector (); - } + finish_block (0, &file_symbols, 0, last_source_start_addr, end_addr); + finish_block (0, &global_symbols, 0, last_source_start_addr, end_addr); + blockvector = make_blockvector (); + current_subfile->line_vector_index = line_vector_index; /* Now create the symtab objects proper, one for each subfile. */ @@ -793,22 +807,16 @@ end_symtab (end_addr) for (subfile = subfiles; subfile; subfile = nextsub) { symtab = (struct symtab *) xmalloc (sizeof (struct symtab)); + symtab->free_ptr = 0; + /* Fill in its components. */ - if (current_symseg) - { - bcopy (current_symseg, symtab, sizeof (struct symtab)); - symtab->free_code = free_linetable; - symtab->free_ptr = 0; - } - else - { - symtab->blockvector = blockvector; - type_vector->length = type_vector_length; - symtab->typevector = type_vector; - symtab->free_code = free_linetable; - if (subfile->next == 0) - symtab->free_ptr = (char *) type_vector; - } + symtab->blockvector = blockvector; + type_vector->length = type_vector_length; + symtab->typevector = type_vector; + symtab->free_code = free_linetable; + if (subfile->next == 0) + symtab->free_ptr = (char *) type_vector; + symtab->filename = subfile->name; lv = subfile->line_vector; lv->nitems = subfile->line_vector_index; @@ -1049,6 +1057,7 @@ symbol_file_command (name) register int val; extern void close (); struct cleanup *old_chain; + struct symtab *symseg; dont_repeat (); @@ -1094,6 +1103,9 @@ symbol_file_command (name) return; } + printf ("Reading symbol data from %s...", name); + fflush (stdout); + /* Now read the string table, all at once. */ val = lseek (desc, N_SYMOFF (hdr) + hdr.a_syms, 0); if (val < 0) @@ -1102,15 +1114,52 @@ symbol_file_command (name) if (val < 0) perror_with_name (name); stringtab = (char *) alloca (buffer); + if (stringtab == NULL) + { + free_all_symtabs (); + printf("%s: symbol table too large for alloca: %d bytes.\n", name, + buffer); + fflush (stdout); + return; + } bcopy (&buffer, stringtab, sizeof buffer); val = myread (desc, stringtab + sizeof buffer, buffer - sizeof buffer); if (val < 0) perror_with_name (name); + /* Throw away the old symbol table. */ + + free_all_symtabs (); + #ifdef READ_GDB_SYMSEGS /* That puts us at the symsegs. Read them. */ symseg_chain = read_symsegs (desc, name); hash_symsegs (); + + /* Free the symtabs made by read_symsegs, but not their contents, + which have been copied into symtabs on symtab_list. */ + for (symseg = symseg_chain; symseg; symseg = symseg->next) + { + int i; + struct sourcevector *sv = (struct sourcevector *) symseg->linetable; + + for (i = 0; i < sv->length; i++) + { + int j; + struct source *source = sv->source[i]; + struct symtab *sp1 + = (struct symtab *) xmalloc (sizeof (struct symtab)); + + bcopy (symseg, sp1, sizeof (struct symtab)); + sp1->filename = savestring (source->name, strlen (source->name)); + sp1->linetable = &source->contents; + sp1->free_code = free_nothing; + sp1->free_ptr = (i == 0) ? (char *) symseg : 0; + + sp1->next = symtab_list; + symtab_list = sp1; + } + } #else /* Where people are using the 4.2 ld program, must not check for symsegs, because that ld puts randonm garbage at the end of @@ -1123,13 +1172,6 @@ symbol_file_command (name) if (val < 0) perror_with_name (name); - printf ("Reading symbol data from %s...", name); - fflush (stdout); - - /* Throw away the old symbol table. */ - - free_all_symtabs (); - init_misc_functions (); make_cleanup (discard_misc_bunches, 0); init_header_files (); @@ -1199,11 +1241,13 @@ read_dbx_symtab (desc, stringtab, nlistlen) register struct symbol *sym, *prev; int hash; int num_object_files = 0; + struct cleanup *old_chain; #ifdef N_BINCL subfile_stack = 0; #endif + old_chain = make_cleanup (free_all_symtabs, 0); nlist_stream_global = stream; nlist_size_global = nlistlen; stringtab_global = stringtab; @@ -1212,6 +1256,7 @@ read_dbx_symtab (desc, stringtab, nlistlen) for (symnum = 0; symnum < nlistlen; symnum++) { + QUIT; /* allow this to be interruptable */ fread (&buf, sizeof buf, 1, stream); namestring = buf.n_un.n_strx ? buf.n_un.n_strx + stringtab : ""; if (buf.n_type & N_STAB) @@ -1303,6 +1348,7 @@ read_dbx_symtab (desc, stringtab, nlistlen) end_symtab (end_of_text_addr); fclose (stream); + discard_cleanups (old_chain); } /* dbx allows the text of a symbol name to be continued into the @@ -1517,6 +1563,317 @@ process_one_symbol (type, desc, value, name) } } +/************************ READ_ADDL_SYM() ***********************************/ + +static void +read_addl_syms (desc, stringtab, nlistlen, text_addr, text_size) + int desc; + register char *stringtab; + register int nlistlen; + unsigned text_addr; + int text_size; +{ + FILE *stream = fdopen (desc, "r"); + struct nlist buf; + register char *namestring; + register struct symbol *sym, *prev; + int hash; + int num_object_files = 0; + +#ifdef N_BINCL + subfile_stack = 0; +#endif + + nlist_stream_global = stream; + nlist_size_global = nlistlen; + stringtab_global = stringtab; + last_source_file = 0; + bzero (global_sym_chain, sizeof global_sym_chain); + + for (symnum = 0; symnum < nlistlen; symnum++) + { + unsigned type; + + fread (&buf, sizeof buf, 1, stream); + + type = buf.n_type & N_TYPE; + if( (type == N_TEXT) || (type == N_DATA) || (type == N_BSS) ) + { + buf.n_value += text_addr; + } /* Right?? ###### */ + + + namestring = buf.n_un.n_strx ? buf.n_un.n_strx + stringtab : ""; + if (buf.n_type & N_STAB) + process_one_symbol (buf.n_type, buf.n_desc, + buf.n_value, namestring); + /* A static text symbol whose name ends in ".o" + can only mean the start of another object file. + So end the symtab of the source file we have been processing. + This is how we avoid counting the libraries as part + or the last source file. + Also this way we find end of first object file (crt0). */ + else if (buf.n_type == N_TEXT + && !strcmp (namestring + strlen (namestring) - 2, ".o")) + { + if (num_object_files++ == 1) + first_object_file_end = buf.n_value; + if (last_source_file) + { + end_symtab (buf.n_value); /* All this not used##### */ + } + } + else if (buf.n_type & N_EXT || buf.n_type == N_TEXT) + { + int used_up = 0; + + /* Record the location of _etext. */ + if (buf.n_type == (N_TEXT | N_EXT) + && !strcmp (namestring, "_etext")) + { + end_of_text_addr = buf.n_value; + } + + /* Global symbol: see if we came across a dbx definition + for a corresponding symbol. If so, store the value. + Remove syms from the chain when their values are stored, + but search the whole chain, as there may be several syms + from different files with the same name. */ + if (buf.n_type & N_EXT) + { + prev = 0; +#ifdef NAMES_HAVE_UNDERSCORE + hash = hashname (namestring + 1); +#else /* not NAMES_HAVE_UNDERSCORE */ + hash = hashname (namestring); +#endif /* not NAMES_HAVE_UNDERSCORE */ + for (sym = global_sym_chain[hash]; + sym;) + { + if ( +#ifdef NAMES_HAVE_UNDERSCORE + *namestring == '_' + && namestring[1] == SYMBOL_NAME (sym)[0] + && + !strcmp (namestring + 2, SYMBOL_NAME (sym) + 1) +#else /* NAMES_HAVE_UNDERSCORE */ + namestring[0] == SYMBOL_NAME (sym)[0] + && + !strcmp (namestring + 1, SYMBOL_NAME (sym) + 1) +#endif /* NAMES_HAVE_UNDERSCORE */ + ) + { + if (prev) + SYMBOL_VALUE (prev) = SYMBOL_VALUE (sym); + else + global_sym_chain[hash] + = (struct symbol *) SYMBOL_VALUE (sym); + SYMBOL_VALUE (sym) = buf.n_value; + if (prev) + sym = (struct symbol *) SYMBOL_VALUE (prev); + else + sym = global_sym_chain[hash]; + + used_up = 1; + } + else + { + prev = sym; + sym = (struct symbol *) SYMBOL_VALUE (sym); + } + } + } + + /* Defined global or text symbol: record as a misc function + if it didn't give its address to a debugger symbol above. */ + if (buf.n_type <= (N_TYPE | N_EXT) + && buf.n_type != N_EXT + && ! used_up) + record_misc_function (namestring, buf.n_value); + } + } + + if (last_source_file) + { + end_symtab (text_addr + text_size); + } + + fclose (stream); +} + +/***************************** CONDENSE_ADDL_MISC_BUNCHES *******************/ + +static void +condense_addl_misc_bunches () +{ + register int i, j; + register struct misc_bunch *bunch; +#ifdef NAMES_HAVE_UNDERSCORE + int offset = 1; +#else + int offset = 0; +#endif + + misc_function_vector + = (struct misc_function *) xrealloc (misc_function_vector, + (misc_count + misc_function_count) * sizeof (struct misc_function)); + + j = misc_function_count; + bunch = misc_bunch; + while (bunch) + { + for (i = 0; i < misc_bunch_index; i++) + { + misc_function_vector[j] = bunch->contents[i]; + misc_function_vector[j].name + = concat (misc_function_vector[j].name + + (misc_function_vector[j].name[0] == '_' ? offset : 0), + "", ""); + j++; + } + bunch = bunch->next; + misc_bunch_index = MISC_BUNCH_SIZE; + } + + misc_function_count += misc_count; + + /* Sort the misc functions by address. */ + + qsort (misc_function_vector, misc_function_count, + sizeof (struct misc_function), compare_misc_functions); +} + +/**************************** ADD_FILE_COMMAND() ****************************/ +/* This function allows the addition of incrementally linked object files. + Useful for debugging `sun_kick'. */ + +void +add_file_command (arg_string) + char* arg_string; +{ + register int desc; + struct exec hdr; + struct nlist *nlist; + char *stringtab; + long buffer; + register int val; + extern void close (); + struct cleanup *old_chain; + char* name; + unsigned text_addr; + + for( ; *arg_string == ' '; arg_string++ ); + name = arg_string; + for( ; *arg_string != ' ' ; arg_string++ ); + *arg_string++ = (char) 0; + for( ; *arg_string == ' '; arg_string++ ); + text_addr = (unsigned) atoi(arg_string); + + printf("filename \"%s\", and text_addr = 0x%x\n", name, text_addr ); + + dont_repeat (); + + if (name == 0) + { + if (symtab_list && !query ("Discard symbol table? ", 0)) + error ("Not confirmed."); + free_all_symtabs (); + return; + } + + /* if (symtab_list && !query ("Add new symbols from \"%s\"? ", name)) + error ("Not confirmed."); + */ + { + char *absolute_name; + desc = openp (getenv ("PATH"), 1, name, O_RDONLY, 0, &absolute_name); + if (desc < 0) + perror_with_name (name); + else + name = absolute_name; + } + + old_chain = make_cleanup (close, desc); + make_cleanup (free_current_contents, &name); + + val = myread (desc, &hdr, sizeof hdr); + if (val < 0) + perror_with_name (name); + + if (N_BADMAG (hdr)) + error ("File \"%s\" has a bad header.", name); + + if (hdr.a_syms == 0) + { + printf ("%s does not have a symbol-table.\n", name); + fflush (stdout); + return; + } + + /* Now read the string table, all at once. */ + val = lseek (desc, N_SYMOFF (hdr) + hdr.a_syms, 0); + if (val < 0) + perror_with_name (name); + val = myread (desc, &buffer, sizeof buffer); + if (val < 0) + perror_with_name (name); + stringtab = (char *) alloca (buffer); + bcopy (&buffer, stringtab, sizeof buffer); + val = myread (desc, stringtab + sizeof buffer, buffer - sizeof buffer); + if (val < 0) + perror_with_name (name); + + /* That puts us at the symsegs. Read them. ########## Also need other + changes if they exist. */ + + + /* Position to read the symbol table. Do not read it all at once. */ + val = lseek (desc, N_SYMOFF (hdr), 0); + if (val < 0) + perror_with_name (name); + + printf ("Reading symbol data from %s...", name); + fflush (stdout); + + init_misc_functions (); + make_cleanup (discard_misc_bunches, 0); + init_header_files (); + make_cleanup (free_header_files, 0); + + read_addl_syms (desc, stringtab, hdr.a_syms / sizeof(struct nlist) + ,text_addr, hdr.a_text) ; + + /* Sort symbols alphabetically within each block. */ + + sort_syms (); + + /* Go over the all misc functions and install them in vector. */ + + condense_addl_misc_bunches (); + + /* Don't allow char * to have a typename (else would get caddr_t.) */ + + TYPE_NAME (lookup_pointer_type (builtin_type_char)) = 0; + + /* Make a default for file to list. */ + + select_source_symtab (symtab_list); + + do_cleanups (old_chain); + + /* Free the symtabs made by read_symsegs, but not their contents, + which have been copied into symtabs on symtab_list. */ + while (symseg_chain) + { + register struct symtab *s = symseg_chain->next; + free (symseg_chain); + symseg_chain = s; + } + + printf ("done.\n"); + fflush (stdout); +} + static struct symbol * define_symbol (value, string, desc) int value; @@ -1668,6 +2025,16 @@ define_symbol (value, string, desc) if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0 && (TYPE_FLAGS (SYMBOL_TYPE (sym)) & TYPE_FLAG_PERM) == 0) TYPE_NAME (SYMBOL_TYPE (sym)) = concat (SYMBOL_NAME (sym), "", ""); + /* C++ vagaries: we may have a type which is derived from + a base type which did not have its name defined when the + derived class was output. We fill in the derived class's + base part member's name here in that case. */ + else if ((TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_STRUCT + || TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_UNION) + && TYPE_BASECLASS (SYMBOL_TYPE (sym)) + && TYPE_FIELD_NAME (SYMBOL_TYPE (sym), 0) == 0) + TYPE_FIELD_NAME (SYMBOL_TYPE (sym), 0) = TYPE_NAME (TYPE_BASECLASS (SYMBOL_TYPE (sym))); + add_symbol_to_list (sym, &file_symbols); break; @@ -1771,6 +2138,10 @@ read_type (pp) break; } /* Skip the name the cross-ref points to. */ + /* Note: for C++, the cross reference may be to a base type which + has not yet been seen. In this case, we skip to the comma, + which will mark the end of the base class name. (The ':' + at the end of the base class name will be skipped as well.) */ *pp = (char *) index (*pp, ','); /* Just allocate the type and leave it zero if nothing known */ return dbx_alloc_type (typenums); @@ -1799,6 +2170,27 @@ read_type (pp) smash_to_pointer_type (type, read_type (pp)); break; + case '@': + { + struct type *domain = read_type (pp); + char c; + struct type *ptrtype; + + if (*(*pp)++ != ',') + error ("invalid member pointer data format, at symtab pos %d.", + symnum); + + ptrtype = read_type (pp); + type = dbx_alloc_type (typenums); + smash_to_member_pointer_type (type, domain, ptrtype); + } + break; + + case '&': + type = dbx_alloc_type (typenums); + smash_to_reference_type (type, read_type (pp)); + break; + case 'f': type = dbx_alloc_type (typenums); smash_to_function_type (type, read_type (pp)); @@ -1892,9 +2284,23 @@ read_struct_type (pp, type) struct nextfield { struct nextfield *next; + int visibility; struct field field; }; + struct next_fnfield + { + struct next_fnfield *next; + int visibility; + struct fn_field fn_field; + }; + + struct next_fnfieldlist + { + struct next_fnfieldlist *next; + struct fn_fieldlist fn_fieldlist; + }; + register struct nextfield *list = 0; struct nextfield *new; int totalsize; @@ -1903,20 +2309,72 @@ read_struct_type (pp, type) int nfields = 0; register int n; + register struct next_fnfieldlist *mainlist = 0; + int nfn_fields = 0; + struct type *baseclass = NULL; + int read_possible_virtual_info = 0; + TYPE_CODE (type) = TYPE_CODE_STRUCT; /* First comes the total size in bytes. */ TYPE_LENGTH (type) = read_number (pp, 0); - /* Now come the fields, as NAME:TYPENUM,BITPOS,BITSIZE; for each one. - At the end, we see a semicolon instead of a field. */ + /* C++: Now, if the class is a derived class, then the next character + will be a '!', followed by the type of the base class. Allocate + pretend that that base class is a sub-structure of this one, + with its field name being the type name of the derived class. This + cannot cause a naming conflict, since field names cannot be + type names. This will magically recurse itself to gound terms + when all is read and done. */ + if (**pp == '!') + { + *pp += 1; + + switch (*(*pp)++) + { + case '0': + break; + case '1': + TYPE_VIA_PROTECTED (type) = 1; + break; + case '2': + TYPE_VIA_PUBLIC (type) = 1; + break; + default: + error ("Invalid symbol data: bad visibility format at symtab pos %d.", + symnum); + } + + if (**pp == '\\') *pp = next_symbol_text (); + new = (struct nextfield *) alloca (sizeof (struct nextfield)); + new->next = list; + list = new; + + baseclass = read_type (pp); + list->field.type = baseclass; + list->field.name = TYPE_NAME (baseclass); + *pp += 1; /* skip ',' */ + list->field.bitpos = 0; + list->field.bitsize = 0; /* this should be an unpacked field! */ + nfields++; + } + + /* Now come the fields, as NAME:?TYPENUM,BITPOS,BITSIZE; for each one. + At the end, we see a semicolon instead of a field. + + In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for + a static field. + + The `?' is a placeholder for one of '+' (public visibility), + '0' (protected visibility), and '-' (private visibility). */ while (**pp != ';') { + int visibility; + /* Check for and handle cretinous dbx symbol name continuation! */ - if (**pp == '\\') - *pp = next_symbol_text (); + if (**pp == '\\') *pp = next_symbol_text (); /* Get space to record the next field's data. */ new = (struct nextfield *) alloca (sizeof (struct nextfield)); @@ -1927,9 +2385,48 @@ read_struct_type (pp, type) p = *pp; while (*p != ':') p++; list->field.name = savestring (*pp, p - *pp); + + /* Check to see if we have hit the methods yet. */ + if (p[1] == ':') + break; + *pp = p + 1; + + /* This means we have a visibility for a field coming. */ + if (**pp == '/') + { + switch (*++*pp) + { + case '0': + visibility = 0; + *pp += 1; + break; + + case '1': + visibility = 1; + *pp += 1; + break; + + case '2': + visibility = 2; + *pp += 1; + break; + } + } + /* else normal dbx-style format. */ + list->field.type = read_type (pp); - if (**pp != ',') + if (**pp == ':') + { + list->field.bitpos = (long)-1; + p = ++(*pp); + while (*p != ';') p++; + list->field.bitsize = (long) savestring (*pp, p - *pp); + *pp = p + 1; + nfields++; + continue; + } + else if (**pp != ',') error ("Invalid symbol data: bad structure-type format at symtab pos %d.", symnum); (*pp)++; /* Skip the comma. */ @@ -1950,18 +2447,218 @@ read_struct_type (pp, type) nfields++; } - (*pp)++; /* Skip the terminating ';'. */ + /* Now come the method fields, as NAME::methods + where each method is of the form TYPENUM,ARGS,...:PHYSNAME; + At the end, we see a semicolon instead of a field. + + For the case of overloaded operators, the format is + OPERATOR::*.methods, where OPERATOR is the string "operator", + `*' holds the place for an operator name (such as `+=') + and `.' marks the end of the operator name. */ + if (p[1] == ':') + { + /* Now, read in the methods. To simplify matters, we + "unread" the name that has been read, so that we can + start from the top. */ + + p = *pp; + + /* chill the list of fields: the last entry (at the head) + is a partially constructed entry which we now scrub. */ + list = list->next; + + /* For each list of method lists... */ + do + { + int i; + struct next_fnfield *sublist = 0; + struct fn_field *fn_fields = 0; + int length = 0; + struct next_fnfieldlist *new_mainlist = + (struct next_fnfieldlist *)alloca (sizeof (struct next_fnfieldlist)); + + /* read in the name. */ + while (*p != ':') p++; + if ((*pp)[0] == 'o' && (*pp)[1] == 'p' && (*pp)[2] == '$') + { + static char opname[32] = "operator "; + char *o = opname + 9; + + /* Skip past '::'. */ + p += 2; + while (*p != '.') + *o++ = *p++; + new_mainlist->fn_fieldlist.name = savestring (opname, o - opname); + /* Skip past '.' */ + *pp = p + 1; + } + else + { + i = 0; + new_mainlist->fn_fieldlist.name = savestring (*pp, p - *pp); + /* Skip past '::'. */ + *pp = p + 2; + } + + do + { + struct next_fnfield *new_sublist = + (struct next_fnfield *)alloca (sizeof (struct next_fnfield)); + + /* Check for and handle cretinous dbx symbol name continuation! */ + if (**pp == '\\') *pp = next_symbol_text (); + + new_sublist->fn_field.type = read_type (pp); + new_sublist->fn_field.args = read_args (pp, ':'); + p = *pp; + while (*p != ';') p++; + new_sublist->fn_field.physname = savestring (*pp, p - *pp); + *pp = p + 1; + new_sublist->visibility = *(*pp)++ - '0'; + if (**pp == '\\') *pp = next_symbol_text (); + + if (*(*pp)++ == '*') + new_sublist->fn_field.voffset = read_number (pp, ';') + 1; + else + new_sublist->fn_field.voffset = 0; + + new_sublist->next = sublist; + sublist = new_sublist; + length++; + } + while (**pp != ';'); + + *pp += 1; + + new_mainlist->fn_fieldlist.fn_fields = + (struct fn_field *) obstack_alloc (symbol_obstack, + sizeof (struct fn_field) * length); + TYPE_FN_PRIVATE_BITS (new_mainlist->fn_fieldlist) = + (int *) obstack_alloc (symbol_obstack, + sizeof (int) * (1 + (length >> 5))); + + TYPE_FN_PROTECTED_BITS (new_mainlist->fn_fieldlist) = + (int *) obstack_alloc (symbol_obstack, + sizeof (int) * (1 + (length >> 5))); + + for (i = length; sublist; sublist = sublist->next) + { + new_mainlist->fn_fieldlist.fn_fields[--i] = sublist->fn_field; + if (sublist->visibility == 0) + B_SET (new_mainlist->fn_fieldlist.private_fn_field_bits, i); + else if (sublist->visibility == 1) + B_SET (new_mainlist->fn_fieldlist.protected_fn_field_bits, i); + } + + new_mainlist->fn_fieldlist.length = length; + new_mainlist->next = mainlist; + mainlist = new_mainlist; + nfn_fields++; + } + while (**pp != ';'); + + *pp += 2; + + if (**pp == '~') + { + read_possible_virtual_info = 1; + *pp += 1; + } + if (**pp == '-') + { + TYPE_HAS_DESTRUCTOR (type) = 1; + TYPE_HAS_CONSTRUCTOR (type) = 1; + *pp += 1; + } + else if (**pp == '+') + { + TYPE_HAS_CONSTRUCTOR (type) = 1; + *pp += 1; + } + } + else *pp += 1; /* Now create the vector of fields, and record how big it is. */ TYPE_NFIELDS (type) = nfields; TYPE_FIELDS (type) = (struct field *) obstack_alloc (symbol_obstack, sizeof (struct field) * nfields); + TYPE_FIELD_PRIVATE_BITS (type) = + (int *) obstack_alloc (symbol_obstack, + sizeof (int) * (1 + (nfields >> 5))); + TYPE_FIELD_PROTECTED_BITS (type) = + (int *) obstack_alloc (symbol_obstack, + sizeof (int) * (1 + (nfields >> 5))); + + TYPE_NFN_FIELDS (type) = nfn_fields; + TYPE_NFN_FIELDS_TOTAL (type) = nfn_fields; + if (baseclass) + TYPE_NFN_FIELDS_TOTAL (type) += TYPE_NFN_FIELDS_TOTAL (baseclass); + + TYPE_FN_FIELDLISTS (type) = + (struct fn_fieldlist *) obstack_alloc (symbol_obstack, + sizeof (struct fn_fieldlist) * nfn_fields); /* Copy the saved-up fields into the field vector. */ for (n = nfields; list; list = list->next) - TYPE_FIELD (type, --n) = list->field; + { + TYPE_FIELD (type, --n) = list->field; + if (list->visibility == 0) + SET_TYPE_FIELD_PRIVATE (type, n); + else if (list->visibility == 1) + SET_TYPE_FIELD_PROTECTED (type, n); + } + + for (n = nfn_fields; mainlist; mainlist = mainlist->next) + TYPE_FN_FIELDLISTS (type)[--n] = mainlist->fn_fieldlist; + + TYPE_BASECLASS (type) = baseclass; + + if (read_possible_virtual_info) + { + /* Read either a '%' or the final ';'. */ + if (*(*pp)++ == '%') + { + /* Now we must record the virtual function table pointer's + field information. */ + + struct type *t; + int i; + + t = read_type (pp); + p = (*pp)++; + while (*p != ';') p++; + TYPE_VPTR_BASETYPE (type) = t; + if (type == t) + { + if (TYPE_FIELD_NAME (t, 0) == 0) + TYPE_VPTR_FIELDNO (type) = i = 0; + else for (i = TYPE_NFIELDS (t) - 1; i >= 0; --i) + if (! strncmp (TYPE_FIELD_NAME (t, i), *pp, + strlen (TYPE_FIELD_NAME (t, i)))) + { + TYPE_VPTR_FIELDNO (type) = i; + break; + } + if (i < 0) + error ("virtual function table field not found"); + } + else + TYPE_VPTR_FIELDNO (type) = TYPE_VPTR_FIELDNO (TYPE_BASECLASS (type)); + *pp = p; + } + else + { + TYPE_VPTR_BASETYPE (type) = 0; + TYPE_VPTR_FIELDNO (type) = -1; + } + } + else + { + TYPE_VPTR_BASETYPE (type) = 0; + TYPE_VPTR_FIELDNO (type) = -1; + } return type; } @@ -1995,8 +2692,7 @@ read_enum_type (pp, type) while (**pp && **pp != ';') { /* Check for and handle cretinous dbx symbol name continuation! */ - if (**pp == '\\') - *pp = next_symbol_text (); + if (**pp == '\\') *pp = next_symbol_text (); p = *pp; while (*p != ':') p++; @@ -2169,6 +2865,48 @@ read_number (pp, end) return n * sign; } +/* Read in an argument list. This is a list of types. It is terminated with + a ':', FYI. Return the list of types read in. */ +static struct type ** +read_args (pp, end) + char **pp; + int end; +{ + struct type *types[1024], **rval; /* allow for fns of 1023 parameters */ + int n = 0; + + while (**pp != end) + { + if (**pp != ',') + error ("Invalid argument list: no ',', at symtab pos %d", symnum); + *pp += 1; + types[n++] = read_type (pp); + } + *pp += 1; /* get past `end' (the ':' character) */ + + if (n == 1) + { + rval = (struct type **) xmalloc (2 * sizeof (struct type *)); + } + else + { + rval = (struct type **) xmalloc (n * sizeof (struct type *)); + } + bcopy (types, rval, n * sizeof (struct type *)); + return rval; +} + +/* This function is really horrible, but to avoid it, there would need + to be more filling in of forward references. */ +int +fill_in_vptr_fieldno (type) + struct type *type; +{ + if (TYPE_VPTR_FIELDNO (type) < 0) + TYPE_VPTR_FIELDNO (type) = fill_in_vptr_fieldno (TYPE_BASECLASS (type)); + return TYPE_VPTR_FIELDNO (type); +} + static initialize () { @@ -2176,6 +2914,9 @@ initialize () add_com ("symbol-file", class_files, symbol_file_command, "Load symbol table (in dbx format) from executable file FILE."); + + add_com ("add-file", class_files, add_file_command, + "Load the symbols from FILE, assuming its codes is at TEXT_START.") ; } END_FILE @@ -73,3 +73,7 @@ struct command_line }; struct command_line *read_command_lines (); + +/* String containing the current directory (what getwd would return). */ + +char *current_directory; diff --git a/gdb/environ.c b/gdb/environ.c index 0b9f913..3dab98c 100644 --- a/gdb/environ.c +++ b/gdb/environ.c @@ -46,32 +46,40 @@ the terms of Paragraph 1 above, provided that you also do the following: that in whole or in part contains or is a derivative of this program or any part thereof, to be licensed at no charge to all third parties on terms identical to those contained in this - License Agreement (except that you may choose to grant more - extensive warranty protection to third parties, at your option). + License Agreement (except that you may choose to grant more extensive + warranty protection to some or all third parties, at your option). c) You may charge a distribution fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. - 3. You may copy and distribute this program or any portion of it in -compiled, executable or object code form under the terms of Paragraphs -1 and 2 above provided that you do the following: - - a) cause each such copy to be accompanied by the - corresponding machine-readable source code, which must - be distributed under the terms of Paragraphs 1 and 2 above; or, - - b) cause each such copy to be accompanied by a - written offer, with no time limit, to give any third party - free (except for a nominal shipping charge) a machine readable - copy of the corresponding source code, to be distributed - under the terms of Paragraphs 1 and 2 above; or, - - c) in the case of a recipient of this program in compiled, executable - or object code form (without the corresponding source code) you - shall cause copies you distribute to be accompanied by a copy - of the written offer of source code which you received along - with the copy you received. +Mere aggregation of another unrelated program with this program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other program under the scope of these terms. + + 3. You may copy and distribute this program (or a portion or derivative +of it, under Paragraph 2) in object code or executable form under the terms +of Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal + shipping charge) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +For an executable file, complete source code means all the source code for +all modules it contains; but, as a special exception, it need not include +source code for modules which are standard libraries that accompany the +operating system on which the executable file runs. 4. You may not copy, sublicense, distribute or transfer this program except as expressly provided under this License Agreement. Any attempt @@ -50,7 +50,7 @@ CORE_ADDR parse_and_eval_address_1 (expptr) char **expptr; { - struct expression *expr = parse_c_1 (expptr, 0); + struct expression *expr = parse_c_1 (expptr, 0, 0); register CORE_ADDR addr; register struct cleanup *old_chain = make_cleanup (free_current_contents, &expr); @@ -73,6 +73,24 @@ parse_and_eval (exp) do_cleanups (old_chain); return val; } + +/* Parse up to a comma (or to a closeparen) + in the string EXPP as an expression, evaluate it, and return the value. + EXPP is advanced to point to the comma. */ + +value +parse_to_comma_and_eval (expp) + char **expp; +{ + struct expression *expr = parse_c_1 (expp, 0, 1); + register value val; + register struct cleanup *old_chain + = make_cleanup (free_current_contents, &expr); + + val = evaluate_expression (expr); + do_cleanups (old_chain); + return val; +} /* Evaluate an expression in internal prefix form such as is constructed by expread.y. @@ -118,8 +136,8 @@ evaluate_subexp (exp, pos, noside) { enum exp_opcode op; int tem; - register int pc; - register value arg1, arg2; + register int pc, pc2, *oldpos; + register value arg1, arg2, arg3; int nargs; value *argvec; @@ -128,6 +146,12 @@ evaluate_subexp (exp, pos, noside) switch (op) { + case OP_SCOPE: + tem = strlen (&exp->elts[pc + 2].string); + (*pos) += 3 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); + return value_static_field (exp->elts[pc + 1].type, + &exp->elts[pc + 2].string, -1); + case OP_LONG: (*pos) += 3; return value_from_long (exp->elts[pc + 1].type, @@ -156,21 +180,6 @@ evaluate_subexp (exp, pos, noside) (*pos) += 2; return value_of_internalvar (exp->elts[pc + 1].internalvar); - case OP_FUNCALL: - (*pos) += 2; - nargs = exp->elts[pc + 1].longconst; - argvec = (value *) alloca (sizeof (value) * (nargs + 1)); - for (tem = 0; tem <= nargs; tem++) - - /* Ensure that array expressions are coerced into pointer objects. */ - argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside); - - if (noside == EVAL_SKIP) - goto nosideret; - if (noside == EVAL_AVOID_SIDE_EFFECTS) - return allocate_value (TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0]))); - return call_function (argvec[0], nargs, argvec + 1); - case OP_STRING: tem = strlen (&exp->elts[pc + 1].string); (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); @@ -193,13 +202,146 @@ evaluate_subexp (exp, pos, noside) return arg2; } + case OP_FUNCALL: + (*pos) += 2; + op = exp->elts[*pos].opcode; + if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR) + { + int fnptr; + int tem2; + + nargs = exp->elts[pc + 1].longconst + 1; + /* First, evaluate the structure into arg2 */ + pc2 = (*pos)++; + + if (noside == EVAL_SKIP) + goto nosideret; + + if (op == STRUCTOP_MEMBER) + { + arg2 = evaluate_subexp_for_address (exp, pos, noside); + } + else + { + arg2 = evaluate_subexp (exp, pos, noside); + } + + /* If the function is a virtual function, then the + aggregate value (providing the structure) plays + its part by providing the vtable. Otherwise, + it is just along for the ride: call the function + directly. */ + + arg1 = evaluate_subexp (exp, pos, noside); + + fnptr = value_as_long (arg1); + if (fnptr < 128) + { + struct type *basetype; + int i, j; + basetype = TYPE_TARGET_TYPE (VALUE_TYPE (arg2)); + basetype = TYPE_VPTR_BASETYPE (basetype); + for (i = TYPE_NFN_FIELDS (basetype) - 1; i >= 0; i--) + { + struct fn_field *f = TYPE_FN_FIELDLIST1 (basetype, i); + /* If one is virtual, then all are virtual. */ + if (TYPE_FN_FIELD_VIRTUAL_P (f, 0)) + for (j = TYPE_FN_FIELDLIST_LENGTH (basetype, i) - 1; j >= 0; --j) + if (TYPE_FN_FIELD_VOFFSET (f, j) == fnptr) + { + value vtbl; + value base = value_ind (arg2); + struct type *fntype = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j)); + + if (TYPE_VPTR_FIELDNO (basetype) < 0) + TYPE_VPTR_FIELDNO (basetype) + = fill_in_vptr_fieldno (basetype); + + VALUE_TYPE (base) = basetype; + vtbl = value_field (base, TYPE_VPTR_FIELDNO (basetype)); + VALUE_TYPE (vtbl) = lookup_pointer_type (fntype); + VALUE_TYPE (arg1) = builtin_type_int; + arg1 = value_subscript (vtbl, arg1); + VALUE_TYPE (arg1) = fntype; + goto got_it; + } + } + if (i < 0) + error ("virtual function at index %d not found", fnptr); + } + else + { + VALUE_TYPE (arg1) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg1))); + } + got_it: + + /* Now, say which argument to start evaluating from */ + tem = 2; + } + else if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR) + { + /* Hair for method invocations */ + int tem2; + + nargs = exp->elts[pc + 1].longconst + 1; + /* First, evaluate the structure into arg2 */ + pc2 = (*pos)++; + tem2 = strlen (&exp->elts[pc2 + 1].string); + *pos += 2 + (tem2 + sizeof (union exp_element)) / sizeof (union exp_element); + if (noside == EVAL_SKIP) + goto nosideret; + + if (op == STRUCTOP_STRUCT) + { + arg2 = evaluate_subexp_for_address (exp, pos, noside); + } + else + { + arg2 = evaluate_subexp (exp, pos, noside); + } + /* Now, say which argument to start evaluating from */ + tem = 2; + } + else + { + nargs = exp->elts[pc + 1].longconst; + tem = 0; + } + argvec = (value *) alloca (sizeof (value) * (nargs + 2)); + for (; tem <= nargs; tem++) + /* Ensure that array expressions are coerced into pointer objects. */ + argvec[tem] = evaluate_subexp_with_coercion (exp, pos, noside); + + /* signal end of arglist */ + argvec[tem] = 0; + + if (op == STRUCTOP_STRUCT || op == STRUCTOP_PTR) + { + argvec[1] = arg2; + argvec[0] = + value_struct_elt (arg2, argvec+1, &exp->elts[pc2 + 1].string, + op == STRUCTOP_STRUCT + ? "structure" : "structure pointer"); + } + else if (op == STRUCTOP_MEMBER || op == STRUCTOP_MPTR) + { + argvec[1] = arg2; + argvec[0] = arg1; + } + + if (noside == EVAL_SKIP) + goto nosideret; + if (noside == EVAL_AVOID_SIDE_EFFECTS) + return allocate_value (TYPE_TARGET_TYPE (VALUE_TYPE (argvec[0]))); + return call_function (argvec[0], nargs, argvec + 1); + case STRUCTOP_STRUCT: tem = strlen (&exp->elts[pc + 1].string); (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); arg1 = evaluate_subexp (exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; - return value_struct_elt (arg1, &exp->elts[pc + 1].string, + return value_struct_elt (arg1, 0, &exp->elts[pc + 1].string, "structure"); case STRUCTOP_PTR: @@ -208,9 +350,37 @@ evaluate_subexp (exp, pos, noside) arg1 = evaluate_subexp (exp, pos, noside); if (noside == EVAL_SKIP) goto nosideret; - return value_struct_elt (arg1, &exp->elts[pc + 1].string, + return value_struct_elt (arg1, 0, &exp->elts[pc + 1].string, "structure pointer"); + case STRUCTOP_MEMBER: + arg1 = evaluate_subexp_for_address (exp, pos, noside); + arg2 = evaluate_subexp (exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + /* Now, convert these values to an address. + @@ We do not know what type we are looking for, + @@ so we must assume that the value requested is a + @@ member address (as opposed to a member function address). */ + arg3 = value_from_long (builtin_type_long, + value_as_long (arg1) + value_as_long (arg2)); + VALUE_TYPE (arg3) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))); + return value_ind (arg3); + + case STRUCTOP_MPTR: + arg1 = evaluate_subexp (exp, pos, noside); + arg2 = evaluate_subexp (exp, pos, noside); + if (noside == EVAL_SKIP) + goto nosideret; + /* Now, convert these values to an address. + @@ We do not know what type we are looking for, + @@ so we must assume that the value requested is a + @@ member address (as opposed to a member function address). */ + arg3 = value_from_long (builtin_type_long, + value_as_long (arg1) + value_as_long (arg2)); + VALUE_TYPE (arg3) = lookup_pointer_type (TYPE_TARGET_TYPE (VALUE_TYPE (arg2))); + return value_ind (arg3); + case BINOP_ASSIGN: arg1 = evaluate_subexp (exp, pos, noside); arg2 = evaluate_subexp (exp, pos, noside); @@ -373,7 +543,22 @@ evaluate_subexp (exp, pos, noside) evaluate_subexp (exp, pos, EVAL_SKIP); goto nosideret; } - return evaluate_subexp_for_address (exp, pos, noside); + /* C++: check for and handle pointer to members. */ + + op = exp->elts[*pos].opcode; + if (op == OP_SCOPE) + { + char *name = &exp->elts[pc+3].string; + int tem = strlen (name); + struct type *domain = exp->elts[pc+2].type; + (*pos) += 2 + (tem + sizeof (union exp_element)) / sizeof (union exp_element); + arg1 = value_struct_elt_for_address (domain, 0, name); + if (arg1) + return arg1; + error ("no field `%s' in structure", name); + } + else + return evaluate_subexp_for_address (exp, pos, noside); case UNOP_SIZEOF: if (noside == EVAL_SKIP) @@ -426,6 +611,13 @@ evaluate_subexp (exp, pos, noside) return arg1; value_assign (arg1, arg2); return arg1; + + case OP_THIS: + (*pos) += 1; + return value_of_this (1); + + default: + error ("internal error: I dont know how to evaluation what you gave me"); } nosideret: diff --git a/gdb/expprint.c b/gdb/expprint.c index 36b31c6..02a1ed3 100644 --- a/gdb/expprint.c +++ b/gdb/expprint.c @@ -79,7 +79,9 @@ static struct op_print op_print_tab[] = {"&", UNOP_ADDR, PREC_PREFIX, 0}, {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0}, {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0}, - {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0} + {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0}, + /* C++ */ + {"::", BINOP_SCOPE, PREC_PREFIX, 0}, }; static void print_subexp (); @@ -119,6 +121,18 @@ print_subexp (exp, pos, stream, prec) opcode = exp->elts[pc].opcode; switch (opcode) { + case OP_SCOPE: + myprec = PREC_PREFIX; + assoc = 0; + (*pos) += 2; + print_subexp (exp, pos, stream, (int) myprec + assoc); + fprintf (stream, " :: "); + nargs = strlen (&exp->elts[pc + 2].string); + (*pos) += 1 + (nargs + sizeof (union exp_element)) / sizeof (union exp_element); + + fprintf (stream, &exp->elts[pc + 2].string); + return; + case OP_LONG: (*pos) += 3; value_print (value_from_long (exp->elts[pc + 1].type, diff --git a/gdb/expread.tab.c b/gdb/expread.tab.c new file mode 100644 index 0000000..e676cf8 --- /dev/null +++ b/gdb/expread.tab.c @@ -0,0 +1,2114 @@ + +/* A Bison parser, made from expread.y */ + +#define INT 258 +#define CHAR 259 +#define FLOAT 260 +#define NAME 261 +#define TYPENAME 262 +#define STRING 263 +#define STRUCT 264 +#define UNION 265 +#define ENUM 266 +#define SIZEOF 267 +#define UNSIGNED 268 +#define COLONCOLON 269 +#define LAST 270 +#define REGNAME 271 +#define VARIABLE 272 +#define ASSIGN_MODIFY 273 +#define THIS 274 +#define ABOVE_COMMA 275 +#define OR 276 +#define AND 277 +#define EQUAL 278 +#define NOTEQUAL 279 +#define LEQ 280 +#define GEQ 281 +#define LSH 282 +#define RSH 283 +#define UNARY 284 +#define INCREMENT 285 +#define DECREMENT 286 +#define ARROW 287 + +#line 30 "expread.y" + +#include "defs.h" +#include "param.h" +#include "symtab.h" +#include "frame.h" +#include "expression.h" + +#include <stdio.h> + +static struct expression *expout; +static int expout_size; +static int expout_ptr; + +static int yylex (); +static yyerror (); +static void write_exp_elt (); +static void write_exp_string (); +static void start_arglist (); +static int end_arglist (); +static void free_funcalls (); +static char *copy_name (); + +/* If this is nonzero, this block is used as the lexical context + for symbol names. */ + +static struct block *expression_context_block; + +/* Number of arguments seen so far in innermost function call. */ +static int arglist_len; + +/* Data structure for saving values of arglist_len + for function calls whose arguments contain other function calls. */ + +struct funcall + { + struct funcall *next; + int arglist_len; + }; + +struct funcall *funcall_chain; + +/* This kind of datum is used to represent the name + of a symbol token. */ + +struct stoken + { + char *ptr; + int length; + }; + +#line 85 "expread.y" +typedef union + { + long lval; + double dval; + struct symbol *sym; + struct type *tval; + struct stoken sval; + int voidval; + struct block *bval; + enum exp_opcode opcode; + struct internalvar *ivar; + + struct type **tvec; + int *ivec; + } YYSTYPE; + +#ifndef YYLTYPE +typedef + struct yyltype + { + int timestamp; + int first_line; + int first_column; + int last_line; + int last_column; + char *text; + } + yyltype; + +#define YYLTYPE yyltype +#endif + +#define YYACCEPT return(0) +#define YYABORT return(1) +#define YYERROR return(1) +#include <stdio.h> + +#ifndef __STDC__ +#define const +#endif + + + +#define YYFINAL 152 +#define YYFLAG -32768 +#define YYNTBASE 57 + +#define YYTRANSLATE(x) ((unsigned)(x) <= 287 ? yytranslate[x] : 68) + +static const char yytranslate[] = { 0, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 48, 2, 2, 2, 40, 27, 2, 51, + 52, 38, 36, 20, 37, 46, 39, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 56, 2, 30, + 22, 31, 55, 41, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 47, 2, 50, 26, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 53, 25, 54, 49, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 21, 23, 24, 28, 29, 32, + 33, 34, 35, 42, 43, 44, 45 +}; + +static const short yyrline[] = { 0, + 152, 156, 157, 162, 165, 168, 172, 176, 180, 184, + 188, 192, 196, 200, 206, 210, 216, 220, 224, 228, + 234, 237, 241, 245, 251, 257, 263, 267, 271, 275, + 279, 283, 287, 291, 295, 299, 303, 307, 311, 315, + 319, 323, 327, 331, 335, 339, 343, 347, 353, 360, + 367, 374, 377, 383, 389, 395, 402, 409, 416, 437, + 448, 461, 474, 510, 575, 576, 578, 580, 582, 584, + 586, 592, 595, 598, 601, 604, 609, 614, 621, 622 +}; + +static const char * const yytname[] = { 0, +"error","$illegal.","INT","CHAR","FLOAT","NAME","TYPENAME","STRING","STRUCT","UNION", +"ENUM","SIZEOF","UNSIGNED","COLONCOLON","LAST","REGNAME","VARIABLE","ASSIGN_MODIFY","THIS","','", +"ABOVE_COMMA","'='","OR","AND","'|'","'^'","'&'","EQUAL","NOTEQUAL","'<'", +"'>'","LEQ","GEQ","LSH","RSH","'+'","'-'","'*'","'/'","'%'", +"'@'","UNARY","INCREMENT","DECREMENT","ARROW","'.'","'['","'!'","'~'","']'", +"'('","')'","'{'","'}'","'?'","':'","start" +}; + +static const short yyr1[] = { 0, + 57, 58, 58, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 60, 59, + 61, 61, 61, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, + 59, 59, 59, 59, 59, 59, 59, 59, 62, 62, + 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, + 64, 65, 65, 65, 65, 65, 66, 66, 67, 67 +}; + +static const short yyr2[] = { 0, + 1, 1, 3, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 3, 4, 3, 4, 4, 0, 5, + 0, 1, 3, 4, 4, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 5, 3, 3, 1, 1, + 1, 1, 1, 1, 1, 4, 1, 1, 1, 3, + 3, 3, 2, 1, 1, 2, 2, 3, 6, 8, + 9, 1, 2, 2, 2, 2, 1, 3, 1, 1 +}; + +static const short yydefact[] = { 0, + 49, 50, 51, 64, 72, 57, 0, 0, 0, 0, + 0, 0, 53, 54, 55, 58, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 1, 2, 0, 52, 0, + 59, 79, 80, 73, 74, 75, 0, 13, 76, 63, + 5, 6, 4, 9, 10, 7, 8, 0, 0, 65, + 72, 0, 65, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 11, 12, 0, 0, 0, + 19, 0, 0, 0, 0, 26, 67, 66, 0, 0, + 0, 0, 0, 3, 48, 47, 45, 44, 43, 42, + 41, 35, 36, 39, 40, 37, 38, 33, 34, 31, + 32, 28, 29, 30, 27, 0, 14, 0, 16, 0, + 21, 0, 61, 62, 56, 0, 25, 68, 24, 15, + 17, 18, 22, 0, 0, 0, 0, 20, 46, 0, + 23, 69, 0, 70, 77, 0, 0, 71, 78, 0, + 0, 0 +}; + +static const short yydefgoto[] = { 150, + 48, 27, 121, 134, 28, 29, 49, 30, 146, 31 +}; + +static const short yypact[] = { 125, +-32768,-32768,-32768, 1,-32768,-32768, 24, 24, 24, 176, + 24, 24,-32768,-32768,-32768,-32768, 125, 125, 125, 125, + 125, 125, 125, 125, 515, 0, 243, 14,-32768, 18, +-32768,-32768,-32768,-32768,-32768,-32768, 125, 472,-32768,-32768, + 472, 472, 472, 472, 472, 472, 472, 21, 52, 19, +-32768, 58, 20, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, + 125, 125, 125, 125, 125,-32768,-32768, -1, 29, 125, +-32768, 125, 24, 24, 119,-32768,-32768,-32768, 515, 125, + 32, 125, -14, 243, 243, 243, 275, 306, 336, 365, + 393, 419, 419, 441, 441, 441, 441, 161, 161, 459, + 459, 104, 104, 104, 472, 125,-32768, 125,-32768, 49, + 125, 208, 26,-32768, 125, 57, 472,-32768, 472, 104, + 104,-32768, 243, 22, 125, 38, 125,-32768, 243, 25, + 243, 27, 16,-32768, 54, 23, 515,-32768, 54, 84, + 86,-32768 +}; + +static const short yypgoto[] = {-32768, + 3, -10,-32768,-32768,-32768,-32768, -21, -23,-32768, 10 +}; + + +#define YYLAST 528 + + +static const short yytable[] = { 38, + 50, 53, 26, 52, 32, 33, 41, 42, 43, 44, + 45, 46, 47, 50, -79, 85, 34, 35, 36, 54, + 39, 40, 51, 128, 7, 8, 9, 83, 11, 32, + 33, 84, 91, 93, 32, 33, 116, 32, 33, -60, + 54, 137, 147, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 126, 118, 144, 54, 128, + 136, 122, 86, 138, 148, 140, 142, 143, 87, 127, + 87, 129, 120, 151, 87, 152, 0, 117, 119, 88, + 0, 88, 123, 124, 0, 88, 0, 0, 132, 0, + 124, 0, 89, 90, 89, 130, 0, 131, 89, 0, + 133, 92, 0, 0, 127, 0, 0, 0, 0, 53, + 0, 145, 0, 53, 139, 149, 141, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 0, 16, 75, 87, 76, 77, 78, 79, + 80, 17, 0, 0, 81, 0, 88, 0, 82, 0, + 0, 18, 19, 0, 0, 0, 0, 20, 21, 89, + 125, 0, 22, 23, 0, 24, 0, 25, 1, 2, + 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 0, 16, 0, 70, 71, 72, 73, + 74, 75, 17, 76, 77, 78, 79, 80, 0, 0, + 0, 81, 18, 19, 0, 82, 0, 0, 20, 21, + 0, 0, 0, 22, 23, 55, 37, 0, 25, 56, + 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 0, + 76, 77, 78, 79, 80, 0, 0, 0, 81, 0, + 55, 0, 82, 135, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 0, 76, 77, 78, 79, 80, + 0, 0, 0, 81, 0, 0, 0, 82, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 0, 76, 77, 78, + 79, 80, 0, 0, 0, 81, 0, 0, 0, 82, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 0, 76, 77, + 78, 79, 80, 0, 0, 0, 81, 0, 0, 0, + 82, 60, 61, 62, 63, 64, 65, 66, 67, 68, + 69, 70, 71, 72, 73, 74, 75, 0, 76, 77, + 78, 79, 80, 0, 0, 0, 81, 0, 0, 0, + 82, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 0, 76, 77, 78, + 79, 80, 0, 0, 0, 81, 0, 0, 0, 82, + 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 0, 76, 77, 78, 79, 80, + 0, 0, 0, 81, 0, 0, 0, 82, 64, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 0, 76, 77, 78, 79, 80, 0, 0, 0, 81, + 0, 0, 0, 82, 68, 69, 70, 71, 72, 73, + 74, 75, 0, 76, 77, 78, 79, 80, 0, 0, + 0, 81, 0, 0, 0, 82, 72, 73, 74, 75, + 0, 76, 77, 78, 79, 80, 0, 0, 0, 81, + 0, 0, 0, 82, 76, 77, 78, 79, 80, 0, + 0, 51, 81, 7, 8, 9, 82, 11 +}; + +static const short yycheck[] = { 10, + 24, 25, 0, 25, 6, 7, 17, 18, 19, 20, + 21, 22, 23, 37, 14, 37, 7, 8, 9, 20, + 11, 12, 7, 38, 9, 10, 11, 14, 13, 6, + 7, 14, 14, 14, 6, 7, 38, 6, 7, 14, + 20, 20, 20, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 89, 38, 52, 20, 38, + 14, 82, 52, 52, 52, 38, 52, 51, 27, 90, + 27, 92, 80, 0, 27, 0, -1, 78, 79, 38, + -1, 38, 83, 84, -1, 38, -1, -1, 50, -1, + 91, -1, 51, 52, 51, 116, -1, 118, 51, -1, + 121, 54, -1, -1, 125, -1, -1, -1, -1, 143, + -1, 143, -1, 147, 135, 147, 137, 3, 4, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, -1, 19, 41, 27, 43, 44, 45, 46, + 47, 27, -1, -1, 51, -1, 38, -1, 55, -1, + -1, 37, 38, -1, -1, -1, -1, 43, 44, 51, + 52, -1, 48, 49, -1, 51, -1, 53, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, -1, 19, -1, 36, 37, 38, 39, + 40, 41, 27, 43, 44, 45, 46, 47, -1, -1, + -1, 51, 37, 38, -1, 55, -1, -1, 43, 44, + -1, -1, -1, 48, 49, 18, 51, -1, 53, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, -1, + 43, 44, 45, 46, 47, -1, -1, -1, 51, -1, + 18, -1, 55, 56, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, -1, 43, 44, 45, 46, 47, + -1, -1, -1, 51, -1, -1, -1, 55, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, -1, 43, 44, 45, + 46, 47, -1, -1, -1, 51, -1, -1, -1, 55, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, -1, 43, 44, + 45, 46, 47, -1, -1, -1, 51, -1, -1, -1, + 55, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, -1, 43, 44, + 45, 46, 47, -1, -1, -1, 51, -1, -1, -1, + 55, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, -1, 43, 44, 45, + 46, 47, -1, -1, -1, 51, -1, -1, -1, 55, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, -1, 43, 44, 45, 46, 47, + -1, -1, -1, 51, -1, -1, -1, 55, 30, 31, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + -1, 43, 44, 45, 46, 47, -1, -1, -1, 51, + -1, -1, -1, 55, 34, 35, 36, 37, 38, 39, + 40, 41, -1, 43, 44, 45, 46, 47, -1, -1, + -1, 51, -1, -1, -1, 55, 38, 39, 40, 41, + -1, 43, 44, 45, 46, 47, -1, -1, -1, 51, + -1, -1, -1, 55, 43, 44, 45, 46, 47, -1, + -1, 7, 51, 9, 10, 11, 55, 13 +}; +#define YYPURE 1 + +#line 2 "bison.simple" + +/* Skeleton output parser for bison, + copyright (C) 1984 Bob Corbett and Richard Stallman + + NO WARRANTY + + BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY +NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT +WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, +RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS" +WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY +AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE +DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR +CORRECTION. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. +STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY +WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE +LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR +OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR +DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR +A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS +PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. + + GENERAL PUBLIC LICENSE TO COPY + + 1. You may copy and distribute verbatim copies of this source file +as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy a valid copyright notice "Copyright +(C) 1985 Free Software Foundation, Inc."; and include following the +copyright notice a verbatim copy of the above disclaimer of warranty +and of this License. You may charge a distribution fee for the +physical act of transferring a copy. + + 2. You may modify your copy or copies of this source file or +any portion of it, and copy and distribute such modifications under +the terms of Paragraph 1 above, provided that you also do the following: + + a) cause the modified files to carry prominent notices stating + that you changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, + that in whole or in part contains or is a derivative of this + program or any part thereof, to be licensed at no charge to all + third parties on terms identical to those contained in this + License Agreement (except that you may choose to grant more + extensive warranty protection to third parties, at your option). + + c) You may charge a distribution fee for the physical act of + transferring a copy, and you may at your option offer warranty + protection in exchange for a fee. + + 3. You may copy and distribute this program or any portion of it in +compiled, executable or object code form under the terms of Paragraphs +1 and 2 above provided that you do the following: + + a) cause each such copy to be accompanied by the + corresponding machine-readable source code, which must + be distributed under the terms of Paragraphs 1 and 2 above; or, + + b) cause each such copy to be accompanied by a + written offer, with no time limit, to give any third party + free (except for a nominal shipping charge) a machine readable + copy of the corresponding source code, to be distributed + under the terms of Paragraphs 1 and 2 above; or, + + c) in the case of a recipient of this program in compiled, executable + or object code form (without the corresponding source code) you + shall cause copies you distribute to be accompanied by a copy + of the written offer of source code which you received along + with the copy you received. + + 4. You may not copy, sublicense, distribute or transfer this program +except as expressly provided under this License Agreement. Any attempt +otherwise to copy, sublicense, distribute or transfer this program is void and +your rights to use the program under this License agreement shall be +automatically terminated. However, parties who have received computer +software programs from you with this License Agreement will not have +their licenses terminated so long as such parties remain in full compliance. + + 5. If you wish to incorporate parts of this program into other free +programs whose distribution conditions are different, write to the Free +Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet +worked out a simple rule that can be stated here, but we will often permit +this. We will be guided by the two goals of preserving the free status of +all derivatives of our free software and of promoting the sharing and reuse of +software. + + +In other words, you are welcome to use, share and improve this program. +You are forbidden to forbid anyone else to use, share and improve +what you give them. Help stamp out software-hoarding! */ + +/* This is the parser code that is written into each bison parser + when the %semantic_parser declaration is not specified in the grammar. + It was written by Richard Stallman by simplifying the hairy parser + used when %semantic_parser is specified. */ + +/* Note: there must be only one dollar sign in this file. + It is replaced by the list of actions, each action + as one case of the switch. */ + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY -2 +#define YYEOF 0 +#define YYFAIL goto yyerrlab; + +#define YYTERROR 1 + +#ifndef YYIMPURE +#define YYLEX yylex() +#endif + +#ifndef YYPURE +#define YYLEX yylex(&yylval, &yylloc) +#endif + +/* If nonreentrant, generate the variables here */ + +#ifndef YYIMPURE + +int yychar; /* the lookahead symbol */ +YYSTYPE yylval; /* the semantic value of the */ + /* lookahead symbol */ + +YYLTYPE yylloc; /* location data for the lookahead */ + /* symbol */ + +int yydebug = 0; /* nonzero means print parse trace */ + +#endif /* YYIMPURE */ + + +/* YYMAXDEPTH indicates the initial size of the parser's stacks */ + +#ifndef YYMAXDEPTH +#define YYMAXDEPTH 200 +#endif + +/* YYMAXLIMIT is the maximum size the stacks can grow to + (effective only if the built-in stack extension method is used). */ + +#ifndef YYMAXLIMIT +#define YYMAXLIMIT 10000 +#endif + + +#line 87 "bison.simple" +int +yyparse() +{ + register int yystate; + register int yyn; + register short *yyssp; + register YYSTYPE *yyvsp; + YYLTYPE *yylsp; + int yyerrstatus; /* number of tokens to shift before error messages enabled */ + int yychar1; /* lookahead token as an internal (translated) token number */ + + short yyssa[YYMAXDEPTH]; /* the state stack */ + YYSTYPE yyvsa[YYMAXDEPTH]; /* the semantic value stack */ + YYLTYPE yylsa[YYMAXDEPTH]; /* the location stack */ + + short *yyss = yyssa; /* refer to the stacks thru separate pointers */ + YYSTYPE *yyvs = yyvsa; /* to allow yyoverflow to reallocate them elsewhere */ + YYLTYPE *yyls = yylsa; + + int yymaxdepth = YYMAXDEPTH; + +#ifndef YYPURE + + int yychar; + YYSTYPE yylval; + YYLTYPE yylloc; + + extern int yydebug; + +#endif + + + YYSTYPE yyval; /* the variable used to return */ + /* semantic values from the action */ + /* routines */ + + int yylen; + + if (yydebug) + fprintf(stderr, "Starting parse\n"); + + yystate = 0; + yyerrstatus = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. */ + + yyssp = yyss - 1; + yyvsp = yyvs; + yylsp = yyls; + +/* Push a new state, which is found in yystate . */ +/* In all cases, when you get here, the value and location stacks + have just been pushed. so pushing a state here evens the stacks. */ +yynewstate: + + *++yyssp = yystate; + + if (yyssp >= yyss + yymaxdepth - 1) + { + /* Give user a chance to reallocate the stack */ + /* Use copies of these so that the &'s don't force the real ones into memory. */ + YYSTYPE *yyvs1 = yyvs; + YYLTYPE *yyls1 = yyls; + short *yyss1 = yyss; + + /* Get the current used size of the three stacks, in elements. */ + int size = yyssp - yyss + 1; + +#ifdef yyoverflow + /* Each stack pointer address is followed by the size of + the data in use in that stack, in bytes. */ + yyoverflow("parser stack overflow", + &yyss1, size * sizeof (*yyssp), + &yyvs1, size * sizeof (*yyvsp), + &yyls1, size * sizeof (*yylsp), + &yymaxdepth); + + yyss = yyss1; yyvs = yyvs1; yyls = yyls1; +#else /* no yyoverflow */ + /* Extend the stack our own way. */ + if (yymaxdepth >= YYMAXLIMIT) + yyerror("parser stack overflow"); + yymaxdepth *= 2; + if (yymaxdepth > YYMAXLIMIT) + yymaxdepth = YYMAXLIMIT; + yyss = (short *) alloca (yymaxdepth * sizeof (*yyssp)); + bcopy ((char *)yyss1, (char *)yyss, size * sizeof (*yyssp)); + yyls = (YYLTYPE *) alloca (yymaxdepth * sizeof (*yylsp)); + bcopy ((char *)yyls1, (char *)yyls, size * sizeof (*yylsp)); + yyvs = (YYSTYPE *) alloca (yymaxdepth * sizeof (*yyvsp)); + bcopy ((char *)yyvs1, (char *)yyvs, size * sizeof (*yyvsp)); +#endif /* no yyoverflow */ + + yyssp = yyss + size - 1; + yylsp = yyls + size - 1; + yyvsp = yyvs + size - 1; + + if (yydebug) + fprintf(stderr, "Stack size increased to %d\n", yymaxdepth); + + if (yyssp >= yyss + yymaxdepth - 1) + YYERROR; + } + + if (yydebug) + fprintf(stderr, "Entering state %d\n", yystate); + +/* Do appropriate processing given the current state. */ +/* Read a lookahead token if we need one and don't already have one. */ +yyresume: + + /* First try to decide what to do without reference to lookahead token. */ + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* yychar is either YYEMPTY or YYEOF + or a valid token in external form. */ + + if (yychar == YYEMPTY) + { + yychar = YYLEX; + } + + /* Convert token to internal form (in yychar1) for indexing tables with */ + + if (yychar <= 0) /* This means end of input. */ + { + yychar1 = 0; + yychar = YYEOF; /* Don't call YYLEX any more */ + + if (yydebug) + fprintf(stderr, "Now at end of input.\n"); + } + else + { + yychar1 = YYTRANSLATE(yychar); + + if (yydebug) + fprintf(stderr, "Parsing next token; it is %d (%s)\n", yychar, yytname[yychar1]); + } + + yyn += yychar1; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != yychar1) + goto yydefault; + + yyn = yytable[yyn]; + + /* yyn is what to do for this token type in this state. + Negative => reduce, -yyn is rule number. + Positive => shift, yyn is new state. + New state is final state => don't bother to shift, + just return success. + 0, or most negative number => error. */ + + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrlab; + + if (yyn == YYFINAL) + YYACCEPT; + + /* Shift the lookahead token. */ + + if (yydebug) + fprintf(stderr, "Shifting token %d (%s), ", yychar, yytname[yychar1]); + + /* Discard the token being shifted unless it is eof. */ + if (yychar != YYEOF) + yychar = YYEMPTY; + + *++yyvsp = yylval; + *++yylsp = yylloc; + + /* count tokens shifted since error; after three, turn off error status. */ + if (yyerrstatus) yyerrstatus--; + + yystate = yyn; + goto yynewstate; + +/* Do the default action for the current state. */ +yydefault: + + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + +/* Do a reduction. yyn is the number of a rule to reduce with. */ +yyreduce: + yylen = yyr2[yyn]; + yyval = yyvsp[1-yylen]; /* implement default value of the action */ + + if (yydebug) + { + if (yylen == 1) + fprintf (stderr, "Reducing 1 value via line %d, ", + yyrline[yyn]); + else + fprintf (stderr, "Reducing %d values via line %d, ", + yylen, yyrline[yyn]); + } + + + switch (yyn) { + +case 3: +#line 158 "expread.y" +{ write_exp_elt (BINOP_COMMA); ; + break;} +case 4: +#line 163 "expread.y" +{ write_exp_elt (UNOP_IND); ; + break;} +case 5: +#line 166 "expread.y" +{ write_exp_elt (UNOP_ADDR); ; + break;} +case 6: +#line 169 "expread.y" +{ write_exp_elt (UNOP_NEG); ; + break;} +case 7: +#line 173 "expread.y" +{ write_exp_elt (UNOP_ZEROP); ; + break;} +case 8: +#line 177 "expread.y" +{ write_exp_elt (UNOP_LOGNOT); ; + break;} +case 9: +#line 181 "expread.y" +{ write_exp_elt (UNOP_PREINCREMENT); ; + break;} +case 10: +#line 185 "expread.y" +{ write_exp_elt (UNOP_PREDECREMENT); ; + break;} +case 11: +#line 189 "expread.y" +{ write_exp_elt (UNOP_POSTINCREMENT); ; + break;} +case 12: +#line 193 "expread.y" +{ write_exp_elt (UNOP_POSTDECREMENT); ; + break;} +case 13: +#line 197 "expread.y" +{ write_exp_elt (UNOP_SIZEOF); ; + break;} +case 14: +#line 201 "expread.y" +{ write_exp_elt (STRUCTOP_PTR); + write_exp_string (yyvsp[0].sval); + write_exp_elt (STRUCTOP_PTR); ; + break;} +case 15: +#line 207 "expread.y" +{ write_exp_elt (STRUCTOP_MPTR); ; + break;} +case 16: +#line 211 "expread.y" +{ write_exp_elt (STRUCTOP_STRUCT); + write_exp_string (yyvsp[0].sval); + write_exp_elt (STRUCTOP_STRUCT); ; + break;} +case 17: +#line 217 "expread.y" +{ write_exp_elt (STRUCTOP_MEMBER); ; + break;} +case 18: +#line 221 "expread.y" +{ write_exp_elt (BINOP_SUBSCRIPT); ; + break;} +case 19: +#line 227 "expread.y" +{ start_arglist (); ; + break;} +case 20: +#line 229 "expread.y" +{ write_exp_elt (OP_FUNCALL); + write_exp_elt (end_arglist ()); + write_exp_elt (OP_FUNCALL); ; + break;} +case 22: +#line 238 "expread.y" +{ arglist_len = 1; ; + break;} +case 23: +#line 242 "expread.y" +{ arglist_len++; ; + break;} +case 24: +#line 246 "expread.y" +{ write_exp_elt (UNOP_MEMVAL); + write_exp_elt (yyvsp[-2].tval); + write_exp_elt (UNOP_MEMVAL); ; + break;} +case 25: +#line 252 "expread.y" +{ write_exp_elt (UNOP_CAST); + write_exp_elt (yyvsp[-2].tval); + write_exp_elt (UNOP_CAST); ; + break;} +case 26: +#line 258 "expread.y" +{ ; + break;} +case 27: +#line 264 "expread.y" +{ write_exp_elt (BINOP_REPEAT); ; + break;} +case 28: +#line 268 "expread.y" +{ write_exp_elt (BINOP_MUL); ; + break;} +case 29: +#line 272 "expread.y" +{ write_exp_elt (BINOP_DIV); ; + break;} +case 30: +#line 276 "expread.y" +{ write_exp_elt (BINOP_REM); ; + break;} +case 31: +#line 280 "expread.y" +{ write_exp_elt (BINOP_ADD); ; + break;} +case 32: +#line 284 "expread.y" +{ write_exp_elt (BINOP_SUB); ; + break;} +case 33: +#line 288 "expread.y" +{ write_exp_elt (BINOP_LSH); ; + break;} +case 34: +#line 292 "expread.y" +{ write_exp_elt (BINOP_RSH); ; + break;} +case 35: +#line 296 "expread.y" +{ write_exp_elt (BINOP_EQUAL); ; + break;} +case 36: +#line 300 "expread.y" +{ write_exp_elt (BINOP_NOTEQUAL); ; + break;} +case 37: +#line 304 "expread.y" +{ write_exp_elt (BINOP_LEQ); ; + break;} +case 38: +#line 308 "expread.y" +{ write_exp_elt (BINOP_GEQ); ; + break;} +case 39: +#line 312 "expread.y" +{ write_exp_elt (BINOP_LESS); ; + break;} +case 40: +#line 316 "expread.y" +{ write_exp_elt (BINOP_GTR); ; + break;} +case 41: +#line 320 "expread.y" +{ write_exp_elt (BINOP_LOGAND); ; + break;} +case 42: +#line 324 "expread.y" +{ write_exp_elt (BINOP_LOGXOR); ; + break;} +case 43: +#line 328 "expread.y" +{ write_exp_elt (BINOP_LOGIOR); ; + break;} +case 44: +#line 332 "expread.y" +{ write_exp_elt (BINOP_AND); ; + break;} +case 45: +#line 336 "expread.y" +{ write_exp_elt (BINOP_OR); ; + break;} +case 46: +#line 340 "expread.y" +{ write_exp_elt (TERNOP_COND); ; + break;} +case 47: +#line 344 "expread.y" +{ write_exp_elt (BINOP_ASSIGN); ; + break;} +case 48: +#line 348 "expread.y" +{ write_exp_elt (BINOP_ASSIGN_MODIFY); + write_exp_elt (yyvsp[-1].opcode); + write_exp_elt (BINOP_ASSIGN_MODIFY); ; + break;} +case 49: +#line 354 "expread.y" +{ write_exp_elt (OP_LONG); + write_exp_elt (builtin_type_long); + write_exp_elt (yyvsp[0].lval); + write_exp_elt (OP_LONG); ; + break;} +case 50: +#line 361 "expread.y" +{ write_exp_elt (OP_LONG); + write_exp_elt (builtin_type_char); + write_exp_elt (yyvsp[0].lval); + write_exp_elt (OP_LONG); ; + break;} +case 51: +#line 368 "expread.y" +{ write_exp_elt (OP_DOUBLE); + write_exp_elt (builtin_type_double); + write_exp_elt (yyvsp[0].dval); + write_exp_elt (OP_DOUBLE); ; + break;} +case 53: +#line 378 "expread.y" +{ write_exp_elt (OP_LAST); + write_exp_elt (yyvsp[0].lval); + write_exp_elt (OP_LAST); ; + break;} +case 54: +#line 384 "expread.y" +{ write_exp_elt (OP_REGISTER); + write_exp_elt (yyvsp[0].lval); + write_exp_elt (OP_REGISTER); ; + break;} +case 55: +#line 390 "expread.y" +{ write_exp_elt (OP_INTERNALVAR); + write_exp_elt (yyvsp[0].ivar); + write_exp_elt (OP_INTERNALVAR); ; + break;} +case 56: +#line 396 "expread.y" +{ write_exp_elt (OP_LONG); + write_exp_elt (builtin_type_int); + write_exp_elt ((long) TYPE_LENGTH (yyvsp[-1].tval)); + write_exp_elt (OP_LONG); ; + break;} +case 57: +#line 403 "expread.y" +{ write_exp_elt (OP_STRING); + write_exp_string (yyvsp[0].sval); + write_exp_elt (OP_STRING); ; + break;} +case 58: +#line 410 "expread.y" +{ write_exp_elt (OP_THIS); + write_exp_elt (OP_THIS); ; + break;} +case 59: +#line 417 "expread.y" +{ + struct symtab *tem = lookup_symtab (copy_name (yyvsp[0].sval)); + struct symbol *sym; + + if (tem) + yyval.bval = BLOCKVECTOR_BLOCK (BLOCKVECTOR (tem), 1); + else + { + sym = lookup_symbol (copy_name (yyvsp[0].sval), + expression_context_block, + VAR_NAMESPACE); + if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) + yyval.bval = SYMBOL_BLOCK_VALUE (sym); + else + error ("No file or function \"%s\".", + copy_name (yyvsp[0].sval)); + } + ; + break;} +case 60: +#line 438 "expread.y" +{ + struct symbol *tem + = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, VAR_NAMESPACE); + if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) + error ("No function \"%s\" in specified context.", + copy_name (yyvsp[-2].bval)); + yyval.bval = SYMBOL_BLOCK_VALUE (tem); + ; + break;} +case 61: +#line 449 "expread.y" +{ + struct symbol *sym; + sym = lookup_symbol (copy_name (yyvsp[0].sval), yyvsp[-2].bval, VAR_NAMESPACE); + if (sym == 0) + error ("No symbol \"%s\" in specified context.", + copy_name (yyvsp[0].sval)); + write_exp_elt (OP_VAR_VALUE); + write_exp_elt (sym); + write_exp_elt (OP_VAR_VALUE); + ; + break;} +case 62: +#line 462 "expread.y" +{ + struct type *type = yyvsp[-2].tval; + if (TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_UNION) + error ("`%s' is not defined as an aggregate type.", + TYPE_NAME (type)); + + write_exp_elt (OP_SCOPE); + write_exp_elt (type); + write_exp_string (yyvsp[0].sval); + write_exp_elt (OP_SCOPE); + ; + break;} +case 63: +#line 475 "expread.y" +{ + char *name = copy_name (yyvsp[0].sval); + struct symbol *sym; + int i; + + sym = lookup_symbol_2 (name, 0, VAR_NAMESPACE); + if (sym) + { + write_exp_elt (OP_VAR_VALUE); + write_exp_elt (sym); + write_exp_elt (OP_VAR_VALUE); + break; + } + for (i = 0; i < misc_function_count; i++) + if (!strcmp (misc_function_vector[i].name, name)) + break; + + if (i < misc_function_count) + { + write_exp_elt (OP_LONG); + write_exp_elt (builtin_type_int); + write_exp_elt (misc_function_vector[i].address); + write_exp_elt (OP_LONG); + write_exp_elt (UNOP_MEMVAL); + write_exp_elt (builtin_type_char); + write_exp_elt (UNOP_MEMVAL); + } + else + if (symtab_list == 0) + error ("No symbol table is loaded. Use the \"symbol-file\" command."); + else + error ("No symbol \"%s\" in current context.", name); + ; + break;} +case 64: +#line 511 "expread.y" +{ struct symbol *sym; + sym = lookup_symbol_1 (copy_name (yyvsp[0].sval), + expression_context_block, + VAR_NAMESPACE); + if (sym) + { + write_exp_elt (OP_VAR_VALUE); + write_exp_elt (sym); + write_exp_elt (OP_VAR_VALUE); + } + else + { + register char *arg = copy_name (yyvsp[0].sval); + register int i; + int v, val; + /* C++: see if it hangs off of `this'. Must + not inadvertently convert from a method call + to data ref. */ + v = (int)value_of_this (0); + if (v) + { + val = check_field (v, arg); + if (val) + { + write_exp_elt (OP_THIS); + write_exp_elt (OP_THIS); + write_exp_elt (STRUCTOP_PTR); + write_exp_string (yyvsp[0].sval); + write_exp_elt (STRUCTOP_PTR); + break; + } + } + sym = lookup_symbol_2 (arg, 0, VAR_NAMESPACE); + if (sym) + { + write_exp_elt (OP_VAR_VALUE); + write_exp_elt (sym); + write_exp_elt (OP_VAR_VALUE); + break; /* YACC-dependent */ + } + for (i = 0; i < misc_function_count; i++) + if (!strcmp (misc_function_vector[i].name, arg)) + break; + + if (i < misc_function_count) + { + write_exp_elt (OP_LONG); + write_exp_elt (builtin_type_int); + write_exp_elt (misc_function_vector[i].address); + write_exp_elt (OP_LONG); + write_exp_elt (UNOP_MEMVAL); + write_exp_elt (builtin_type_char); + write_exp_elt (UNOP_MEMVAL); + } + else + if (symtab_list == 0) + error ("No symbol table is loaded. Use the \"symbol-file\" command."); + else + error ("No symbol \"%s\" in current context.", + copy_name (yyvsp[0].sval)); + } + ; + break;} +case 66: +#line 577 "expread.y" +{ yyval.tval = lookup_pointer_type (yyvsp[-1].tval); ; + break;} +case 67: +#line 579 "expread.y" +{ yyval.tval = lookup_reference_type (yyvsp[-1].tval); ; + break;} +case 68: +#line 581 "expread.y" +{ yyval.tval = lookup_member_pointer_type (builtin_type_int, yyvsp[-2].tval); ; + break;} +case 69: +#line 583 "expread.y" +{ yyval.tval = lookup_member_pointer_type (yyvsp[-5].tval, yyvsp[-3].tval); ; + break;} +case 70: +#line 585 "expread.y" +{ yyval.tval = lookup_member_pointer_type (lookup_function_type (yyvsp[-7].tval, 0), yyvsp[-5].tval); ; + break;} +case 71: +#line 587 "expread.y" +{ yyval.tval = lookup_member_pointer_type (lookup_function_type (yyvsp[-8].tval, yyvsp[-1].tvec), yyvsp[-6].tval); + free (yyvsp[-1].tvec); ; + break;} +case 72: +#line 593 "expread.y" +{ yyval.tval = lookup_typename (copy_name (yyvsp[0].sval), + expression_context_block, 0); ; + break;} +case 73: +#line 596 "expread.y" +{ yyval.tval = lookup_struct (copy_name (yyvsp[0].sval), + expression_context_block); ; + break;} +case 74: +#line 599 "expread.y" +{ yyval.tval = lookup_union (copy_name (yyvsp[0].sval), + expression_context_block); ; + break;} +case 75: +#line 602 "expread.y" +{ yyval.tval = lookup_enum (copy_name (yyvsp[0].sval), + expression_context_block); ; + break;} +case 76: +#line 605 "expread.y" +{ yyval.tval = lookup_unsigned_typename (copy_name (yyvsp[0].sval)); ; + break;} +case 77: +#line 610 "expread.y" +{ yyval.tvec = (struct type **)xmalloc (sizeof (struct type *) * 2); + yyval.tvec[0] = (struct type *)0; + yyval.tvec[1] = yyvsp[0].tval; + ; + break;} +case 78: +#line 615 "expread.y" +{ int len = sizeof (struct type *) * ++(yyvsp[-2].ivec[0]); + yyval.tvec = (struct type **)xrealloc (yyvsp[-2].tvec, len); + yyval.tvec[yyval.ivec[0]] = yyvsp[0].tval; + ; + break;} +} + /* the action file gets copied in in place of this dollarsign */ +#line 303 "bison.simple" + + yyvsp -= yylen; + yylsp -= yylen; + yyssp -= yylen; + + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "state stack now", yyssp-yyss); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } + + *++yyvsp = yyval; + + yylsp++; + if (yylen == 0) + { + yylsp->first_line = yylloc.first_line; + yylsp->first_column = yylloc.first_column; + yylsp->last_line = (yylsp-1)->last_line; + yylsp->last_column = (yylsp-1)->last_column; + yylsp->text = 0; + } + else + { + yylsp->last_line = (yylsp+yylen-1)->last_line; + yylsp->last_column = (yylsp+yylen-1)->last_column; + } + + /* Now "shift" the result of the reduction. + Determine what state that goes to, + based on the state we popped back to + and the rule number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTBASE] + *yyssp; + if (yystate >= 0 && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTBASE]; + + goto yynewstate; + +yyerrlab: /* here on detecting error */ + + if (! yyerrstatus) + /* If not already recovering from an error, report this error. */ + { +#ifdef ESKIT + db_yyerror("parse error", yyssp, yychar); +#else + yyerror("parse error"); +#endif + } + + if (yyerrstatus == 3) + { + /* if just tried and failed to reuse lookahead token after an error, discard it. */ + + /* return failure if at end of input */ + if (yychar == YYEOF) + YYERROR; + + if (yydebug) + fprintf(stderr, "Discarding token %d (%s).\n", yychar, yytname[yychar1]); + + yychar = YYEMPTY; + } + + /* Else will try to reuse lookahead token + after shifting the error token. */ + + yyerrstatus = 3; /* Each real token shifted decrements this */ + + goto yyerrhandle; + +yyerrdefault: /* current state does not do anything special for the error token. */ + +#if 0 + /* This is wrong; only states that explicitly want error tokens + should shift them. */ + yyn = yydefact[yystate]; /* If its default is to accept any token, ok. Otherwise pop it.*/ + if (yyn) goto yydefault; +#endif + +yyerrpop: /* pop the current state because it cannot handle the error token */ + + if (yyssp == yyss) YYERROR; + yyvsp--; + yylsp--; + yystate = *--yyssp; + + if (yydebug) + { + short *ssp1 = yyss - 1; + fprintf (stderr, "Error: state stack now", yyssp-yyss); + while (ssp1 != yyssp) + fprintf (stderr, " %d", *++ssp1); + fprintf (stderr, "\n"); + } + +yyerrhandle: + + yyn = yypact[yystate]; + if (yyn == YYFLAG) + goto yyerrdefault; + + yyn += YYTERROR; + if (yyn < 0 || yyn > YYLAST || yycheck[yyn] != YYTERROR) + goto yyerrdefault; + + yyn = yytable[yyn]; + if (yyn < 0) + { + if (yyn == YYFLAG) + goto yyerrpop; + yyn = -yyn; + goto yyreduce; + } + else if (yyn == 0) + goto yyerrpop; + + if (yyn == YYFINAL) + YYACCEPT; + + if (yydebug) + fprintf(stderr, "Shifting error token, "); + + *++yyvsp = yylval; + *++yylsp = yylloc; + + yystate = yyn; + goto yynewstate; +} +#line 624 "expread.y" + + +/* Begin counting arguments for a function call, + saving the data about any containing call. */ + +static void +start_arglist () +{ + register struct funcall *new = (struct funcall *) xmalloc (sizeof (struct funcall)); + + new->next = funcall_chain; + new->arglist_len = arglist_len; + arglist_len = 0; + funcall_chain = new; +} + +/* Return the number of arguments in a function call just terminated, + and restore the data for the containing function call. */ + +static int +end_arglist () +{ + register int val = arglist_len; + register struct funcall *call = funcall_chain; + funcall_chain = call->next; + arglist_len = call->arglist_len; + free (call); + return val; +} + +/* Free everything in the funcall chain. + Used when there is an error inside parsing. */ + +static void +free_funcalls () +{ + register struct funcall *call, *next; + + for (call = funcall_chain; call; call = next) + { + next = call->next; + free (call); + } +} + +/* This page contains the functions for adding data to the struct expression + being constructed. */ + +/* Add one element to the end of the expression. */ + +static void +write_exp_elt (expelt) + union exp_element expelt; +{ + if (expout_ptr >= expout_size) + { + expout_size *= 2; + expout = (struct expression *) xrealloc (expout, + sizeof (struct expression) + + expout_size * sizeof (union exp_element)); + } + expout->elts[expout_ptr++] = expelt; +} + +/* Add a string constant to the end of the expression. + Follow it by its length in bytes, as a separate exp_element. */ + +static void +write_exp_string (str) + struct stoken str; +{ + register int len = str.length; + register int lenelt + = (len + sizeof (union exp_element)) / sizeof (union exp_element); + + expout_ptr += lenelt; + + if (expout_ptr >= expout_size) + { + expout_size = max (expout_size * 2, expout_ptr + 10); + expout = (struct expression *) xrealloc (expout, + sizeof (struct expression) + + expout_size * sizeof (union exp_element)); + } + bcopy (str.ptr, (char *) &expout->elts[expout_ptr - lenelt], len); + ((char *) &expout->elts[expout_ptr - lenelt])[len] = 0; + write_exp_elt (len); +} + +/* During parsing of a C expression, the pointer to the next character + is in this variable. */ + +static char *lexptr; + +/* Tokens that refer to names do so with explicit pointer and length, + so they can share the storage that lexptr is parsing. + + When it is necessary to pass a name to a function that expects + a null-terminated string, the substring is copied out + into a block of storage that namecopy points to. + + namecopy is allocated once, guaranteed big enough, for each parsing. */ + +static char *namecopy; + +/* Current depth in parentheses within the expression. */ + +static int paren_depth; + +/* Nonzero means stop parsing on first comma (if not within parentheses). */ + +static int comma_terminates; + +/* Take care of parsing a number (anything that starts with a digit). + Set yylval and return the token type; update lexptr. + LEN is the number of characters in it. */ + +/*** Needs some error checking for the float case ***/ + +static int +parse_number (olen) + int olen; +{ + register char *p = lexptr; + register long n = 0; + register int c; + register int base = 10; + register int len = olen; + char *err_copy; + + extern double atof (); + + for (c = 0; c < len; c++) + if (p[c] == '.') + { + /* It's a float since it contains a point. */ + yylval.dval = atof (p); + lexptr += len; + return FLOAT; + } + + if (len >= 3 && (!strncmp (p, "0x", 2) || !strncmp (p, "0X", 2))) + { + p += 2; + base = 16; + len -= 2; + } + else if (*p == '0') + base = 8; + + while (len-- > 0) + { + c = *p++; + n *= base; + if (c >= '0' && c <= '9') + n += c - '0'; + else + { + if (c >= 'A' && c <= 'Z') c += 'a' - 'A'; + if (base == 16 && c >= 'a' && c <= 'f') + n += c - 'a' + 10; + else if (len == 0 && c == 'l') + ; + else + { + err_copy = (char *) alloca (olen + 1); + bcopy (lexptr, err_copy, olen); + err_copy[olen] = 0; + error ("Invalid number \"%s\".", err_copy); + } + } + } + + lexptr = p; + yylval.lval = n; + return INT; +} + +struct token +{ + char *operator; + int token; + enum exp_opcode opcode; +}; + +static struct token tokentab3[] = + { + {">>=", ASSIGN_MODIFY, BINOP_RSH}, + {"<<=", ASSIGN_MODIFY, BINOP_LSH} + }; + +static struct token tokentab2[] = + { + {"+=", ASSIGN_MODIFY, BINOP_ADD}, + {"-=", ASSIGN_MODIFY, BINOP_SUB}, + {"*=", ASSIGN_MODIFY, BINOP_MUL}, + {"/=", ASSIGN_MODIFY, BINOP_DIV}, + {"%=", ASSIGN_MODIFY, BINOP_REM}, + {"|=", ASSIGN_MODIFY, BINOP_LOGIOR}, + {"&=", ASSIGN_MODIFY, BINOP_LOGAND}, + {"^=", ASSIGN_MODIFY, BINOP_LOGXOR}, + {"++", INCREMENT, BINOP_END}, + {"--", DECREMENT, BINOP_END}, + {"->", ARROW, BINOP_END}, + {"&&", AND, BINOP_END}, + {"||", OR, BINOP_END}, + {"::", COLONCOLON, BINOP_END}, + {"<<", LSH, BINOP_END}, + {">>", RSH, BINOP_END}, + {"==", EQUAL, BINOP_END}, + {"!=", NOTEQUAL, BINOP_END}, + {"<=", LEQ, BINOP_END}, + {">=", GEQ, BINOP_END} + }; + +/* Read one token, getting characters through lexptr. */ + +static int +yylex () +{ + register int c; + register int namelen; + register int i; + register char *tokstart; + + retry: + + tokstart = lexptr; + /* See if it is a special token of length 3. */ + for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++) + if (!strncmp (tokstart, tokentab3[i].operator, 3)) + { + lexptr += 3; + yylval.opcode = tokentab3[i].opcode; + return tokentab3[i].token; + } + + /* See if it is a special token of length 2. */ + for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++) + if (!strncmp (tokstart, tokentab2[i].operator, 2)) + { + lexptr += 2; + yylval.opcode = tokentab2[i].opcode; + return tokentab2[i].token; + } + + switch (c = *tokstart) + { + case 0: + return 0; + + case ' ': + case '\t': + case '\n': + lexptr++; + goto retry; + + case '\'': + lexptr++; + c = *lexptr++; + if (c == '\\') + c = parse_escape (&lexptr); + yylval.lval = c; + c = *lexptr++; + if (c != '\'') + error ("Invalid character constant."); + return CHAR; + + case '(': + paren_depth++; + lexptr++; + return c; + + case ')': + if (paren_depth == 0) + return 0; + paren_depth--; + lexptr++; + return c; + + case ',': + if (comma_terminates && paren_depth == 0) + return 0; + lexptr++; + return c; + + case '+': + case '-': + case '*': + case '/': + case '%': + case '|': + case '&': + case '^': + case '~': + case '!': + case '@': + case '<': + case '>': + case '[': + case ']': + case '.': + case '?': + case ':': + case '=': + case '{': + case '}': + lexptr++; + return c; + + case '"': + for (namelen = 1; (c = tokstart[namelen]) != '"'; namelen++) + if (c == '\\') + { + c = tokstart[++namelen]; + if (c >= '0' && c <= '9') + { + c = tokstart[++namelen]; + if (c >= '0' && c <= '9') + c = tokstart[++namelen]; + } + } + yylval.sval.ptr = tokstart + 1; + yylval.sval.length = namelen - 1; + lexptr += namelen + 1; + return STRING; + } + if (c >= '0' && c <= '9') + { + /* It's a number */ + for (namelen = 0; + c = tokstart[namelen], + (c == '_' || c == '$' || c == '.' || (c >= '0' && c <= '9') + || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); + namelen++) + ; + return parse_number (namelen); + } + + if (!(c == '_' || c == '$' + || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))) + error ("Invalid token in expression."); + + /* It is a name. See how long it is. */ + + for (namelen = 0; + c = tokstart[namelen], + (c == '_' || c == '$' || (c >= '0' && c <= '9') + || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')); + namelen++) + ; + + /* The token "if" terminates the expression and is NOT + removed from the input stream. */ + if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f') + { + return 0; + } + + lexptr += namelen; + + /* Handle the tokens $digits; also $ (short for $0) and $$ (short for $$1) + and $$digits (equivalent to $<-digits> if you could type that). + Make token type LAST, and put the number (the digits) in yylval. */ + + if (*tokstart == '$') + { + register int negate = 0; + c = 1; + /* Double dollar means negate the number and add -1 as well. + Thus $$ alone means -1. */ + if (namelen >= 2 && tokstart[1] == '$') + { + negate = 1; + c = 2; + } + if (c == namelen) + { + /* Just dollars (one or two) */ + yylval.lval = - negate; + return LAST; + } + /* Is the rest of the token digits? */ + for (; c < namelen; c++) + if (!(tokstart[c] >= '0' && tokstart[c] <= '9')) + break; + if (c == namelen) + { + yylval.lval = atoi (tokstart + 1 + negate); + if (negate) + yylval.lval = - yylval.lval; + return LAST; + } + } + + /* Handle tokens that refer to machine registers: + $ followed by a register name. */ + + if (*tokstart == '$') + for (c = 0; c < NUM_REGS; c++) + if (namelen - 1 == strlen (reg_names[c]) + && !strncmp (tokstart + 1, reg_names[c], namelen - 1)) + { + yylval.lval = c; + return REGNAME; + } + + if (namelen == 6 && !strncmp (tokstart, "struct", 6)) + { + return STRUCT; + } + if (namelen == 5) + { + if (!strncmp (tokstart, "union", 5)) + { + return UNION; + } + } + if (namelen == 4) + { + if (!strncmp (tokstart, "enum", 4)) + { + return ENUM; + } + if (!strncmp (tokstart, "this", 4)) + { + return THIS; + } + } + if (namelen == 6 && !strncmp (tokstart, "sizeof", 6)) + { + return SIZEOF; + } + if (namelen == 8 && !strncmp (tokstart, "unsigned", 6)) + { + return UNSIGNED; + } + yylval.sval.ptr = tokstart; + yylval.sval.length = namelen; + + /* Any other names starting in $ are debugger internal variables. */ + + if (*tokstart == '$') + { + yylval.ivar = (struct internalvar *) lookup_internalvar (copy_name (yylval.sval) + 1); + return VARIABLE; + } + + /* Use token-type TYPENAME for symbols that happen to be defined + currently as names of types; NAME for other symbols. + The caller is not constrained to care about the distinction. */ + if (lookup_typename (copy_name (yylval.sval), expression_context_block, 1)) + return TYPENAME; + return NAME; +} + +static +yyerror () +{ + error ("Invalid syntax in expression."); +} + +/* Return a null-terminated temporary copy of the name + of a string token. */ + +static char * +copy_name (token) + struct stoken token; +{ + bcopy (token.ptr, namecopy, token.length); + namecopy[token.length] = 0; + return namecopy; +} + +/* Reverse an expression from suffix form (in which it is constructed) + to prefix form (in which we can conveniently print or execute it). */ + +static void prefixify_subexp (); + +static void +prefixify_expression (expr) + register struct expression *expr; +{ + register int len = sizeof (struct expression) + + expr->nelts * sizeof (union exp_element); + register struct expression *temp; + register int inpos = expr->nelts, outpos = 0; + + temp = (struct expression *) alloca (len); + + /* Copy the original expression into temp. */ + bcopy (expr, temp, len); + + prefixify_subexp (temp, expr, inpos, outpos); +} + +/* Return the number of exp_elements in the subexpression of EXPR + whose last exp_element is at index ENDPOS - 1 in EXPR. */ + +static int +length_of_subexp (expr, endpos) + register struct expression *expr; + register int endpos; +{ + register int oplen = 1; + register int args = 0; + register int i; + + if (endpos < 0) + error ("?error in length_of_subexp"); + + i = (int) expr->elts[endpos - 1].opcode; + + switch (i) + { + /* C++ */ + case OP_SCOPE: + oplen = 4 + ((expr->elts[endpos - 2].longconst + + sizeof (union exp_element)) + / sizeof (union exp_element)); + break; + + case OP_LONG: + case OP_DOUBLE: + oplen = 4; + break; + + case OP_VAR_VALUE: + case OP_LAST: + case OP_REGISTER: + case OP_INTERNALVAR: + oplen = 3; + break; + + case OP_FUNCALL: + oplen = 3; + args = 1 + expr->elts[endpos - 2].longconst; + break; + + case UNOP_CAST: + case UNOP_MEMVAL: + oplen = 3; + args = 1; + break; + + case STRUCTOP_STRUCT: + case STRUCTOP_PTR: + args = 1; + case OP_STRING: + oplen = 3 + ((expr->elts[endpos - 2].longconst + + sizeof (union exp_element)) + / sizeof (union exp_element)); + break; + + case TERNOP_COND: + args = 3; + break; + + case BINOP_ASSIGN_MODIFY: + oplen = 3; + args = 2; + break; + + /* C++ */ + case OP_THIS: + oplen = 2; + break; + + default: + args = 1 + (i < (int) BINOP_END); + } + + while (args > 0) + { + oplen += length_of_subexp (expr, endpos - oplen); + args--; + } + + return oplen; +} + +/* Copy the subexpression ending just before index INEND in INEXPR + into OUTEXPR, starting at index OUTBEG. + In the process, convert it from suffix to prefix form. */ + +static void +prefixify_subexp (inexpr, outexpr, inend, outbeg) + register struct expression *inexpr; + struct expression *outexpr; + register int inend; + int outbeg; +{ + register int oplen = 1; + register int args = 0; + register int i; + int *arglens; + enum exp_opcode opcode; + + /* Compute how long the last operation is (in OPLEN), + and also how many preceding subexpressions serve as + arguments for it (in ARGS). */ + + opcode = inexpr->elts[inend - 1].opcode; + switch (opcode) + { + /* C++ */ + case OP_SCOPE: + oplen = 4 + ((inexpr->elts[inend - 2].longconst + + sizeof (union exp_element)) + / sizeof (union exp_element)); + break; + + case OP_LONG: + case OP_DOUBLE: + oplen = 4; + break; + + case OP_VAR_VALUE: + case OP_LAST: + case OP_REGISTER: + case OP_INTERNALVAR: + oplen = 3; + break; + + case OP_FUNCALL: + oplen = 3; + args = 1 + inexpr->elts[inend - 2].longconst; + break; + + case UNOP_CAST: + case UNOP_MEMVAL: + oplen = 3; + args = 1; + break; + + case STRUCTOP_STRUCT: + case STRUCTOP_PTR: + args = 1; + case OP_STRING: + oplen = 3 + ((inexpr->elts[inend - 2].longconst + + sizeof (union exp_element)) + / sizeof (union exp_element)); + + break; + + case TERNOP_COND: + args = 3; + break; + + case BINOP_ASSIGN_MODIFY: + oplen = 3; + args = 2; + break; + + /* C++ */ + case OP_THIS: + oplen = 2; + break; + + default: + args = 1 + ((int) opcode < (int) BINOP_END); + } + + /* Copy the final operator itself, from the end of the input + to the beginning of the output. */ + inend -= oplen; + bcopy (&inexpr->elts[inend], &outexpr->elts[outbeg], + oplen * sizeof (union exp_element)); + outbeg += oplen; + + /* Find the lengths of the arg subexpressions. */ + arglens = (int *) alloca (args * sizeof (int)); + for (i = args - 1; i >= 0; i--) + { + oplen = length_of_subexp (inexpr, inend); + arglens[i] = oplen; + inend -= oplen; + } + + /* Now copy each subexpression, preserving the order of + the subexpressions, but prefixifying each one. + In this loop, inend starts at the beginning of + the expression this level is working on + and marches forward over the arguments. + outbeg does similarly in the output. */ + for (i = 0; i < args; i++) + { + oplen = arglens[i]; + inend += oplen; + prefixify_subexp (inexpr, outexpr, inend, outbeg); + outbeg += oplen; + } +} + +/* This page contains the two entry points to this file. */ + +/* Read a C expression from the string *STRINGPTR points to, + parse it, and return a pointer to a struct expression that we malloc. + Use block BLOCK as the lexical context for variable names; + if BLOCK is zero, use the block of the selected stack frame. + Meanwhile, advance *STRINGPTR to point after the expression, + at the first nonwhite character that is not part of the expression + (possibly a null character). + + If COMMA is nonzero, stop if a comma is reached. */ + +struct expression * +parse_c_1 (stringptr, block, comma) + char **stringptr; + struct block *block; +{ + struct cleanup *old_chain; + + lexptr = *stringptr; + + comma_terminates = comma; + + if (lexptr == 0 || *lexptr == 0) + error_no_arg ("expression to compute"); + + old_chain = make_cleanup (free_funcalls, 0); + funcall_chain = 0; + + expression_context_block = block ? block : get_selected_block (); + + namecopy = (char *) alloca (strlen (lexptr) + 1); + expout_size = 10; + expout_ptr = 0; + expout = (struct expression *) xmalloc (sizeof (struct expression) + + expout_size * sizeof (union exp_element)); + make_cleanup (free_current_contents, &expout); + if (yyparse ()) + yyerror (); + discard_cleanups (old_chain); + expout->nelts = expout_ptr; + expout = (struct expression *) + xrealloc (expout, + sizeof (struct expression) + + expout_ptr * sizeof (union exp_element)); + prefixify_expression (expout); + *stringptr = lexptr; + return expout; +} + +/* Parse STRING as an expression, and complain if this fails + to use up all of the contents of STRING. */ + +struct expression * +parse_c_expression (string) + char *string; +{ + register struct expression *exp; + exp = parse_c_1 (&string, 0, 0); + if (*string) + error ("Junk after end of expression."); + return exp; +} diff --git a/gdb/expread.y b/gdb/expread.y index 468d409..d9a18ea 100644 --- a/gdb/expread.y +++ b/gdb/expread.y @@ -93,10 +93,14 @@ struct stoken struct block *bval; enum exp_opcode opcode; struct internalvar *ivar; + + struct type **tvec; + int *ivec; } %type <voidval> exp exp1 start variable %type <tval> type typebase +%type <tvec> nonempty_typelist %type <bval> block %token <lval> INT CHAR @@ -122,6 +126,9 @@ struct stoken %token <opcode> ASSIGN_MODIFY +/* C++ */ +%token THIS + %left ',' %left ABOVE_COMMA %right '=' ASSIGN_MODIFY @@ -196,12 +203,20 @@ exp : exp ARROW name write_exp_elt (STRUCTOP_PTR); } ; +exp : exp ARROW '*' exp + { write_exp_elt (STRUCTOP_MPTR); } + ; + exp : exp '.' name { write_exp_elt (STRUCTOP_STRUCT); write_exp_string ($3); write_exp_elt (STRUCTOP_STRUCT); } ; +exp : exp '.' '*' exp + { write_exp_elt (STRUCTOP_MEMBER); } + ; + exp : exp '[' exp1 ']' { write_exp_elt (BINOP_SUBSCRIPT); } ; @@ -390,8 +405,17 @@ exp : STRING write_exp_elt (OP_STRING); } ; +/* C++. */ +exp : THIS + { write_exp_elt (OP_THIS); + write_exp_elt (OP_THIS); } + ; + +/* end of C++. */ + block : name - { struct symtab *tem = lookup_symtab (copy_name ($1)); + { + struct symtab *tem = lookup_symtab (copy_name ($1)); struct symbol *sym; if (tem) @@ -406,34 +430,88 @@ block : name else error ("No file or function \"%s\".", copy_name ($1)); - }} + } + } ; block : block COLONCOLON name - { struct symbol *tem + { + struct symbol *tem = lookup_symbol (copy_name ($3), $1, VAR_NAMESPACE); if (!tem || SYMBOL_CLASS (tem) != LOC_BLOCK) error ("No function \"%s\" in specified context.", - copy_name ($3)); - $$ = SYMBOL_BLOCK_VALUE (tem); } + copy_name ($1)); + $$ = SYMBOL_BLOCK_VALUE (tem); + } ; variable: block COLONCOLON name - { struct symbol *sym; - sym = lookup_symbol ($3, copy_name ($1), VAR_NAMESPACE); + { + struct symbol *sym; + sym = lookup_symbol (copy_name ($3), $1, VAR_NAMESPACE); if (sym == 0) error ("No symbol \"%s\" in specified context.", copy_name ($3)); write_exp_elt (OP_VAR_VALUE); write_exp_elt (sym); - write_exp_elt (OP_VAR_VALUE); } + write_exp_elt (OP_VAR_VALUE); + } + ; + +variable: typebase COLONCOLON name + { + struct type *type = $1; + if (TYPE_CODE (type) != TYPE_CODE_STRUCT + && TYPE_CODE (type) != TYPE_CODE_UNION) + error ("`%s' is not defined as an aggregate type.", + TYPE_NAME (type)); + + write_exp_elt (OP_SCOPE); + write_exp_elt (type); + write_exp_string ($3); + write_exp_elt (OP_SCOPE); + } + | COLONCOLON name + { + char *name = copy_name ($2); + struct symbol *sym; + int i; + + sym = lookup_symbol_2 (name, 0, VAR_NAMESPACE); + if (sym) + { + write_exp_elt (OP_VAR_VALUE); + write_exp_elt (sym); + write_exp_elt (OP_VAR_VALUE); + break; + } + for (i = 0; i < misc_function_count; i++) + if (!strcmp (misc_function_vector[i].name, name)) + break; + + if (i < misc_function_count) + { + write_exp_elt (OP_LONG); + write_exp_elt (builtin_type_int); + write_exp_elt (misc_function_vector[i].address); + write_exp_elt (OP_LONG); + write_exp_elt (UNOP_MEMVAL); + write_exp_elt (builtin_type_char); + write_exp_elt (UNOP_MEMVAL); + } + else + if (symtab_list == 0) + error ("No symbol table is loaded. Use the \"symbol-file\" command."); + else + error ("No symbol \"%s\" in current context.", name); + } ; variable: NAME { struct symbol *sym; - sym = lookup_symbol (copy_name ($1), - expression_context_block, - VAR_NAMESPACE); + sym = lookup_symbol_1 (copy_name ($1), + expression_context_block, + VAR_NAMESPACE); if (sym) { write_exp_elt (OP_VAR_VALUE); @@ -444,6 +522,32 @@ variable: NAME { register char *arg = copy_name ($1); register int i; + int v, val; + /* C++: see if it hangs off of `this'. Must + not inadvertently convert from a method call + to data ref. */ + v = (int)value_of_this (0); + if (v) + { + val = check_field (v, arg); + if (val) + { + write_exp_elt (OP_THIS); + write_exp_elt (OP_THIS); + write_exp_elt (STRUCTOP_PTR); + write_exp_string ($1); + write_exp_elt (STRUCTOP_PTR); + break; + } + } + sym = lookup_symbol_2 (arg, 0, VAR_NAMESPACE); + if (sym) + { + write_exp_elt (OP_VAR_VALUE); + write_exp_elt (sym); + write_exp_elt (OP_VAR_VALUE); + break; /* YACC-dependent */ + } for (i = 0; i < misc_function_count; i++) if (!strcmp (misc_function_vector[i].name, arg)) break; @@ -471,6 +575,17 @@ variable: NAME type : typebase | type '*' { $$ = lookup_pointer_type ($1); } + | type '&' + { $$ = lookup_reference_type ($1); } + | typebase COLONCOLON '*' + { $$ = lookup_member_pointer_type (builtin_type_int, $1); } + | type '(' typebase COLONCOLON '*' ')' + { $$ = lookup_member_pointer_type ($1, $3); } + | type '(' typebase COLONCOLON '*' ')' '(' ')' + { $$ = lookup_member_pointer_type (lookup_function_type ($1, 0), $3); } + | type '(' typebase COLONCOLON '*' ')' '(' nonempty_typelist ')' + { $$ = lookup_member_pointer_type (lookup_function_type ($1, $8), $3); + free ($8); } ; typebase @@ -490,6 +605,19 @@ typebase { $$ = lookup_unsigned_typename (copy_name ($2)); } ; +nonempty_typelist + : type + { $$ = (struct type **)xmalloc (sizeof (struct type *) * 2); + $$[0] = (struct type *)0; + $$[1] = $1; + } + | nonempty_typelist ',' type + { int len = sizeof (struct type *) * ++($<ivec>1[0]); + $$ = (struct type **)xrealloc ($1, len); + $$[$<ivec>$[0]] = $3; + } + ; + name : NAME | TYPENAME ; @@ -598,6 +726,14 @@ static char *lexptr; static char *namecopy; +/* Current depth in parentheses within the expression. */ + +static int paren_depth; + +/* Nonzero means stop parsing on first comma (if not within parentheses). */ + +static int comma_terminates; + /* Take care of parsing a number (anything that starts with a digit). Set yylval and return the token type; update lexptr. LEN is the number of characters in it. */ @@ -753,6 +889,24 @@ yylex () error ("Invalid character constant."); return CHAR; + case '(': + paren_depth++; + lexptr++; + return c; + + case ')': + if (paren_depth == 0) + return 0; + paren_depth--; + lexptr++; + return c; + + case ',': + if (comma_terminates && paren_depth == 0) + return 0; + lexptr++; + return c; + case '+': case '-': case '*': @@ -766,8 +920,6 @@ yylex () case '@': case '<': case '>': - case '(': - case ')': case '[': case ']': case '.': @@ -776,7 +928,6 @@ yylex () case '=': case '{': case '}': - case ',': lexptr++; return c; @@ -881,13 +1032,23 @@ yylex () { return STRUCT; } - if (namelen == 5 && !strncmp (tokstart, "union", 5)) + if (namelen == 5) { - return UNION; + if (!strncmp (tokstart, "union", 5)) + { + return UNION; + } } - if (namelen == 4 && !strncmp (tokstart, "enum", 4)) + if (namelen == 4) { - return ENUM; + if (!strncmp (tokstart, "enum", 4)) + { + return ENUM; + } + if (!strncmp (tokstart, "this", 4)) + { + return THIS; + } } if (namelen == 6 && !strncmp (tokstart, "sizeof", 6)) { @@ -968,10 +1129,20 @@ length_of_subexp (expr, endpos) register int args = 0; register int i; + if (endpos < 0) + error ("?error in length_of_subexp"); + i = (int) expr->elts[endpos - 1].opcode; switch (i) { + /* C++ */ + case OP_SCOPE: + oplen = 4 + ((expr->elts[endpos - 2].longconst + + sizeof (union exp_element)) + / sizeof (union exp_element)); + break; + case OP_LONG: case OP_DOUBLE: oplen = 4; @@ -1002,7 +1173,6 @@ length_of_subexp (expr, endpos) oplen = 3 + ((expr->elts[endpos - 2].longconst + sizeof (union exp_element)) / sizeof (union exp_element)); - break; case TERNOP_COND: @@ -1014,6 +1184,11 @@ length_of_subexp (expr, endpos) args = 2; break; + /* C++ */ + case OP_THIS: + oplen = 2; + break; + default: args = 1 + (i < (int) BINOP_END); } @@ -1051,6 +1226,13 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg) opcode = inexpr->elts[inend - 1].opcode; switch (opcode) { + /* C++ */ + case OP_SCOPE: + oplen = 4 + ((inexpr->elts[inend - 2].longconst + + sizeof (union exp_element)) + / sizeof (union exp_element)); + break; + case OP_LONG: case OP_DOUBLE: oplen = 4; @@ -1093,6 +1275,11 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg) args = 2; break; + /* C++ */ + case OP_THIS: + oplen = 2; + break; + default: args = 1 + ((int) opcode < (int) BINOP_END); } @@ -1136,10 +1323,12 @@ prefixify_subexp (inexpr, outexpr, inend, outbeg) if BLOCK is zero, use the block of the selected stack frame. Meanwhile, advance *STRINGPTR to point after the expression, at the first nonwhite character that is not part of the expression - (possibly a null character). */ + (possibly a null character). + + If COMMA is nonzero, stop if a comma is reached. */ struct expression * -parse_c_1 (stringptr, block) +parse_c_1 (stringptr, block, comma) char **stringptr; struct block *block; { @@ -1147,6 +1336,8 @@ parse_c_1 (stringptr, block) lexptr = *stringptr; + comma_terminates = comma; + if (lexptr == 0 || *lexptr == 0) error_no_arg ("expression to compute"); @@ -1182,7 +1373,7 @@ parse_c_expression (string) char *string; { register struct expression *exp; - exp = parse_c_1 (&string, 0); + exp = parse_c_1 (&string, 0, 0); if (*string) error ("Junk after end of expression."); return exp; diff --git a/gdb/expression.h b/gdb/expression.h index 7a7bd83..ee3791f 100644 --- a/gdb/expression.h +++ b/gdb/expression.h @@ -60,6 +60,18 @@ enum exp_opcode BINOP_COMMA, /* , */ BINOP_SUBSCRIPT, /* x[y] */ BINOP_EXP, /* Exponentiation */ + +/* C++. */ + BINOP_SCOPE, /* :: */ + + /* STRUCTOP_MEMBER is used for pointer-to-member constructs. + X . * Y translates into X STRUCTOP_MEMBER Y. */ + STRUCTOP_MEMBER, + /* STRUCTOP_MPTR is used for pointer-to-member constructs + when X is a pointer instead of an aggregate. */ + STRUCTOP_MPTR, +/* end of C++. */ + BINOP_END, BINOP_ASSIGN_MODIFY, /* +=, -=, *=, and so on. @@ -144,6 +156,17 @@ enum exp_opcode (after the string), followed by another STRUCTOP_... code. */ STRUCTOP_STRUCT, STRUCTOP_PTR, + +/* C++ */ + /* OP_THIS is just a placeholder for the class instance variable. + It just comes in a tight (OP_THIS, OP_THIS) pair. */ + OP_THIS, + + /* OP_SCOPE surrounds a type name and a field name. The type + name is encoded as one element, but the field name stays as + a string, which, of course, is variable length. */ + OP_SCOPE, + }; union exp_element diff --git a/gdb/findvar.c b/gdb/findvar.c index 1f92b16..465e00a 100644 --- a/gdb/findvar.c +++ b/gdb/findvar.c @@ -213,7 +213,7 @@ read_var_value (var, frame) register int len; if (SYMBOL_CLASS (var) == LOC_BLOCK) - type = lookup_function_type (type); + type = lookup_function_type (type, 0); v = allocate_value (type); VALUE_LVAL (v) = lval_memory; /* The most likely possibility. */ @@ -368,7 +368,7 @@ locate_var_value (var, frame) test.i = 1; if (test.c != 1 && len < REGISTER_RAW_SIZE (val)) /* Big-endian, and we want less than full size. */ - addr+ = REGISTER_RAW_SIZE (val) - len; + addr += REGISTER_RAW_SIZE (val) - len; break; } error ("Address requested for identifier \"%s\" which is in a register.", diff --git a/gdb/firstfile.c b/gdb/firstfile.c index 60d6bf8..b50ea9e 100644 --- a/gdb/firstfile.c +++ b/gdb/firstfile.c @@ -48,32 +48,40 @@ the terms of Paragraph 1 above, provided that you also do the following: that in whole or in part contains or is a derivative of this program or any part thereof, to be licensed at no charge to all third parties on terms identical to those contained in this - License Agreement (except that you may choose to grant more - extensive warranty protection to third parties, at your option). + License Agreement (except that you may choose to grant more extensive + warranty protection to some or all third parties, at your option). c) You may charge a distribution fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. - 3. You may copy and distribute this program or any portion of it in -compiled, executable or object code form under the terms of Paragraphs -1 and 2 above provided that you do the following: - - a) cause each such copy to be accompanied by the - corresponding machine-readable source code, which must - be distributed under the terms of Paragraphs 1 and 2 above; or, - - b) cause each such copy to be accompanied by a - written offer, with no time limit, to give any third party - free (except for a nominal shipping charge) a machine readable - copy of the corresponding source code, to be distributed - under the terms of Paragraphs 1 and 2 above; or, - - c) in the case of a recipient of this program in compiled, executable - or object code form (without the corresponding source code) you - shall cause copies you distribute to be accompanied by a copy - of the written offer of source code which you received along - with the copy you received. +Mere aggregation of another unrelated program with this program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other program under the scope of these terms. + + 3. You may copy and distribute this program (or a portion or derivative +of it, under Paragraph 2) in object code or executable form under the terms +of Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal + shipping charge) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +For an executable file, complete source code means all the source code for +all modules it contains; but, as a special exception, it need not include +source code for modules which are standard libraries that accompany the +operating system on which the executable file runs. 4. You may not copy, sublicense, distribute or transfer this program except as expressly provided under this License Agreement. Any attempt diff --git a/gdb/foo.c b/gdb/foo.c deleted file mode 100644 index 59e559f..0000000 --- a/gdb/foo.c +++ /dev/null @@ -1,13 +0,0 @@ -main() { - int i; - - for (i = 0; i >= 0; i++) - bar(); -} - -bar() -{ - int i; - - i = 10; -} diff --git a/gdb/foo.nm b/gdb/foo.nm deleted file mode 100644 index 7a14364..0000000 --- a/gdb/foo.nm +++ /dev/null @@ -1,39 +0,0 @@ - - -Symbols from foo: - -Name Value Class Type Size Line Section - -crt0.s | | file | | | | -foo.c | | file | | | | -main | 228|extern| int( )| 66| |.text -.bf | 228|fcn | | | 1|.text -i | -4|auto | int| | | -.ef | 274|fcn | | | 6|.text -bar | 294|extern| int( )| 50| |.text -.bf | 294|fcn | | | 9|.text -i | -4|auto | int| | | -.ef | 324|fcn | | | 5|.text -dbxxx.s | | file | | | | -initfpu.s | | file | | | | -cuexit.s | | file | | | | -fakcu.c | | file | | | | -_cleanup | 404|extern| ( )| 42| |.text -.bf | 404|fcn | | | 23|.text -.ef | 426|fcn | | | 2|.text -_ac_r | 4194760|static| *char| | |.data -copyright.c | | file | | | | -_ac_r | 4194764|static| *char| | |.data -_start | 168|extern| | | |.text -_dbargs | 4195016|extern| | | |.bss -exit | 388|extern| | | |.text -initfpu | 380|extern| | | |.text -environ | 4194756|extern| | | |.data -splimit% | 4194752|extern| | | |.data -_dbsubc | 344|extern| | | |.text -_dbsubn | 376|extern| | | |.text -_ac_s | 4194768|extern| char[0]| | |.data -etext | 448|extern| | | | -edata | 4195016|extern| | | | -end | 4195528|extern| | | | -_sorigin | 4195528|extern| | | | diff --git a/gdb/foo.od b/gdb/foo.od deleted file mode 100644 index ce2a186..0000000 --- a/gdb/foo.od +++ /dev/null @@ -1,213 +0,0 @@ -0000000 0150 0003 21fc 7629 0000 0310 0000 0032 - 001 P \0 003 ! 374 v ) \0 \0 003 020 \0 \0 \0 2 -0000020 001c 0103 010b 0000 0000 0118 0000 0108 - \0 034 001 003 001 013 \0 \0 \0 \0 001 030 \0 \0 001 \b -0000040 0000 0200 0000 00a8 0000 00a8 0040 01c0 - \0 \0 002 \0 \0 \0 \0 250 \0 \0 \0 250 \0 @ 001 300 -0000060 2e74 6578 7400 0000 0000 00a8 0000 00a8 - . t e x t \0 \0 \0 \0 \0 \0 250 \0 \0 \0 250 -0000100 0000 0118 0000 00a8 0000 0000 0000 02c8 - \0 \0 001 030 \0 \0 \0 250 \0 \0 \0 \0 \0 \0 002 310 -0000120 0000 000c 0000 0020 2e64 6174 6100 0000 - \0 \0 \0 \f \0 \0 \0 . d a t a \0 \0 \0 -0000140 0040 01c0 0040 01c0 0000 0108 0000 01c0 - \0 @ 001 300 \0 @ 001 300 \0 \0 001 \b \0 \0 001 300 -0000160 0000 0000 0000 0000 0000 0000 0000 0040 - \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 @ -0000200 2e62 7373 0000 0000 0040 02c8 0040 02c8 - . b s s \0 \0 \0 \0 \0 @ 002 310 \0 @ 002 310 -0000220 0000 0200 0000 0000 0000 0000 0000 0000 - \0 \0 002 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 -0000240 0000 0000 0000 0080 23c0 0040 01c0 518f - \0 \0 \0 \0 \0 \0 \0 200 # 300 \0 @ 001 300 Q 217 -0000260 2eaf 0008 41ef 000c 2f48 0004 2248 4a98 - . 257 \0 \b A 357 \0 \f / H \0 004 " H J 230 -0000300 66fc 2f48 0008 23c8 0040 01c4 4eb9 0000 - f 374 / H \0 \b # 310 \0 @ 001 304 N 271 \0 \0 -0000320 017c 4eb9 0000 00e4 2e80 4eb9 0000 0184 - 001 | N 271 \0 \0 \0 344 . 200 N 271 \0 \0 001 204 -0000340 7001 4e40 480e ffff fff8 48ef 0000 0004 - p 001 N @ H 016 377 377 377 370 H 357 \0 \0 \0 004 -0000360 f237 f000 0170 0000 0004 42ae fffc 4aae - 362 7 360 \0 001 p \0 \0 \0 004 B 256 377 374 J 256 -0000400 fffc 6d00 000e 4eba 001e 52ae fffc 6000 - 377 374 m \0 \0 016 N 272 \0 036 R 256 377 374 ` \0 -0000420 ffee 4cef 0000 0004 f237 d000 0170 0000 - 377 356 L 357 \0 \0 \0 004 362 7 320 \0 001 p \0 \0 -0000440 0004 4e5e 4e75 480e ffff fff8 48ef 0000 - \0 004 N ^ N u H 016 377 377 377 370 H 357 \0 \0 -0000460 0004 f237 f000 0170 0000 0004 2d7c 0000 - \0 004 362 7 360 \0 001 p \0 \0 \0 004 - | \0 \0 -0000500 000a fffc 4cef 0000 0004 f237 d000 0170 - \0 \n 377 374 L 357 \0 \0 \0 004 362 7 320 \0 001 p -0000520 0000 0004 4e5e 4e75 4e56 0000 207c 0040 - \0 \0 \0 004 N ^ N u N V \0 \0 | \0 @ -0000540 02c8 2258 2018 2200 e581 d1c1 6002 2f20 - 002 310 " X 030 " \0 345 201 321 301 ` 002 / -0000560 51c8 fffc 4e91 4e5e 4e41 4e71 4e56 fffc - Q 310 377 374 N 221 N ^ N A N q N V 377 374 -0000600 4e5e 4e75 4eb9 0000 0194 7001 4e40 4e72 - N ^ N u N 271 \0 \0 001 224 p 001 N @ N r -0000620 0000 4e71 480e ffff fffc 48ef 0000 0004 - \0 \0 N q H 016 377 377 377 374 H 357 \0 \0 \0 004 -0000640 f237 f000 0170 0000 0004 4cef 0000 0004 - 362 7 360 \0 001 p \0 \0 \0 004 L 357 \0 \0 \0 004 -0000660 f237 d000 0170 0000 0004 4e5e 4e75 4e71 - 362 7 320 \0 001 p \0 \0 \0 004 N ^ N u N q -0000700 0000 0000 0000 0000 0040 01d0 0040 01d0 - \0 \0 \0 \0 \0 \0 \0 \0 \0 @ 001 320 \0 @ 001 320 -0000720 436f 7079 7269 6768 7420 2863 2920 3139 - C o p y r i g h t ( c ) 1 9 -0000740 3837 2041 7070 6c65 2043 6f6d 7075 7465 - 8 7 A p p l e C o m p u t e -0000760 722c 2049 6e63 2e2c 2031 3938 3520 4164 - r , I n c . , 1 9 8 5 A d -0001000 6f62 6520 5379 7374 656d 7320 496e 636f - o b e S y s t e m s I n c o -0001020 7270 6f72 6174 6564 2c20 3139 3833 2d38 - r p o r a t e d , 1 9 8 3 - 8 -0001040 3720 4154 2654 2d49 532c 2031 3938 352d - 7 A T & T - I S , 1 9 8 5 - -0001060 3837 204d 6f74 6f72 6f6c 6120 496e 632e - 8 7 M o t o r o l a I n c . -0001100 2c20 3139 3830 2d38 3720 5375 6e20 4d69 - , 1 9 8 0 - 8 7 S u n M i -0001120 6372 6f73 7973 7465 6d73 2049 6e63 2e2c - c r o s y s t e m s I n c . , -0001140 2031 3938 302d 3837 2054 6865 2052 6567 - 1 9 8 0 - 8 7 T h e R e g -0001160 656e 7473 206f 6620 7468 6520 556e 6976 - e n t s o f t h e U n i v -0001200 6572 7369 7479 206f 6620 4361 6c69 666f - e r s i t y o f C a l i f o -0001220 726e 6961 2c20 3139 3835 2d38 3720 556e - r n i a , 1 9 8 5 - 8 7 U n -0001240 6973 6f66 7420 436f 7270 6f72 6174 696f - i s o f t C o r p o r a t i o -0001260 6e2c 2041 6c6c 2052 6967 6874 7320 5265 - n , A l l R i g h t s R e -0001300 7365 7276 6564 2e00 0000 0004 0000 0000 - s e r v e d . \0 \0 \0 \0 004 \0 \0 \0 \0 -0001320 00e4 0001 0000 00fa 0004 0000 0106 0005 - \0 344 \0 001 \0 \0 \0 372 \0 004 \0 \0 001 006 \0 005 -0001340 0000 0112 0006 0000 000b 0000 0000 0126 - \0 \0 001 022 \0 006 \0 \0 \0 013 \0 \0 \0 \0 001 & -0001360 0001 0000 013c 0004 0000 0144 0005 0000 - \0 001 \0 \0 001 < \0 004 \0 \0 001 D \0 005 \0 \0 -0001400 001a 0000 0000 0194 0001 0000 01aa 0002 - \0 032 \0 \0 \0 \0 001 224 \0 001 \0 \0 001 252 \0 002 -0001420 2e66 696c 6500 0000 0000 0002 fffe 0000 - . f i l e \0 \0 \0 \0 \0 \0 002 377 376 \0 \0 -0001440 6701 6372 7430 2e73 0000 0000 0000 0000 - g 001 c r t 0 . s \0 \0 \0 \0 \0 \0 \0 \0 -0001460 0000 0000 2e66 696c 6500 0000 0000 0012 - \0 \0 \0 \0 . f i l e \0 \0 \0 \0 \0 \0 022 -0001500 fffe 0000 6701 666f 6f2e 6300 0000 0000 - 377 376 \0 \0 g 001 f o o . c \0 \0 \0 \0 \0 -0001520 0000 0000 0000 0000 6d61 696e 0000 0000 - \0 \0 \0 \0 \0 \0 \0 \0 m a i n \0 \0 \0 \0 -0001540 0000 00e4 0001 0024 0201 0000 0000 0000 - \0 \0 \0 344 \0 001 \0 $ 002 001 \0 \0 \0 \0 \0 \0 -0001560 0042 0000 02c8 0000 000b 0000 2e62 6600 - \0 B \0 \0 002 310 \0 \0 \0 013 \0 \0 . b f \0 -0001600 0000 0000 0000 00e4 0001 0000 6501 0000 - \0 \0 \0 \0 \0 \0 \0 344 \0 001 \0 \0 e 001 \0 \0 -0001620 0000 0001 0000 0000 0000 0000 0000 0000 - \0 \0 \0 001 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 -0001640 6900 0000 0000 0000 ffff fffc ffff 0004 - i \0 \0 \0 \0 \0 \0 \0 377 377 377 374 377 377 \0 004 -0001660 0100 2e65 6600 0000 0000 0000 0112 0001 - 001 \0 . e f \0 \0 \0 \0 \0 \0 \0 001 022 \0 001 -0001700 0000 6501 0000 0000 0006 0000 0000 0000 - \0 \0 e 001 \0 \0 \0 \0 \0 006 \0 \0 \0 \0 \0 \0 -0001720 0000 0000 0000 6261 7200 0000 0000 0000 - \0 \0 \0 \0 \0 \0 b a r \0 \0 \0 \0 \0 \0 \0 -0001740 0126 0001 0024 0201 0000 0000 0000 0032 - 001 & \0 001 \0 $ 002 001 \0 \0 \0 \0 \0 \0 \0 2 -0001760 0000 02e6 0000 0012 0000 2e62 6600 0000 - \0 \0 002 346 \0 \0 \0 022 \0 \0 . b f \0 \0 \0 -0002000 0000 0000 0126 0001 0000 6501 0000 0000 - \0 \0 \0 \0 001 & \0 001 \0 \0 e 001 \0 \0 \0 \0 -0002020 0009 0000 0000 0000 0000 0000 0000 6900 - \0 \t \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 i \0 -0002040 0000 0000 0000 ffff fffc ffff 0004 0100 - \0 \0 \0 \0 \0 \0 377 377 377 374 377 377 \0 004 001 \0 -0002060 2e65 6600 0000 0000 0000 0144 0001 0000 - . e f \0 \0 \0 \0 \0 \0 \0 001 D \0 001 \0 \0 -0002100 6501 0000 0000 0005 0000 0000 0000 0000 - e 001 \0 \0 \0 \0 \0 005 \0 \0 \0 \0 \0 \0 \0 \0 -0002120 0000 0000 2e66 696c 6500 0000 0000 0014 - \0 \0 \0 \0 . f i l e \0 \0 \0 \0 \0 \0 024 -0002140 fffe 0000 6701 6462 7878 782e 7300 0000 - 377 376 \0 \0 g 001 d b x x x . s \0 \0 \0 -0002160 0000 0000 0000 0000 2e66 696c 6500 0000 - \0 \0 \0 \0 \0 \0 \0 \0 . f i l e \0 \0 \0 -0002200 0000 0016 fffe 0000 6701 696e 6974 6670 - \0 \0 \0 026 377 376 \0 \0 g 001 i n i t f p -0002220 752e 7300 0000 0000 0000 0000 2e66 696c - u . s \0 \0 \0 \0 \0 \0 \0 \0 \0 . f i l -0002240 6500 0000 0000 0018 fffe 0000 6701 6375 - e \0 \0 \0 \0 \0 \0 030 377 376 \0 \0 g 001 c u -0002260 6578 6974 2e73 0000 0000 0000 0000 0000 - e x i t . s \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 -0002300 2e66 696c 6500 0000 0000 0021 fffe 0000 - . f i l e \0 \0 \0 \0 \0 \0 ! 377 376 \0 \0 -0002320 6701 6661 6b63 752e 6300 0000 0000 0000 - g 001 f a k c u . c \0 \0 \0 \0 \0 \0 \0 -0002340 0000 0000 5f63 6c65 616e 7570 0000 0194 - \0 \0 \0 \0 _ c l e a n u p \0 \0 001 224 -0002360 0001 0020 0201 0000 0000 0000 002a 0000 - \0 001 \0 002 001 \0 \0 \0 \0 \0 \0 \0 * \0 \0 -0002400 02fe 0000 0020 0000 2e62 6600 0000 0000 - 002 376 \0 \0 \0 \0 \0 . b f \0 \0 \0 \0 \0 -0002420 0000 0194 0001 0000 6501 0000 0000 0017 - \0 \0 001 224 \0 001 \0 \0 e 001 \0 \0 \0 \0 \0 027 -0002440 0000 0000 0000 0000 0000 0000 2e65 6600 - \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 . e f \0 -0002460 0000 0000 0000 01aa 0001 0000 6501 0000 - \0 \0 \0 \0 \0 \0 001 252 \0 001 \0 \0 e 001 \0 \0 -0002500 0000 0002 0000 0000 0000 0000 0000 0000 - \0 \0 \0 002 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 -0002520 5f61 635f 7200 0000 0040 01c8 0002 0012 - _ a c _ r \0 \0 \0 \0 @ 001 310 \0 002 \0 022 -0002540 0300 2e66 696c 6500 0000 0000 0024 fffe - 003 \0 . f i l e \0 \0 \0 \0 \0 \0 $ 377 376 -0002560 0000 6701 636f 7079 7269 6768 742e 6300 - \0 \0 g 001 c o p y r i g h t . c \0 -0002600 0000 0000 0000 5f61 635f 7200 0000 0040 - \0 \0 \0 \0 \0 \0 _ a c _ r \0 \0 \0 \0 @ -0002620 01cc 0002 0012 0300 5f73 7461 7274 0000 - 001 314 \0 002 \0 022 003 \0 _ s t a r t \0 \0 -0002640 0000 00a8 0001 0000 0200 5f64 6261 7267 - \0 \0 \0 250 \0 001 \0 \0 002 \0 _ d b a r g -0002660 7300 0040 02c8 0003 0000 0200 6578 6974 - s \0 \0 @ 002 310 \0 003 \0 \0 002 \0 e x i t -0002700 0000 0000 0000 0184 0001 0000 0200 696e - \0 \0 \0 \0 \0 \0 001 204 \0 001 \0 \0 002 \0 i n -0002720 6974 6670 7500 0000 017c 0001 0000 0200 - i t f p u \0 \0 \0 001 | \0 001 \0 \0 002 \0 -0002740 656e 7669 726f 6e00 0040 01c4 0002 0000 - e n v i r o n \0 \0 @ 001 304 \0 002 \0 \0 -0002760 0200 7370 6c69 6d69 7425 0040 01c0 0002 - 002 \0 s p l i m i t % \0 @ 001 300 \0 002 -0003000 0000 0200 5f64 6273 7562 6300 0000 0158 - \0 \0 002 \0 _ d b s u b c \0 \0 \0 001 X -0003020 0001 0000 0200 5f64 6273 7562 6e00 0000 - \0 001 \0 \0 002 \0 _ d b s u b n \0 \0 \0 -0003040 0178 0001 0000 0200 5f61 635f 7300 0000 - 001 x \0 001 \0 \0 002 \0 _ a c _ s \0 \0 \0 -0003060 0040 01d0 0002 0032 0201 0000 0000 0000 - \0 @ 001 320 \0 002 \0 2 002 001 \0 \0 \0 \0 \0 \0 -0003100 0000 0000 0000 0000 0000 0000 6574 6578 - \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 e t e x -0003120 7400 0000 0000 01c0 ffff 0000 0200 6564 - t \0 \0 \0 \0 \0 001 300 377 377 \0 \0 002 \0 e d -0003140 6174 6100 0000 0040 02c8 ffff 0000 0200 - a t a \0 \0 \0 \0 @ 002 310 377 377 \0 \0 002 \0 -0003160 656e 6400 0000 0000 0040 04c8 ffff 0000 - e n d \0 \0 \0 \0 \0 \0 @ 004 310 377 377 \0 \0 -0003200 0200 5f73 6f72 6967 696e 0040 04c8 ffff - 002 \0 _ s o r i g i n \0 @ 004 310 377 377 -0003220 0000 0200 - \0 \0 002 \0 -0003224 diff --git a/gdb/foo.s b/gdb/foo.s deleted file mode 100644 index a7079d5..0000000 --- a/gdb/foo.s +++ /dev/null @@ -1,65 +0,0 @@ - file "foo.c" - data 1 - text - def main; val main; scl 2; type 044; endef - global main -main: - ln 1 - def ~bf; val ~; scl 101; line 1; endef - link.l %fp,&F%1 - movm.l &M%1,(4,%sp) - fmovm &FPM%1,(FPO%1,%sp) - def i; val -4+S%1; scl 1; type 04; endef - ln 4 - clr.l ((S%1-4).w,%fp) -L%15: - tst.l ((S%1-4).w,%fp) - blt L%14 - ln 5 - jsr bar -L%13: - add.l &1,((S%1-4).w,%fp) - bra L%15 -L%14: -L%12: - def ~ef; val ~; scl 101; line 6; endef - ln 6 - movm.l (4,%sp),&M%1 - fmovm (FPO%1,%sp),&FPM%1 - unlk %fp - rts - def main; val ~; scl -1; endef - set S%1,0 - set T%1,0 - set F%1,-8 - set FPO%1,4 - set FPM%1,0x0000 - set M%1,0x0000 - data 1 - text - def bar; val bar; scl 2; type 044; endef - global bar -bar: - ln 1 - def ~bf; val ~; scl 101; line 9; endef - link.l %fp,&F%2 - movm.l &M%2,(4,%sp) - fmovm &FPM%2,(FPO%2,%sp) - def i; val -4+S%2; scl 1; type 04; endef - ln 4 - mov.l &10,((S%2-4).w,%fp) -L%17: - def ~ef; val ~; scl 101; line 5; endef - ln 5 - movm.l (4,%sp),&M%2 - fmovm (FPO%2,%sp),&FPM%2 - unlk %fp - rts - def bar; val ~; scl -1; endef - set S%2,0 - set T%2,0 - set F%2,-8 - set FPO%2,4 - set FPM%2,0x0000 - set M%2,0x0000 - data 1 diff --git a/gdb/foo.sym b/gdb/foo.sym deleted file mode 100644 index 4b6595a..0000000 --- a/gdb/foo.sym +++ /dev/null @@ -1,114 +0,0 @@ -Symtab for file _globals_ - -Line table: - - -Blockvector: - -block #000 (object 0x41a5cc) [0x0..0x0] - char _ac_s[0]; static at 0x4001d0, - int _dbargs; static at 0x4002c8, - int environ; static at 0x4001c4, - int splimit%; static at 0x4001c0, - block #001 (object 0x41a5a8) [0x0..0x0] (under 0x41a5cc) - - -Symtab for file copyright.c - -Line table: - - -Blockvector: - -block #000 (object 0x41a460) [0x0..0x0] - block #001 (object 0x41a444) [0x0..0x0] (under 0x41a460) - char *_ac_r; static at 0x4001cc, - - -Symtab for file fakcu.c - -Line table: - - line 23 at 194 - line 24 at 1aa - -Blockvector: - -block #000 (object 0x41a3f0) [0x0..0x0] - void _cleanup; block (object 0x41a380) starting at 0x194, - block #001 (object 0x41a3d4) [0x0..0x0] (under 0x41a3f0) - char *_ac_r; static at 0x4001c8, - block #002 (object 0x41a380) [0x194..0x1b0] (under 0x41a3d4) _cleanup - - -Symtab for file cuexit.s - -Line table: - - -Blockvector: - -block #000 (object 0x41f210) [0x0..0x0] - block #001 (object 0x41f1ec) [0x0..0x0] (under 0x41f210) - - -Symtab for file initfpu.s - -Line table: - - -Blockvector: - -block #000 (object 0x41e1c4) [0x0..0x0] - block #001 (object 0x41e1a0) [0x0..0x0] (under 0x41e1c4) - - -Symtab for file dbxxx.s - -Line table: - - -Blockvector: - -block #000 (object 0x41d178) [0x0..0x0] - block #001 (object 0x41d154) [0x0..0x0] (under 0x41d178) - - -Symtab for file foo.c - -Line table: - - line 1 at e4 - line 2 at fa - line 4 at fa - line 5 at 106 - line 6 at 112 - line 7 at 126 - line 9 at 126 - line 10 at 13c - line 12 at 13c - line 13 at 144 - -Blockvector: - -block #000 (object 0x41a2d8) [0x0..0x0] - int bar; block (object 0x41a2b0) starting at 0x126, - int main; block (object 0x41a220) starting at 0xe4, - block #001 (object 0x41a23c) [0x0..0x0] (under 0x41a2d8) - block #002 (object 0x41a220) [0xe4..0x120] (under 0x41a23c) main - int i; local at 0xfffffffc, - block #003 (object 0x41a2b0) [0x126..0x150] (under 0x41a23c) bar - int i; local at 0xfffffffc, - - -Symtab for file crt0.s - -Line table: - - -Blockvector: - -block #000 (object 0x41b178) [0x0..0x0] - block #001 (object 0x41b154) [0x0..0x0] (under 0x41b178) - - diff --git a/gdb/gdb+.texinfo b/gdb/gdb+.texinfo new file mode 100644 index 0000000..627f7ad --- /dev/null +++ b/gdb/gdb+.texinfo @@ -0,0 +1,2788 @@ +\input texinfo +@setfilename ../info/gdb +@settitle GDB+, The GNU Debugger for GNU C++ +@ifinfo +This file documents the GNU debugger GDB+. + +Copyright (C) 1988 Richard M. Stallman. +Modified by Michael Tiemann + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +@ignore +Permission is granted to process this file through Tex and print the +results, provided the printed document carries copying permission +notice identical to this one except for the removal of this paragraph +(this paragraph not being relevant to the printed manual). + +@end ignore +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +sections entitled ``Distribution'' and ``GDB General Public License'' are +included exactly as in the original, and provided that the entire resulting +derived work is distributed under the terms of a permission notice +identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that the sections entitled ``Distribution'' and ``GDB General Public +License'' may be included in a translation approved by the author instead +of in the original English. +@end ifinfo + +@setchapternewpage odd +@settitle GDB+ Manual +@titlepage +@sp 6 +@center @titlefont{GDB+ Manual} +@sp 1 +@center The GNU Source-Level Debugger for GNU C++ +@sp 4 +@center Second Edition, GDB+ version 2.5.0 +@sp 1 +@center February 1988 +@sp 5 +@center Richard M. Stallman +@page +@vskip 0pt plus 1filll +Copyright @copyright{} 1988 Richard M. Stallman. +Modified by Michael Tiemann + +Permission is granted to make and distribute verbatim copies of +this manual provided the copyright notice and this permission notice +are preserved on all copies. + +Permission is granted to copy and distribute modified versions of this +manual under the conditions for verbatim copying, provided also that the +sections entitled ``Distribution'' and ``GDB General Public License'' are +included exactly as in the original, and provided that the entire resulting +derived work is distributed under the terms of a permission notice +identical to this one. + +Permission is granted to copy and distribute translations of this manual +into another language, under the above conditions for modified versions, +except that the sections entitled ``Distribution'' and ``GDB General Public +License'' may be included in a translation approved by the author instead +of in the original English. +@end titlepage +@page + +@node Top, Commands,, (DIR) +@unnumbered Summary of GDB+ + +The purpose of a debugger such as GDB+ is to allow you to execute another +program while examining what is going on inside it. We call the other +program ``your program'' or ``the program being debugged''. + +GDB+ can do four kinds of things (plus other things in support of these): + +@enumerate +@item +Start the program, specifying anything that might affect its behavior. + +@item +Make the program stop on specified conditions. + +@item +Examine what has happened, when the program has stopped, so that you +can see bugs happen. + +@item +Change things in the program, so you can correct the effects of one bug +and go on to learn about another without having to recompile first. +@end enumerate + +@menu +* License:: The GDB General Public License gives you permission + to redistribute GDB+ on certain terms; and also + explains that there is no warranty. +* Input:: GDB+ command syntax and input conventions. +* Files:: Specifying files for GDB+ to operate on. +* Options:: GDB+ arguments and options. +* Compilation::Compiling your program so you can debug it. +* Running:: Running your program under GDB+. +* Stopping:: Making your program stop. Why it may stop. What to do then. +* Stack:: Examining your program's stack. +* Source:: Examining your program's source files. +* Data:: Examining data in your program. +* Symbols:: Examining the debugger's symbol table. +* Altering:: Altering things in your program. +* Sequences:: Canned command sequences for repeated use. +* Emacs:: Using GDB through GNU Emacs. +* Remote:: Remote kernel debugging across a serial line. +* Commands:: Index of GDB+ commands. +* Concepts:: Index of GDB+ concepts. +@end menu + +@node License, Input, Top, Top +@unnumbered GDB General Public License +@center (Clarified 11 Feb 1988) + + The license agreements of most software companies keep you at the mercy +of those companies. By contrast, our general public license is intended to +give everyone the right to share GDB. To make sure that you get the rights +we want you to have, we need to make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. Hence this +license agreement. + + Specifically, we want to make sure that you have the right to give away +copies of GDB, that you receive source code or else can get it if you want +it, that you can change GDB or use pieces of it in new free programs, and +that you know you can do these things. + + To make sure that everyone has such rights, we have to forbid you to +deprive anyone else of these rights. For example, if you distribute copies +of GDB, you must give the recipients all the rights that you have. You +must make sure that they, too, receive or can get the source code. And you +must tell them their rights. + + Also, for our own protection, we must make certain that everyone finds +out that there is no warranty for GDB. If GDB is modified by someone else +and passed on, we want its recipients to know that what they have is not +what we distributed, so that any problems introduced by others will not +reflect on our reputation. + + Therefore we (Richard Stallman and the Free Software Foundation, +Inc.) make the following terms which say what you must do to be +allowed to distribute or change GDB. + +@unnumberedsec Copying Policies + +@enumerate +@item +You may copy and distribute verbatim copies of GDB source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each file a valid copyright notice ``Copyright +@copyright{} 1988 Free Software Foundation, Inc.'' (or with whatever year +is appropriate); keep intact the notices on all files that +refer to this License Agreement and to the absence of any warranty; and +give any other recipients of the GDB program a copy of this License +Agreement along with the program. You may charge a distribution fee +for the physical act of transferring a copy. + +@item +You may modify your copy or copies of GDB source code or any portion +of it, and copy and distribute such modifications under the terms of +Paragraph 1 above, provided that you also do the following: + +@itemize @bullet +@item +cause the modified files to carry prominent notices stating +that you changed the files and the date of any change; and + +@item +cause the whole of any work that you distribute or publish, that +in whole or in part contains or is a derivative of GDB or any +part thereof, to be licensed at no charge to all third parties on +terms identical to those contained in this License Agreement +(except that you may choose to grant more extensive warranty +protection to some or all third parties, at your option). + +@item +if the modified program serves as a debugger, cause it, when +started running in the simplest and usual way, to print an +announcement including a valid copyright notice ``Copyright +@copyright{} 1988 Free Software Foundation, Inc.'' (or with the +year that is appropriate), saying that there is no warranty (or +else, saying that you provide a warranty) and that users may +redistribute the program under these conditions, and telling the +user how to view a copy of this License Agreement. + +@item +You may charge a distribution fee for the physical act of +transferring a copy, and you may at your option offer warranty +protection in exchange for a fee. +@end itemize + +Mere aggregation of another unrelated program with this program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other program under the scope of these terms. + +@item +You may copy and distribute GDB (or a portion or derivative of it, +under Paragraph 2) in object code or executable form under the terms +of Paragraphs 1 and 2 above provided that you also do one of the +following: + +@itemize @bullet +@item +accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of +Paragraphs 1 and 2 above; or, + +@item +accompany it with a written offer, valid for at least three +years, to give any third party free (except for a nominal +shipping charge) a complete machine-readable copy of the +corresponding source code, to be distributed under the terms of +Paragraphs 1 and 2 above; or, + +@item +accompany it with the information you received as to where the +corresponding source code may be obtained. (This alternative is +allowed only for noncommercial distribution and only if you +received the program in object code or executable form alone.) +@end itemize + +For an executable file, complete source code means all the source code +for all modules it contains; but, as a special exception, it need not +include source code for modules which are standard libraries that +accompany the operating system on which the executable file runs. + +@item +You may not copy, sublicense, distribute or transfer GDB except as +expressly provided under this License Agreement. Any attempt +otherwise to copy, sublicense, distribute or transfer GDB is void and +your rights to use GDB under this License agreement shall be +automatically terminated. However, parties who have received computer +software programs from you with this License Agreement will not have +their licenses terminated so long as such parties remain in full +compliance. + +@item +If you wish to incorporate parts of GDB into other free programs whose +distribution conditions are different, write to the Free Software +Foundation. We have not yet worked out a simple rule that can be +stated here, but we will often permit this. We will be guided by the +two goals of preserving the free status of all derivatives our free +software and of promoting the sharing and reuse of software. +@end enumerate + +@iftex +@vfil +@eject +@end iftex +@unnumberedsec NO WARRANTY + + BECAUSE GDB IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY +NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT +WHEN OTHERWISE STATED IN WRITING, THE FREE SOFTWARE FOUNDATION, INC, +RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE GDB ``AS IS'' +WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY +AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE GDB +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY +SERVICING, REPAIR OR CORRECTION. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL FREE SOFTWARE +FOUNDATION, INC., RICHARD M. STALLMAN, AND/OR ANY OTHER PARTY WHO MAY +MODIFY AND REDISTRIBUTE GDB AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER +SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR +INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA +BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY +FREE SOFTWARE FOUNDATION, INC.) THE PROGRAM, EVEN IF YOU HAVE BEEN +ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR ANY CLAIM BY ANY +OTHER PARTY. + +@node Input, Files, License, Top +@chapter GDB+ Input Conventions + +GDB+ is invoked with the shell command @samp{gdb+}. Once started, it reads +commands from the terminal until you tell it to exit. + +A GDB+ command is a single line of input. There is no limit on how long +it can be. It starts with a command name, which is followed by arguments +whose meaning depends on the command name. Some command names do not +allow arguments. + +GDB+ command names may always be abbreviated if the abbreviation is +unambiguous. Sometimes even ambiguous abbreviations are allowed; for +example, @samp{s} is specially defined as equivalent to @samp{step} +even though there are other commands whose names start with @samp{s}. +Possible command abbreviations are often stated in the documentation +of the individual commands. + +A blank line as input to GDB+ means to repeat the previous command verbatim. +Certain commands do not allow themselves to be repeated this way; these are +commands for which unintentional repetition might cause trouble and which +you are unlikely to want to repeat. Certain others (@samp{list} and +@samp{x}) act differently when repeated because that is more useful. + +A line of input starting with @samp{#} is a comment; it does nothing. +This is useful mainly in command files (@xref{Command Files}). + +GDB+ @dfn{prompts} for commands with a string that is normally @samp{(gdb+)}. +When debugging GDB+ with GDB+, it is useful to change the prompt in one of +the GDB+s so that you can distinguish them. This can be done with the +@samp{set-prompt} command. + +@table @code +@item set-prompt @var{newprompt} +@kindex set-prompt +Directs GDB+ to use @var{newprompt} as its prompt string henceforth. +@end table + +@cindex exiting GDB+ +@kindex quit +To exit GDB+, use the @samp{quit} command (abbreviated @samp{q}). +@kbd{Ctrl-c} will not exit from GDB+, but rather will terminate the action +of any GDB+ command that is in progress and return to GDB+ command level. +It is safe to type @kbd{Ctrl-c} at any time because GDB+ does not allow +it to take effect until a time when it is safe. + +@node Files, Options, Input, Top +@chapter Specifying GDB+'s Files + +@cindex core dump file +@cindex executable file +@cindex symbol table +GDB+ needs to know the filename of the program to be debugged. To debug a +core dump of a previous run, GDB+ must be told the filename of the core +dump. + +@menu +* Arguments: File Arguments. Specifying files with arguments + (when you start GDB+). +* Commands: File Commands. Specifying files with GDB+ commands. +@end menu + +@node File Arguments, File Commands, Files, Files +@section Specifying Files with Arguments + +The usual way to specify the executable and core dump file names is with +two command arguments given when you start GDB+. The first argument is used +as the file for execution and symbols, and the second argument (if any) is +used as the core dump file name. Thus, + +@example +GDB+ progm core +@end example + +@noindent +specifies @file{progm} as the executable program and @file{core} as a core +dump file to examine. (You do not need to have a core dump file if what +you plan to do is debug the program interactively.) + +@xref{Options}, for full information on command options and arguments for +GDB+. + +@node File Commands,, File Arguments, Files +@section Specifying Files with Commands + +Usually you specify the files for GDB+ to work with by giving arguments when +you invoke GDB+. But occasionally it is necessary to change to a different +file during a GDB+ session. Or you may run GDB+ and forget to specify the +files you want to use. In these situations the GDB+ commands to specify new +files are useful. + +@table @code +@item exec-file @var{filename} +@kindex exec-file +Specify that the program to be run is found in @var{filename}. If you +do not specify a directory and the file is not found in GDB+'s working +directory, GDB+ will use the environment variable @samp{PATH} as a list +of directories to search, just as the shell does when looking for a +program to run. + +@item symbol-file @var{filename} +@kindex symbol-file +Read symbol table information from file @var{filename}. @samp{PATH} +is searched when necessary. Most of the time you will use both the +@samp{exec-file} and @samp{symbol-file} commands on the same file. + +@samp{symbol-file} with no argument clears out GDB+'s symbol table. + +@item core-file @var{filename} +@kindex core-file +Specify the whereabouts of a core dump file to be used as the +``contents of memory''. Note that the core dump contains only the +writable parts of memory; the read-only parts must come from the +executable file. + +@samp{core-file} with no argument specifies that no core file is +to be used. + +@item kill +@kindex kill +Cancel running the program under GDB+. This could be used if you wish +to debug a core dump instead. GDB+ ignores any core dump file if it is +actually running the program, so the @samp{kill} command is the only +sure way to go back to using the core dump file. + +@item info files +@kindex info files +Print the names of the executable and core dump files currently in +use by GDB+, and the file from which symbols were loaded. +@end table + +While all three file-specifying commands allow both absolute and relative +file names as arguments, GDB+ always converts the file name to an absolute +one and remembers it that way. + +The @samp{symbol-file} command causes GDB+ to forget the contents of its +convenience variables, the value history, and all breakpoints and +auto-display expressions. This is because they may contain pointers to the +internal data recording symbols and data types, which are part of the old +symbol table data being discarded inside GDB+. + +@node Options, Compilation, Files, Top +@chapter Options and Arguments for GDB+ + +When you invoke GDB+, you can pass commands telling it what files to +operate on and what other things to do. + +@menu +* Mode Options:: Options controlling modes of operation. +* File Options:: Options to specify files (executable, coredump, commands) +* Other Arguments:: Any other arguments without options + also specify files. +@end menu + +@node Mode Options, File Options, Options, Options +@section Mode Options + +@table @samp +@item -nx +Do not execute commands from the init files @file{.gdbinit}. +Normally, the commands in these files are executed after all the +command options and arguments have been processed. @xref{Command +Files}. + +@item -q +``Quiet''. Do not print the usual introductory messages. + +@item -batch +Run in batch mode. Exit with code 1 after processing all the command +files specified with @samp{-x} (and @file{./.gdbinit}, if not inhibited). +Exit also if, due to an error, GDB+ would otherwise attempt to read a +command from the terminal. + +@item -fullname +This option is used when Emacs runs GDB as a subprocess. It tells GDB +to output the full file name and line number in a standard, +recognizable fashion each time a stack frame is displayed (which +includes each time the program stops). This recognizable format looks +like two @samp{\032} characters, followed by the filename, line number +and character position separated by colons, and a newline. The +Emacs-to-GDB interface program uses the two @samp{\032} characters as +a signal to display the source code for the frame. +@end table + +@node File Options, Other Arguments, Mode Options, Options +@section File-specifying Options + +All the options and command line arguments given are processed +in sequential order. The order makes a difference when the +@samp{-x} command is used. + +@table @samp +@item -s @var{file} +Read symbol table from file @var{file}. + +@item -e @var{file} +Use file @var{file} as the executable file to execute when +appropriate, and for examining pure data in conjunction with a core +dump. + +@item -se @var{file} +Read symbol table from file @var{file} and use it as the executable +file. + +@item -c @var{file} +Use file @var{file} as a core dump to examine. + +@item -x @var{file} +Execute GDB+ commands from file @var{file}. + +@item -d @var{directory} +Add @var{directory} to the path to search for source files. +@end table + +@node Other Arguments,, File Options, Options +@section Other Arguments + +If there are arguments to GDB+ that are not options or associated with +options, the first one specifies the symbol table and executable file name +(as if it were preceded by @samp{-se}) and the second one specifies a core +dump file name (as if it were preceded by @samp{-c}). + +@node Compilation, Running, Options, Top +@chapter Compiling Your Program for Debugging + +In order to debug a program effectively, you need to ask for debugging +information when you compile it. This information in the object file +describes the data type of each variable or function and the correspondence +between source line numbers and addresses in the executable code. + +To request debugging information, specify the @samp{-g} option when you run +the compiler. + +The Unix C compiler is unable to handle the @samp{-g} and @samp{-O} options +together. This means that you cannot ask for optimization if you ask for +debugger information. + +The GNU C compiler supports @samp{-g} with or without @samp{-O}, making it +possible to debug optimized code. We recommend that you @emph{always} use +@samp{-g} whenever you compile a program. You may think the program is +correct, but there's no sense in pushing your luck. + +If you are using the GNU C compiler, the GNU assembler and the GNU linker, +you can choose between two formats of debugging information: the standard +Unix format, which is what you get with @samp{-g}, and GDB's own format, +which you request by using @samp{-gg} instead of @samp{-g}. This stores +debugging information in the executable file in a format much like that +which is used inside GDB. This has these advantages and disadvantages: + +@itemize @bullet +@item +GDB can read @samp{-gg} format more than twice as fast as Unix +@samp{-g} format. + +@item +The @samp{-gg} format uses much more disk space than Unix format. + +@item +The Unix debuggers can understand only Unix format, so you cannot use +Unix source-level debuggers if you compile with @samp{-gg}. (The +@code{adb} debugger works with either format; it does not use this +information in any case.) +@end itemize + +@node Running, Stopping, Compilation, Top +@chapter Running Your Program Under GDB+ + +@cindex running +@kindex run +To start your program under GDB+, use the @samp{run} command. The program +must already have been specified using the @samp{exec-file} command or with +an argument to GDB+ (@pxref{Files}); what @samp{run} does is create an +inferior process, load the program into it, and set it in motion. + +The execution of a program is affected by certain information it receives +from its superior. GDB+ provides ways to specify them, which you must do +@i{before} starting the program. (You can change them after starting the +program, but such changes do not affect the program unless you start it +over again.) + +@table @asis +@item The @i{arguments.} +You specify the arguments to give the program as the arguments of the +@samp{run} command. + +@item The @i{environment.} +The program normally inherits its environment from GDB+, but you can +use the GDB+ commands @samp{set-environment} and +@samp{unset-environment} to change parts of the environment that will +be given to the program.@refill + +@item The @i{working directory.} +The program inherits its working directory from GDB+. You can set GDB+'s +working directory with the @samp{cd} command in GDB+. +@end table + +After the @samp{run} command, the debugger does nothing but wait for your +program to stop. @xref{Stopping}. + +@menu +* Arguments:: Specifying the arguments for your program. +* Environment:: Specifying the environment for your program. +* Working Directory:: Specifying the working directory for giving + to your program when it is run. +* Input/Output:: Specifying the program's standard input and output. +* Attach:: Debugging a process started outside GDB. +@end menu + +@node Arguments, Environment, Running, Running +@section Your Program's Arguments + +@cindex arguments (to your program) +You specify the arguments to give the program as the arguments of the +@samp{run} command. They are passed to a shell, which expands wildcard +characters and performs redirection of I/O, and thence to the program. + +@samp{run} with no arguments uses the same arguments used by the previous +@samp{run}. + +@kindex set-args +The command @samp{set-args} can be used to specify the arguments to be used +the next time the program is run. If @samp{set-args} has no arguments, it +means to use no arguments the next time the program is run. If you have +run your program with arguments and want to run it again with no arguments, +this is the only way to do so. + +@node Environment, Working Directory, Arguments, Running +@section Your Program's Environment + +@cindex environment (of your program) +The @dfn{environment} consists of a set of @dfn{environment variables} and +their values. Environment variables conventionally record such things as +your user name, your home directory, your terminal type, and your search +path for programs to run. Usually you set up environment variables with +the shell and they are inherited by all the other programs you run. When +debugging, it can be useful to try running the program with different +environments without having to start the debugger over again. + +@table @code +@item info environment @var{varname} +@kindex info environment +Print the value of environment variable @var{varname} to be given to +your program when it is started. This command can be abbreviated +@samp{i env @var{varname}}. + +@item info environment +Print the names and values of all environment variables to be given to +your program when it is started. This command can be abbreviated +@samp{i env}. + +@item set-environment @var{varname} @var{value} +@kindex set-environment +Sets environment variable @var{varname} to @var{value}, for your +program only, not for GDB+ itself. @var{value} may be any string; the +values of environment variables are just strings, and any +interpretation is supplied by your program itself. This command +can be abbreviated as short as @samp{set-e}. + +@item unset-environment @var{varname} +@kindex unset-environment +Remove variable @var{varname} from the environment to be passed to +your program. This is different from @samp{set-env @var{varname} =} +because @samp{unset-environment} makes a variable not be defined at +all, which is distinguishable from an empty value. This command can +be abbreviated @samp{unset}. +@end table + +@node Working Directory, Input/Output, Environment, Running +@section Your Program's Working Directory + +@cindex working directory (of your program) +Each time you start your program with @samp{run}, it inherits its working +directory from the current working directory of GDB+. GDB+'s working +directory is initially whatever it inherited from its superior, but you can +specify the working directory for GDB+ with the @samp{cd} command. + +The GDB+ working directory also serves as a default for the commands +that specify files for GDB+ to operate on. @xref{Files}. + +@table @code +@item cd @var{directory} +@kindex cd +Set GDB+'s working directory to @var{directory}. + +@item pwd +@kindex pwd +Print GDB+'s working directory. +@end table + +@node Input/Output, Attach, Working Directory, Running +@section Your Program's Input and Output + +@cindex redirection +By default, the program you run under GDB does input and output to the same +terminal that GDB uses. + +You can redirect the program's input and/or output using @samp{sh}-style +redirection commands in the @samp{run} command. For example, + +@example +run > outfile +@end example + +@noindent +starts the program, diverting its output to the file @file{outfile}. + +@kindex tty +Another way to specify where the program should do input and output is with +the @samp{tty} command. This command accepts a file name as argument, and +causes this file to be the default for future @samp{run} commands. For +example, + +@example +tty /dev/ttyb +@end example + +@noindent +directs that processes started with subsequent @samp{run} commands default +to do input and output on the terminal @file{/dev/ttyb}. An explicit +redirection in @samp{run} overrides the @samp{tty} command. + +When you use the @samp{tty} command or redirect input in the @samp{run} +command, the @emph{input for your program} comes from the specified file, +but the input for GDB still comes from your terminal. The program's +controlling terminal is your (GDB's) terminal, not the terminal that the +program is reading from; so if you want to type @kbd{C-c} to stop the +program, you must type it on your (GDB's) terminal. A @kbd{C-c} typed on +the program's terminal is available to the program as ordinary input. + +@node Attach,, Input/Output, Running +@section Debugging an Already-Running Process +@kindex detach +@kindex attach +@cindex attach + +Some operating systems (in particular, Sun) allow GDB to begin debugging an +already-running process that was started outside of GDB. To do this you +must use the @samp{attach} command instead of the @samp{run} command. + +The @samp{attach} command requires one argument, which is the process-id of +the process you want to debug. (The usual way to find out the process-id +of the process is with the @samp{ps} utility.) + +The first thing GDB after arranging to debug the process is to stop it. +You can examine and modify an attached process with all the GDB commands +that ordinarily available when you start processes with @samp{run}. You +can insert breakpoints; you can step and continue; you can modify storage. +If you would rather the process continue running, use the @samp{continue} +command after attaching. + +When you are finished debugging the attached process, you can use the +@samp{detach} command to release it from GDB's control. Detaching +the process continues its execution. After the @samp{detach} command, +that process and GDB become completely independent once more, and you +are ready to @samp{attach} another process or start one with @samp{run}. + +If you exit GDB or use the @samp{run} command while you have an attached +process, you kill that process. You will be asked for confirmation if you +try to do either of these things. + +@node Stopping, Stack, Running, Top +@chapter Stopping and Continuing + +When you run a program normally, it runs until exiting. The purpose +of using a debugger is so that you can stop it before that point; +or so that if the program runs into trouble you can find out why. + +@menu +* Signals:: Fatal signals in your program just stop it; + then you can use GDB+ to see what is going on. +* Breakpoints:: Breakpoints let you stop your program when it + reaches a specified point in the code. +* Continuing:: Resuming execution until the next signal or breakpoint. +* Stepping:: Stepping runs the program a short distance and + then stops it wherever it has come to. +@end menu + +@node Signals, Breakpoints, Stopping, Stopping +@section Signals + +A signal is an asynchronous event that can happen in a program. The +operating system defines the possible kinds of signals, and gives each kind +a name and a number. For example, @code{SIGINT} is the signal a program +gets when you type @kbd{Ctrl-c}; @code{SIGSEGV} is the signal a program +gets from referencing a place in memory far away from all the areas in use; +@code{SIGALRM} occurs when the alarm clock timer goes off (which happens +only if the program has requested an alarm). + +Some signals, including @code{SIGALRM}, are a normal part of the +functioning of the program. Others, such as @code{SIGSEGV}, indicate +errors; these signals are @dfn{fatal} (kill the program immediately) if the +program has not specified in advance some other way to handle the signal. +@code{SIGINT} does not indicate an error in the program, but it is normally +fatal so it can carry out the purpose of @kbd{Ctrl-c}: to kill the program. + +GDB+ has the ability to detect any occurrence of a signal in the program +running under GDB+'s control. You can tell GDB+ in advance what to do for +each kind of signal. + +Normally, GDB+ is set up to ignore non-erroneous signals like @code{SIGALRM} +(so as not to interfere with their role in the functioning of the program) +but to stop the program immediately whenever an error signal happens. +You can change these settings with the @samp{handle} command. You must +specify which signal you are talking about with its number. + +@table @code +@item info signal +@kindex info signal +Print a table of all the kinds of signals and how GDB+ has been told to +handle each one. You can use this to see the signal numbers of all +the defined types of signals. + +@item handle @var{signalnum} @var{keywords}@dots{} +@kindex handle +Change the way GDB+ handles signal @var{signalnum}. The @var{keywords} +say what change to make. +@end table + +To use the @samp{handle} command you must know the code number of the +signal you are concerned with. To find the code number, type @samp{info +signal} which prints a table of signal names and numbers. + +The keywords allowed by the handle command can be abbreviated. Their full +names are + +@table @code +@item stop +GDB+ should stop the program when this signal happens. This implies +the @samp{print} keyword as well. + +@item print +GDB+ should print a message when this signal happens. + +@item nostop +GDB+ should not stop the program when this signal happens. It may +still print a message telling you that the signal has come in. + +@item noprint +GDB+ should not mention the occurrence of the signal at all. This +implies the @samp{nostop} keyword as well. + +@item pass +GDB+ should allow the program to see this signal; the program will be +able to handle the signal, or may be terminated if the signal is fatal +and not handled. + +@item nopass +GDB+ should not allow the program to see this signal. +@end table + +When a signal has been set to stop the program, the program cannot see the +signal until you continue. It will see the signal then, if @samp{pass} is +in effect for the signal in question @i{at that time}. In other words, +after GDB+ reports a signal, you can use the @samp{handle} command with +@samp{pass} or @samp{nopass} to control whether that signal will be seen by +the program when you later continue it. + +You can also use the @samp{signal} command to prevent the program from +seeing a signal, or cause it to see a signal it normally would not see, +or to give it any signal at any time. @xref{Signaling}. + +@node Breakpoints, Continuing, Signals, Stopping +@section Breakpoints + +@cindex breakpoints +A @dfn{breakpoint} makes your program stop whenever a certain point in the +program is reached. You set breakpoints explicitly with GDB+ commands, +specifying the place where the program should stop by line number, function +name or exact address in the program. You can add various other conditions +to control whether the program will stop. + +Each breakpoint is assigned a number when it is created; these numbers are +successive integers starting with 1. In many of the commands for controlling +various features of breakpoints you use the breakpoint number to say which +breakpoint you want to change. Each breakpoint may be @dfn{enabled} or +@dfn{disabled}; if disabled, it has no effect on the program until you +enable it again. + +@kindex info break +@kindex $_ +The command @samp{info break} prints a list of all breakpoints set and not +cleared, showing their numbers, where in the program they are, and any +special features in use for them. Disabled breakpoints are included in the +list, but marked as disabled. @samp{info break} with a breakpoint number +as argument lists only that breakpoint. The convenience variable @samp{$_} +and the default examining-address for the @samp{x} command are set to the +address of the last breakpoint listed (@pxref{Memory}). + +@menu +* Set Breaks:: How to establish breakpoints. +* Clear Breaks:: How to remove breakpoints no longer needed. +* Disabling:: How to disable breakpoints (turn them off temporarily). +* Conditions:: Making extra conditions on whether to stop. +* Break Commands:: Commands to be executed at a breakpoint. +* Error in Breakpoints:: "Cannot insert breakpoints" error--why, what to do. +@end menu + +@node Set Breaks, Clear Breaks, Breakpoints, Breakpoints +@subsection Setting Breakpoints + +@kindex break +Breakpoints are set with the @samp{break} command (abbreviated @samp{b}). +You have several ways to say where the breakpoint should go. + +@table @code +@item break @var{function} +Set a breakpoint at entry to function @var{function}. + +@item break @var{linenum} +Set a breakpoint at line @var{linenum} in the current source file. +That file is the last file whose source text was printed. This +breakpoint will stop the program just before it executes any of the +code on that line. + +@item break @var{filename}:@var{linenum} +Set a breakpoint at line @var{linenum} in source file @var{filename}. + +@item break @var{filename}:@var{function} +Set a breakpoint at entry to function @var{function} found in file +@var{filename}. Specifying a filename as well as a function name is +superfluous except when multiple files contain similarly named +functions. + +@item break *@var{address} +Set a breakpoint at address @var{address}. You can use this to set +breakpoints in parts of the program which do not have debugging +information or source files. + +@item break +Set a breakpoint at the next instruction to be executed in the +selected stack frame (@pxref{Stack}). This is a silly thing to do in +the innermost stack frame because the program would stop immediately +after being started, but it is very useful with another stack frame, +because it will cause the program to stop as soon as control returns +to that frame. + +@item break @dots{} if @var{cond} +Set a breakpoint with condition @var{cond}; evaluate the expression +@var{cond} each time the breakpoint is reached, and stop only if the +value is nonzero. @samp{@dots{}} stands for one of the possible +arguments described above (or no argument) specifying where to break. +@xref{Conditions}, for more information on breakpoint conditions. + +@item tbreak @var{args} +@kindex tbreak +Set a breakpoint enabled only for one stop. @var{args} are the +same as in the @samp{break} command, and the breakpoint is set in the same +way, but the breakpoint is automatically @dfn{disabled} the first time it +is hit. +@end table + +GDB allows you to set any number of breakpoints at the same place in the +program. There is nothing silly or meaningless about this. When the +breakpoints are conditional, this is even useful (@pxref{Conditions}). + +@node Clear Breaks, Disabling, Set Breaks, Breakpoints +@subsection Clearing Breakpoints + +@cindex clear breakpoint +@cindex delete breakpoints +It is often necessary to eliminate a breakpoint once it has done its job +and you no longer want the program to stop there. This is called +@dfn{clearing} or @samp{deleting} the breakpoint. A breakpoint that +has been cleared no longer exists in any sense. + +With the @samp{clear} command you can clear breakpoints according to where +they are in the program. With the @samp{delete} command you can clear +individual breakpoints by specifying their breakpoint numbers. + +@b{It is not necessary to clear a breakpoint to proceed past it.} GDB+ +automatically ignores breakpoints in the first instruction to be executed +when you continue execution at the same address where the program stopped. + +@table @code +@item clear +@kindex clear +Clear any breakpoints at the next instruction to be executed in the +selected stack frame (@pxref{Selection}). When the innermost frame +is selected, this is a good way to clear a breakpoint that the program +just stopped at. + +@item clear @var{function} +@itemx clear @var{filename}:@var{function} +Clear any breakpoints set at entry to the function @var{function}. + +@item clear @var{linenum} +@item clear @var{filename}:@var{linenum} +Clear any breakpoints set at or within the code of the specified line. + +@item delete @var{bnums}@dots{} +@kindex delete +Delete the breakpoints of the numbers specified as arguments. +A breakpoint deleted is forgotten completely. +@end table + +@node Disabling, Conditions, Clear Breaks, Breakpoints +@subsection Disabling Breakpoints + +@cindex disabled breakpoints +@cindex enabled breakpoints +Rather than clearing a breakpoint, you might prefer to @dfn{disable} it. +This makes the breakpoint inoperative as if it had been cleared, but +remembers the information on the breakpoint so that you can @dfn{enable} +it again later. + +You disable and enable breakpoints with the @samp{enable} and +@samp{disable} commands, specifying one or more breakpoint numbers as +arguments. Use @samp{info break} to print a list of breakpoints if you +don't know which breakpoint numbers to use. + +A breakpoint can have any of four different states of enablement: + +@itemize @bullet +@item +Enabled. The breakpoint will stop the program. A breakpoint made +with the @samp{break} command starts out in this state. +@item +Disabled. The breakpoint has no effect on the program. +@item +Enabled once. The breakpoint will stop the program, but +when it does so it will become disabled. A breakpoint made +with the @samp{tbreak} command starts out in this state. +@item +Enabled for deletion. The breakpoint will stop the program, but +immediately after it does so it will be deleted permanently. +@end itemize + +You change the state of enablement of a breakpoint with the following +commands: + +@table @code +@item disable @var{bnums}@dots{} +@kindex disable +Disable the specified breakpoints. A disabled breakpoint has no +effect but is not forgotten. All options such as ignore-counts, +conditions and commands are remembered in case the breakpoint is +enabled again later. + +@item enable @var{bnums}@dots{} +@kindex enable +Enable the specified breakpoints. They become effective once again in +stopping the program, until you specify otherwise. + +@item enable once @var{bnums}@dots{} +Enable the specified breakpoints temporarily. Each will be disabled +again the next time it stops the program (unless you have used one of +these commands to specify a different state before that time comes). + +@item enable delete @var{bnums}@dots{} +Enable the specified breakpoints to work once and then die. Each of +the breakpoints will be deleted the next time it stops the program +(unless you have used one of these commands to specify a different +state before that time comes). +@end table + +Aside from the automatic disablement or deletion of a breakpoint when it +stops the program, which happens only in certain states, the state of +enablement of a breakpoint changes only when one of the commands above +is used. + +@node Conditions, Break Commands, Disabling, Breakpoints +@subsection Break Conditions + +@cindex conditions +The simplest sort of breakpoint breaks every time the program reaches a +specified place. You can also specify a @dfn{condition} for a breakpoint. +A condition is just a boolean expression in your programming language. +A breakpoint with a condition evaluates the expression each time the +program reaches it, and the program stops only if the condition is true. + +Break conditions may have side effects, and may even call functions in your +program. These may sound like strange things to do, but their effects are +completely predictable unless there is another enabled breakpoint at the +same address. (In that case, GDB+ might see the other breakpoint first and +stop the program without checking the condition of this one.) Note that +breakpoint commands are usually more convenient and flexible for the +purpose of performing side effects when a breakpoint is reached +(@pxref{Break Commands}). + +Break conditions can be specified when a breakpoint is set, by using +@samp{if} in the arguments to the @samp{break} command. @xref{Set Breaks}. +They can also be changed at any time with the @samp{condition} command: + +@table @code +@item condition @var{bnum} @var{expression} +@kindex condition +Specify @var{expression} as the break condition for breakpoint number +@var{bnum}. From now on, this breakpoint will stop the program only if +the value of @var{expression} is true (nonzero, in C). @var{expression} +is not evaluated at the time the @samp{condition} command is given. + +@item condition @var{bnum} +Remove the condition from breakpoint number @var{bnum}. It becomes +an ordinary unconditional breakpoint. +@end table + +@cindex ignore count (of breakpoint) +A special feature is provided for one kind of condition: to prevent the +breakpoint from doing anything until it has been reached a certain number +of times. This is done with the @dfn{ignore count} of the breakpoint. +When the program reaches a breakpoint whose ignore count is positive, then +instead of stopping, it just decrements the ignore count by one and +continues. + +@table @code +@item ignore @var{bnum} @var{count} +@kindex ignore +Set the ignore count of breakpoint number @var{bnum} to @var{count}. +The next @var{count} times the breakpoint is reached, it will not stop. + +To make the breakpoint stop the next time it is reached, specify +a count of zero. + +@item cont @var{count} +Continue execution of the program, setting the ignore count of the +breakpoint that the program stopped at to @var{count} minus one. +Continuing through the breakpoint does not itself count as one of +@var{count}. Thus, the program will not stop at this breakpoint until the +@var{count}'th time it is hit. + +This command is allowed only when the program stopped due to a +breakpoint. At other times, the argument to @samp{cont} is ignored. +@end table + +If a breakpoint has a positive ignore count and a condition, the condition +is not checked. Once the ignore count reaches zero, the condition will +start to be checked. + +Note that you could achieve the effect of the ignore count with a condition +such as @samp{$foo-- <= 0} using a debugger convenience variable that is +decremented each time. That is why the ignore count is considered a +special case of a condition. @xref{Convenience Vars}. + +@node Break Commands, Error in Breakpoints, Conditions, Breakpoints +@subsection Commands Executed on Breaking + +@cindex breakpoint commands +You can give any breakpoint a series of commands to execute when the +program stops due to that breakpoint. For example, you might want to +print the values of certain expressions, or enable other breakpoints. + +@table @code +@item commands @var{bnum} +Specify commands for breakpoint number @var{bnum}. The commands +themselves appear on the following lines. Type a line containing just +@samp{end} to terminate the commands. + +To remove all commands from a breakpoint, use the command +@samp{commands} and follow it immediately by @samp{end}; that is, give +no commands. +@end table + +It is possible for breakpoint commands to start the program up again. +Simply use the @samp{cont} command, or @samp{step}, or any other command +to resume execution. However, any remaining breakpoint commands are +ignored. When the program stops again, GDB+ will act according to why +that stop took place. + +@kindex silent +If the first command specified is @samp{silent}, the usual message about +stopping at a breakpoint is not printed. This may be desirable for +breakpoints that are to print a specific message and then continue. +If the remaining commands too print nothing, you will see no sign that +the breakpoint was reached at all. @samp{silent} is not really a command; +it is meaningful only at the beginning of the commands for a breakpoint. + +The commands @samp{echo} and @samp{output} that allow you to print precisely +controlled output are often useful in silent breakpoints. @xref{Output}. + +For example, here is how you could use breakpoint commands to print the +value of @code{x} at entry to @code{foo} whenever it is positive. We +assume that the newly created breakpoint is number 4; @samp{break} will +print the number that is assigned. + +@example +break foo if x>0 +commands 4 +silent +echo x is\040 +output x +echo \n +cont +end +@end example + +One application for breakpoint commands is to correct one bug so you can +test another. Put a breakpoint just after the erroneous line of code, give +it a condition to detect the case in which something erroneous has been +done, and give it commands to assign correct values to any variables that +need them. End with the @samp{cont} command so that the program does not +stop, and start with the @samp{silent} command so that no output is +produced. Here is an example: + +@example +break 403 +commands 5 +silent +set x = y + 4 +cont +end +@end example + +One deficiency in the operation of automatically continuing breakpoints +under Unix appears when your program uses raw mode for the terminal. +GDB+ options back to its own terminal modes (not raw) before executing +commands, and then must switch back to raw mode when your program is +continued. This causes any pending terminal input to be lost. + +In the GNU system, this will be fixed by changing the behavior of +terminal modes. + +Under Unix, when you have this problem, you might be able to get around +it by putting your actions into the breakpoint condition instead of +commands. For example + +@example +condition 5 (x = y + 4), 0 +@end example + +@noindent +is a condition expression that will change @code{x} as needed, then always +have the value 0 so the program will not stop. Loss of input is avoided +here because break conditions are evaluated without changing the terminal +modes. When you want to have nontrivial conditions for performing the side +effects, the operators @samp{&&}, @samp{||} and @samp{?@: @dots{} :@:} may be useful. + +@node Error in Breakpoints,, Break Commands, Breakpoints +@subsection ``Cannot Insert Breakpoints'' Error + +Under Unix, breakpoints cannot be used in a program if any other process +is running that program. Attempting to run or continue the program with +a breakpoint in this case will cause GDB+ to stop it. + +When this happens, you have two ways to proceed: + +@enumerate +@item +Remove or disable the breakpoints, then continue. + +@item +Suspend GDB+, and copy the file containing the program to a new name. +Resume GDB+ and use the @samp{exec-file} command to specify that GDB+ +should run the program under that name. Then start the program again. +@end enumerate + +@node Continuing, Stepping, Breakpoints, Stopping +@section Continuing + +After your program stops, most likely you will want it to run some more if +the bug you are looking for has not happened yet. + +@table @code +@item cont +Continue running the program at the place where it stopped. +@end table + +If the program stopped at a breakpoint, the place to continue running +is the address of the breakpoint. You might expect that continuing would +just stop at the same breakpoint immediately. In fact, @samp{cont} +takes special care to prevent that from happening. You do not need +to clear the breakpoint to proceed through it after stopping at it. + +You can, however, specify an ignore-count for the breakpoint that the +program stopped at, by means of an argument to the @samp{cont} command. +@xref{Conditions}. + +If the program stopped because of a signal other than @code{SIGINT} or +@code{SIGTRAP}, continuing will cause the program to see that signal. +You may not want this to happen. For example, if the program stopped +due to some sort of memory reference error, you might store correct +values into the erroneous variables and continue, hoping to see more +execution; but the program would probably terminate immediately as +a result of the fatal signal once it sees the signal. To prevent this, +you can continue with @samp{signal 0}. @xref{Signaling}. You can +also act in advance to prevent the program from seeing certain kinds +of signals, using the @samp{handle} command (@pxref{Signals}). + +@node Stepping,, Continuing, Stopping +@section Stepping + +@cindex stepping +@dfn{Stepping} means setting your program in motion for a limited time, so +that control will return automatically to the debugger after one line of +code or one machine instruction. Breakpoints are active during stepping +and the program will stop for them even if it has not gone as far as the +stepping command specifies. + +@table @code +@item step +@kindex step +Proceed the program until control reaches a different line, then stop +it and return to the debugger. This command is abbreviated @samp{s}. + +@item step @var{count} +Proceed as in @samp{step}, but do so @var{count} times. If a breakpoint +or a signal not related to stepping is reached before @var{count} steps, +stepping stops right away. + +@item next +@kindex next +Similar to @samp{step}, but any function calls appearing within the line of +code are executed without stopping. Execution stops when control reaches a +different line of code at the stack level which was executing when the +@samp{next} command was given. This command is abbreviated @samp{n}. + +An argument is a repeat count, as in @samp{step}. + +@item finish +@kindex finish +Continue running until just after the selected stack frame returns +(or until there is some other reason to stop, such as a fatal signal +or a breakpoint). + +Contrast this with the @samp{return} command (@pxref{Returning}). + +@item stepi +@itemx si +@kindex stepi +@kindex si +Proceed one machine instruction, then stop and return to the debugger. + +It is often useful to do @samp{display/i $pc} when stepping by machine +instructions. This will cause the next instruction to be executed to +be displayed automatically at each stop. @xref{Auto Display}. + +An argument is a repeat count, as in @samp{step}. + +@item nexti +@itemx ni +@kindex nexti +@kindex ni +Proceed one machine instruction, but if it is a subroutine call, +proceed until the subroutine returns. + +An argument is a repeat count, as in @samp{next}. +@end table + +A typical technique for using stepping is to put a breakpoint +(@pxref{Breakpoints}) at the beginning of the function or the section of +the program in which a problem is believed to lie, and then step through +the suspect area, examining the variables that are interesting, until the +problem happens. + +The @samp{cont} command can be used after stepping to resume execution +until the next breakpoint or signal. + +@node Stack, Source, Stopping, Top +@chapter Examining the Stack + +When your program has stopped, the first thing you need to know is where it +stopped and how it got there. + +@cindex call stack +Each time your program performs a function call, the information about +where in the program the call was made from is saved in a block of data +called a @dfn{stack frame}. The frame also contains the arguments of the +call and the local variables of the function that was called. All the +stack frames are allocated in a region of memory called the @dfn{call +stack}. + +When your program stops, the GDB+ commands for examining the stack allow you +to see all of this information. + +One of the stack frames is @dfn{selected} by GDB+ and many GDB+ commands +refer implicitly to the selected frame. In particular, whenever you ask +GDB+ for the value of a variable in the program, the value is found in the +selected frame. There are special GDB+ commands to select whichever frame +you are interested in. + +When the program stops, GDB+ automatically selects the currently executing +frame and describes it briefly as the @samp{frame} command does +(@pxref{Frame Info, Info}). + +@menu +* Frames:: Explanation of stack frames and terminology. +* Backtrace:: Summarizing many frames at once. +* Selection:: How to select a stack frame. +* Info: Frame Info, Commands to print information on stack frames. +@end menu + +@node Frames, Backtrace, Stack, Stack +@section Stack Frames + +@cindex frame +The call stack is divided up into contiguous pieces called @dfn{frames}; +each frame is the data associated with one call to one function. The frame +contains the arguments given to the function, the function's local +variables, and the address at which the function is executing. + +@cindex initial frame +@cindex outermost frame +@cindex innermost frame +When your program is started, the stack has only one frame, that of the +function @code{main}. This is called the @dfn{initial} frame or the +@dfn{outermost} frame. Each time a function is called, a new frame is +made. Each time a function returns, the frame for that function invocation +is eliminated. If a function is recursive, there can be many frames for +the same function. The frame for the function in which execution is +actually occurring is called the @dfn{innermost} frame. This is the most +recently created of all the stack frames that still exist. + +@cindex frame pointer +Inside your program, stack frames are identified by their addresses. A +stack frame consists of many bytes, each of which has its own address; each +kind of computer has a convention for choosing one of those bytes whose +address serves as the address of the frame. Usually this address is kept +in a register called the @dfn{frame pointer register} while execution is +going on in that frame. + +@cindex frame number +GDB+ assigns numbers to all existing stack frames, starting with zero for +the innermost frame, one for the frame that called it, and so on upward. +These numbers do not really exist in your program; they are to give you a +way of talking about stack frames in GDB+ commands. + +@cindex selected frame +Many GDB+ commands refer implicitly to one stack frame. GDB+ records a stack +frame that is called the @dfn{selected} stack frame; you can select any +frame using one set of GDB+ commands, and then other commands will operate +on that frame. When your program stops, GDB+ automatically selects the +innermost frame. + +@node Backtrace, Selection, Frames, Stack +@section Backtraces + +A backtrace is a summary of how the program got where it is. It shows one +line per frame, for many frames, starting with the currently executing +frame (frame zero), followed by its caller (frame one), and on up the +stack. + +@table @code +@item backtrace +@itemx bt +Print a backtrace of the entire stack: one line per frame for all +frames in the stack. + +You can stop the backtrace at any time by typing the system interrupt +character, normally @kbd{Control-C}. + +@item backtrace @var{n} +@itemx bt @var{n} +Similar, but stop after @var{n} frames. +@end table + +Each line in a backtrace shows the frame number, the program counter, the +function and its arguments, and the source file name and line number (if +known). The program counter is is omitted if is the beginning of the code for +the source line. This is the same as the first of the two lines printed +when you select a frame. + +@node Selection, Frame Info, Backtrace, Stack +@section Selecting a Frame + +Most commands for examining the stack and other data in the program work on +whichever stack frame is selected at the moment. Here are the commands for +selecting a stack frame; all of them finish by printing a brief description +of the stack frame just selected. + +@table @code +@item frame @var{n} +@kindex frame +Select frame number @var{n}. Recall that frame zero is the innermost +(currently executing) frame, frame one is the frame that called the +innermost one, and so on. The highest-numbered frame is @code{main}'s +frame. + +@item frame @var{addr} +Select the frame at address @var{addr}. This is useful mainly if the +chaining of stack frames has been damaged by a bug, making it +impossible for GDB+ to assign numbers properly to all frames. In +addition, this can be useful when the program has multiple stacks and +options between them. + +@item up @var{n} +@kindex up +Select the frame @var{n} frames up from the frame previously selected. +For positive numbers @var{n}, this advances toward the outermost +frame, to higher frame numbers, to frames that have existed longer. +@var{n} defaults to one. + +@item down @var{n} +@kindex down +Select the frame @var{n} frames down from the frame previously +selected. For positive numbers @var{n}, this advances toward the +innermost frame, to lower frame numbers, to frames that were created +more recently. @var{n} defaults to one. +@end table + +All of these commands end by printing some information on the frame that +has been selected: the frame number, the function name, the arguments, the +source file and line number of execution in that frame, and the text of +that source line. For example: + +@example +#3 main (argc=3, argv=??, env=??) at main.c, line 67 +67 read_input_file (argv[i]); +@end example + +After such a printout, the @samp{list} command with no arguments will print +ten lines centered on the point of execution in the frame. @xref{List}. + +@node Frame Info,, Selection, Stack +@section Information on a Frame + +There are several other commands to print information about the selected +stack frame. + +@table @code +@item frame +This command prints a brief description of the selected stack frame. +It can be abbreviated @samp{f}. With an argument, this command is +used to select a stack frame; with no argument, it does not change +which frame is selected, but still prints the same information. + +@item info frame +@kindex info frame +This command prints a verbose description of the selected stack frame, +including the address of the frame, the addresses of the next frame in +(called by this frame) and the next frame out (caller of this frame), +the address of the frame's arguments, the program counter saved in it +(the address of execution in the caller frame), and which registers +were saved in the frame. The verbose description is useful when +something has gone wrong that has made the stack format fail to fit +the usual conventions. + +@item info frame @var{addr} +Print a verbose description of the frame at address @var{addr}, +without selecting that frame. The selected frame remains unchanged by +this command. + +@item info args +@kindex info args +Print the arguments of the selected frame, each on a separate line. + +@item info locals +@kindex info locals +Print the local variables of the selected frame, each on a separate +line. These are all variables declared static or automatic within all +program blocks that execution in this frame is currently inside of. +@end table + +@node Source, Data, Stack, Top +@chapter Examining Source Files + +GDB+ knows which source files your program was compiled from, and +can print parts of their text. When your program stops, GDB+ +spontaneously prints the line it stopped in. Likewise, when you +select a stack frame (@pxref{Selection}), GDB+ prints the line +which execution in that frame has stopped in. You can also +print parts of source files by explicit command. + +@menu +* List:: Using the @samp{list} command to print source files. +* Search:: Commands for searching source files. +* Source Path:: Specifying the directories to search for source files. +@end menu + +@node List, Search, Source, Source +@section Printing Source Lines + +@kindex list +To print lines from a source file, use the @samp{list} command +(abbreviated @samp{l}). There are several ways to specify what part +of the file you want to print. + +Here are the forms of @samp{list} command most commonly used: + +@table @code +@item list @var{linenum} +Print ten lines centered around line number @var{linenum} in the +current source file. + +@item list @var{function} +Print ten lines centered around the beginning of function +@var{function}. + +@item list +Print ten more lines. If the last lines printed were printed with a +@samp{list} command, this prints ten lines following the last lines +printed; however, if the last line printed was a solitary line printed +as part of displaying a stack frame (@pxref{Stack}), this prints ten +lines centered around that line. + +@item list @minus{} +Print ten lines just before the lines last printed. +@end table + +Repeating a @samp{list} command with @key{RET} discards the argument, +so it is equivalent to typing just @samp{list}. This is more useful +than listing the same lines again. An exception is made for an +argument of @samp{-}; that argument is preserved in repetition so that +each repetition moves up in the file. + +In general, the @samp{list} command expects you to supply zero, one or two +@dfn{linespecs}. Linespecs specify source lines; there are several ways +of writing them but the effect is always to specify some source line. +Here is a complete description of the possible arguments for @samp{list}: + +@table @code +@item list @var{linespec} +Print ten lines centered around the line specified by @var{linespec}. + +@item list @var{first},@var{last} +Print lines from @var{first} to @var{last}. Both arguments are +linespecs. + +@item list ,@var{last} +Print ten lines ending with @var{last}. + +@item list @var{first}, +Print ten lines starting with @var{first}. + +@item list + +Print ten lines just after the lines last printed. + +@item list @minus{} +Print ten lines just before the lines last printed. + +@item list +As described in the preceding table. +@end table + +Here are the ways of specifying a single source line---all the +kinds of linespec. + +@table @asis +@item @var{linenum} +Specifies line @var{linenum} of the current source file. +When a @samp{list} command has two linespecs, this refers to +the same source file as the first linespec. + +@item +@var{offset} +Specifies the line @var{offset} lines after the last line printed. +When used as the second linespec in a @samp{list} command that has +two, this specifies the line @var{offset} lines down from the +first linespec. + +@item @minus{}@var{offset} +Specifies the line @var{offset} lines before the last line printed. + +@item @var{filename}:@var{linenum} +Specifies line @var{linenum} in the source file @var{filename}. + +@item @var{function} +Specifies the line of the open-brace that begins the body of the +function @var{function}. + +@item @var{filename}:@var{function} +Specifies the line of the open-brace that begins the body of the +function @var{function} in the file @var{filename}. The file name is +needed with a function name only for disambiguation of identically +named functions in different source files. + +@item *@var{address} +Specifies the line containing the program address @var{address}. +@var{address} may be any expression. +@end table + +One other command is used to map source lines to program addresses. + +@table @code +@item info line @var{linenum} +@kindex info line +Print the starting and ending addresses of the compiled code for +source line @var{linenum}. + +@kindex $_ +The default examine address for the @samp{x} command is changed to the +starting address of the line, so that @samp{x/i} is sufficient to +begin examining the machine code (@pxref{Memory}). Also, this address +is saved as the value of the convenience variable @samp{$_} +(@pxref{Convenience Vars}). +@end table + +@node Search, Source Path, List, Source +@section Searching Source Files +@cindex searching +@kindex forward-search +@kindex reverse-search + +There are two commands for searching through the current source file for a +regular expression. + +The command @samp{forward-search @var{regexp}} checks each line, starting +with the one following the last line listed, for a match for @var{regexp}. +It lists the line that is found. You can abbreviate the command name +as @samp{fo}. + +The command @samp{reverse-search @var{regexp}} checks each line, starting +with the one before the last line listed and going backward, for a match +for @var{regexp}. It lists the line that is found. You can abbreviate +this command with as little as @samp{rev}. + +@node Source Path,, Search, Source +@section Specifying Source Directories + +@cindex source path +@cindex directories for source files +Executable programs do not record the directories of the source files they +were compiled from, just the names. GDB+ remembers a list of directories to +search for source files; this is called the @dfn{source path}. Each time +GDB+ wants a source file, it tries all the directories in the list, in the +order they are present in the list, until it finds a file with the desired +name. + +@kindex directory +When you start GDB+, its source path contains just the current working +directory. To add other directories, use the @samp{directory} command. +@b{Note that the search path for executable files and the working directory +are @i{not} used for finding source files.} + +@table @code +@item directory @var{dirname} +Add directory @var{dirname} to the end of the source path. + +@item directory +Reset the source path to just the current working directory of GDB+. +This requires confirmation. + +@samp{directory} with no argument can cause source files previously +found by GDB+ to be found in a different directory. To make this work +correctly, this command also clears out the tables GDB+ maintains +about the source files it has already found. + +@item info directories +@kindex info directories +Print the source path: show which directories it contains. +@end table + +Because the @samp{directory} command adds to the end of the source path, +it does not affect any file that GDB+ has already found. If the source +path contains directories that you do not want, and these directories +contain misleading files with names matching your source files, the +way to correct the situation is as follows: + +@enumerate +@item +Choose the directory you want at the beginning of the source path. +Use the @samp{cd} command to make that the current working directory. + +@item +Use @samp{directory} with no argument to reset the source path to just +that directory. + +@item +Use @samp{directory} with suitable arguments to add any other +directories you want in the source path. +@end enumerate + +@node Data, Symbols, Source, Top +@chapter Examining Data + +@cindex printing data +@cindex examining data +@kindex print +The usual way of examining data in your program is with the @samp{print} +command (abbreviated @samp{p}). It evaluates and prints the value of any +valid expression of the language the program is written in (for now, C). +You type + +@example +print @var{exp} +@end example + +@noindent +where @var{exp} is any valid expression, and the value of @var{exp} +is printed in a format appropriate to its data type. + +A more low-level way of examining data is with the @samp{x} command. +It examines data in memory at a specified address and prints it in a +specified format. + +@menu +* Expressions:: Expressions that can be computed and printed. +* Variables:: Using your program's variables in expressions. +* Assignment:: Setting your program's variables. +* Arrays:: Examining part of memory as an array. +* Formats:: Specifying formats for printing values. +* Memory:: Examining memory explicitly. +* Auto Display:: Printing certain expressions whenever program stops. +* Value History:: Referring to values previously printed. +* Convenience Vars:: Giving names to values for future reference. +* Registers:: Referring to and storing in machine registers. +@end menu + +@node Expressions, Variables, Data, Data +@section Expressions + +@cindex expressions +Many different GDB+ commands accept an expression and compute its value. +Any kind of constant, variable or operator defined by the programming +language you are using is legal in an expression in GDB+. This includes +conditional expressions, function calls, casts and string constants. + +In addition to supporting operators normally found in the C programming +language, GDB+ also supports some C++ constructs. For example, one can +call member functions (GDB+ automatically uses @code{this} when necessary), +and examine and manipulate pointers to members, pointers to member +functions (virtual or otherwise). + +Casts are supported in all languages, not just in C, because it is so +useful to cast a number into a pointer so as to examine a structure +at that address in memory. GDB+ allows pointers to members and pointer to +member functions to be cast to any type and vice-versa. + +GDB+ supports three kinds of operator in addition to those of programming +languages: + +@table @code +@item @@ +@samp{@@} is a binary operator for treating parts of memory as arrays. +@xref{Arrays}, for more information. + +@item :: +@samp{::} allows you to specify a variable in terms of the file or +function it is defined in. @xref{Variables}. It also supports the C++ +convention of qualifying a variable reference according to a type name (or +the global scope). This makes it easy to examing static class variables, +for example. + +@item @{@var{type}@} @var{addr} +Refers to an object of type @var{type} stored at address @var{addr} in +memory. @var{addr} may be any expression whose value is an integer or +pointer (but parentheses are required around nonunary operators, just as in +a cast). This construct is allowed regardless of what kind of data is +officially supposed to reside at @var{addr}.@refill +@end table + +@node Variables, Arrays, Expressions, Data +@section Program Variables + +The most common kind of expression to use is the name of a variable +in your program. + +Variables in expressions are understood in the selected stack frame +(@pxref{Selection}); they must either be global (or static) or be visible +according to the scope rules of the programming language from the point of +execution in that frame. This means that in the function + +@example +foo (a) + int a; +@{ + bar (a); + @{ + int b = test (); + bar (b); + @} +@} +@end example + +@noindent +the variable @code{a} is usable whenever the program is executing +within the function @code{foo}, but the variable @code{b} is visible +only while the program is executing inside the block in which @code{b} +is declared. + +@node Arrays, Formats, Variables, Data +@section Artificial Arrays + +@cindex artificial array +It is often useful to print out several successive objects of the +same type in memory; a section of an array, or an array of +dynamically determined size for which only a pointer exists in the +program. + +This can be done by constructing an @dfn{artificial array} with the +binary operator @samp{@@}. The left operand of @samp{@@} should be +the first element of the desired array, as an individual object. +The right operand should be the length of the array. The result is +an array value whose elements are all of the type of the left argument. +The first element is actually the left argument; the second element +comes from bytes of memory immediately following those that hold the +first element, and so on. Here is an example. If a program says + +@example +int *array = (int *) malloc (len * sizeof (int)); +@end example + +@noindent +you can print the contents of @code{array} with + +@example +p *array@@len +@end example + +The left operand of @samp{@@} must reside in memory. Array values made +with @samp{@@} in this way behave just like other arrays in terms of +subscripting, and are coerced to pointers when used in expressions. +(It would probably appear in an expression via the value history, +after you had printed it out.) + +@node Formats, Memory, Arrays, Data +@section Formats + +@cindex formatted output +@cindex output formats +GDB+ normally prints all values according to their data types. Sometimes +this is not what you want. For example, you might want to print a number +in hex, or a pointer in decimal. Or you might want to view data in memory +at a certain address as a character string or an instruction. These things +can be done with @dfn{output formats}. + +The simplest use of output formats is to say how to print a value +already computed. This is done by starting the arguments of the +@samp{print} command with a slash and a format letter. The format +letters supported are: + +@table @samp +@item x +Regard the bits of the value as an integer, and print the integer in +hexadecimal. + +@item d +Print as integer in signed decimal. + +@item u +Print as integer in unsigned decimal. + +@item o +Print as integer in octal. + +@item a +Print as an address, both absolute in hex and then relative +to a symbol defined as an address below it. + +@item c +Regard as an integer and print it as a character constant. + +@item f +Regard the bits of the value as a floating point number and print +using typical floating point syntax. +@end table + +For example, to print the program counter in hex (@pxref{Registers}), type + +@example +p/x $pc +@end example + +@noindent +Note that no space is required before the slash; this is because command +names in GDB+ cannot contain a slash. + +To reprint the last value in the value history with a different format, +you can use the @samp{print} command with just a format and no +expression. For example, @samp{p/x} reprints the last value in hex. + +@node Memory, Auto Display, Formats, Data +@subsection Examining Memory + +@cindex examining memory +@kindex x +The command @samp{x} (for `examine') can be used to examine memory under +explicit control of formats, without reference to the program's data types. + +@samp{x} is followed by a slash and an output format specification, +followed by an expression for an address. The expression need not have +a pointer value (though it may); it is used as an integer, as the +address of a byte of memory. + +The output format in this case specifies both how big a unit of memory +to examine and how to print the contents of that unit. It is done +with one or two of the following letters: + +These letters specify just the size of unit to examine: + +@table @samp +@item b +Examine individual bytes. + +@item h +Examine halfwords (two bytes each). + +@item w +Examine words (four bytes each). + +@cindex word +Many assemblers and cpu designers still use `word' for a 16-bit quantity, +as a holdover from specific predecessor machines of the 1970's that really +did use two-byte words. But more generally the term `word' has always +referred to the size of quantity that a machine normally operates on and +stores in its registers. This is 32 bits for all the machines that GNU +runs on. + +@item g +Examine giant words (8 bytes). +@end table + +These letters specify just the way to print the contents: + +@table @samp +@item x +Print as integers in unsigned hexadecimal. + +@item d +Print as integers in signed decimal. + +@item u +Print as integers in unsigned decimal. + +@item o +Print as integers in unsigned octal. + +@item a +Print as an address, both absolute in hex and then relative +to a symbol defined as an address below it. + +@item c +Print as character constants. + +@item f +Print as floating point. This works only with sizes @samp{w} and +@samp{g}. + +@item s +Print a null-terminated string of characters. The specified unit size +is ignored; instead, the unit is however many bytes it takes to reach +a null character (including the null character). + +@item i +Print a machine instruction in assembler syntax (or nearly). The +specified unit size is ignored; the number of bytes in an instruction +varies depending on the type of machine, the opcode and the addressing +modes used. +@end table + +If either the manner of printing or the size of unit fails to be specified, +the default is to use the same one that was used last. If you don't want +to use any letters after the slash, you can omit the slash as well. + +You can also omit the address to examine. Then the address used is +just after the last unit examined. This is why string and instruction +formats actually compute a unit-size based on the data: so that the +next string or instruction examined will start in the right place. +The @samp{print} command sometimes sets the default address for +the @samp{x} command; when the value printed resides in memory, the +default is set to examine the same location. @samp{info line} also +sets the default for @samp{x}, to the address of the start of the +machine code for the specified line and @samp{info breakpoints} sets +it to the address of the last breakpoint listed. + +When you use @key{RET} to repeat an @samp{x} command, it does not repeat +exactly the same: the address specified previously (if any) is ignored, so +that the repeated command examines the successive locations in memory +rather than the same ones. + +You can examine several consecutive units of memory with one command by +writing a repeat-count after the slash (before the format letters, if any). +The repeat count must be a decimal integer. It has the same effect as +repeating the @samp{x} command that many times except that the output may +be more compact with several units per line. + +@example +x/10i $pc +@end example + +@noindent +Prints ten instructions starting with the one to be executed next in the +selected frame. After doing this, you could print another ten following +instructions with + +@example +x/10 +@end example + +@noindent +in which the format and address are allowed to default. + +@kindex $_ +@kindex $__ +The addresses and contents printed by the @samp{x} command are not put in +the value history because there is often too much of them and they would +get in the way. Instead, GDB+ makes these values available for subsequent +use in expressions as values of the convenience variables @samp{$_} and +@samp{$__}. + +After an @samp{x} command, the last address examined is available for use +in expressions in the convenience variable @samp{$_}. The contents of that +address, as examined, are available in the convenience variable @samp{$__}. + +If the @samp{x} command has a repeat count, the address and contents saved +are from the last memory unit printed; this is not the same as the last +address printed if several units were printed on the last line of output. + +@node Auto Display, Value History, Memory, Data +@section Automatic Display + +If you find that you want to print the value of an expression frequently +(to see how it changes), you might want to add it to the @dfn{automatic +display list} so that GDB+ will print its value each time the program stops. +Each expression added to the list is given a number to identify it; +to remove an expression from the list, you specify that number. +The automatic display looks like this: + +@example +2: foo = 38 +3: bar[5] = (struct hack *) 0x3804 +@end example + +@noindent +showing item numbers, expressions and their current values. + +@table @code +@item display @var{exp} +@kindex display +Add the expression @var{exp} to the list of expressions to display +each time the program stops. + +@item display/@var{fmt} @var{exp} +For @var{fmt} specifying only a display format and not a size or +count, add the expression @var{exp} to the auto-display list but +arranges to display it each time in the specified format @var{fmt}. + +@item display/@var{fmt} @var{addr} +For @var{fmt} @samp{i} or @samp{s}, or including a unit-size or a +number of units, add the expression @var{addr} as a memory address to +be examined each time the program stops. Examining means in effect +doing @samp{x/@var{fmt} @var{addr}}. @xref{Memory}. + +@item undisplay @var{n} +@kindex undisplay +Remove item number @var{n} from the list of expressions to display. + +@item display +Display the current values of the expressions on the list, just as is +done when the program stops. + +@item info display +@kindex info display +Print the list of expressions to display automatically, each one +with its item number, but without showing the values. +@end table + +@node Value History, Convenience Vars, Auto Display, Data +@section Value History + +@cindex value history +Every value printed by the @samp{print} command is saved for the entire +session in GDB+'s @dfn{value history} so that you can refer to it in +other expressions. + +@cindex $ +@cindex $$ +The values printed are given @dfn{history numbers} for you to refer to them +by. These are successive integers starting with 1. @samp{print} shows you +the history number assigned to a value by printing @samp{$@var{n} = } +before the value; here @var{n} is the history number. + +To refer to any previous value, use @samp{$} followed by the value's +history number. The output printed by @samp{print} is designed to remind +you of this. Just @samp{$} refers to the most recent value in the history, +and @samp{$$} refers to the value before that. + +For example, suppose you have just printed a pointer to a structure and +want to see the contents of the structure. It suffices to type + +@example +p *$ +@end example + +If you have a chain of structures where the component @samp{next} points +to the next one, you can print the contents of the next one with + +@example +p *$.next +@end example + +It might be useful to repeat this command many times by typing @key{RET}. + +Note that the history records values, not expressions. If the value of +@code{x} is 4 and you type + +@example +print x +set x=5 +@end example + +@noindent +then the value recorded in the value history by the @samp{print} command +remains 4 even though @code{x}'s value has changed. + +@table @code +@item info history +@kindex info history +Print the last ten values in the value history, with their item +numbers. This is like @samp{p $$9} repeated ten times, except that +@samp{info history} does not change the history. + +@item info history @var{n} +Print ten history values centered on history item number @var{n}. +@end table + +@node Convenience Vars, Registers, Value History, Data +@section Convenience Variables + +@cindex convenience variables +GDB+ provides @dfn{convenience variables} that you can use within GDB+ to +hold on to a value and refer to it later. These variables exist entirely +within GDB+; they are not part of your program, and setting a convenience +variable has no effect on further execution of your program. That's why +you can use them freely. + +Convenience variables have names starting with @samp{$}. Any name starting +with @samp{$} can be used for a convenience variable, unless it is one of +the predefined set of register names (@pxref{Registers}). + +You can save a value in a convenience variable with an assignment +expression, just as you would set a variable in your program. Example: + +@example +set $foo = *object_ptr +@end example + +@noindent +would save in @samp{$foo} the value contained in the object pointed to by +@code{object_ptr}. + +Using a convenience variable for the first time creates it; but its value +is @code{void} until you assign a new value. You can alter the value with +another assignment at any time. + +Convenience variables have no fixed types. You can assign a convenience +variable any type of value, even if it already has a value of a different +type. The convenience variable as an expression has whatever type its +current value has. + +@table @code +@item info convenience +@kindex info convenience +Print a list of convenience variables used so far, and their values. +Abbreviated @samp{i con}. +@end table + +One of the ways to use a convenience variable is as a counter to be +incremented or a pointer to be advanced. For example: + +@example +set $i = 0 +print bar[$i++]->contents +@i{@dots{}repeat that command by typing @key{RET}.} +@end example + +Some convenience variables are created automatically by GDB+ and given +values likely to be useful. + +@table @samp +@item $_ +The variable @samp{$_} is automatically set by the @samp{x} command to +the last address examined (@pxref{Memory}). Other commands which +provide a default address for @samp{x} to examine also set @samp{$_} +to that address; these commands include @samp{info line} and @samp{info +breakpoint}. + +@item $__ +The variable @samp{$__} is automatically set by the @samp{x} command +to the value found in the last address examined. +@end table + +@node Registers,, Convenience Vars, Data +@section Registers + +@cindex registers +Machine register contents can be referred to in expressions as variables +with names starting with @samp{$}. The names of registers are different +for each machine; use @samp{info registers} to see the names used on your +machine. The names @samp{$pc} and @samp{$sp} are used on all machines for +the program counter register and the stack pointer. Often @samp{$fp} is +used for a register that contains a pointer to the current stack frame. + +GDB+ always considers the contents of an ordinary register as an integer +when the register is examined in this way. Programs can store floating +point values in registers also, but there is currently no GDB+ command +to examine a specified register in floating point. (However, if the +variable in your program which is stored in the register is a floating +point variable, you can see the floating point value by examining +the variable.) + +Some machines have special floating point registers. GDB+ considers these +registers' values as floating point when you examine them explicitly. + +Some registers have distinct ``raw'' and ``virtual'' data formats. This +means that the data format in which the register contents are saved by the +operating system is not the same one that your program normally sees. For +example, the registers of the 68881 floating point coprocessor are always +saved in ``extended'' format, but all C programs expect to work with +``double'' format. In such cases, GDB+ normally works with the virtual +format only (the format that makes sense for your program), but the +@samp{info registers} command prints the data in both formats. + +Register values are relative to the selected stack frame +(@pxref{Selection}). This means that you get the value that the register +would contain if all stack frames farther in were exited and their saved +registers restored. In order to see the real contents of all registers, +you must select the innermost frame (with @samp{frame 0}). + +Some registers are never saved (typically those numbered zero or one) +because they are used for returning function values; for these registers, +relativization makes no difference. + +@table @code +@item info registers +@kindex info registers +Print the names and relativized values of all registers. + +@item info registers @var{regname} +Print the relativized value of register @var{regname}. @var{regname} +may be any register name valid on the machine you are using, with +or without the initial @samp{$}. +@end table + +@subsection Examples + +You could print the program counter in hex with + +@example +p/x $pc +@end example + +@noindent +or print the instruction to be executed next with + +@example +x/i $pc +@end example + +@noindent +or add four to the stack pointer with + +@example +set $sp += 4 +@end example + +@noindent +The last is a way of removing one word from the stack, on machines where +stacks grow downward in memory (most machines, nowadays). This assumes +that the innermost stack frame is selected. Setting @samp{$sp} is +not allowed when other stack frames are selected. + +@node Symbols, Altering, Data, Top +@chapter Examining the Symbol Table + +The commands described in this section allow you to make inquiries for +information about the symbols (names of variables, functions and types) +defined in your program. This information is found by GDB+ in the symbol +table loaded by the @samp{symbol-file} command; it is inherent in the text +of your program and does not change as the program executes. + +@table @code +@item whatis @var{exp} +@kindex whatis +Print the data type of expression @var{exp}. @var{exp} is not +actually evaluated, and any side-effecting operations (such as +assignments or function calls) inside it do not take place. + +@item whatis +Print the data type of @samp{$}, the last value in the value history. + +@item info address @var{symbol} +@kindex info address +Describe where the data for @var{symbol} is stored. For register +variables, this says which register. For other automatic variables, +this prints the stack-frame offset at which the variable is always +stored. Note the contrast with @samp{print &@var{symbol}}, which does +not work at all for register variables and for automatic variables +prints the exact address of the current instantiation of the variable. + +@item ptype @var{typename} +@kindex ptype +Print a description of data type @var{typename}. @var{typename} may be +the name of a type, or for C code it may have the form +@samp{struct @var{struct-tag}}, @samp{union @var{union-tag}} or +@samp{enum @var{enum-tag}}.@refill + +@item info sources +@kindex info sources +Print the names of all source files in the program for which there +is debugging information. + +@item info functions +@kindex info functions +Print the names and data types of all defined functions. + +@item info functions @var{regexp} +Print the names and data types of all defined functions +whose names contain a match for regular expression @var{regexp}. +Thus, @samp{info fun step} finds all functions whose names +include @samp{step}; @samp{info fun ^step} finds those whose names +start with @samp{step}. + +@item info variables +@kindex info variables +Print the names and data types of all variables that are declared +outside of functions. + +@item info variables @var{regexp} +Print the names and data types of all variables, declared outside of +functions, whose names contain a match for regular expression +@var{regexp}. + +@item info types +@kindex info types +Print all data types that are defined in the program. + +@item info types @var{regexp} +Print all data types that are defined in the program whose names +contain a match for regular expression @var{regexp}. + +@item printsyms @var{filename} +@kindex printsyms +Write a complete dump of the debugger's symbol data into the +file @var{filename}. +@end table + +@node Altering, Sequences, Symbols, Top +@chapter Altering Execution + +There are several ways to alter the execution of your program with GDB+ +commands. + +@menu +* Assignment:: Altering variable values or memory contents. +* Jumping:: Altering control flow. +* Signaling:: Making signals happen in the program. +* Returning:: Making a function return prematurely. +@end menu + +@node Assignment, Jumping, Altering, Altering +@section Assignment to Variables + +@cindex assignment +@cindex setting variables +To alter the value of a variable, evaluate an assignment expression. +For example, + +@example +print x=4 +@end example + +@noindent +would store the value 4 into the variable @code{x}, and then print +the value of the assignment expression (which is 4). + +@kindex set +If you are not interested in seeing the value of the assignment, use the +@samp{set} command instead of the @samp{print} command. @samp{set} is +really the same as @samp{print} except that the expression's value is not +printed and is not put in the value history (@pxref{Value History}). The +expression is evaluated only for side effects. + +GDB+ allows more implicit conversions in assignments than C does; you can +freely store an integer value into a pointer variable or vice versa, and +any structure can be converted to any other structure that is the same +length or shorter. + +In C, all the other assignment operators such as @samp{+=} and @samp{++} +are supported as well. + +To store into arbitrary places in memory, use the @samp{@{@dots{}@}} +construct to generate a value of specified type at a specified address +(@pxref{Expressions}). For example, + +@example +set @{int@}0x83040 = 4 +@end example + +@node Jumping, Signaling, Assignment, Altering +@section Continuing at a Different Address + +@table @code +@item jump @var{linenum} +@kindex jump +Resume execution at line number @var{linenum}. Execution may stop +immediately if there is a breakpoint there. + +The @samp{jump} command does not change the current stack frame, or +the stack pointer, or the contents of any memory location or any +register other than the program counter. If line @var{linenum} is in +a different function from the one currently executing, the results may +be wild if the two functions expect different patterns of arguments or +of local variables. For his reason, the @samp{jump} command requests +confirmation if the specified line is not in the function currently +executing. However, even wild results are predictable based on +changing the program counter. + +@item jump *@var{address} +Resume execution at the instruction at address @var{address}. +@end table + +A similar effect can be obtained by storing a new value into the register +@samp{$pc}, but not exactly the same. + +@example +set $pc = 0x485 +@end example + +@noindent +specifies the address at which execution will resume, but does not resume +execution. That does not happen until you use the @samp{cont} command or a +stepping command (@pxref{Stepping}). + +@node Signaling, Returning, Jumping, Altering +@section Giving the Program a Signal + +@table @code +@item signal @var{signalnum} +@kindex signal +Resume execution where the program stopped, but give it immediately +the signal number @var{signalnum}. + +Alternatively, if @var{signalnum} is zero, continue execution and give +no signal. This may be useful when the program has received a signal +and the @samp{cont} command would allow the program to see that +signal. +@end table + +@node Returning,, Signaling, Altering +@section Returning from a Function + +@cindex returning from a function +@kindex return +You can make any function call return immediately, using the @samp{return} +command. + +First select the stack frame that you wish to return from +(@pxref{Selection}). Then type the @samp{return} command. If you wish to +specify the value to be returned, give that as an argument. + +This pops the selected stack frame (and any other frames inside of it), +leaving its caller as the innermost remaining frame. That frame becomes +selected. The specified value is stored in the registers used for +returning values of functions. + +The @samp{return} command does not resume execution; it leaves the program +stopped in the state that would exist if the function had just returned. +Contrast this with the @samp{finish} command (@pxref{Stepping}), which +resumes execution @i{until} the selected stack frame returns naturally. + +@node Sequences, Emacs, Altering, Top +@chapter Canned Sequences of Commands + +GDB+ provides two ways to store sequences of commands for execution as a +unit: user-defined commands and command files. + +@menu +* Define:: User-defined commands. +* Command Files:: Command files. +* Output:: Controlled output commands useful in + user-defined commands and command files. +@end menu + +@node Define, Command Files, Sequences, Sequences +@section User-Defined Commands + +@cindex user-defined commands +A @dfn{user-defined command} is a sequence of GDB+ commands to which you +assign a new name as a command. This is done with the @samp{define} +command. + +@table @code +@item define @var{commandname} +@kindex define +Define a command named @var{commandname}. If there is already a command +by that name, you are asked to confirm that you want to redefine it. + +The definition of the command is made up of other GDB+ command lines, +which are given following the @samp{define} command. The end of these +commands is marked by a line containing @samp{end}. + +@item document @var{commandname} +@kindex document +Give documentation to the user-defined command @var{commandname}. The +command @var{commandname} must already be defined. This command reads +lines of documentation just as @samp{define} reads the lines of the +command definition. After the @samp{document} command is finished, +@samp{help} on command @var{commandname} will print the documentation +you have specified. + +You may use the @samp{document} command again to change the +documentation of a command. Redefining the command with @samp{define} +does not change the documentation. +@end table + +User-defined commands do not take arguments. When they are executed, the +commands of the definition are not printed. An error in any command +stops execution of the user-defined command. + +Commands that would ask for confirmation if used interactively proceed +without asking when used inside a user-defined command. Many GDB+ commands +that normally print messages to say what they are doing omit the messages +when used in user-defined command. + +@node Command Files, Output, Define, Sequences +@section Command Files + +@cindex command files +A command file for GDB+ is a file of lines that are GDB+ commands. Comments +(lines starting with @samp{#}) may also be included. An empty line in a +command file does nothing; it does not mean to repeat the last command, as +it would from the terminal. + +@cindex init file +@cindex .gdbinit +When GDB+ starts, it automatically executes its @dfn{init files}, command +files named @file{.gdbinit}. GDB+ reads the init file (if any) in your home +directory and then the init file (if any) in the current working +directory. (The init files are not executed if the @samp{-nx} option +is given.) You can also request the execution of a command file with the +@samp{source} command: + +@table @code +@item source @var{filename} +@kindex source +Execute the command file @var{filename}. +@end table + +The lines in a command file are executed sequentially. They are not +printed as they are executed. An error in any command terminates execution +of the command file. + +Commands that would ask for confirmation if used interactively proceed +without asking when used in a command file. Many GDB+ commands that +normally print messages to say what they are doing omit the messages +when used in a command file. + +@node Output,, Command Files, Sequences +@section Commands for Controlled Output + +During the execution of a command file or a user-defined command, the only +output that appears is what is explicitly printed by the commands of the +definition. This section describes three commands useful for generating +exactly the output you want. + +@table @code +@item echo @var{text} +@kindex echo +Print @var{text}. Nonprinting characters can be included in +@var{text} using C escape sequences, such as @samp{\n} to print a +newline. @b{No newline will be printed unless you specify one.} + +A backslash at the end of @var{text} is ignored. It is useful for +outputting a string ending in spaces, since trailing spaces are +trimmed from all arguments. A backslash at the beginning preserves +leading spaces in the same way, because @samp{\ } as an escape +sequence stands for a space. Thus, to print @samp{ and foo = }, do + +@example +echo \ and foo = \ +@end example + +@item output @var{expression} +@kindex output +Print the value of @var{expression} and nothing but that value: no +newlines, no @samp{$@var{nn} = }. The value is not entered in the +value history either. + +@item output/@var{fmt} @var{expression} +Print the value of @var{expression} in format @var{fmt}. +@xref{Formats}, for more information. + +@item printf @var{string}, @var{expressions}@dots{} +@kindex printf +Print the values of the @var{expressions} under the control of +@var{string}. The @var{expressions} are separated by commas and may +be either numbers or pointers. Their values are printed as specified +by @var{string}, exactly as if the program were to execute + +@example +printf (@var{string}, @var{expressions}@dots{}); +@end example + +For example, you can print two values in hex like this: + +@example +printf "foo, bar-foo = 0x%x, 0x%x\n", foo, bar-foo +@end example + +The only backslash-escape sequences that you can use in the string are +the simple ones that consist of backslash followed by a letter. +@end table + +@node Emacs, Remote, Sequences, Top +@chapter Using GDB under GNU Emacs + +A special interface allows you to use GNU Emacs to view (and +edit) the source files for the program you are debugging with +GDB. + +To use this interface, use the command @kbd{M-x gdb} in Emacs. +Give the executable file you want to debug as an argument. This +command starts a GDB process as a subprocess of Emacs, with input +and output through a newly created Emacs buffer. + +Using this GDB process is just like using GDB normally except for two things: + +@itemize @bullet +@item +All ``terminal'' input and output goes through the Emacs buffer. This +applies both to GDB commands and their output, and to the input and +output done by the program you are debugging. + +This is useful because it means that you can copy the text of previous +commands and input them again; you can even use parts of the output +in this way. + +All the facilities of Emacs's Shell mode are available for this purpose. + +@item +GDB displays source code through Emacs. Each time GDB displays a +stack frame, Emacs automatically finds the source file for that frame +and puts an arrow (@samp{=>}) at the left margin of the current line. + +Explicit GDB @samp{list} or search commands still produce output as +usual, but you probably will have no reason to use them. +@end itemize + +In the GDB I/O buffer, you can use these special Emacs commands: + +@table @kbd +@item M-s +Execute to another source line, like the GDB @samp{step} command. + +@item M-n +Execute to next source line in this function, skipping all function +calls, like the GDB @samp{next} command. + +@item M-i +Execute one instruction, like the GDB @samp{stepi} command. + +@item M-u +Move up one stack frame (and display that frame's source file in +Emacs), like the GDB @samp{up} command. + +@item M-d +Move down one stack frame (and display that frame's source file in +Emacs), like the GDB @samp{down} command. (This means that you cannot +delete words in the usual fashion in the GDB buffer; I am guessing you +won't often want to do that.) + +@item C-c C-f +Execute until exit from the selected stack frame, like the GDB +@samp{finish} command. +@end table + +In any source file, the Emacs command @kbd{C-x SPC} (@code{gdb-break}) +tells GDB to set a breakpoint on the source line point is on. + +The source files displayed in Emacs are in ordinary Emacs buffers +which are visiting the source files in the usual way. You can edit +the files with these buffers if you wish; but keep in mind that GDB +communicates with Emacs in terms of line numbers. If you add or +delete lines from the text, the line numbers that GDB knows will cease +to correspond properly to the code. + +@node Remote, Commands, Emacs, Top +@chapter Remote Kernel Debugging + +GDB has a special facility for debugging a remote machine via a serial +connection. This can be used for kernel debugging. + +The program to be debugged on the remote machine needs to contain a +debugging device driver which talks to GDB over the serial line using the +protocol described below. The same version of GDB that is used ordinarily +can be used for this. + +@menu +* Remote Commands:: Commands used to start and finish remote debugging. +@end menu + +For details of the communication protocol, see the comments in the GDB +source file @file{remote.c}. + +@node Remote Commands,, Remote, Remote +@section Commands for Remote Debugging + +To start remote debugging, first run GDB and specify as an executable file +the program that is running in the remote machine. This tells GDB how +to find the program's symbols and the contents of its pure text. Then +establish communication using the @samp{attach} command with a device +name rather than a pid as an argument. For example: + +@example +attach /dev/ttyd +@end example + +@noindent +if the serial line is connected to the device named @file{/dev/ttyd}. This +will stop the remote machine if it is not already stopped. + +Now you can use all the usual commands to examine and change data and to +step and continue the remote program. + +To resume the remote program and stop debugging it, use the @samp{detach} +command. + +@node Commands, Concepts, Remote, Top +@unnumbered Command Index + +@printindex ky + +@node Concepts,, Commands, Top +@unnumbered Concept Index + +@printindex cp + +@contents +@bye diff --git a/gdb/gdb.1 b/gdb/gdb.1 deleted file mode 100644 index 11a42a6..0000000 --- a/gdb/gdb.1 +++ /dev/null @@ -1,91 +0,0 @@ -.TH GDB 1 "13 April 1987" -.UC 4 -.SH NAME -gdb \- Project GNU's DeBugger -.SH SYNOPSIS -\fBgdb\fP [ \fBoptions\fP ] See documentation mentioned below. -.SH DESCRIPTION -\fIgdb\fP is a source level symbolic debugger for C programs, created by -Richard M. Stallman (rms) for the GNU Project, and distributed by the -Free Software Foundation. Eventually GNU (Gnu's Not Unix) will be a -complete replacement for Berkeley Unix, all of which everyone will be -able to use freely. See the \fIGNU Emacs\fP man page for pointers to more -information. -.PP -\fIgdb\fP has something of the flavor of \fIdbx\fP, -but has more features and power. It can also be used to debug o/s -kernels, but needs to be configured differently for that task. -.PP -Project GNU isn't using Unix man pages. Its style of complete -documentation can be found by: -.PP -The help and info commands inside \fIgdb\fP. -.PP -In the Info system in \fIGNU Emacs\fP. Type C-h i, and follow the -directions. This is equivalent to the reference manual for -\fIgdb\fP, and has about 55 pages of text. -.PP -\fIgdb\fP could be extended to work with other languages (e.g. Pascal) and -machines (e.g. encores). If you like, copy the sources and give it a -try. When you have it working send \fIdiff -c\fP's of the changed files to -bug-gdb@prep.ai.mit.edu (fuller details below), so they can benefit everyone. -.SH DISTRIBUTION -\fIgdb\fP is free; anyone may redistribute copies of -\fIgdb\fP to anyone under the terms stated in the -\fIgdb\fP General Public License, a copy of which accompanies each copy of -\fIgdb\fP, is readable with the info command inside \fIgdb\fP, -and which also appears in the \fIgdb\fP reference manual. -.PP -Copies of \fIgdb\fP may sometimes be received packaged with -distributions of Unix systems, but it is never included in the scope -of any license covering those systems. Such inclusion would violate -the terms on which distribution is permitted. In fact, the primary -purpose of the General Public License is to prohibit anyone from -attaching any other restrictions to redistribution of \fIgdb\fP. -.PP -You can order printed copies of the \fIgdb\fP reference manual for $10.00/copy -postpaid from the Free Software Foundation, which develops GNU software -(contact them for quantity prices on the manual). Their address is: -.nf - Free Software Foundation - 1000 Mass Ave. - Cambridge, MA 02138 -.fi -As with all software and publications from FSF, everyone is permitted to -make and distribute copies of the \fIgdb\fP reference manual. -The TeX source to the \fIgdb\fP reference -manual is also included in the \fIGNU Emacs\fP source distribution. -.PP -.SH OPTIONS -See documentation. -.SH EXAMPLES -See documentation. -.SH "SEE ALSO" -adb(1), sdb(1), dbx(1) -.SH BUGS -There is a mailing list, bug-gdb@prep.ai.mit.edu on the internet -(ucbvax!prep.ai.mit.edu!bug-gdb on UUCPnet), for reporting \fIgdb\fP -bugs and fixes. But before reporting something as a bug, please try -to be sure that it really is a bug, not a misunderstanding or a -deliberate feature. We ask you to read the section ``Reporting Emacs -Bugs'' near the end of the \fIGNU Emacs\fP reference manual -(or Info system) for hints -on how and when to report bugs. Also, include the version number of -the \fIgdb\fP you are running in \fIevery\fR bug report that you send in. -.PP -Do not expect a personal answer to a bug report. The purpose of reporting -bugs is to get them fixed for everyone in the next release, if possible. -For personal assistance, look in the SERVICE file -(see the \fIGNU Emacs\fP man page) for -a list of people who offer it. -.PP -Please do not send anything but bug reports to this mailing list. -Send other stuff to gnu@prep.ai.mit.edu (or the -corresponding UUCP address). For more information about GNU mailing -lists, see the file MAILINGLISTS (see the \fIGNU Emacs\fP man page). Bugs tend -actually to be fixed if they can be isolated, so it is in your -interest to report them in such a way that they can be easily -reproduced. -.PP -No bugs are known at this time. - diff --git a/gdb/gdb.ideas b/gdb/gdb.ideas deleted file mode 100644 index 7b9e976..0000000 --- a/gdb/gdb.ideas +++ /dev/null @@ -1,694 +0,0 @@ -BABYL OPTIONS: -Version: 5 -Labels: -Note: This is the header of an rmail file. -Note: If you are seeing it in rmail, -Note: it means the file has no messages in it. - -From: mly@MICHAEL.AI.MIT.EDU (Richard Mlynarik) -To: rms@prep.ai.mit.edu -Subject: gdb suggestions (from hpux cdb) -Reply-To: mly-prep@prep.ai.mit.edu - -"find-bug" command says "I can see the problem, but it will do you -good to find it yourself" - -The gdb manual should explicitly state that gdb has no control over -forked (or execed or whatever) subprocesses. - -I'd still like it if "delete" said what it had done. - - -Date: Tuesday, 13 May 1986, 00:40-EDT -From: <rms@LMI-ANGEL> -Sender: JC@LMI-ANGEL -Subject: interesting sdb features -To: rms@angel - -output format p = pointer to procedure. - -foo/x or foo/4x uses size of foo as size to print. - -foo[1;4] to get elements 1 thru 4. - -Continue to specified line number. - -Interactively delete all breakpoints (asking about each one). - - - -Command to write backtrace into a file, or even better to duplicate all -output to a file. This could work by playing with descriptor 1, -making it a pipe to `tee'. The original descriptor 1 is saved and -this mode can be turned off by putting it back. - Date: Wed, 18 Feb 87 15:37:14 EST - From: rms (Richard M. Stallman) - Message-Id: <8702182037.AA16492@prep.ai.mit.edu> - To: mly-prep@prep.ai.mit.edu - In-Reply-To: <8702181913.AA16118@prep.ai.mit.edu> - Subject: gdb "photo" command - - I don't think all this is worth the trouble to do now, - because the right way to do it on TRIX is totally different - and much easier. - - -Commands to enable and disable the autodisplays. Associate -autodisplays with breakpoints perhaps, so they only display -at those breakpoints; this is easier than using breakpoint commands. - -Remember how each breakpoint's position was specified. -Have command to reread symbol table and respecify each -breakpoint using same args (line number or function name) as before. - -Have way to proceed process in background so that can then suspend -gdb but have subprocess continue - - -Date: Fri, 24 Jul 87 21:30:25 EDT -From: phr@PREP.AI.MIT.EDU (Paul Rubin) -To: bug-gdb@PREP.AI.MIT.EDU - -After rereading the symbol table when user runs the "symbol-file" -command, when GDB notices that some of the source files are newer -it should reload them rather than just printing a message saying -they are newer. - - - -Message-Id: <8704171941.AA05045@orville.arpa> -To: mly@prep.ai.mit.edu -Cc: raible@orville.arpa, fouts@orville.arpa, creon@orville.arpa -Subject: gdb hack/questions, etc -Date: 17 Apr 87 11:41:42 PST (Fri) -From: raible@orville.arpa - - -A couple of things: - -1) Will gdb ever get dbx-sytly tracing? Wouldn't it be fairly easy to add? - -2) How about an xemacs gdb mode which has various windows, perhaps using - terminal.el for generality? - -3) Any word about that stupid IRIS SIGIOT problem? Do you know of anyone - else who has gotten IRIS subprocesses to work more reliably? - -4) Below is a hack adapted from ramsdell@linus.uucp which can be pretty - useful in gdb. Instead of using gdb to patch extensive changes to a - particular function, you can do the following (assuming the 50 lines - of code below is part of your executable): - 1) create a new file (foo.c) containing the new function - 2) run cc -c foo.c - 3) in gdb, and patch in the new function as follows: - -(gdb) info breakpoints -/* Load in the new object code... */ -#1 y 0x00000125 in main (dyn.c line 46) - break only if $function = funload ("foo"), 1 - silent - echo new code for func ($function) initialized\n - cont - -/* ...and use it instead of the old code. */ -#2 y 0x000001c2 in func (dyn.c line 59) - break only if $ret = $function (a), 1 - silent - set a = $ret - j 60 /* func has a return on line 60 */ - - This is more complicated than it has to be because of 2 bugs in v2.1: - 1) function calls in a breakpoint command list seem to abort - the execution of the rest of the command list. This is - why all function calls are in the conditional part. - (gdb reference manual section 5.5). - - 2) A 'return' in a command list also aborts the execution, and - in addition, prompts you for a y/n. - (gdb reference manual section 11.1). - - On the other hand, after doing 'cc -c foo.c' (which is pretty fast), - you can simply rerun your program to check out the changes. - This can be a big win! - -The code for this is included below (compile with cc -g): -======================================================== - -#include <stdio.h> -#include <a.out.h> - -typedef int (*intfun)(); -char *myname; - -intfun funload (filename) /* Dynamically load 1st function from a .o */ - char *filename; -{ - int fd, size; - struct exec hdr; - char buf[100]; - intfun fun; - - /* -A => incremental loading - use dyn as the base symbol table - -T => set the text segment origin to the following hex address - -N => magic number 407 (text not read-only) - */ - sprintf (buf, "ld -A %s -T %x -N %s.o -o %s -lc", - myname, sbrk (0), filename, filename); - - /* NOTE: if anything mallocs space between here and below, this will fail */ - system (buf); - - fd = open (filename, 0); - read (fd, &hdr, sizeof(hdr)); - size = hdr.a_text + hdr.a_data + hdr.a_bss; - - if ((fun = (intfun) sbrk (size)) < 0) - printf ("Couldn't find the space"), exit(); - - read (fd, fun, size); /* Load code. */ - /* NOTE: if anything mallocs space between here and above, this will fail */ - - close (fd); - return ((intfun) fun); -} - -main (argc, argv) - char **argv; -{ - intfun fun1, fun2; - - myname = *argv; - - fun1 = funload("fun1"); - printf ("The answer is %d.\n", (*fun1)(11) ); - - fun2 = funload("fun2"); - printf ("The answer is %d.\n", (*fun2)() ); -} -1,edited,, -Received: by PREP.AI.MIT.EDU; Tue, 16 Jun 87 03:12:54 EDT -Date: Tue, 16 Jun 87 03:12:54 EDT -From: rms (Richard M. Stallman) -Message-Id: <8706160712.AA07910@prep.ai.mit.edu> -To: rms -Subject: GDB ideas - -*** EOOH *** -Date: Tue, 16 Jun 87 03:12:54 EDT -From: rms (Richard M. Stallman) -To: rms -Subject: GDB ideas - -* Within a user-defined command, have local convenience variables, -local functions, local defined commands. - -** Optionally echo commands within a user-defined command. - -** Optionally record all user-typed commands in a log file. -Optionally record GDB output there too, marked as output so it -will not be executed if replayed. - -* Execution commands - -** Step until next branch, or next call. -(finish is step until next return). - -step branch -or should it be -continue branch - -** Stop on any branch, call or return -affecting ordinary step and continue commands. - -stop branch - -** Trace all branches, calls, returns. -This could be done by stopping on those events -and having a continue command to be executed after. - -stop branch -commands branch -continue -end - -** Commands to continue or step without any display after stop. -These may be useful in user-defined commands. - -Have one prefix command that does this, modifying whatever other -command you might use. For example, - -silent step 5 -silent cont - -** Clear all breakpoint ignore-counts when inferior exits or is killed. - -** Trace changes to a location (watchpoint). -Enable and disable them. - -** Info command to show command-line for running the program. - -* Auto-display - -** Enable and disable display expressions. -Allow syntax 1d, 2d, etc. in enable, disable and delete commands. -Then there is no more need for an undisplay command. - -** Displaying an auto variable should not do it in the wrong stack frame. -Either it should search for the proper stack frame to apply to -or it should deactivate itself when in the wrong frame. - -* Printing - -** Print an address as <file:line>+offset. - -** Abbreviate initial whitespace modulo 16. - -** p/x of an array should print each element with /x. - -** Change the stack scan so that it has a more general idea -of what info is needed to describe a frame fully. - -* Expressions - -** Array slices. Can replace @. - -** %name for use of symbol names containing funny characters. - -** User-defined convenience functions that can appear in expressions. - -** Expression syntax to convert line number to address. - -** Expression syntax to specify a name scope with an address, line number -or frame number. - -Use the line number by itself, or an address with *, just as in b or l cmd: -38:foo or *0x40a:foo. No good; the latter would be parsed as -*(0x40a:foo). - -** Expression syntax to convert a frame number to its pc. -Perhaps unary %. - -* Possible bugs - -** Does set $pc= cause the current scope to be recalculated? -It should. - -1,, -Received: by PREP.AI.MIT.EDU; Wed, 17 Jun 87 09:59:37 EDT -From: phr@ATHENA.MIT.EDU -Received: by ATHENA (5.45/4.7) - id AA09084; Wed, 17 Jun 87 08:54:36 EDT -Received: by ORPHEUS.MIT.EDU (5.45/4.7) id AA02565; Wed, 17 Jun 87 08:54:29 EDT -Date: Wed, 17 Jun 87 08:54:29 EDT -Message-Id: <8706171254.AA02565@ORPHEUS.MIT.EDU> -To: rms@prep.ai.mit.edu -Subject: gdb suggestion -Status: RO - -*** EOOH *** -From: phr@ATHENA.MIT.EDU -Date: Wed, 17 Jun 87 08:54:29 EDT -To: rms@prep.ai.mit.edu -Subject: gdb suggestion - -Completion of file and function names; e.g. typing - break XWriteBi -prints - No such symbol: XWriteBi. - Setting default command to "break XWriteBitmapFile" -so you can set a break at XWriteBitmapFile by hitting return a second -time. Other interfaces ("complete to XWriteBitmapFile? (y/n)") -are also possible. - - -1,edited,, -Received: by PREP.AI.MIT.EDU; Wed, 24 Sep 86 16:33:11 EDT -Date: Wed, 24 Sep 86 16:33:11 EDT -From: mly (Richard Mlynarik) -Message-Id: <8609242033.AA11520@prep.ai.mit.edu> -To: rms -Cc: mly-prep -Subject: gdb gripes/suggestions/requests - -*** EOOH *** -Date: Wed, 24 Sep 86 16:33:11 EDT -From: mly (Richard Mlynarik) -To: rms -Cc: mly-prep -Subject: gdb gripes/suggestions/requests - -If would be really nice to have some way to do conditionals in user - commands -- though this is really stretching the functionality of - gdb a little too much, perhaps. (see ~mly/e/.gdbint for some of - the contortions I go through with || to get conditional - evaluation...) - -A -real- win wuold be some way to execute until he next function-call - (like c-d in the cadr debugger) This would even be useful if it - were rather slow -- it would probably be faster than setting - temporary breakpoints in all the functions which might be called, - and would certainly be faster than "step"ping one's way until a - funcall happened. - -"info source" should mention what the directory search-path is (ie - what "info dir" says) and in which directory it found each of the - source files (and which source files it cannot locate in the - search-path) - - -1,, -Received: by xcssun.Berkeley.EDU (5.57/1.25) - id AA22869; Thu, 22 Oct 87 09:50:30 PDT -Received: from prep.ai.mit.edu by wheaties.ai.mit.edu; Thu, 22 Oct 87 12:17:59 EDT -Received: by PREP.AI.MIT.EDU; Thu, 22 Oct 87 12:21:00 EDT -Received: from pp.mcc.com by MCC.COM with TCP; Thu 22 Oct 87 10:54:41-CDT -Posted-Date: Thu, 22 Oct 87 10:55:13 CDT -Received: from big-d.aca.mcc.com by pp.mcc.com (4.12/KA70822) - id AA16571; Thu, 22 Oct 87 10:55:19 cdt -Return-Path: <tiemann@big-d.aca.mcc.com> -Received: by big-d.aca.mcc.com (3.2/KA70106) - id AA04247; Thu, 22 Oct 87 10:55:13 CDT -Date: Thu, 22 Oct 87 10:55:13 CDT -From: tiemann%pp.mcc.com@mcc.com (Michael Tiemann) -Message-Id: <8710221555.AA04247@big-d.aca.mcc.com> -To: bug-gdb@prep.ai.mit.edu -Subject: expanding file names - -*** EOOH *** -Posted-Date: Thu, 22 Oct 87 10:55:13 CDT -Return-Path: <tiemann@big-d.aca.mcc.com> -Date: Thu, 22 Oct 87 10:55:13 CDT -From: tiemann%pp.mcc.com@mcc.com (Michael Tiemann) -To: bug-gdb@prep.ai.mit.edu -Subject: expanding file names - -When running a program, gdb thoughtfully passes the argument list -through the shell, expanding files and environment variables as -needed. It would be nice if the same facility were added to the -command which adds directories to search paths. For example, it would -be nice to say "dir ~/foo" . - -Michael - - -1,, -Received: by xcssun.Berkeley.EDU (5.57/1.25) - id AA25075; Fri, 23 Oct 87 10:42:52 PDT -Received: from prep.ai.mit.edu by wheaties.ai.mit.edu; Fri, 23 Oct 87 13:39:37 EDT -Received: by PREP.AI.MIT.EDU; Fri, 23 Oct 87 13:42:53 EDT -Received: from relay2.cs.net by RELAY.CS.NET id ac11193; 23 Oct 87 13:03 EDT -Received: from umb.edu by RELAY.CS.NET id ac05949; 23 Oct 87 13:01 EDT -Received: by umb.umb.edu; Fri, 23 Oct 87 10:18:40 EDT -Received: by ileaf.uucp (1.1/SMI-3.0DEV3) - id AA00599; Wed, 21 Oct 87 10:56:52 EDT -Received: from marvin.io.uucp by io.uucp (1.1/SMI-3.0DEV3) - id AA01359; Wed, 21 Oct 87 10:58:45 EDT -Received: by marvin.io.uucp (3.2/SMI-3.2) - id AA00334; Wed, 21 Oct 87 11:02:20 EDT -Date: Wed, 21 Oct 87 11:02:20 EDT -From: Mark Dionne <io!marvin!md%ileaf.uucp%umb.umb.edu@relay.cs.net> -Message-Id: <8710211502.AA00334@marvin.io.uucp> -To: ileaf!umb!bug-gdb@prep.ai.mit.edu -Subject: gdb bug - -*** EOOH *** -Date: Wed, 21 Oct 87 11:02:20 EDT -From: Mark Dionne <io!marvin!md%ileaf.uucp%umb.umb.edu@relay.cs.net> -To: ileaf!umb!bug-gdb@prep.ai.mit.edu -Subject: gdb bug - -The /FMT and @ options of the "print" command seem to interact -in GDB 2.1. For example: - -(gdb) p ($cmpn.buf[-1])@($cmpn.gapb - $cmpn.buf + 1) -$17 = {-16383, -24285, 55, 27944, -24285, -24285, 55, 28010, -24285, --24285, 55, 28076, -24285, -24285, 55, 28142, -24285} -(gdb) p/x ($cmpn.buf[-1])@($cmpn.gapb - $cmpn.buf + 1) -$18 = 0xc001 - -I guess I see what's happening: the /x is applying to the whole -array rather than to the individual elements. Feature or bug? - - ...!harvard!umb!ileaf!md Mark Dionne, Interleaf - ...!sun!sunne!ileaf!md Ten Canal Park, Cambridge, MA 02141 - (617) 577-9813 x5551 - - - -1,, -Received: by PREP.AI.MIT.EDU; Sun, 6 Sep 87 14:27:19 EDT -Message-Id: <8709061827.AA18170@prep.ai.mit.edu> -Received: from relay2.cs.net by RELAY.CS.NET id af03990; 6 Sep 87 14:22 EDT -Received: from umb.edu by RELAY.CS.NET id ab03029; 6 Sep 87 14:16 EDT -Received: by umb.umb.edu; Sun, 6 Sep 87 12:10:34 EDT -Date: Sun, 6 Sep 87 12:10:34 EDT -Received: by typo.umb.edu; Sun, 6 Sep 87 12:04:21 EDT -From: Robert Morris <ram%typo.umb.edu@RELAY.CS.NET> -To: bug-gdb@PREP.AI.MIT.EDU -Subject: convenient script - -*** EOOH *** -Date: Sun, 6 Sep 87 12:10:34 EDT -From: Robert Morris <ram%typo.umb.edu@RELAY.CS.NET> -To: bug-gdb@PREP.AI.MIT.EDU -Subject: convenient script - -I find it easier to maintain binaries on our heterogenous -network if I keep this trivial script in gdb source directory. Use it -if you want. - - ------------- - -#! /bin/csh -f -# SETUP -# setup gdb files for presently known machines -# ram@umb.edu -# (ram%umb.edu@relay.cs.net if you have an incomplete mailer) -# or ...!harvard!umb!ram -# -# e.g. SETUP sun3 -# note that sunX means major release X of sun software, generally -# sun3 at this writing (gnu 18.41) -# -# note GDB with gnuemacs 18.41 is already configured for vaxen - -# Bob Morris, UMASS-Boston 9/6/87 -switch ($1) - case "sun2": - ; - case "sun3" : - set cputype="m68k"; - set inittype="suninit"; - breaksw; - default : - set cputype=$1; - set inittype=$1init; - breaksw; -endsw -echo \#include \"m-$1.h\" > param.h -echo \#include \"$cputype-pinsn.c\" > pinsn.c -ed initialize.h <<! >& /dev/null -/init.h/ -c -#include "m-$inittype.h" -. -w -q -! - - - - -1,answered,, -Received: from prep.ai.mit.edu by wheaties.ai.mit.edu; Sat, 19 Dec 87 18:18:50 EST -Received: by PREP.AI.MIT.EDU; Sat, 19 Dec 87 18:24:38 EST -Received: from big-d.aca.mcc.com by MCC.COM with TCP; Sat 19 Dec 87 17:19:48-CST -Date: Sat, 19 Dec 87 17:19:41 CST -From: tiemann@mcc.com (Michael Tiemann) -Posted-Date: Sat, 19 Dec 87 17:19:41 CST -Message-Id: <8712192319.AA26775@big-d.aca.mcc.com> -Received: by big-d.aca.mcc.com (3.2/ACA-V2.1) - id AA26775; Sat, 19 Dec 87 17:19:41 CST -To: rms@prep.ai.mit.edu -Subject: gdb - -*** EOOH *** -Date: Sat, 19 Dec 87 17:19:41 CST -From: tiemann@mcc.com (Michael Tiemann) -Posted-Date: Sat, 19 Dec 87 17:19:41 CST -To: rms@prep.ai.mit.edu -Subject: gdb - -file values.c, function unpack_field_as_long: - - val &= (1 << bitsize) - 1; - -This is not as machine independent as it could be. If you feel like -fixing this potential problem, there are many other instances to worry -about. - -Michael - - -1,, -Received: by xcssun.Berkeley.EDU (5.57/1.25) - id AA04771; Thu, 20 Aug 87 22:33:25 PDT -Received: from [128.52.22.14] by ucbvax.Berkeley.EDU (5.58/1.27) - id AA07119; Thu, 20 Aug 87 00:37:04 PDT -Received: by PREP.AI.MIT.EDU; Thu, 20 Aug 87 03:37:35 EDT -Date: Thu, 20 Aug 87 03:37:35 EDT -From: rms@prep.ai.mit.edu (Richard M. Stallman) -Message-Id: <8708200737.AA15589@prep.ai.mit.edu> -To: rms@prep.ai.mit.edu -Subject: GDB changes for next version - -*** EOOH *** -Date: Thu, 20 Aug 87 03:37:35 EDT -From: rms@prep.ai.mit.edu (Richard M. Stallman) -To: rms@prep.ai.mit.edu -Subject: GDB changes for next version - -1. Use links, rather than editing some files, to configure it. - -2. Can misc functions eval as their addresses rather than as - a char in that address? Is this reasonable in all cases - given that non-functions cannot be distinguished - and that you might use the result in various ways (arithmetic, etc.). - - -1,, -Received: by xcssun.Berkeley.EDU (5.57/1.25) - id AA09136; Sat, 29 Aug 87 02:20:15 PDT -Received: from PREP.AI.MIT.EDU by ucbvax.Berkeley.EDU (5.58/1.27) - id AA26072; Sat, 29 Aug 87 02:21:51 PDT -Received: by PREP.AI.MIT.EDU; Sat, 29 Aug 87 05:22:30 EDT -Received: by RUTGERS.EDU (5.54/1.14) with UUCP - id AA22247; Sat, 29 Aug 87 05:21:13 EDT -Received: from sequent.UUCP by spool.wisc.edu; Sat, 29 Aug 87 04:18:41 CDT -Received: from reed.UUCP by ogcvax.OGC.EDU (5.51/OGC_4.8) - id AA08044; Fri, 28 Aug 87 20:06:41 PDT -Received: by reed.UUCP (5.51/5.17) - id AA05059; Fri, 28 Aug 87 19:19:15 PDT -From: uwvax!sequent!ogcvax!reed!keith@rutgers.edu (Keith Packard) -Message-Id: <8708290219.AA05059@reed.UUCP> -To: rms@prep.ai.mit.edu -Subject: Re: GDB -In-Reply-To: Your message of Thu, 20 Aug 87 03:39:37 EDT. - <8708200735.AA26546@EDDIE.MIT.EDU> -Date: Fri, 28 Aug 87 19:19:13 PDT - -*** EOOH *** -From: uwvax!sequent!ogcvax!reed!keith@rutgers.edu (Keith Packard) -To: rms@prep.ai.mit.edu -Subject: Re: GDB -In-Reply-To: Your message of Thu, 20 Aug 87 03:39:37 EDT. - <8708200735.AA26546@EDDIE.MIT.EDU> -Date: Fri, 28 Aug 87 19:19:13 PDT - - -Here is a simple test program for exibiting the trouble with signals: - ------ -# include <signal.h> - -main () -{ - int handle (); - int i; - signal (SIGALRM, handle); - alarm (5); - for (i = 0; i < 100000; i++) - printf ("%d\n", i); -} - -handle () -{ - printf ("signal!\n"); - alarm (5); -} ------ - -To demonstrate the problem, simply place a breakpoint before the call to -alarm and then start stepping through the program: - -(gdb) break 7 -(gdb) step -... -... - -Eventually, the alarm call occurs and the program ends up in some -signal handling code -- unfortuantely a machine dependent location. At this -point, because the fp has moved out of the current function (in fact on -many machines the frame is not in a consistent state at this point) gdb -assumes that a new function has started and suspends execution with another -prompt. - -A reasonable solution would be to have gdb insert a breakpoint at the -expected signal return address and continue to that breakpoint -- I've -implemented this and found that it works. There is, however, one nasty -problem -- longjmp around the suspended frame and the breakpoint is not hit -at the expected time. - -Have fun... - -keith packard - -tektronix!reed!keith - - -1,, -Received: by xcssun.Berkeley.EDU (5.57/1.25) - id AA09143; Sat, 29 Aug 87 02:24:58 PDT -Received: by neptune.Berkeley.EDU (5.57/1.25) - id AA03738; Sat, 29 Aug 87 02:24:50 PDT -Date: Sat, 29 Aug 87 02:24:50 PDT -From: rms@neptune.berkeley.edu (Richard Stallman) -Message-Id: <8708290924.AA03738@neptune.Berkeley.EDU> -To: rms@neptune.Berkeley.EDU -Subject: GDB bug -Reply-To: rms@prep.ai.mit.edu - -*** EOOH *** -Date: Sat, 29 Aug 87 02:24:50 PDT -From: rms@neptune.berkeley.edu (Richard Stallman) -To: rms@neptune.Berkeley.EDU -Subject: GDB bug -Reply-To: rms@prep.ai.mit.edu - -Is there any way to make GDB, when stepping across a function call, -notice any attempt to longjump out of that call? -Perhaps an implicit breakpoint at longjump. -If longjump is called, find the pc in the jmp_buf and put -a self-deleting breakpoint there. - - -1,, -Received: by xcssun.Berkeley.EDU (5.57/1.25) - id AA07976; Fri, 28 Aug 87 09:26:12 PDT -Received: from PREP.AI.MIT.EDU by ucbvax.Berkeley.EDU (5.58/1.27) - id AA03230; Fri, 28 Aug 87 09:28:04 PDT -Received: by PREP.AI.MIT.EDU; Fri, 28 Aug 87 12:28:43 EDT -Date: Fri, 28 Aug 87 12:28:43 EDT -From: phr@prep.ai.mit.edu (Paul Rubin) -Message-Id: <8708281628.AA09926@prep.ai.mit.edu> -To: rms@prep.ai.mit.edu -Subject: gdb suggestions - -*** EOOH *** -Date: Fri, 28 Aug 87 12:28:43 EDT -From: phr@prep.ai.mit.edu (Paul Rubin) -To: rms@prep.ai.mit.edu -Subject: gdb suggestions - -1. I wish gdb had a command to re-read the sources so that I can edit -the program and recompile it without having to kill and restart gdb. - -2. Would be nice if gdb could somehow connect the subprocess's tty channels -to a pty, so I can run gdb in an X window and the subprocess in a different -(xterm) window. - -This might need hair to detect if the subprocess is running when you try -to examine variables, etc. and stop the subproc or report an error if it is. - -
\ No newline at end of file diff --git a/gdb/infcmd.c b/gdb/infcmd.c index f2a9944..c66809d 100644 --- a/gdb/infcmd.c +++ b/gdb/infcmd.c @@ -1,5 +1,5 @@ /* Memory-access and commands for inferior process, for GDB. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. + Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. GDB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone @@ -31,47 +31,7 @@ anyone else from sharing it farther. Help stamp out software hoarding! #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."); @@ -161,7 +121,7 @@ set_args_command (args) if (!args) args = ""; inferior_args = concat (" ", args, ""); } - + void tty_command (file) char *file; @@ -197,19 +157,32 @@ Start it from the beginning? ")) error ("Program already started."); } - if (args) - set_args_command (args); - - exec_file = (char *) get_exec_file (); - if (from_tty) + if (remote_debugging) { - printf ("Starting program: %s%s\n", - exec_file, inferior_args); - fflush (stdout); + free (allargs); + if (from_tty) + { + printf ("Starting program: %s%s\n", + exec_file, inferior_args); + fflush (stdout); + } } + else + { + if (args) + set_args_command (args); - allargs = concat ("exec ", exec_file, inferior_args); - inferior_pid = create_inferior (allargs, environ_vector (inferior_environ)); + 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 (); @@ -326,6 +299,7 @@ jump_command (arg, from_tty) int from_tty; { register CORE_ADDR addr; + struct symtabs_and_lines sals; struct symtab_and_line sal; ERROR_NO_INFERIOR; @@ -333,7 +307,14 @@ jump_command (arg, from_tty) if (!arg) error_no_arg ("starting address"); - sal = decode_line_spec (arg, 1); + sals = decode_line_spec (arg, 1); + if (sals.nelts != 1) + { + error ("Unreasonable jump request"); + } + + sal = sals.sals[0]; + free (sals.sals); if (sal.symtab == 0 && sal.pc == 0) error ("No source file has been specified."); @@ -751,8 +732,8 @@ registers_info (addr_exp) /* * 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 + * This stops it cold in its 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 @@ -762,11 +743,17 @@ attach_command (args, from_tty) { char *exec_file; int pid; + int remote; dont_repeat(); if (!args) error_no_arg ("process-id to attach"); + + while (*args == ' ' || *args == '\t') args++; + + if (args[0] == '/') + remote = 1; else pid = atoi (args); @@ -782,12 +769,21 @@ attach_command (args, from_tty) if (from_tty) { - printf ("Attaching program: %s pid %d\n", - exec_file, pid); + if (remote) + printf ("Attaching remote machine\n"); + else + printf ("Attaching program: %s pid %d\n", + exec_file, pid); fflush (stdout); } - attach_program (pid); + if (remote) + { + remote_open (args, from_tty); + start_remote (); + } + else + attach_program (pid); } /* diff --git a/gdb/inferior.h b/gdb/inferior.h index 21c937c..8fa1c19 100644 --- a/gdb/inferior.h +++ b/gdb/inferior.h @@ -27,6 +27,10 @@ extern char *inferior_io_terminal; extern int inferior_pid; +/* Nonzero if debugging a remote machine via a serial link or ethernet. */ + +extern int remote_debugging; + /* Last signal that the inferior received (why it stopped). */ extern int stop_signal; diff --git a/gdb/inflow.c b/gdb/inflow.c index 7bed594..b88352c 100644 --- a/gdb/inflow.c +++ b/gdb/inflow.c @@ -25,25 +25,14 @@ anyone else from sharing it farther. Help stamp out software hoarding! #include "inferior.h" #include <stdio.h> -#include <sys/types.h> #include <sys/param.h> #include <sys/dir.h> +#include <sys/user.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 @@ -53,10 +42,6 @@ anyone else from sharing it farther. Help stamp out software hoarding! #include <machine/reg.h> #endif -#ifdef SYSV_TTYS -#include <termio.h> -#endif - extern int errno; /* Nonzero if we are debugging an attached outside process @@ -64,31 +49,21 @@ extern int errno; 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; @@ -107,15 +82,13 @@ static int terminal_is_ours; void terminal_init_inferior () { + if (remote_debugging) + return; -#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; @@ -128,18 +101,17 @@ terminal_init_inferior () void terminal_inferior () { + if (remote_debugging) + return; + if (terminal_is_ours) /* && inferior_thisrun_terminal == 0) */ { fcntl (0, F_SETFL, tflags_inferior); fcntl (0, F_SETFL, tflags_inferior); -#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; @@ -156,6 +128,9 @@ terminal_inferior () void terminal_ours_for_output () { + if (remote_debugging) + return; + terminal_ours_1 (1); } @@ -166,6 +141,9 @@ terminal_ours_for_output () void terminal_ours () { + if (remote_debugging) + return; + terminal_ours_1 (0); } @@ -188,55 +166,37 @@ terminal_ours_1 (output_only) 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; + + fcntl (0, F_SETFL, tflags_ours); + fcntl (0, F_SETFL, tflags_ours); 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; + + if (remote_debugging) + { + printf ("No terminal status when remote debugging.\n"); + return; + } + 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); @@ -248,7 +208,6 @@ term_status_command () for (i = 0; i < sizeof (struct ltchars); i++) printf ("0x%x ", ((char *)<c_inferior)[i]); printf ("\n"); -#endif } static void @@ -334,6 +293,8 @@ create_inferior (allargs, env) static void kill_command () { + if (remote_debugging) + return; if (inferior_pid == 0) error ("The program is not being run."); if (!query ("Kill the inferior process? ")) @@ -343,6 +304,8 @@ kill_command () kill_inferior () { + if (remote_debugging) + return; if (inferior_pid == 0) return; ptrace (8, inferior_pid, 0, 0); @@ -370,9 +333,14 @@ resume (step, signal) int signal; { errno = 0; - ptrace (step ? 9 : 7, inferior_pid, 1, signal); - if (errno) - perror_with_name ("ptrace"); + if (remote_debugging) + remote_resume (step, signal); + else + { + ptrace (step ? 9 : 7, inferior_pid, 1, signal); + if (errno) + perror_with_name ("ptrace"); + } } #ifdef NEW_SUN_PTRACE @@ -415,17 +383,22 @@ fetch_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); + if (remote_debugging) + remote_fetch_registers (registers); + else + { + 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. @@ -439,17 +412,22 @@ store_inferior_registers (regno) 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); + if (remote_debugging) + remote_store_registers (registers); + else + { + 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 @@ -467,7 +445,7 @@ fetch_inferior_registers () #else struct user u; unsigned int offset = (char *) &u.u_ar0 - (char *) &u; - offset = ptrace (3, inferior_pid, offset, 0) & UPAGE_MASK; + offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; #endif for (regno = 0; regno < NUM_REGS; regno++) @@ -497,7 +475,7 @@ store_inferior_registers (regno) #else struct user u; unsigned int offset = (char *) &u.u_ar0 - (char *) &u; - offset = ptrace (3, inferior_pid, offset, 0) & UPAGE_MASK; + offset = ptrace (3, inferior_pid, offset, 0) - KERNEL_U_ADDR; #endif if (regno >= 0) @@ -551,13 +529,18 @@ read_inferior_memory (memaddr, myaddr, len) /* Read all the longwords */ for (i = 0; i < count; i++, addr += sizeof (int)) - buffer[i] = ptrace (1, inferior_pid, addr, 0); + { + if (remote_debugging) + buffer[i] = remote_fetch_word (addr); + else + 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 +/* Copy LEN bytes of data from debugger memory at MYADDR to inferior's memory at MEMADDR. On failure (cannot write the inferior) returns the value of errno. */ @@ -580,11 +563,21 @@ write_inferior_memory (memaddr, myaddr, len) /* Fill start and end extra bytes of buffer with existing memory data. */ - buffer[0] = ptrace (1, inferior_pid, addr, 0); + if (remote_debugging) + buffer[0] = remote_fetch_word (addr); + else + buffer[0] = ptrace (1, inferior_pid, addr, 0); + if (count > 1) - buffer[count - 1] - = ptrace (1, inferior_pid, - addr + (count - 1) * sizeof (int), 0); + { + if (remote_debugging) + buffer[count - 1] + = remote_fetch_word (addr + (count - 1) * sizeof (int)); + else + buffer[count - 1] + = ptrace (1, inferior_pid, + addr + (count - 1) * sizeof (int), 0); + } /* Copy data to be written over corresponding part of buffer */ @@ -595,7 +588,10 @@ write_inferior_memory (memaddr, myaddr, len) for (i = 0; i < count; i++, addr += sizeof (int)) { errno = 0; - ptrace (4, inferior_pid, addr, buffer[i]); + if (remote_debugging) + remote_store_word (addr, buffer[i]); + else + ptrace (4, inferior_pid, addr, buffer[i]); if (errno) return errno; } @@ -611,7 +607,7 @@ try_writing_regs_command () extern int errno; if (inferior_pid == 0) - error ("The program is not being run."); + error ("There is no inferior process now."); for (i = 0; ; i += 2) { @@ -644,14 +640,10 @@ Report which ones can be written."); 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); diff --git a/gdb/infrun.c b/gdb/infrun.c index e980cec..97966e4 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -1,5 +1,5 @@ /* Start and stop the inferior process, for GDB. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. + Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. GDB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone @@ -90,6 +90,10 @@ static int stop_after_attach; int pc_changed; +/* Nonzero if debugging a remote machine via a serial link or ethernet. */ + +int remote_debugging; + /* Save register contents here when about to pop a stack dummy frame. */ char stop_registers[REGISTER_BYTES]; @@ -238,8 +242,38 @@ start_inferior () /* Install inferior's terminal modes. */ terminal_inferior (); + if (remote_debugging) + { + trap_expected = 0; + fetch_inferior_registers(); + set_current_frame (read_register(FP_REGNUM)); + stop_frame = get_current_frame(); + inferior_pid = 3; + if (insert_breakpoints()) + fatal("Can't insert breakpoints"); + breakpoints_inserted = 1; + proceed(-1, -1, 0); + } + else + { + wait_for_inferior (); + normal_stop (); + } +} + +/* Start remote-debugging of a machine over a serial link. */ + +void +start_remote () +{ + clear_proceed_status (); + running_in_shell = 0; + trap_expected = 0; + inferior_pid = 3; + breakpoints_inserted = 0; + mark_breakpoints_out (); wait_for_inferior (); - normal_stop (); + normal_stop(); } #ifdef ATTACH_DETACH @@ -290,7 +324,16 @@ wait_for_inferior () while (1) { prev_pc = read_pc (); - pid = wait (&w); + + if (remote_debugging) + remote_wait (&w); + else + { + pid = wait (&w); + if (pid != inferior_pid) + continue; + } + pc_changed = 0; fetch_inferior_registers (); stop_pc = read_pc (); @@ -530,6 +573,7 @@ wait_for_inferior () else if (!random_signal && step_range_end) { newfun = find_pc_function (stop_pc); + newmisc = -1; if (newfun) { newfun_pc = BLOCK_START (SYMBOL_BLOCK_VALUE (newfun)) diff --git a/gdb/initialize.h b/gdb/initialize.h index e727c80..05d570e 100644 --- a/gdb/initialize.h +++ b/gdb/initialize.h @@ -49,32 +49,40 @@ the terms of Paragraph 1 above, provided that you also do the following: that in whole or in part contains or is a derivative of this program or any part thereof, to be licensed at no charge to all third parties on terms identical to those contained in this - License Agreement (except that you may choose to grant more - extensive warranty protection to third parties, at your option). + License Agreement (except that you may choose to grant more extensive + warranty protection to some or all third parties, at your option). c) You may charge a distribution fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. - 3. You may copy and distribute this program or any portion of it in -compiled, executable or object code form under the terms of Paragraphs -1 and 2 above provided that you do the following: - - a) cause each such copy to be accompanied by the - corresponding machine-readable source code, which must - be distributed under the terms of Paragraphs 1 and 2 above; or, - - b) cause each such copy to be accompanied by a - written offer, with no time limit, to give any third party - free (except for a nominal shipping charge) a machine readable - copy of the corresponding source code, to be distributed - under the terms of Paragraphs 1 and 2 above; or, - - c) in the case of a recipient of this program in compiled, executable - or object code form (without the corresponding source code) you - shall cause copies you distribute to be accompanied by a copy - of the written offer of source code which you received along - with the copy you received. +Mere aggregation of another unrelated program with this program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other program under the scope of these terms. + + 3. You may copy and distribute this program (or a portion or derivative +of it, under Paragraph 2) in object code or executable form under the terms +of Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal + shipping charge) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +For an executable file, complete source code means all the source code for +all modules it contains; but, as a special exception, it need not include +source code for modules which are standard libraries that accompany the +operating system on which the executable file runs. 4. You may not copy, sublicense, distribute or transfer this program except as expressly provided under this License Agreement. Any attempt diff --git a/gdb/m-mac-aux.h b/gdb/m-mac-aux.h deleted file mode 100644 index 2f1f84d..0000000 --- a/gdb/m-mac-aux.h +++ /dev/null @@ -1,485 +0,0 @@ -/* 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"); } diff --git a/gdb/m-mac-auxinit.h b/gdb/m-mac-auxinit.h deleted file mode 100644 index bd420ef..0000000 --- a/gdb/m-mac-auxinit.h +++ /dev/null @@ -1,5 +0,0 @@ - -/* 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) diff --git a/gdb/m-merlin.h b/gdb/m-merlin.h deleted file mode 100644 index 7f87979..0000000 --- a/gdb/m-merlin.h +++ /dev/null @@ -1,437 +0,0 @@ -/* Definitions to make GDB run on a merlin under utek 2.1 - 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 ns16000 -#define ns16000 -#endif - -# include <machine/reg.h> - -/* Define this if the C compiler puts an underscore at the front - of external names before giving them to the linker. */ - -#define NAMES_HAVE_UNDERSCORE - -/* Debugger information will be in DBX format. */ - -#define READ_DBX_FORMAT - -/* Offset from address of function to start of its code. - Zero on most machines. */ - -#define FUNCTION_START_OFFSET 0 - -/* Advance PC across any function entry prologue instructions - to reach some "real" code. */ - -#define SKIP_PROLOGUE(pc) \ -{ register int op = read_memory_integer (pc, 1); \ - if (op == 0x82) \ - { op = read_memory_integer (pc+2,1); \ - if ((op & 0x80) == 0) pc += 3; \ - else if ((op & 0xc0) == 0x80) pc += 4; \ - else pc += 6; \ - }} - -/* Immediately after a function call, return the saved pc. - Can't always go through the frames for this because on some machines - the new frame is not set up until the new function executes - some instructions. */ - -#define SAVED_PC_AFTER_CALL(frame) \ - read_memory_integer (read_register (SP_REGNUM), 4) - -/* This is the amount to subtract from u.u_ar0 - to get the offset in the core file of the register values. */ - -#define KERNEL_U_ADDR (0xfef000) - -/* Address of end of stack space. */ - -#define STACK_END_ADDR (0x800000) - -/* Stack grows downward. */ - -#define INNER_THAN < - -/* Sequence of bytes for breakpoint instruction. */ - -#define BREAKPOINT {0xf2} - -/* Amount PC must be decremented by after a breakpoint. - This is often the number of bytes in BREAKPOINT - but not always. */ - -#define DECR_PC_AFTER_BREAK 0 - -/* Nonzero if instruction at PC is a return instruction. */ - -#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0x12) - -/* Return 1 if P points to an invalid floating point value. */ - -#define INVALID_FLOAT(p, len) 0 - -/* Define this to say that the "svc" insn is followed by - codes in memory saying which kind of system call it is. */ - -#define NS32K_SVC_IMMED_OPERANDS - -/* Say how long (ordinary) registers are. */ - -#define REGISTER_TYPE long - -/* Number of machine registers */ - -#define NUM_REGS 25 - -#define NUM_GENERAL_REGS 8 - -/* Initializer for an array of names of registers. - There should be NUM_REGS strings in this initializer. */ - -#define REGISTER_NAMES {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ - "pc", "sp", "fp", "ps", \ - "fsr", \ - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ - "l0", "l1", "l2", "l3", "l4", \ - } - -/* 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 AP_REGNUM FP_REGNUM -#define FP_REGNUM 10 /* Contains address of executing stack frame */ -#define SP_REGNUM 9 /* Contains address of top of stack */ -#define PC_REGNUM 8 /* Contains program counter */ -#define PS_REGNUM 11 /* Contains processor status */ -#define FPS_REGNUM 12 /* Floating point status register */ -#define FP0_REGNUM 13 /* Floating point register 0 */ -#define LP0_REGNUM 21 /* Double register 0 (same as FP0) */ - -#define REGISTER_U_ADDR(addr, blockend, regno) \ -{ \ - switch (regno) { \ - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: \ - addr = blockend + (R0 - regno) * sizeof (int); break; \ - case PC_REGNUM: \ - addr = blockend + PC * sizeof (int); break; \ - case SP_REGNUM: \ - addr = blockend + SP * sizeof (int); break; \ - case FP_REGNUM: \ - addr = blockend + FP * sizeof (int); break; \ - case PS_REGNUM: \ - addr = blockend + 12 * sizeof (int); break; \ - case FPS_REGNUM: \ - addr = 108; break; \ - case FP0_REGNUM + 0: case FP0_REGNUM + 1: \ - case FP0_REGNUM + 2: case FP0_REGNUM + 3: \ - case FP0_REGNUM + 4: case FP0_REGNUM + 5: \ - case FP0_REGNUM + 6: case FP0_REGNUM + 7: \ - addr = 76 + (regno - FP0_REGNUM) * sizeof (float); break; \ - case LP0_REGNUM + 0: case LP0_REGNUM + 1: \ - case LP0_REGNUM + 2: case LP0_REGNUM + 3: \ - addr = 76 + (regno - LP0_REGNUM) * sizeof (double); break; \ - default: \ - printf ("bad argument to REGISTER_U_ADDR %d\n", regno); \ - abort (); \ - } \ -} - -/* Total amount of space needed to store our copies of the machine's - register state, the array `registers'. */ -#define REGISTER_BYTES ((NUM_REGS - 4) * sizeof (int) + 4 * sizeof (double)) - -/* Index within `registers' of the first byte of the space for - register N. */ - -#define REGISTER_BYTE(N) ((N) >= LP0_REGNUM ? \ - LP0_REGNUM * 4 + ((N) - LP0_REGNUM) * 8 : (N) * 4) - -/* Number of bytes of storage in the actual machine representation - for register N. On the 32000, all regs are 4 bytes - except for the doubled floating registers. */ - -#define REGISTER_RAW_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4) - -/* Number of bytes of storage in the program's representation - for register N. On the 32000, all regs are 4 bytes - except for the doubled floating registers. */ - -#define REGISTER_VIRTUAL_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4) - -/* Largest value REGISTER_RAW_SIZE can have. */ - -#define MAX_REGISTER_RAW_SIZE 8 - -/* Largest value REGISTER_VIRTUAL_SIZE can have. */ - -#define MAX_REGISTER_VIRTUAL_SIZE 8 - -/* Nonzero if register N requires conversion - from raw format to virtual format. */ - -#define REGISTER_CONVERTIBLE(N) 0 - -/* Convert data from raw format for register REGNUM - to virtual format for register REGNUM. */ - -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \ - bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM)); - -/* Convert data from virtual format for register REGNUM - to raw format for register REGNUM. */ - -#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \ - bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM)); - -/* Return the GDB type object for the "standard" data type - of data in register N. */ - -#define REGISTER_VIRTUAL_TYPE(N) \ - ((N) >= FP0_REGNUM ? \ - ((N) >= LP0_REGNUM ? \ - builtin_type_double \ - : builtin_type_float) \ - : 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)) - -/* 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 Merlin, the frame's nominal address is the FP value, - and at that address is saved previous FP value as a 4-byte word. */ - -#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)) - -/* compute base of arguments */ -#define FRAME_ARGS_ADDRESS(fi) ((fi).frame) - -#define FRAME_LOCALS_ADDRESS(fi) ((fi).frame) - -/* Return number of args passed to a frame. - Can return -1, meaning no way to tell. */ - -#define FRAME_NUM_ARGS(numargs, fi) \ -{ CORE_ADDR pc; \ - int insn; \ - int addr_mode; \ - int width; \ - \ - pc = FRAME_SAVED_PC (fi.frame); \ - insn = read_memory_integer (pc,2); \ - addr_mode = (insn >> 11) & 0x1f; \ - insn = insn & 0x7ff; \ - if ((insn & 0x7fc) == 0x57c \ - && addr_mode == 0x14) /* immediate */ \ - { if (insn == 0x57c) /* adjspb */ \ - width = 1; \ - else if (insn == 0x57d) /* adjspw */ \ - width = 2; \ - else if (insn == 0x57f) /* adjspd */ \ - width = 4; \ - numargs = read_memory_integer (pc+2,width); \ - if (width > 1) \ - flip_bytes (&numargs, width); \ - numargs = - sign_extend (numargs, width*8) / 4; } \ - else numargs = -1; \ -} - -/* 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) \ -{ int regmask,regnum; \ - int localcount; \ - CORE_ADDR enter_addr; \ - CORE_ADDR next_addr; \ - \ - enter_addr = get_pc_function_start ((frame_info).pc); \ - regmask = read_memory_integer (enter_addr+1, 1); \ - localcount = ns32k_localcount (enter_addr); \ - next_addr = (frame_info).frame + localcount; \ - for (regnum = 0; regnum < 8; regnum++, regmask >>= 1) \ - (frame_saved_regs).regs[regnum] \ - = (regmask & 1) ? (next_addr -= 4) : 0; \ - (frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 4; \ - (frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4; \ - (frame_saved_regs).regs[FP_REGNUM] \ - = read_memory_integer ((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; \ - sp = push_word (sp, read_register (PC_REGNUM)); \ - sp = push_word (sp, read_register (FP_REGNUM)); \ - write_register (FP_REGNUM, sp); \ - for (regnum = 0; regnum < 8; regnum++) \ - sp = push_word (sp, read_register (regnum)); \ - write_register (SP_REGNUM, sp); \ -} - -/* Discard from the stack the innermost frame, restoring all registers. */ - -#define POP_FRAME \ -{ register CORE_ADDR fp = read_register (FP_REGNUM); \ - register int regnum; \ - struct frame_saved_regs fsr; \ - struct frame_info fi; \ - fi = get_frame_info (fp); \ - get_frame_saved_regs (&fi, &fsr); \ - for (regnum = 0; regnum < 8; regnum++) \ - if (fsr.regs[regnum]) \ - write_register (regnum, read_memory_integer (fsr.regs[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); \ -} - -/* This sequence of words is the instructions - enter 0xff,0 82 ff 00 - jsr @0x00010203 7f ae c0 01 02 03 - adjspd 0x69696969 7f a5 01 02 03 04 - bpt f2 - Note this is 16 bytes. */ - -#define CALL_DUMMY { 0x7f00ff82, 0x0201c0ae, 0x01a57f03, 0xf2040302 } - -#define CALL_DUMMY_START_OFFSET 3 -#define CALL_DUMMY_LENGTH 16 -#define CALL_DUMMY_ADDR 5 -#define CALL_DUMMY_NARGS 11 - -/* 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 flipped = fun | 0xc0000000; \ - flip_bytes (&flipped, 4); \ - *((int *) (((char *) dummyname)+CALL_DUMMY_ADDR)) = flipped; \ - flipped = - nargs * 4; \ - flip_bytes (&flipped, 4); \ - *((int *) (((char *) dummyname)+CALL_DUMMY_NARGS)) = flipped; \ -} - -#ifdef notdef -/* 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, SIGKILL, SIGSEGV, 0, 0, 0, 0, 0, \ - 0, 0, SIGTRAP, SIGTRAP, 0, 0, 0, 0, \ - 0, 0, 0, 0, 0, 0, 0, 0} - -/* 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 ("movl $ end, sp"); \ - asm ("clrl fp"); } - -/* Push the frame pointer register on the stack. */ -#define PUSH_FRAME_PTR \ - asm ("pushl fp"); - -/* Copy the top-of-stack to the frame pointer register. */ -#define POP_FRAME_PTR \ - asm ("movl (sp), fp"); - -/* After KDB is entered by a fault, push all registers - that GDB thinks about (all NUM_REGS of them), - so that they appear in order of ascending GDB register number. - The fault code will be on the stack beyond the last register. */ - -#define PUSH_REGISTERS \ -{ asm ("pushl 8(sp)"); \ - asm ("pushl 8(sp)"); \ - asm ("pushal 0x14(sp)"); \ - asm ("pushr $037777"); } - -/* 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 ("popr $037777"); \ - asm ("subl2 $8,(sp)"); \ - asm ("movl (sp),sp"); \ - asm ("rei"); } -#endif diff --git a/gdb/m-news800.h b/gdb/m-news800.h deleted file mode 100644 index 44583e3..0000000 --- a/gdb/m-news800.h +++ /dev/null @@ -1,566 +0,0 @@ -/* Parameters for execution on a Sony/NEWS, for GDB, the GNU debugger. - -Here is an m-news800.h file for gdb version 2.1. It supports the 68881 -registers. - -Now(9/2 '87) NEWS's printf has a bug. -And support Sun assembly format instead of Motorola one. -Probably not well support floating registers from core file rarely that -I do not know detail. -(hikichi@srava.sra.junet or hikichi%srava.sra.junet%kddlabs%seismo.CSS.GOV) - -Here is IEEE nan routine to use such bug fixed. - - printf("%g\n", Nan); - -> struct ieee { |* IEEE floating format *| -> unsigned int s:1; -> unsigned int e:11; -> unsigned int f1:20; -> unsigned int f2; -> }; -> -> #define ZERO_F(x) ((x.f1 == 0) && (x.f2 == 0)) |* zero fraction ? *| -> #define ZERO_E(x) (x.e == 0) |* zero exponential ? *| -> #define MAX_E(x) (x.e == 0x7ff) |* max exponential ? *| -> #define MINUS_S(x) (x.s == 1) |* minus ? *| -> -> int -> is_nan(arg) |* Not a Number ? *| -> struct ieee arg; -> { -> if (MAX_E(arg) && !ZERO_F(arg)) -> return (1); -> else -> return (0); -> } -> -> int -> is_plus_infinity(arg) -> struct ieee arg; -> { -> if (!MINUS_S(arg) && MAX_E(arg) && ZERO_F(arg)) -> return (1); -> else -> return (0); -> } -> -> int -> is_minus_infinity(arg) -> struct ieee arg; -> { -> if (MINUS_S(arg) && MAX_E(arg) && ZERO_F(arg)) -> return (1); -> else -> return (0); -> } -> -> int -> is_denormal(arg) -> struct ieee arg; -> { -> if (ZERO_E(arg)) -> return (1); -> else -> return (0); -> } - - 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! -*/ - -#ifdef 0 /* cannot use RCS id since initialize routine fails. */ -static char *RCSid = -"$Header: m-news800.h,v 1.1 87/09/21 21:27:52 hikichi Exp $"; -#endif lint - -/* - * $Log: m-news800.h,v $ - * Revision 1.1 87/09/21 21:27:52 hikichi - * Initial revision - * - */ - -/* Identify this machine */ -#ifndef news800 -#define news800 -#endif - -/* #define USE_GAS */ - -/* Motorola assembly format */ -#ifndef USE_GAS -#define MOTOROLA -#endif - -/* bug when printf special number; NAN */ -#define PRINTF_BUG - -/* Define this if the C compiler puts an underscore at the front - of external names before giving them to the linker. */ - -#define NAMES_HAVE_UNDERSCORE - -/* 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 always go through the frames for this because on some machines - the new frame is not set up until the new function executes - some instructions. */ - -#define SAVED_PC_AFTER_CALL(frame) \ -read_memory_integer (read_register (SP_REGNUM), 4) - -/* THis is the amount to subtract from u.u_ar0 - to get the offset in the core file of the register values. */ - -#define KERNEL_U_ADDR UADDR - -/* Address of end of stack space. */ - -#define STACK_END_ADDR (0x80000000 - ctob(UPAGES + 1)) - -/* 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) 0 /* Just a first guess; not checked */ - -/* Say how long registers are. */ - -#define REGISTER_TYPE long - -/* Number of machine registers */ - -#define NUM_REGS 29 - -/* Initializer for an array of names of registers. - There should be NUM_REGS strings in this initializer. */ - -#define REGISTER_NAMES \ - {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", \ - "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp", \ - "pc", "ps", \ - "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7", \ - "fpcontrol", "fpstatus", "fpiaddr" } - -/* Register numbers of various important registers. - Note that some of these values are "real" register numbers, - and correspond to the general registers of the machine, - and some are "phony" register numbers which are too large - to be actual register numbers as far as the user is concerned - but do serve to get the desired values when passed to read_register. */ - -#define FP_REGNUM 14 /* Contains address of executing stack frame */ -#define SP_REGNUM 15 /* Contains address of top of stack */ -#define PC_REGNUM 16 /* Contains program counter */ -#define PS_REGNUM 17 /* Contains processor status */ -#define FP0_REGNUM 18 /* Floating point register 0 */ -#define FPC_REGNUM 26 /* 68881 control register */ - -#define REGISTER_U_ADDR(addr, blockend, regno) \ -{ if (regno <= FP_REGNUM) \ - addr = blockend + 4 + regno * 4; \ - else if (regno == SP_REGNUM) \ - addr = blockend - 4 * 4; \ - else if (regno <= PS_REGNUM) \ - addr = blockend + (regno - PS_REGNUM) * 4; \ - else if (regno < FPC_REGNUM) \ - addr = blockend + 4 + 4 * 14 + 4 * 5 + (regno - FP0_REGNUM) * 12; \ - else \ - addr = blockend + 4 + 4 * 16 + (regno - FPC_REGNUM) * 4; \ -} - -/* Total amount of space needed to store our copies of the machine's - register state, the array `registers'. */ -#define REGISTER_BYTES (16*4+8*12+8+12) - -/* Index within `registers' of the first byte of the space for - register N. */ - -#define REGISTER_BYTE(N) \ - ((N) >= FPC_REGNUM ? (((N) - FPC_REGNUM) * 4) + 168 \ - : (N) >= FP0_REGNUM ? (((N) - FP0_REGNUM) * 12) + 72 \ - : (N) * 4) - -/* Number of bytes of storage in the actual machine representation - for register N. On the 68000, all regs are 4 bytes - except the floating point regs which are 12 bytes. */ - -#define REGISTER_RAW_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 12 : 4) - -/* Number of bytes of storage in the program's representation - for register N. On the 68000, all regs are 4 bytes - except the floating point regs which are 8-byte doubles. */ - -#define REGISTER_VIRTUAL_SIZE(N) (((unsigned)(N) - FP0_REGNUM) < 8 ? 8 : 4) - -/* Largest value REGISTER_RAW_SIZE can have. */ - -#define MAX_REGISTER_RAW_SIZE 12 - -/* Largest value REGISTER_VIRTUAL_SIZE can have. */ - -#define MAX_REGISTER_VIRTUAL_SIZE 8 - -/* Nonzero if register N requires conversion - from raw format to virtual format. */ - -#define REGISTER_CONVERTIBLE(N) (((unsigned)(N) - FP0_REGNUM) < 8) - -/* Convert data from raw format for register REGNUM - to virtual format for register REGNUM. */ - -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \ -{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \ - convert_from_68881 ((FROM), (TO)); \ - else \ - bcopy ((FROM), (TO), 4); } - -/* Convert data from virtual format for register REGNUM - to raw format for register REGNUM. */ - -#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \ -{ if ((REGNUM) >= FP0_REGNUM && (REGNUM) < FPC_REGNUM) \ - convert_to_68881 ((FROM), (TO)); \ - else \ - bcopy ((FROM), (TO), 4); } - -/* Return the GDB type object for the "standard" data type - of data in register N. */ - -#define REGISTER_VIRTUAL_TYPE(N) \ - (((unsigned)(N) - FP0_REGNUM) < 8 ? builtin_type_double : builtin_type_int) - -/* 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 NEWS, 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) - -/* Return number of args passed to a frame. - Can return -1, meaning no way to tell. */ - -#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; } - -/* 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; \ - register int insn; \ - register int offset; \ - 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, \ - or a branch followed by a link a6 instruction; \ - if not we lose. If we win, find the address above the saved \ - regs using the amount of storage from the link instruction. */\ -retry: \ - insn = read_memory_integer (pc, 2); \ - if (insn == 044016) \ - next_addr = (frame_info).frame - read_memory_integer (pc += 2, 4), pc+=4; \ - else if (insn == 047126) \ - next_addr = (frame_info).frame - read_memory_integer (pc += 2, 2), pc+=2; \ - else if ((insn & 0177400) == 060000) /* bra insn */ \ - { offset = insn & 0377; \ - pc += 2; /* advance past bra */ \ - if (offset == 0) /* bra #word */ \ - offset = read_memory_integer (pc, 2), pc += 2; \ - else if (offset == 0377) /* bra #long */ \ - offset = read_memory_integer (pc, 4), pc += 4; \ - pc += offset; \ - goto retry; \ - } 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) */ \ - insn = read_memory_integer (pc, 2), pc += 2; \ - regmask = read_memory_integer (pc, 2); \ - if ((insn & 0177760) == 022700) /* movl rn, (sp) */ \ - (frame_saved_regs).regs[(insn&7) + ((insn&010)?8:0)] = next_addr; \ - else if ((insn & 0177760) == 024700) /* movl rn, -(sp) */ \ - (frame_saved_regs).regs[(insn&7) + ((insn&010)?8:0)] = next_addr-=4; \ - else if (insn == 0044327) /* moveml mask, (sp) */ \ - { pc += 2; \ - /* Regmask's low bit is for register 0, the first written */ \ - next_addr -= 4; \ - for (regnum = 0; regnum < 16; regnum++, regmask >>= 1) \ - if (regmask & 1) \ - (frame_saved_regs).regs[regnum] = (next_addr += 4); \ - } else if (insn == 0044347) /* moveml mask, -(sp) */ \ - { pc += 2; \ - /* 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); } \ - /* clrw -(sp); movw ccr,-(sp) may follow. */ \ - if (read_memory_integer (pc, 2) == 041147 \ - && read_memory_integer (pc+2, 2) == 042347) \ - (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 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); \ -} - -/* This sequence of words is the instructions - fmove.m #<f0-f7>,-(sp) - movem.l 0xfffc,-(sp) - clr.w -(sp) - move.w 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. *../ - jbsr (#32323232) - add.l #69696969,sp - bpt - nop -Note this is 24 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. */ - -#ifdef MOTOROLA -#define INIT_STACK(beg, end) \ -{ asm (".globl end"); \ - asm ("move.l $ end, sp"); \ - asm ("clr.l fp"); } -#else -#define INIT_STACK(beg, end) \ -{ asm (".globl end"); \ - asm ("movel $ end, sp"); \ - asm ("clrl fp"); } -#endif - -/* Push the frame pointer register on the stack. */ -#ifdef MOTOROLA -#define PUSH_FRAME_PTR \ - asm ("move.l fp, -(sp)"); -#else -#define PUSH_FRAME_PTR \ - asm ("movel fp, -(sp)"); -#endif - -/* Copy the top-of-stack to the frame pointer register. */ -#ifdef MOTOROLA -#define POP_FRAME_PTR \ - asm ("move.l (sp), fp"); -#else -#define POP_FRAME_PTR \ - asm ("movl (sp), fp"); -#endif - -/* 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. */ - -#ifdef MOTOROLA -#define PUSH_REGISTERS \ -{ asm ("clr.w -(sp)"); \ - asm ("pea (10,sp)"); \ - asm ("movem $ 0xfffe,-(sp)"); } -#else -#define PUSH_REGISTERS \ -{ asm ("clrw -(sp)"); \ - asm ("pea 10(sp)"); \ - asm ("movem $ 0xfffe,-(sp)"); } -#endif - -/* 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. */ - -#ifdef MOTOROLA -#define POP_REGISTERS \ -{ asm ("subi.l $8,28(sp)"); \ - asm ("movem (sp),$ 0xffff"); \ - asm ("rte"); } -#else -#define POP_REGISTERS \ -{ asm ("subil $8,28(sp)"); \ - asm ("movem (sp),$ 0xffff"); \ - asm ("rte"); } -#endif - diff --git a/gdb/m-newsinit.h b/gdb/m-newsinit.h deleted file mode 100644 index d902edf..0000000 --- a/gdb/m-newsinit.h +++ /dev/null @@ -1,4 +0,0 @@ -/* This is how the size of an individual .o file's text segment - is rounded on a SONY NEWS. */ - -#define FILEADDR_ROUND(addr) ((addr + 3) & -4) diff --git a/gdb/m-sun3.h b/gdb/m-sun3.h index 9d703aa..61b67cd 100644 --- a/gdb/m-sun3.h +++ b/gdb/m-sun3.h @@ -400,7 +400,7 @@ read_memory_integer (read_register (SP_REGNUM), 4) the following jsr instruction. *../ jsr @#32323232 addl #69696969,sp - bpt + trap #15 nop Note this is 28 bytes. We actually start executing at the jsr, since the pushing of the diff --git a/gdb/m-suninit.h b/gdb/m-suninit.h index 2e2f08c..5f71ea1 100644 --- a/gdb/m-suninit.h +++ b/gdb/m-suninit.h @@ -2,4 +2,4 @@ /* This is how the size of an individual .o file's text segment is rounded on a sun. */ -#define FILEADDR_ROUND(addr) (addr) +#define FILEADDR_ROUND(addr) ((addr + 3) & -4) diff --git a/gdb/m-umax.h b/gdb/m-umax.h deleted file mode 100644 index d894b56..0000000 --- a/gdb/m-umax.h +++ /dev/null @@ -1,425 +0,0 @@ -/* Definitions to make GDB run on an encore under umax 4.2 - 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! -*/ - -#ifndef ns16000 -#define ns16000 -#endif - -#define HAVE_WAIT_STRUCT - -/* Encore's modifications to ptrace format */ - -#define UMAX_PTRACE - -/* Encore's modifications to core-file format */ - -#define UMAX_CORE - -/* Define this if the C compiler puts an underscore at the front - of external names before giving them to the linker. */ - -#define NAMES_HAVE_UNDERSCORE - -/* Exec files and symbol tables are in COFF format */ - -#define COFF_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 unsigned char op = read_memory_integer (pc, 1); \ - if (op == 0x82) { op = read_memory_integer (pc+2,1); \ - if ((op & 0x80) == 0) pc += 3; \ - else if ((op & 0xc0) == 0x80) pc += 4; \ - else pc += 6; \ - } \ -} - -/* Immediately after a function call, return the saved pc. - Can't always go through the frames for this because on some machines - the new frame is not set up until the new function executes - some instructions. */ - -#define SAVED_PC_AFTER_CALL(frame) \ - read_memory_integer (read_register (SP_REGNUM), 4) - -/* Address of end of stack space. */ - -#define STACK_END_ADDR (0xfffff000) - -/* Stack grows downward. */ - -#define INNER_THAN < - -/* Sequence of bytes for breakpoint instruction. */ - -#define BREAKPOINT {0xf2} - -/* Amount PC must be decremented by after a breakpoint. - This is often the number of bytes in BREAKPOINT - but not always. */ - -#define DECR_PC_AFTER_BREAK 0 - -/* Nonzero if instruction at PC is a return instruction. */ - -#define ABOUT_TO_RETURN(pc) (read_memory_integer (pc, 1) == 0x12) - -#ifndef NaN -#include <nan.h> -#endif NaN - -/* Return 1 if P points to an invalid floating point value. */ - -#define INVALID_FLOAT(p, s) \ - ((s == sizeof (float))? \ - NaF (*(float *) p) : \ - NaD (*(double *) p)) - -/* Say how long (ordinary) registers are. */ - -#define REGISTER_TYPE long - -/* Number of machine registers */ - -#define NUM_REGS 25 - -#define NUM_GENERAL_REGS 8 - -/* Initializer for an array of names of registers. - There should be NUM_REGS strings in this initializer. */ - -#define REGISTER_NAMES {"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", \ - "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", \ - "sp", "fp", "pc", "ps", \ - "fsr", \ - "l0", "l1", "l2", "l3", "xx", \ - } - -/* 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 FP0_REGNUM 8 /* Floating point register 0 */ -#define SP_REGNUM 16 /* Contains address of top of stack */ -#define AP_REGNUM FP_REGNUM -#define FP_REGNUM 17 /* Contains address of executing stack frame */ -#define PC_REGNUM 18 /* Contains program counter */ -#define PS_REGNUM 19 /* Contains processor status */ -#define FPS_REGNUM 20 /* Floating point status register */ -#define LP0_REGNUM 21 /* Double register 0 (same as FP0) */ - -/* called from register_addr() -- blockend not used for now */ -#define REGISTER_U_ADDR(addr, blockend, regno) \ -{ \ - switch (regno) { \ - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: \ - addr = PU_R0 - (regno * sizeof (int)); break; \ - case SP_REGNUM: \ - addr = PU_SP; break; \ - case PC_REGNUM: \ - addr = PU_PC; break; \ - case FP_REGNUM: \ - addr = PU_FP; break; \ - case PS_REGNUM: \ - addr = PU_PSL; break; \ - case FPS_REGNUM: \ - addr = PU_FSR; break; \ - case FP0_REGNUM + 0: case FP0_REGNUM + 1: \ - case FP0_REGNUM + 2: case FP0_REGNUM + 3: \ - case FP0_REGNUM + 4: case FP0_REGNUM + 5: \ - case FP0_REGNUM + 6: case FP0_REGNUM + 7: \ - addr = PU_F0 + (regno - FP0_REGNUM) * sizeof (float); break; \ - case LP0_REGNUM + 0: case LP0_REGNUM + 1: \ - case LP0_REGNUM + 2: case LP0_REGNUM + 3: \ - addr = PU_F0 + (regno - LP0_REGNUM) * sizeof (double); break; \ - default: \ - printf ("bad argument to REGISTER_U_ADDR %d\n", regno); \ - abort (); \ - } \ -} - -/* Total amount of space needed to store our copies of the machine's - register state, the array `registers'. */ -#define REGISTER_BYTES ((NUM_REGS - 4) * sizeof (int) + 4 * sizeof (double)) - -/* Index within `registers' of the first byte of the space for - register N. */ - -#define REGISTER_BYTE(N) ((N) >= LP0_REGNUM ? \ - LP0_REGNUM * 4 + ((N) - LP0_REGNUM) * 8 : (N) * 4) - -/* Number of bytes of storage in the actual machine representation - for register N. On the 32000, all regs are 4 bytes - except for the doubled floating registers. */ - -#define REGISTER_RAW_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4) - -/* Number of bytes of storage in the program's representation - for register N. On the 32000, all regs are 4 bytes - except for the doubled floating registers. */ - -#define REGISTER_VIRTUAL_SIZE(N) ((N) >= LP0_REGNUM ? 8 : 4) - -/* Largest value REGISTER_RAW_SIZE can have. */ - -#define MAX_REGISTER_RAW_SIZE 8 - -/* Largest value REGISTER_VIRTUAL_SIZE can have. */ - -#define MAX_REGISTER_VIRTUAL_SIZE 8 - -/* Nonzero if register N requires conversion - from raw format to virtual format. */ - -#define REGISTER_CONVERTIBLE(N) 0 - -/* Convert data from raw format for register REGNUM - to virtual format for register REGNUM. */ - -#define REGISTER_CONVERT_TO_VIRTUAL(REGNUM,FROM,TO) \ - bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM)); - -/* Convert data from virtual format for register REGNUM - to raw format for register REGNUM. */ - -#define REGISTER_CONVERT_TO_RAW(REGNUM,FROM,TO) \ - bcopy ((FROM), (TO), REGISTER_VIRTUAL_SIZE(REGNUM)); - -/* Return the GDB type object for the "standard" data type - of data in register N. */ - -#define REGISTER_VIRTUAL_TYPE(N) \ - (((N) < FP0_REGNUM) ? \ - builtin_type_int : \ - ((N) < FP0_REGNUM + 8) ? \ - builtin_type_float : \ - ((N) < LP0_REGNUM) ? \ - builtin_type_int : \ - builtin_type_double) - -/* 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+REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 0), 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 (REGISTER_BYTE (TYPE_CODE (TYPE) == TYPE_CODE_FLT ? FP0_REGNUM : 0), VALBUF, TYPE_LENGTH (TYPE)) - -/* Extract from an array REGBUF containing the (raw) register state - the address in which a function should return its structure value, - as a CORE_ADDR (or an expression that can be used as one). */ - -#define EXTRACT_STRUCT_VALUE_ADDRESS(REGBUF) (*(int *)(REGBUF)) - -/* Describe the pointer in each stack frame to the previous stack frame - (its caller). */ - -/* FRAME_CHAIN takes a frame's nominal address - and produces the frame's chain-pointer. - - FRAME_CHAIN_COMBINE takes the chain pointer and the frame's nominal address - and produces the nominal address of the caller frame. - - However, if FRAME_CHAIN_VALID returns zero, - it means the given frame is the outermost one and has no caller. - In that case, FRAME_CHAIN_COMBINE is not used. */ - -/* In the case of the ns32000 series, the frame's nominal address is the FP - value, and at that address is saved previous FP value as a 4-byte word. */ - -#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)) - -/* Compute base of arguments. */ - -#define FRAME_ARGS_ADDRESS(fi) \ - ((n32k_get_enter_addr (fi.pc) > 1) ? \ - ((fi).frame) : (read_register (SP_REGNUM) - 4)) - -#define FRAME_LOCALS_ADDRESS(fi) ((fi).frame) - -/* Get the address of the enter opcode for this function, if it is active. - Returns positive address > 1 if pc is between enter/exit, - 1 if pc before enter or after exit, 0 otherwise. */ - -extern CORE_ADDR n32k_get_enter_addr (); - -/* Return number of args passed to a frame. - Can return -1, meaning no way to tell. - Encore's C compiler often reuses same area on stack for args, - so this will often not work properly. If the arg names - are known, it's likely most of them will be printed. */ - -#define FRAME_NUM_ARGS(numargs, fi) \ -{ CORE_ADDR pc; \ - CORE_ADDR enter_addr; \ - unsigned int insn; \ - unsigned int addr_mode; \ - int width; \ - \ - numargs = -1; \ - enter_addr = n32k_get_enter_addr (fi.pc); \ - if (enter_addr > 0) \ - { \ - pc = (enter_addr == 1) ? \ - SAVED_PC_AFTER_CALL () : \ - FRAME_SAVED_PC (fi.frame); \ - insn = read_memory_integer (pc,2); \ - addr_mode = (insn >> 11) & 0x1f; \ - insn = insn & 0x7ff; \ - if ((insn & 0x7fc) == 0x57c && \ - addr_mode == 0x14) /* immediate */ \ - { \ - if (insn == 0x57c) /* adjspb */ \ - width = 1; \ - else if (insn == 0x57d) /* adjspw */ \ - width = 2; \ - else if (insn == 0x57f) /* adjspd */ \ - width = 4; \ - numargs = read_memory_integer (pc+2,width); \ - if (width > 1) \ - flip_bytes (&numargs, width); \ - numargs = - sign_extend (numargs, width*8) / 4;\ - } \ - } \ -} - -/* 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 regmask, regnum; \ - int localcount; \ - register CORE_ADDR enter_addr; \ - register CORE_ADDR next_addr; \ - \ - bzero (&(frame_saved_regs), sizeof (frame_saved_regs)); \ - enter_addr = n32k_get_enter_addr ((frame_info).pc); \ - if (enter_addr > 1) \ - { \ - regmask = read_memory_integer (enter_addr+1, 1) & 0xff; \ - localcount = n32k_localcount (enter_addr); \ - next_addr = (frame_info).frame + localcount; \ - for (regnum = 0; regnum < 8; regnum++, regmask >>= 1) \ - (frame_saved_regs).regs[regnum] = (regmask & 1) ? \ - (next_addr -= 4) : 0; \ - (frame_saved_regs).regs[SP_REGNUM] = (frame_info).frame + 4;\ - (frame_saved_regs).regs[PC_REGNUM] = (frame_info).frame + 4;\ - (frame_saved_regs).regs[FP_REGNUM] = \ - (read_memory_integer ((frame_info).frame, 4));\ - } \ - else if (enter_addr == 1) \ - { \ - CORE_ADDR sp = read_register (SP_REGNUM); \ - (frame_saved_regs).regs[PC_REGNUM] = sp; \ - (frame_saved_regs).regs[SP_REGNUM] = sp + 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; \ - sp = push_word (sp, read_register (PC_REGNUM)); \ - sp = push_word (sp, read_register (FP_REGNUM)); \ - write_register (FP_REGNUM, sp); \ - for (regnum = 0; regnum < 8; regnum++) \ - sp = push_word (sp, read_register (regnum)); \ - write_register (SP_REGNUM, sp); \ -} - -/* Discard from the stack the innermost frame, restoring all registers. */ - -#define POP_FRAME \ -{ register CORE_ADDR fp = read_register (FP_REGNUM); \ - register int regnum; \ - struct frame_saved_regs fsr; \ - struct frame_info fi; \ - fi = get_frame_info (fp); \ - get_frame_saved_regs (&fi, &fsr); \ - for (regnum = 0; regnum < 8; regnum++) \ - if (fsr.regs[regnum]) \ - write_register (regnum, read_memory_integer (fsr.regs[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); \ -} - -/* This sequence of words is the instructions - enter 0xff,0 82 ff 00 - jsr @0x00010203 7f ae c0 01 02 03 - adjspd 0x69696969 7f a5 01 02 03 04 - bpt f2 - Note this is 16 bytes. */ - -#define CALL_DUMMY { 0x7f00ff82, 0x0201c0ae, 0x01a57f03, 0xf2040302 } - -#define CALL_DUMMY_START_OFFSET 3 -#define CALL_DUMMY_LENGTH 16 -#define CALL_DUMMY_ADDR 5 -#define CALL_DUMMY_NARGS 11 - -/* 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 flipped; \ - flipped = fun | 0xc0000000; \ - flip_bytes (&flipped, 4); \ - *((int *) (((char *) dummyname)+CALL_DUMMY_ADDR)) = flipped; \ - flipped = - nargs * 4; \ - flip_bytes (&flipped, 4); \ - *((int *) (((char *) dummyname)+CALL_DUMMY_NARGS)) = flipped; \ -} diff --git a/gdb/m68k-pinsn.c b/gdb/m68k-pinsn.c index a22a36a..5b59ee1 100644 --- a/gdb/m68k-pinsn.c +++ b/gdb/m68k-pinsn.c @@ -345,7 +345,7 @@ print_insn_arg (d, buffer, p, addr, stream) case 'd': val = NEXTWORD (p); - fprintf (stream, "%d(%s)", val, fetch_arg (buffer, place, 3)); + fprintf (stream, "%d(%s)", val, reg_names[fetch_arg (buffer, place, 3)]); break; case 's': @@ -710,20 +710,6 @@ print_base (regno, disp, stream) 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; @@ -736,14 +722,12 @@ convert_from_68881 (from, to) #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); + asm (".word 020156"); + asm (".word 8"); + asm (".word 021156"); + asm (".word 12"); + asm (".long 0xf2104800"); + asm (".long 0xf2117400"); #endif } @@ -761,13 +745,11 @@ convert_to_68881 (from, to) 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); + asm (".word 020156"); + asm (".word 8"); + asm (".word 021156"); + asm (".word 12"); + asm (".long 0xf2105400"); + asm (".long 0xf2116800"); #endif } @@ -18,7 +18,6 @@ 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> @@ -49,6 +48,13 @@ struct cmd_list_element *infolist; FILE *instream; +/* Current working directory. */ + +char *current_directory; + +/* The directory name is actually stored here. */ +static char dirbuf[MAXPATHLEN]; + /* Nonzero if we should refrain from using an X window. */ int inhibit_windows = 0; @@ -59,6 +65,8 @@ int inhibit_windows = 0; void (*window_hook) (); +extern int frame_file_full_name; + void free_command_lines (); char *read_line (); static void initialize_main (); @@ -106,6 +114,9 @@ main (argc, argv, envp) line = (char *) xmalloc (linesize); instream = stdin; + getwd (dirbuf); + current_directory = dirbuf; + #ifdef SET_STACK_LIMIT_HUGE { struct rlimit rlim; @@ -118,6 +129,8 @@ main (argc, argv, envp) } #endif /* SET_STACK_LIMIT_HUGE */ + /* Run the init function of each source file */ + /* Look for flag arguments. */ for (i = 1; i < argc; i++) @@ -128,6 +141,8 @@ main (argc, argv, envp) inhibit_gdbinit = 1; else if (!strcmp (argv[i], "-nw")) inhibit_windows = 1; + else if (!strcmp (argv[i], "-fullname")) + frame_file_full_name = 1; else if (!strcmp (argv[i], "-batch")) batch = 1, quiet = 1; else if (argv[i][0] == '-') @@ -160,7 +175,8 @@ main (argc, argv, envp) extern void tty_command (); if (!strcmp (arg, "-q") || !strcmp (arg, "-nx") - || !strcmp (arg, "quiet") || !strcmp (arg, "-batch")) + || !strcmp (arg, "-quiet") || !strcmp (arg, "-batch") + || !strcmp (arg, "-fullname")) /* Already processed above */ continue; @@ -369,6 +385,10 @@ read_line (repeat) c = fgetc (instream); if (c == -1 || c == '\n') break; + else if (c == '\\') + if ((c = fgetc (instream)) == '\n') + continue; + else ungetc (c, instream); if (p - line == linesize - 1) { linesize *= 2; @@ -378,7 +398,6 @@ read_line (repeat) } *p++ = c; } - signal (SIGTSTP, SIG_DFL); immediate_quit--; @@ -649,10 +668,12 @@ copying_info () { immediate_quit++; printf (" GDB GENERAL PUBLIC LICENSE\n\ +\n (Clarified 11 Feb 1988)\ \n\ - Copyright (C) 1986 Richard M. Stallman\n\ + Copyright (C) 1988 Richard M. Stallman\n\ Everyone is permitted to copy and distribute verbatim copies\n\ of this license, but changing it is not allowed.\n\ + You can also use this wording to make the terms for other programs.\n\ \n\ The license agreements of most software companies keep you at the\n\ mercy of those companies. By contrast, our general public license is\n\ @@ -695,8 +716,8 @@ allowed to distribute or change GDB.\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\ +\(C) 1988 Free Software Foundation, Inc.\" (or with whatever year is\n\ +appropriate); keep intact the notices on all files that refer\n\ to this License Agreement and to the absence of any warranty; and give\n\ any other recipients of the GDB program a copy of this License\n\ Agreement along with the program. You may charge a distribution fee\n\ @@ -717,48 +738,55 @@ Paragraph 1 above, provided that you also do the following:\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\ + you may choose to grant more extensive warranty protection to some\n\ + or all third parties, at your option).\n\ \n"); printf ("\ c) if the modified program serves as a debugger, cause it\n\ when started running in the simplest and usual way, to print\n\ an announcement including a valid copyright notice\n\ - \"Copyright (C) 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\ + \"Copyright (C) 1988 Free Software Foundation, Inc.\" (or with\n\ + the year that is appropriate), saying that there is no warranty\n\ + (or else, saying that you provide a warranty) and that users may\n\ + redistribute the program under these conditions, and telling the user\n\ + how to view a copy of this License Agreement.\n\ \n\ d) You may charge a distribution fee for the physical act of\n\ transferring a copy, and you may at your option offer warranty\n\ protection in exchange for a fee.\n\ +\n\ +Mere aggregation of another unrelated program with this program (or its\n\ +derivative) on a volume of a storage or distribution medium does not bring\n\ +the other program under the scope of these terms.\n\ --Type Return to print more--"); fflush (stdout); 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\ + 3. You may copy and distribute GDB (or a portion or derivative of it,\n\ +under Paragraph 2) in object code or executable form under the terms of\n\ +Paragraphs 1 and 2 above provided that you also do one of the following:\n\ \n\ - a) 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\ + a) accompany it with the complete corresponding machine-readable\n\ + source code, which must be distributed under the terms of\n\ + Paragraphs 1 and 2 above; or,\n\ \n\ - b) 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"); + b) accompany it with a written offer, valid for at least three\n\ + years, to give any third party free (except for a nominal\n\ + shipping charge) a complete machine-readable copy of the\n\ + corresponding source code, to be distributed under the terms of\n\ + Paragraphs 1 and 2 above; or,\n\n"); printf ("\ - c) 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\ + c) accompany it with the information you received as to where the\n\ + corresponding source code may be obtained. (This alternative is\n\ + allowed only for noncommercial distribution and only if you\n\ + received the program in object code or executable form alone.)\n\ +\n\ +For an executable file, complete source code means all the source code for\n\ +all modules it contains; but, as a special exception, it need not include\n\ +source code for modules which are standard libraries that accompany the\n\ +operating system on which the executable file runs.\n\ --Type Return to print more--"); fflush (stdout); read_line (); @@ -819,7 +847,7 @@ ANY CLAIM BY ANY OTHER PARTY.\n"); static void print_gdb_version () { - printf ("GDB %s, Copyright (C) 1987 Free Software Foundation, Inc.\n\ + printf ("GDB %s, Copyright (C) 1988 Free Software Foundation, Inc.\n\ There is ABSOLUTELY NO WARRANTY for GDB; type \"info warranty\" for details.\n\ GDB is free software and you are welcome to distribute copies of it\n\ under certain conditions; type \"info copying\" to see the conditions.\n", @@ -901,9 +929,8 @@ 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)); + printf ("Working directory %s.\n", dirbuf); } static void @@ -916,6 +943,7 @@ cd_command (dir, from_tty) if (chdir (dir) < 0) perror_with_name (dir); + getwd (dirbuf); if (from_tty) pwd_command ((char *) 0, 1); } @@ -996,7 +1024,7 @@ dump_me_command () static void initialize_main () { - prompt = savestring ("(gdb) ", 6); + prompt = savestring ("(gdb+) ", 7); /* Define the classes of commands. They will appear in the help list in the reverse of this order. */ diff --git a/gdb/ns32k-opcode.h b/gdb/ns32k-opcode.h deleted file mode 100644 index 2d5ff30..0000000 --- a/gdb/ns32k-opcode.h +++ /dev/null @@ -1,307 +0,0 @@ -/* ns32k-opcode.h */ - -#ifndef ns32k_opcodeT -#define ns32k_opcodeT int -#endif /* no ns32k_opcodeT */ - -struct not_wot /* ns32k opcode table: wot to do with this */ - /* particular opcode */ -{ - int obits; /* number of opcode bits */ - int ibits; /* number of instruction bits */ - ns32k_opcodeT code; /* op-code (may be > 8 bits!) */ - char *args; /* how to compile said opcode */ -}; - -struct not /* ns32k opcode text */ -{ - char * name; /* opcode name: lowercase string [key] */ - struct not_wot detail; /* rest of opcode table [datum] */ -}; - -/* F : 32 bit float - * L : 64 bit float - * B : byte - * W : word - * D : double-word - * Q : quad-word - * d : displacement - * q : quick - * i : immediate (8 bits) - * r : register number (3 bits) - * p : displacement - pc relative addressing -*/ -static struct not -notstrs[] = -{ - { "absf", 14,24, 0x35be, "1F2F" }, - { "absl", 14,24, 0x34be, "1L2L" }, - { "absb", 14,24, 0x304e, "1B2B" }, - { "absw", 14,24, 0x314e, "1W2W" }, - { "absd", 14,24, 0x334e, "1D2D" }, - { "acbb", 7,16, 0x4c, "2B1q3p" }, - { "addf", 14,24, 0x01be, "1F2F" }, - { "addl", 14,24, 0x00be, "1L2L" }, - { "addb", 6,16, 0x00, "1B2B" }, - { "addw", 6,16, 0x01, "1W2W" }, - { "addd", 6,16, 0x03, "1D2D" }, - { "addcb", 6,16, 0x10, "1B2B" }, - { "addcw", 6,16, 0x11, "1W2W" }, - { "addcd", 6,16, 0x13, "1D2D" }, - { "addpb", 14,24, 0x3c4e, "1B2B" }, - { "addpw", 14,24, 0x3d4e, "1W2W" }, - { "addpd", 14,24, 0x3f4e, "1D2D" }, - { "addqb", 7,16, 0x0c, "2B1q" }, - { "addqw", 7,16, 0x0d, "2W1q" }, - { "addqd", 7,16, 0x0f, "2D1q" }, - { "addr", 6,16, 0x27, "1D2D" }, - { "adjspb", 11,16, 0x057c, "1B" }, - { "adjspw", 11,16, 0x057d, "1W" }, - { "adjspd", 11,16, 0x057f, "1D" }, - { "andb", 6,16, 0x28, "1B2B" }, - { "andw", 6,16, 0x29, "1W2W" }, - { "andd", 6,16, 0x2b, "1D2D" }, - { "ashb", 14,24, 0x044e, "1B2B" }, - { "ashw", 14,24, 0x054e, "1B2W" }, - { "ashd", 14,24, 0x074e, "1B2D" }, - { "beq", 8,8, 0x0a, "1p" }, - { "bne", 8,8, 0x1a, "1p" }, - { "bcs", 8,8, 0x2a, "1p" }, - { "bcc", 8,8, 0x3a, "1p" }, - { "bhi", 8,8, 0x4a, "1p" }, - { "bls", 8,8, 0x5a, "1p" }, - { "bgt", 8,8, 0x6a, "1p" }, - { "ble", 8,8, 0x7a, "1p" }, - { "bfs", 8,8, 0x8a, "1p" }, - { "bfc", 8,8, 0x9a, "1p" }, - { "blo", 8,8, 0xaa, "1p" }, - { "bhs", 8,8, 0xba, "1p" }, - { "blt", 8,8, 0xca, "1p" }, - { "bge", 8,8, 0xda, "1p" }, - { "bicb", 6,16, 0x08, "1B2B" }, - { "bicw", 6,16, 0x09, "1W2W" }, - { "bicd", 6,16, 0x0b, "1D2D" }, - { "bicpsrb", 11,16, 0x17c, "1B" }, - { "bicpsrw", 11,16, 0x17d, "1W" }, - { "bispsrb", 11,16, 0x37c, "1B" }, - { "bispsrw", 11,16, 0x37d, "1W" }, - { "bpt", 8,8, 0xf2, "" }, - { "br", 8,8, 0xea, "1p" }, - { "bsr", 8,8, 0x02, "1p" }, - { "caseb", 11,16, 0x77c, "1B" }, - { "casew", 11,16, 0x77d, "1W" }, - { "cased", 11,16, 0x77f, "1D" }, - { "cbitb", 14,24, 0x084e, "1B2D" }, - { "cbitw", 14,24, 0x094e, "1W2D" }, - { "cbitd", 14,24, 0x0b4e, "1D2D" }, - { "cbitib", 14,24, 0x0c4e, "1B2D" }, - { "cbitiw", 14,24, 0x0d4e, "1W2D" }, - { "cbitid", 14,24, 0x0f4e, "1D2D" }, - { "checkb", 11,24, 0x0ee, "2A3B1r" }, - { "checkw", 11,24, 0x1ee, "2A3B1r" }, - { "checkd", 11,24, 0x3ee, "2A3D1r" }, - { "cmpf", 14,24, 0x09be, "1F2F" }, - { "cmpl", 14,24, 0x08be, "1L2L" }, - { "cmpb", 6,16, 0x04, "1B2B" }, - { "cmpw", 6,16, 0x05, "1W2W" }, - { "cmpd", 6,16, 0x07, "1D2D" }, - { "cmpmb", 14,24, 0x04ce, "1D2D3d" }, - { "cmpmw", 14,24, 0x05ce, "1D2D3d" }, - { "cmpmd", 14,24, 0x07ce, "1D2D3d" }, - { "cmpqb", 7,16, 0x1c, "2B1q" }, - { "cmpqw", 7,16, 0x1d, "2W1q" }, - { "cmpqd", 7,16, 0x1f, "2D1q" }, - { "cmpsb", 16,16, 0x040e, "1i" }, - { "cmpsw", 16,16, 0x050e, "1i" }, - { "cmpsd", 16,16, 0x070e, "1i" }, - { "cmpst", 16,16, 0x840e, "1i" }, - { "comb", 14,24, 0x344e, "1B2B" }, - { "comw", 14,24, 0x354e, "1W2W" }, - { "comd", 14,24, 0x374e, "1D2D" }, - { "cvtp", 11,24, 0x036e, "2D3D1r" }, - { "cxp", 8,8, 0x22, "1p" }, - { "cxpd", 11,16, 0x07f, "1D" }, - { "deib", 14,24, 0x2cce, "1B2W" }, - { "deiw", 14,24, 0x2cce, "1W2D" }, - { "deid", 14,24, 0x2cce, "1D2Q" }, - { "dia", 8,8, 0xc2, "" }, - { "divf", 14,24, 0x21be, "1F2F" }, - { "divl", 14,24, 0x20be, "1L2L" }, - { "divb", 14,24, 0x3cce, "1B2B" }, - { "divw", 14,24, 0x3dce, "1W2W" }, - { "divd", 14,24, 0x3fce, "1D2D" }, - { "enter", 8,8, 0x82, "1i2d" }, - { "exit", 8,8, 0x92, "1i" }, - { "extb", 11,24, 0x02e, "2D3B1r4d" }, - { "extw", 11,24, 0x12e, "2D3W1r4d" }, - { "extd", 11,24, 0x32e, "2D3D1r4d" }, - { "extsb", 14,24, 0x0cce, "1D2B3i" }, - { "extsw", 14,24, 0x0dce, "1D2W3i" }, - { "extsd", 14,24, 0x0fce, "1D2D3i" }, - { "ffsb", 14,24, 0x046e, "1B2B" }, - { "ffsw", 14,24, 0x056e, "1W2B" }, - { "ffsd", 14,24, 0x076e, "1D2B" }, - { "flag", 8,8, 0xd2, "" }, - { "floorfb", 14,24, 0x3c3e, "1F2B" }, - { "floorfw", 14,24, 0x3d3e, "1F2W" }, - { "floorfd", 14,24, 0x3f3e, "1F2D" }, - { "floorlb", 14,24, 0x383e, "1L2B" }, - { "floorlw", 14,24, 0x393e, "1L2W" }, - { "floorld", 14,24, 0x3b3e, "1L2D" }, - { "ibitb", 14,24, 0x384e, "1B2D" }, - { "ibitw", 14,24, 0x394e, "1W2D" }, - { "ibitd", 14,24, 0x3b4e, "1D2D" }, - { "indexb", 11,24, 0x42e, "2B3B1r" }, - { "indexw", 11,24, 0x52e, "2W3W1r" }, - { "indexd", 11,24, 0x72e, "2D3D1r" }, - { "insb", 11,24, 0x0ae, "2B3B1r4d" }, - { "insw", 11,24, 0x1ae, "2W3W1r4d" }, - { "insd", 11,24, 0x3ae, "2D3D1r4d" }, - { "inssb", 14,24, 0x08ce, "1B2D3i" }, - { "inssw", 14,24, 0x09ce, "1W2D3i" }, - { "inssd", 14,24, 0x0bce, "1D2D3i" }, - { "jsr", 11,16, 0x67f, "1A" }, - { "jump", 11,16, 0x27f, "1A" }, - { "lfsr", 19,24, 0x00f3e,"1D" }, - { "lmr", 15,24, 0x0b1e, "2D1q" }, - { "lprb", 7,16, 0x6c, "2B1q" }, - { "lprw", 7,16, 0x6d, "2W1q" }, - { "lprd", 7,16, 0x6f, "2D1q" }, - { "lshb", 14,24, 0x144e, "1B2B" }, - { "lshw", 14,24, 0x154e, "1B2W" }, - { "lshd", 14,24, 0x174e, "1B2D" }, - { "meib", 14,24, 0x24ce, "1B2W" }, - { "meiw", 14,24, 0x25ce, "1W2D" }, - { "meid", 14,24, 0x27ce, "1D2Q" }, - { "modb", 14,24, 0x38ce, "1B2B" }, - { "modw", 14,24, 0x39ce, "1W2W" }, - { "modd", 14,24, 0x3bce, "1D2D" }, - { "movf", 14,24, 0x05be, "1F2F" }, - { "movl", 14,24, 0x04be, "1L2L" }, - { "movb", 6,16, 0x14, "1B2B" }, - { "movw", 6,16, 0x15, "1W2W" }, - { "movd", 6,16, 0x17, "1D2D" }, - { "movbf", 14,24, 0x043e, "1B2F" }, - { "movwf", 14,24, 0x053e, "1W2F" }, - { "movdf", 14,24, 0x073e, "1D2F" }, - { "movbl", 14,24, 0x003e, "1B2L" }, - { "movwl", 14,24, 0x013e, "1W2L" }, - { "movdl", 14,24, 0x033e, "1D2L" }, - { "movfl", 14,24, 0x1b3e, "1F2L" }, - { "movlf", 14,24, 0x163e, "1L2F" }, - { "movmb", 14,24, 0x00ce, "1D2D3d" }, - { "movmw", 14,24, 0x00de, "1D2D3d" }, - { "movmd", 14,24, 0x00fe, "1D2D3d" }, - { "movqb", 7,16, 0x5c, "2B1q" }, - { "movqw", 7,16, 0x5d, "2B1q" }, - { "movqd", 7,16, 0x5f, "2B1q" }, - { "movsb", 16,16, 0x000e, "1i" }, - { "movsw", 16,16, 0x010e, "1i" }, - { "movsd", 16,16, 0x030e, "1i" }, - { "movst", 16,16, 0x800e, "1i" }, - { "movsub", 14,24, 0x0cae, "1A1A" }, - { "movsuw", 14,24, 0x0dae, "1A1A" }, - { "movsud", 14,24, 0x0fae, "1A1A" }, - { "movusb", 14,24, 0x1cae, "1A1A" }, - { "movusw", 14,24, 0x1dae, "1A1A" }, - { "movusd", 14,24, 0x1fae, "1A1A" }, - { "movxbd", 14,24, 0x1cce, "1B2D" }, - { "movxwd", 14,24, 0x1dce, "1W2D" }, - { "movxbw", 14,24, 0x10ce, "1B2W" }, - { "movzbd", 14,24, 0x18ce, "1B2D" }, - { "movzwd", 14,24, 0x19ce, "1W2D" }, - { "movzbw", 14,24, 0x14ce, "1B2W" }, - { "mulf", 14,24, 0x31be, "1F2F" }, - { "mull", 14,24, 0x30be, "1L2L" }, - { "mulb", 14,24, 0x20ce, "1B2B" }, - { "mulw", 14,24, 0x21ce, "1W2W" }, - { "muld", 14,24, 0x23ce, "1D2D" }, - { "negf", 14,24, 0x15be, "1F2F" }, - { "negl", 14,24, 0x14be, "1L2L" }, - { "negb", 14,24, 0x204e, "1B2B" }, - { "negw", 14,24, 0x214e, "1W2W" }, - { "negd", 14,24, 0x234e, "1D2D" }, - { "nop", 8,8, 0xa2, "" }, - { "notb", 14,24, 0x244e, "1B2B" }, - { "notw", 14,24, 0x254e, "1W2W" }, - { "notd", 14,24, 0x274e, "1D2D" }, - { "orb", 6,16, 0x18, "1B1B" }, - { "orw", 6,16, 0x19, "1W1W" }, - { "ord", 6,16, 0x1b, "1D1D" }, - { "quob", 14,24, 0x30ce, "1B2B" }, - { "quow", 14,24, 0x31ce, "1W2W" }, - { "quod", 14,24, 0x33ce, "1D2D" }, - { "rdval", 19,24, 0x0031e,"1A" }, - { "remb", 14,24, 0x34ce, "1B2B" }, - { "remw", 14,24, 0x35ce, "1W2W" }, - { "remd", 14,24, 0x37ce, "1D2D" }, - { "restore", 8,8, 0x72, "1i" }, - { "ret", 8,8, 0x12, "1d" }, - { "reti", 8,8, 0x52, "" }, - { "rett", 8,8, 0x42, "" }, - { "rotb", 14,24, 0x004e, "1B2B" }, - { "rotw", 14,24, 0x014e, "1B2W" }, - { "rotd", 14,24, 0x034e, "1B2D" }, - { "roundfb", 14,24, 0x243e, "1F2B" }, - { "roundfw", 14,24, 0x253e, "1F2W" }, - { "roundfd", 14,24, 0x273e, "1F2D" }, - { "roundlb", 14,24, 0x203e, "1L2B" }, - { "roundlw", 14,24, 0x213e, "1L2W" }, - { "roundld", 14,24, 0x233e, "1L2D" }, - { "rxp", 8,8, 0x32, "1d" }, - { "sCONDb", 7,16, 0x3c, "2B1q" }, - { "sCONDw", 7,16, 0x3d, "2D1q" }, - { "sCONDd", 7,16, 0x3f, "2D1q" }, - { "save", 8,8, 0x62, "1i" }, - { "sbitb", 14,24, 0x184e, "1B2A" }, - { "sbitw", 14,24, 0x194e, "1W2A" }, - { "sbitd", 14,24, 0x1b4e, "1D2A" }, - { "sbitib", 14,24, 0x1c4e, "1B2A" }, - { "sbitiw", 14,24, 0x1d4e, "1W2A" }, - { "sbitid", 14,24, 0x1f4e, "1D2A" }, - { "setcfg", 15,24, 0x0b0e, "5D1q" }, - { "sfsr", 14,24, 0x673e, "5D1D" }, - { "skpsb", 16,16, 0x0c0e, "1i" }, - { "skpsw", 16,16, 0x0d0e, "1i" }, - { "skpsd", 16,16, 0x0f0e, "1i" }, - { "skpst", 16,16, 0x8c0e, "1i" }, - { "smr", 15,24, 0x0f1e, "2D1q" }, - { "sprb", 7,16, 0x2c, "2B1q" }, - { "sprw", 7,16, 0x2d, "2W1q" }, - { "sprd", 7,16, 0x2f, "2D1q" }, - { "subf", 14,24, 0x11be, "1F2F" }, - { "subl", 14,24, 0x10be, "1L2L" }, - { "subb", 6,16, 0x20, "1B2B" }, - { "subw", 6,16, 0x21, "1W2W" }, - { "subd", 6,16, 0x23, "1D2D" }, - { "subcb", 6,16, 0x30, "1B2B" }, - { "subcw", 6,16, 0x31, "1W2W" }, - { "subcd", 6,16, 0x33, "1D2D" }, - { "subpb", 14,24, 0x2c4e, "1B2B" }, - { "subpw", 14,24, 0x2d4e, "1W2W" }, - { "subpd", 14,24, 0x2f4e, "1D2D" }, -#ifndef NS32K_SVC_IMMED_OPERANDS - { "svc", 8,8, 0xe2, "2i1i" }, /* not really, but unix uses it */ -#else - { "svc", 8,8, 0xe2, "" }, /* not really, but unix uses it */ -#endif - { "tbitb", 6,16, 0x34, "1B2A" }, - { "tbitw", 6,16, 0x35, "1W2A" }, - { "tbitd", 6,16, 0x37, "1D2A" }, - { "truncfb", 14,24, 0x2c3e, "1F2B" }, - { "truncfw", 14,24, 0x2d3e, "1F2W" }, - { "truncfd", 14,24, 0x2f3e, "1F2D" }, - { "trunclb", 14,24, 0x283e, "1L2B" }, - { "trunclw", 14,24, 0x293e, "1L2W" }, - { "truncld", 14,24, 0x2b3e, "1L2D" }, - { "wait", 8,8, 0xb2, "" }, - { "wrval", 19,24, 0x0071e,"1A" }, - { "xorb", 6,16, 0x38, "1B2B" }, - { "xorw", 6,16, 0x39, "1W2W" }, - { "xord", 6,16, 0x3b, "1D2D" }, -}; /* notstrs */ - -/* end: ns32k.opcode.h */ - -#define MAX_ARGS 4 -#define ARG_LEN 50 diff --git a/gdb/ns32k-pinsn.c b/gdb/ns32k-pinsn.c deleted file mode 100644 index 7afee48..0000000 --- a/gdb/ns32k-pinsn.c +++ /dev/null @@ -1,437 +0,0 @@ -/* Print 32000 instructions 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 "defs.h" -#include "param.h" -#include "symtab.h" -#include "ns32k-opcode.h" - -/* 32000 instructions are never longer than this. */ -#define MAXLEN 62 - -/* Number of elements in the opcode table. */ -#define NOPCODES (sizeof notstrs / sizeof notstrs[0]) - -extern char *reg_names[]; - -#define NEXT_IS_ADDR '|' - -/* - * extract "count" bits starting "offset" bits - * into buffer - */ - -int -bit_extract (buffer, offset, count) - char *buffer; - int offset; - int count; -{ - int result; - int mask; - int bit; - - buffer += offset >> 3; - offset &= 7; - bit = 1; - result = 0; - while (count--) - { - if ((*buffer & (1 << offset))) - result |= bit; - if (++offset == 8) - { - offset = 0; - buffer++; - } - bit <<= 1; - } - return result; -} - -double -dbit_extract (buffer, offset, count) -{ - union { - struct {int low, high; } ival; - double dval; - } foo; - - foo.ival.low = bit_extract (buffer, offset, 32); - foo.ival.high = bit_extract (buffer, offset+32, 32); - return foo.dval; -} - -sign_extend (value, bits) -{ - value = value & ((1 << bits) - 1); - return (value & (1 << (bits-1)) - ? value | (~((1 << bits) - 1)) - : value); -} - -flip_bytes (ptr, count) - char *ptr; - int count; -{ - char tmp; - - while (count > 0) - { - tmp = *ptr; - ptr[0] = ptr[count-1]; - ptr[count-1] = tmp; - ptr++; - count -= 2; - } -} - - -/* Print the 32000 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; - unsigned short first_word; - int gen, disp; - int ioffset; /* bits into instruction */ - int aoffset; /* bits into arguments */ - char arg_bufs[MAX_ARGS+1][ARG_LEN]; - int argnum; - int maxarg; - - read_memory (memaddr, buffer, MAXLEN); - - first_word = *(unsigned short *) buffer; - for (i = 0; i < NOPCODES; i++) - if ((first_word & ((1 << notstrs[i].detail.obits) - 1)) - == notstrs[i].detail.code) - break; - - /* Handle undefined instructions. */ - if (i == NOPCODES) - { - fprintf (stream, "0%o", buffer[0]); - return 1; - } - - fprintf (stream, "%s", notstrs[i].name); - - ioffset = notstrs[i].detail.ibits; - aoffset = notstrs[i].detail.ibits; - d = notstrs[i].detail.args; - - if (*d) - { - fputc ('\t', stream); - - maxarg = 0; - while (*d) - { - argnum = *d - '1'; - d++; - if (argnum > maxarg && argnum < MAX_ARGS) - maxarg = argnum; - ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer, - memaddr, arg_bufs[argnum]); - d++; - } - for (argnum = 0; argnum <= maxarg; argnum++) - { - CORE_ADDR addr; - char *ch, *index (); - for (ch = arg_bufs[argnum]; *ch;) - { - if (*ch == NEXT_IS_ADDR) - { - ++ch; - addr = atoi (ch); - print_address (addr, stream); - while (*ch && *ch != NEXT_IS_ADDR) - ++ch; - if (*ch) - ++ch; - } - else - putc (*ch++, stream); - } - if (argnum < maxarg) - fprintf (stream, ", "); - } - } - return aoffset / 8; -} - -print_insn_arg (d, ioffset, aoffsetp, buffer, addr, result) - char d; - int ioffset, *aoffsetp; - char *buffer; - CORE_ADDR addr; - char *result; -{ - int addr_mode; - float Fvalue; - double Lvalue; - int Ivalue; - int disp1, disp2; - int index; - - switch (d) - { - case 'F': - case 'L': - case 'B': - case 'W': - case 'D': - case 'A': - addr_mode = bit_extract (buffer, ioffset-5, 5); - ioffset -= 5; - switch (addr_mode) - { - case 0x0: case 0x1: case 0x2: case 0x3: - case 0x4: case 0x5: case 0x6: case 0x7: - sprintf (result, "r%d", addr_mode); - break; - case 0x8: case 0x9: case 0xa: case 0xb: - case 0xc: case 0xd: case 0xe: case 0xf: - disp1 = get_displacement (buffer, aoffsetp); - sprintf (result, "%d(r%d)", disp1, addr_mode & 7); - break; - case 0x10: - case 0x11: - case 0x12: - disp1 = get_displacement (buffer, aoffsetp); - disp2 = get_displacement (buffer, aoffsetp); - sprintf (result, "%d(%d(%s))", disp2, disp1, - addr_mode==0x10?"fp":addr_mode==0x11?"sp":"sb"); - break; - case 0x13: - sprintf (result, "reserved"); - break; - case 0x14: - switch (d) - { - case 'B': - Ivalue = bit_extract (buffer, *aoffsetp, 8); - Ivalue = sign_extend (Ivalue, 8); - *aoffsetp += 8; - sprintf (result, "$%d", Ivalue); - break; - case 'W': - Ivalue = bit_extract (buffer, *aoffsetp, 16); - flip_bytes (&Ivalue, 2); - *aoffsetp += 16; - Ivalue = sign_extend (Ivalue, 16); - sprintf (result, "$%d", Ivalue); - break; - case 'D': - Ivalue = bit_extract (buffer, *aoffsetp, 32); - flip_bytes (&Ivalue, 4); - *aoffsetp += 32; - sprintf (result, "$%d", Ivalue); - break; - case 'A': - Ivalue = bit_extract (buffer, *aoffsetp, 32); - flip_bytes (&Ivalue, 4); - *aoffsetp += 32; - sprintf (result, "$|%d|", Ivalue); - break; - case 'F': - Fvalue = (float) bit_extract (buffer, *aoffsetp, 32); - flip_bytes (&Fvalue, 4); - *aoffsetp += 32; - sprintf (result, "$%g", Fvalue); - break; - case 'L': - Lvalue = dbit_extract (buffer, *aoffsetp, 64); - flip_bytes (&Lvalue, 8); - *aoffsetp += 64; - sprintf (result, "$%g", Lvalue); - break; - } - break; - case 0x15: - disp1 = get_displacement (buffer, aoffsetp); - sprintf (result, "@|%d|", disp1); - break; - case 0x16: - disp1 = get_displacement (buffer, aoffsetp); - disp2 = get_displacement (buffer, aoffsetp); - sprintf (result, "EXT(%d) + %d", disp1, disp2); - break; - case 0x17: - sprintf (result, "tos"); - break; - case 0x18: - disp1 = get_displacement (buffer, aoffsetp); - sprintf (result, "%d(fp)", disp1); - break; - case 0x19: - disp1 = get_displacement (buffer, aoffsetp); - sprintf (result, "%d(sp)", disp1); - break; - case 0x1a: - disp1 = get_displacement (buffer, aoffsetp); - sprintf (result, "%d(sb)", disp1); - break; - case 0x1b: - disp1 = get_displacement (buffer, aoffsetp); - sprintf (result, "|%d|", addr + disp1); - break; - case 0x1c: - case 0x1d: - case 0x1e: - case 0x1f: - index = bit_extract (buffer, *aoffsetp, 8); - *aoffsetp += 8; - print_insn_arg (d, *aoffsetp, aoffsetp, buffer, addr, - result); - { - static char *ind[] = {"b", "w", "d", "q"}; - char *off; - - off = result + strlen (result); - sprintf (off, "[r%d:%s]", index & 7, - ind[addr_mode & 3]); - } - break; - } - break; - case 'q': - Ivalue = bit_extract (buffer, ioffset-4, 4); - Ivalue = sign_extend (Ivalue, 4); - sprintf (result, "%d", Ivalue); - ioffset -= 4; - break; - case 'r': - Ivalue = bit_extract (buffer, ioffset-3, 3); - sprintf (result, "r%d", Ivalue&7); - ioffset -= 3; - break; - case 'd': - sprintf (result, "%d", get_displacement (buffer, aoffsetp)); - break; - case 'p': - sprintf (result, "%c%d%c", NEXT_IS_ADDR, - addr + get_displacement (buffer, aoffsetp), - NEXT_IS_ADDR); - break; - case 'i': - Ivalue = bit_extract (buffer, *aoffsetp, 8); - *aoffsetp += 8; - sprintf (result, "0x%x", Ivalue); - break; - } - return ioffset; -} - -get_displacement (buffer, aoffsetp) - char *buffer; - int *aoffsetp; -{ - int Ivalue; - - Ivalue = bit_extract (buffer, *aoffsetp, 8); - switch (Ivalue & 0xc0) - { - case 0x00: - case 0x40: - Ivalue = sign_extend (Ivalue, 7); - *aoffsetp += 8; - break; - case 0x80: - Ivalue = bit_extract (buffer, *aoffsetp, 16); - flip_bytes (&Ivalue, 2); - Ivalue = sign_extend (Ivalue, 14); - *aoffsetp += 16; - break; - case 0xc0: - Ivalue = bit_extract (buffer, *aoffsetp, 32); - flip_bytes (&Ivalue, 4); - Ivalue = sign_extend (Ivalue, 30); - *aoffsetp += 32; - break; - } - return Ivalue; -} - -/* Return the number of locals in the current frame given a pc - pointing to the enter instruction. This is used in the macro - FRAME_FIND_SAVED_REGS. */ - -ns32k_localcount (enter_pc) - CORE_ADDR enter_pc; -{ - unsigned char localtype; - int localcount; - - localtype = read_memory_integer (enter_pc+2, 1); - if ((localtype & 0x80) == 0) - localcount = localtype; - else if ((localtype & 0xc0) == 0x80) - localcount = (((localtype & 0x3f) << 8) - | (read_memory_integer (enter_pc+3, 1) & 0xff)); - else - localcount = (((localtype & 0x3f) << 24) - | ((read_memory_integer (enter_pc+3, 1) & 0xff) << 16) - | ((read_memory_integer (enter_pc+4, 1) & 0xff) << 8 ) - | (read_memory_integer (enter_pc+5, 1) & 0xff)); - return localcount; -} - -/* - * Get the address of the enter opcode for the function - * containing PC, if there is an enter for the function, - * and if the pc is between the enter and exit. - * Returns positive address if pc is between enter/exit, - * 1 if pc before enter or after exit, 0 otherwise. - */ - -CORE_ADDR -n32k_get_enter_addr (pc) - CORE_ADDR pc; -{ - CORE_ADDR enter_addr; - unsigned char op; - - if (ABOUT_TO_RETURN (pc)) - return 1; /* after exit */ - - enter_addr = get_pc_function_start (pc); - - if (pc == enter_addr) - return 1; /* before enter */ - - op = read_memory_integer (enter_addr, 1); - - if (op != 0x82) - return 0; /* function has no enter/exit */ - - return enter_addr; /* pc is between enter and exit */ -} diff --git a/gdb/obstack.c b/gdb/obstack.c index 887f348..320e1b7 120000..100644 --- a/gdb/obstack.c +++ b/gdb/obstack.c @@ -1 +1,324 @@ -../gcc/gcc-1.22/obstack.c
\ No newline at end of file +/* obstack.c - subroutines used implicitly by object stack macros + Copyright (C) 1988 Free Software Foundation, Inc. + + NO WARRANTY + + BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY +NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT +WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, +RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS" +WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY +AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE +DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR +CORRECTION. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. +STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY +WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE +LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR +OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR +DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR +A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS +PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. + + GENERAL PUBLIC LICENSE TO COPY + + 1. You may copy and distribute verbatim copies of this source file +as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy a valid copyright notice "Copyright + (C) 1988 Free Software Foundation, Inc."; and include following the +copyright notice a verbatim copy of the above disclaimer of warranty +and of this License. You may charge a distribution fee for the +physical act of transferring a copy. + + 2. You may modify your copy or copies of this source file or +any portion of it, and copy and distribute such modifications under +the terms of Paragraph 1 above, provided that you also do the following: + + a) cause the modified files to carry prominent notices stating + that you changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, + that in whole or in part contains or is a derivative of this + program or any part thereof, to be licensed at no charge to all + third parties on terms identical to those contained in this + License Agreement (except that you may choose to grant more extensive + warranty protection to some or all third parties, at your option). + + c) You may charge a distribution fee for the physical act of + transferring a copy, and you may at your option offer warranty + protection in exchange for a fee. + +Mere aggregation of another unrelated program with this program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other program under the scope of these terms. + + 3. You may copy and distribute this program (or a portion or derivative +of it, under Paragraph 2) in object code or executable form under the terms +of Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal + shipping charge) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +For an executable file, complete source code means all the source code for +all modules it contains; but, as a special exception, it need not include +source code for modules which are standard libraries that accompany the +operating system on which the executable file runs. + + 4. You may not copy, sublicense, distribute or transfer this program +except as expressly provided under this License Agreement. Any attempt +otherwise to copy, sublicense, distribute or transfer this program is void and +your rights to use the program under this License agreement shall be +automatically terminated. However, parties who have received computer +software programs from you with this License Agreement will not have +their licenses terminated so long as such parties remain in full compliance. + + 5. If you wish to incorporate parts of this program into other free +programs whose distribution conditions are different, write to the Free +Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet +worked out a simple rule that can be stated here, but we will often permit +this. We will be guided by the two goals of preserving the free status of +all derivatives our free software and of promoting the sharing and reuse of +software. + + +In other words, you are welcome to use, share and improve this program. +You are forbidden to forbid anyone else to use, share and improve +what you give them. Help stamp out software-hoarding! */ + + +#include "obstack.h" + +#ifdef __STDC__ +#define POINTER void * +#else +#define POINTER char * +#endif + +/* The non-GNU-C macros copy the obstack into this global variable + to avoid multiple evaluation. */ + +struct obstack *_obstack; + +/* Initialize an obstack H for use. Specify chunk size SIZE. + Objects start on multiples of ALIGNMENT. + CHUNKFUN is the function to use to allocate chunks, + and FREEFUN the function to free them. */ + +void +_obstack_begin (h, size, alignment, chunkfun, freefun) + struct obstack *h; + int size; + int alignment; + POINTER (*chunkfun) (); + void (*freefun) (); +{ + register struct _obstack_chunk* chunk; /* points to new chunk */ + h->chunkfun = (struct _obstack_chunk * (*)()) chunkfun; + h->freefun = freefun; + h->chunk_size = size; + h->alignment_mask = alignment - 1; + + chunk = h->chunk = (*h->chunkfun) (h->chunk_size); + h->next_free = h->object_base = chunk->contents; + h->chunk_limit = chunk->limit + = (char *) chunk + h->chunk_size; + chunk->prev = 0; +} + +/* Allocate a new current chunk for the obstack *H + on the assumption that LENGTH bytes need to be added + to the current object, or a new object of length LENGTH allocated. + Copies any partial object from the end of the old chunk + to the beginning of the new one. */ + +void +_obstack_newchunk (h, length) + struct obstack *h; + int length; +{ + register struct _obstack_chunk* old_chunk = h->chunk; + register struct _obstack_chunk* new_chunk; + register long new_size; + register int obj_size = h->next_free - h->object_base; + register int i; + + /* Compute size for new chunk. */ + new_size = (obj_size + length) << 1; + if (new_size < h->chunk_size) + new_size = h->chunk_size; + + /* Allocate and initialize the new chunk. */ + new_chunk = h->chunk = (*h->chunkfun) (new_size); + new_chunk->prev = old_chunk; + new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size; + + /* Move the existing object to the new chunk. + Word at a time is fast and is safe because these + structures are aligned at least that much. */ + for (i = (obj_size + sizeof (int) - 1) / sizeof (int); i >= 0; i--) + ((int *)new_chunk->contents)[i] = ((int *)h->object_base)[i]; + + h->object_base = new_chunk->contents; + h->next_free = h->object_base + obj_size; +} + +/* Free objects in obstack H, including OBJ and everything allocate + more recently than OBJ. If OBJ is zero, free everything in H. */ + +void +#ifdef __STDC__ +#undef obstack_free +obstack_free (h, obj) + +#else +_obstack_free (h, obj) +#endif + struct obstack *h; + POINTER obj; +{ + register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */ + register struct _obstack_chunk* plp; /* point to previous chunk if any */ + + lp = (h)->chunk; + while (lp != 0 && ((POINTER)lp > obj || (POINTER)(lp)->limit < obj)) + { + plp = lp -> prev; + (*h->freefun) (lp); + lp = plp; + } + if (lp) + { + (h)->object_base = (h)->next_free = (char *)(obj); + (h)->chunk_limit = lp->limit; + (h)->chunk = lp; + } + else if (obj != 0) + /* obj is not in any of the chunks! */ + abort (); +} + +/* Now define the functional versions of the obstack macros. + Define them to simply use the corresponding macros to do the job. */ + +#ifdef __STDC__ +/* These function definitions do not work with non-ANSI preprocessors; + they won't pass through the macro names in parentheses. */ + +/* The function names appear in parentheses in order to prevent + the macro-definitions of the names from being expanded there. */ + +POINTER (obstack_base) (obstack) + struct obstack *obstack; +{ + return obstack_base (obstack); +} + +POINTER (obstack_next_free) (obstack) + struct obstack *obstack; +{ + return obstack_next_free (obstack); +} + +int (obstack_object_size) (obstack) + struct obstack *obstack; +{ + return obstack_object_size (obstack); +} + +int (obstack_room) (obstack) + struct obstack *obstack; +{ + return obstack_room (obstack); +} + +void (obstack_grow) (obstack, pointer, length) + struct obstack *obstack; + POINTER pointer; + int length; +{ + obstack_grow (obstack, pointer, length); +} + +void (obstack_grow0) (obstack, pointer, length) + struct obstack *obstack; + POINTER pointer; + int length; +{ + obstack_grow0 (obstack, pointer, length); +} + +void (obstack_1grow) (obstack, character) + struct obstack *obstack; + int character; +{ + obstack_1grow (obstack, character); +} + +void (obstack_blank) (obstack, length) + struct obstack *obstack; + int length; +{ + obstack_blank (obstack, length); +} + +void (obstack_1grow_fast) (obstack, character) + struct obstack *obstack; + int character; +{ + obstack_1grow_fast (obstack, character); +} + +void (obstack_blank_fast) (obstack, length) + struct obstack *obstack; + int length; +{ + obstack_blank_fast (obstack, length); +} + +POINTER (obstack_finish) (obstack) + struct obstack *obstack; +{ + return obstack_finish (obstack); +} + +POINTER (obstack_alloc) (obstack, length) + struct obstack *obstack; + int length; +{ + return obstack_alloc (obstack, length); +} + +POINTER (obstack_copy) (obstack, pointer, length) + struct obstack *obstack; + POINTER pointer; + int length; +{ + return obstack_copy (obstack, pointer, length); +} + +POINTER (obstack_copy0) (obstack, pointer, length) + struct obstack *obstack; + POINTER pointer; + int length; +{ + return obstack_copy0 (obstack, pointer, length); +} + +#endif /* __STDC__ */ diff --git a/gdb/obstack.h b/gdb/obstack.h index db1184b..069afc6 120000..100644 --- a/gdb/obstack.h +++ b/gdb/obstack.h @@ -1 +1,443 @@ -../gcc/gcc-1.19/obstack.h
\ No newline at end of file +/* obstack.h - object stack macros + Copyright (C) 1986, 1988 Free Software Foundation, Inc. + + NO WARRANTY + + BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY +NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT +WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, +RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS" +WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, +BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY +AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE +DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR +CORRECTION. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. +STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY +WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE +LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR +OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR +DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR +A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS +PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. + + GENERAL PUBLIC LICENSE TO COPY + + 1. You may copy and distribute verbatim copies of this source file +as you receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy a valid copyright notice "Copyright +(C) 1988 Free Software Foundation, Inc."; and include following the +copyright notice a verbatim copy of the above disclaimer of warranty +and of this License. You may charge a distribution fee for the +physical act of transferring a copy. + + 2. You may modify your copy or copies of this source file or +any portion of it, and copy and distribute such modifications under +the terms of Paragraph 1 above, provided that you also do the following: + + a) cause the modified files to carry prominent notices stating + that you changed the files and the date of any change; and + + b) cause the whole of any work that you distribute or publish, + that in whole or in part contains or is a derivative of this + program or any part thereof, to be licensed at no charge to all + third parties on terms identical to those contained in this + License Agreement (except that you may choose to grant more extensive + warranty protection to some or all third parties, at your option). + + c) You may charge a distribution fee for the physical act of + transferring a copy, and you may at your option offer warranty + protection in exchange for a fee. + +Mere aggregation of another unrelated program with this program (or its +derivative) on a volume of a storage or distribution medium does not bring +the other program under the scope of these terms. + + 3. You may copy and distribute this program (or a portion or derivative +of it, under Paragraph 2) in object code or executable form under the terms +of Paragraphs 1 and 2 above provided that you also do one of the following: + + a) accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of + Paragraphs 1 and 2 above; or, + + b) accompany it with a written offer, valid for at least three + years, to give any third party free (except for a nominal + shipping charge) a complete machine-readable copy of the + corresponding source code, to be distributed under the terms of + Paragraphs 1 and 2 above; or, + + c) accompany it with the information you received as to where the + corresponding source code may be obtained. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form alone.) + +For an executable file, complete source code means all the source code for +all modules it contains; but, as a special exception, it need not include +source code for modules which are standard libraries that accompany the +operating system on which the executable file runs. + + 4. You may not copy, sublicense, distribute or transfer this program +except as expressly provided under this License Agreement. Any attempt +otherwise to copy, sublicense, distribute or transfer this program is void and +your rights to use the program under this License agreement shall be +automatically terminated. However, parties who have received computer +software programs from you with this License Agreement will not have +their licenses terminated so long as such parties remain in full compliance. + + 5. If you wish to incorporate parts of this program into other free +programs whose distribution conditions are different, write to the Free +Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet +worked out a simple rule that can be stated here, but we will often permit +this. We will be guided by the two goals of preserving the free status of +all derivatives our free software and of promoting the sharing and reuse of +software. + + +In other words, you are welcome to use, share and improve this program. +You are forbidden to forbid anyone else to use, share and improve +what you give them. Help stamp out software-hoarding! */ + + +/* Summary: + +All the apparent functions defined here are macros. The idea +is that you would use these pre-tested macros to solve a +very specific set of problems, and they would run fast. +Caution: no side-effects in arguments please!! They may be +evaluated MANY times!! + +These macros operate a stack of objects. Each object starts life +small, and may grow to maturity. (Consider building a word syllable +by syllable.) An object can move while it is growing. Once it has +been "finished" it never changes address again. So the "top of the +stack" is typically an immature growing object, while the rest of the +stack is of mature, fixed size and fixed address objects. + +These routines grab large chunks of memory, using a function you +supply, called `obstack_chunk_alloc'. On occasion, they free chunks, +by calling `obstack_chunk_free'. You must define them and declare +them before using any obstack macros. + +Each independent stack is represented by a `struct obstack'. +Each of the obstack macros expects a pointer to such a structure +as the first argument. + +One motivation for this package is the problem of growing char strings +in symbol tables. Unless you are "facist pig with a read-only mind" +[Gosper's immortal quote from HAKMEM item 154, out of context] you +would not like to put any arbitrary upper limit on the length of your +symbols. + +In practice this often means you will build many short symbols and a +few long symbols. At the time you are reading a symbol you don't know +how long it is. One traditional method is to read a symbol into a +buffer, realloc()ating the buffer every time you try to read a symbol +that is longer than the buffer. This is beaut, but you still will +want to copy the symbol from the buffer to a more permanent +symbol-table entry say about half the time. + +With obstacks, you can work differently. Use one obstack for all symbol +names. As you read a symbol, grow the name in the obstack gradually. +When the name is complete, finalize it. Then, if the symbol exists already, +free the newly read name. + +The way we do this is to take a large chunk, allocating memory from +low addresses. When you want to build a aymbol in the chunk you just +add chars above the current "high water mark" in the chunk. When you +have finished adding chars, because you got to the end of the symbol, +you know how long the chars are, and you can create a new object. +Mostly the chars will not burst over the highest address of the chunk, +because you would typically expect a chunk to be (say) 100 times as +long as an average object. + +In case that isn't clear, when we have enough chars to make up +the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed) +so we just point to it where it lies. No moving of chars is +needed and this is the second win: potentially long strings need +never be explicitly shuffled. Once an object is formed, it does not +change its address during its lifetime. + +When the chars burst over a chunk boundary, we allocate a larger +chunk, and then copy the partly formed object from the end of the old +chunk to the beggining of the new larger chunk. We then carry on +accreting characters to the end of the object as we normaly would. + +A special macro is provided to add a single char at a time to a +growing object. This allows the use of register variables, which +break the ordinary 'growth' macro. + +Summary: + We allocate large chunks. + We carve out one object at a time from the current chunk. + Once carved, an object never moves. + We are free to append data of any size to the currently + growing object. + Exactly one object is growing in an obstack at any one time. + You can run one obstack per control block. + You may have as many control blocks as you dare. + Because of the way we do it, you can `unwind' a obstack + back to a previous state. (You may remove objects much + as you would with a stack.) +*/ + + +/* Don't do the contents of this file more than once. */ + +#ifndef __OBSTACKS__ +#define __OBSTACKS__ + +#ifdef __STDC__ + +/* Do the function-declarations before defining the macros. */ + +void obstack_init (struct obstack *obstack); + +void * obstack_alloc (struct obstack *obstack, int size); + +void * obstack_copy (struct obstack *obstack, void *address, int size); +void * obstack_copy0 (struct obstack *obstack, void *address, int size); + +void obstack_free (struct obstack *obstack, void *block); + +void obstack_blank (struct obstack *obstack, int size); + +void obstack_grow (struct obstack *obstack, void *data, int size); +void obstack_grow0 (struct obstack *obstack, void *data, int size); + +void obstack_1grow (struct obstack *obstack, int data_char); + +void * obstack_finish (struct obstack *obstack); + +int obstack_object_size (struct obstack *obstack); + +int obstack_room (struct obstack *obstack); +void obstack_1grow_fast (struct obstack *obstack, int data_char); +void obstack_blank_fast (struct obstack *obstack, int size); + +void * object_base (struct obstack *obstack); +void * object_next_free (struct obstack *obstack); +int obstack_alignment_mask (struct obstack *obstack); +int obstack_chunk_size (struct obstack *obstack); + +#endif /* __STDC__ */ + +/* Non-ANSI C cannot really support alternative functions for these macros, + so we do not declare them. */ + +struct _obstack_chunk /* Lives at front of each chunk. */ +{ + char *limit; /* 1 past end of this chunk */ + struct _obstack_chunk *prev; /* address of prior chunk or NULL */ + char contents[4]; /* objects begin here */ +}; + +struct obstack /* control current object in current chunk */ +{ + long chunk_size; /* preferred size to allocate chunks in */ + struct _obstack_chunk* chunk; /* address of current struct obstack_chunk */ + char *object_base; /* address of object we are building */ + char *next_free; /* where to add next char to current object */ + char *chunk_limit; /* address of char after current chunk */ + int temp; /* Temporary for some macros. */ + int alignment_mask; /* Mask of alignment for each object. */ + struct _obstack_chunk *(*chunkfun) (); /* User's fcn to allocate a chunk. */ + void (*freefun) (); /* User's function to free a chunk. */ +}; + +/* Pointer to beginning of object being allocated or to be allocated next. + Note that this might not be the final address of the object + because a new chunk might be needed to hold the final size. */ + +#define obstack_base(h) ((h)->object_base) + +/* Size for allocating ordinary chunks. */ + +#define obstack_chunk_size(h) ((h)->chunk_size) + +/* Pointer to next byte not yet allocated in current chunk. */ + +#define obstack_next_free(h) ((h)->next_free) + +/* Mask specifying low bits that should be clear in address of an object. */ + +#define obstack_alignment_mask(h) ((h)->alignment_mask) + +#define obstack_init(h) \ + _obstack_begin ((h), 4096 - 4, 4, obstack_chunk_alloc, obstack_chunk_free) + +#define obstack_begin(h, size) \ + _obstack_begin ((h), (size), 4, obstack_chunk_alloc, obstack_chunk_free) + +#define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = achar) + +#define obstack_blank_fast(h,n) ((h)->next_free += (n)) + +#if defined (__GNU__) && defined (__STDC__) + +/* For GNU C we can define these macros to compute all args only once + without using a global variable. + Also, we can avoid using the `temp' slot, to make faster code. + + By checking both __GNU__ and __STDC__, we can make sure + both GNU language extensions and ANSI preprocessing are available. */ + +#define obstack_object_size(OBSTACK) \ + ({ struct obstack *__o = (OBSTACK); \ + (unsigned) (__o->next_free - __o->object_base); }) + +#define obstack_room(OBSTACK) \ + ({ struct obstack *__o = (OBSTACK); \ + (unsigned) (__o->chunk_limit - __o->next_free); }) + +#define obstack_grow(OBSTACK,where,length) \ +({ struct obstack *__o = (OBSTACK); \ + int __len = (length); \ + ((__o->next_free + __len > __o->chunk_limit) \ + ? _obstack_newchunk (__o, __len) : 0); \ + bcopy (where, __o->next_free, __len); \ + __o->next_free += __len; \ + (void) 0; }) + +#define obstack_grow0(OBSTACK,where,length) \ +({ struct obstack *__o = (OBSTACK); \ + int __len = (length); \ + ((__o->next_free + __len + 1 > __o->chunk_limit) \ + ? _obstack_newchunk (__o, __len + 1) : 0), \ + bcopy (where, __o->next_free, __len), \ + __o->next_free += __len, \ + *(__o->next_free)++ = 0; \ + (void) 0; }) + +#define obstack_1grow(OBSTACK,datum) \ +({ struct obstack *__o = (OBSTACK); \ + ((__o->next_free + 1 > __o->chunk_limit) \ + ? _obstack_newchunk (__o, 1) : 0), \ + *(__o->next_free)++ = (datum); \ + (void) 0; }) + +#define obstack_blank(OBSTACK,length) \ +({ struct obstack *__o = (OBSTACK); \ + int __len = (length); \ + ((__o->next_free + __len > __o->chunk_limit) \ + ? _obstack_newchunk (__o, __len) : 0); \ + __o->next_free += __len; \ + (void) 0; }) + +#define obstack_alloc(OBSTACK,length) \ +({ struct obstack *__h = (OBSTACK); \ + obstack_blank (__h, (length)); \ + obstack_finish (__h); }) + +#define obstack_copy(OBSTACK,where,length) \ +({ struct obstack *__h = (OBSTACK); \ + obstack_grow (__h, (where), (length)); \ + obstack_finish (__h); }) + +#define obstack_copy0(OBSTACK,where,length) \ +({ struct obstack *__h = (OBSTACK); \ + obstack_grow0 (__h, (where), (length)); \ + obstack_finish (__h); }) + +#define obstack_finish(OBSTACK) \ +({ struct obstack *__o = (OBSTACK); \ + void *value = (void *) __o->object_base; \ + __o->next_free \ + = (char*)((int)(__o->next_free+__o->alignment_mask) \ + & ~ (__o->alignment_mask)); \ + ((__o->next_free - (char *)__o->chunk \ + > __o->chunk_limit - (char *)__o->chunk) \ + ? __o->next_free = __o->chunk_limit : 0); \ + __o->object_base = __o->next_free; \ + value; }) + +#define obstack_free(OBSTACK, OBJ) \ +({ struct obstack *__o = (OBSTACK); \ + void *__obj = (OBJ); \ + if (__obj >= (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \ + __o->next_free = __o->object_base = __obj; \ + else (obstack_free) (__o, __obj); }) + +#else /* not __GNU__ */ + +/* The non-GNU macros copy the obstack-pointer into this global variable + to avoid multiple evaluation. */ + +extern struct obstack *_obstack; + +#define obstack_object_size(h) \ + (unsigned) (_obstack = (h), (h)->next_free - (h)->object_base) + +#define obstack_room(h) \ + (unsigned) (_obstack = (h), (h)->chunk_limit - (h)->next_free) + +#define obstack_grow(h,where,length) \ +( (h)->temp = (length), \ + (((h)->next_free + (h)->temp > (h)->chunk_limit) \ + ? _obstack_newchunk ((h), (h)->temp) : 0), \ + bcopy (where, (h)->next_free, (h)->temp), \ + (h)->next_free += (h)->temp) + +#define obstack_grow0(h,where,length) \ +( (h)->temp = (length), \ + (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit) \ + ? _obstack_newchunk ((h), (h)->temp + 1) : 0), \ + bcopy (where, (h)->next_free, (h)->temp), \ + (h)->next_free += (h)->temp, \ + *((h)->next_free)++ = 0) + +#define obstack_1grow(h,datum) \ +( (((h)->next_free + 1 > (h)->chunk_limit) \ + ? _obstack_newchunk ((h), 1) : 0), \ + *((h)->next_free)++ = (datum)) + +#define obstack_blank(h,length) \ +( (h)->temp = (length), \ + (((h)->next_free + (h)->temp > (h)->chunk_limit) \ + ? _obstack_newchunk ((h), (h)->temp) : 0), \ + (h)->next_free += (h)->temp) + +#define obstack_alloc(h,length) \ + (obstack_blank ((h), (length)), obstack_finish ((h))) + +#define obstack_copy(h,where,length) \ + (obstack_grow ((h), (where), (length)), obstack_finish ((h))) + +#define obstack_copy0(h,where,length) \ + (obstack_grow0 ((h), (where), (length)), obstack_finish ((h))) + +#define obstack_finish(h) \ +( (h)->temp = (int) (h)->object_base, \ + (h)->next_free \ + = (char*)((int)((h)->next_free+(h)->alignment_mask) \ + & ~ ((h)->alignment_mask)), \ + (((h)->next_free - (char *)(h)->chunk \ + > (h)->chunk_limit - (char *)(h)->chunk) \ + ? (h)->next_free = (h)->chunk_limit : 0), \ + (h)->object_base = (h)->next_free, \ + (char *) (h)->temp) + +#ifdef __STDC__ +#define obstack_free(h,obj) \ +( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \ + (((h)->temp >= 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ + ? (int) ((h)->next_free = (h)->object_base \ + = (h)->temp + (char *) (h)->chunk) \ + : (int) (obstack_free) ((h), (h)->temp + (char *) (h)->chunk))) +#else +#define obstack_free(h,obj) \ +( (h)->temp = (char *)(obj) - (char *) (h)->chunk, \ + (((h)->temp >= 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\ + ? (int) ((h)->next_free = (h)->object_base \ + = (h)->temp + (char *) (h)->chunk) \ + : (int) _obstack_free ((h), (h)->temp + (char *) (h)->chunk))) +#endif + +#endif /* not __GNU__ */ + +#endif /* not __OBSTACKS__ */ + diff --git a/gdb/param.h b/gdb/param.h index 56f2c8a..426593f 100644 --- a/gdb/param.h +++ b/gdb/param.h @@ -1 +1 @@ -#include "m-mac-aux.h" +#include "m-sun3.h" diff --git a/gdb/parent.c b/gdb/parent.c new file mode 100644 index 0000000..38b845a --- /dev/null +++ b/gdb/parent.c @@ -0,0 +1,126 @@ +#include <stdio.h> + +class math_stuff +{ + char name[40]; + int value; + +public: + + void bla(); + + math_stuff(char*); + + ~math_stuff(); + + void add(int); + + void print_value(char*); +}; + +void math_stuff::bla() +{ + printf("bla\n"); +} + +math_stuff::math_stuff(char* new_name) +{ + sprintf((char *)this->name,(char *)"MATH_STUFF_%s",new_name); + value = 0; +} + +math_stuff::~math_stuff() +{ + printf((char *)"Deleting MATH_STUFF instance '%s'\n",this->name); +} + +void math_stuff::add(int x) +{ + this->value += x; +} + +void math_stuff::print_value(char *where) +{ + printf((char *)"current value of '%s' at '%s' = %d\n", this->name, where, this->value); +} + +class derived : public math_stuff +{ + char *dname; + int val; + +public: + math_stuff stuff; + derived(char*); + ~derived(); + void print_all(char*); +}; + +derived::derived(char *der_name) + : ((char *)"hello, world!"), stuff("derived stuff"), val(10) +{ + printf((char *)"derived name = %s\n", der_name); + dname = der_name; + stuff.add(6); + stuff.print_value ((char *)"grind"); +} + +derived::~derived() +{ + printf ((char *)"Good bye! \n"); +} + +derived::print_all(char *msg) +{ + printf((char *)"Here's the lowdown:\n"); + printf((char *)"My name is %s\n", dname); + printf((char *)"My value = %d\n", val); + stuff.print_value ((char *)"low"); + this->print_value((char *)"down"); + printf((char *)"That's all you get tonight.\n\n"); +} + +main() +{ + int pid; + int i; + + pid = vfork(); + if (pid > 0) + printf(" the inferior pid of the child is %d\n",pid); + if (pid == 0) + { +/* execl ("/bin/sh", "sh", "-c",argv[1],0);*/ + + math_stuff* a; + derived* d; + math_stuff b $ (" no gnus are good gnus "); + int child; + child = getpid(); + printf( " the child from parent.c is %d\n",child); + ptrace (0); + + a = new math_stuff((char *)"a"); + + d = new derived((char *)"two words"); + + a->add(2); + a->add(4); + a->add(5); + a->print_value((char *)"here"); + a->add(7); + a->print_value((char *)"there"); + a->add(3); + a->add(1); + a->print_value((char *)"end"); + + d->print_all ((char *)"all"); + + delete a; + delete d; + exit(0); + } + i = 5; + i = 6; + i = 7; +} diff --git a/gdb/printcmd.c b/gdb/printcmd.c index d84dd9d..04dda07 100644 --- a/gdb/printcmd.c +++ b/gdb/printcmd.c @@ -1,5 +1,5 @@ /* Print values for GNU debugger gdb. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. + Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. GDB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone @@ -95,6 +95,10 @@ decode_format (string_ptr, oformat, osize) break; } + /* Make sure 'g' size is not used on integer types. */ + if (val.size == 'g' && val.format != 'f') + val.size = 'w'; + while (*p == ' ' || *p == '\t') p++; *string_ptr = p; @@ -103,12 +107,15 @@ decode_format (string_ptr, oformat, osize) /* Print value VAL on stdout according to FORMAT, a letter or 0. Do not end with a newline. - 0 means print VAL according to its own type. */ + 0 means print VAL according to its own type. + SIZE is the letter for the size of datum being printed. + This is used to pad hex numbers so they line up. */ static void -print_formatted (val, format) +print_formatted (val, format, size) register value val; register char format; + char size; { register CORE_ADDR val_long; int len = TYPE_LENGTH (VALUE_TYPE (val)); @@ -143,7 +150,24 @@ print_formatted (val, format) break; case 'x': - printf ("0x%x", val_long); + switch (size) + { + case 'b': + printf ("0x%02x", val_long); + break; + case 'h': + printf ("0x%04x", val_long); + break; + case 0: /* no size specified, like in print */ + case 'w': + printf ("0x%08x", val_long); + break; + case 'g': + printf ("0x%16x", val_long); + break; + default: + error ("Undefined output size \"%c\".", size); + } break; case 'd': @@ -279,6 +303,7 @@ do_examine (fmt, addr) while (count > 0) { print_address (next_address, stdout); + fputc (':', stdout); for (i = maxelts; i > 0 && count > 0; i--, count--) @@ -287,7 +312,7 @@ do_examine (fmt, addr) /* Note that this sets next_address for the next object. */ last_examine_address = next_address; last_examine_value = value_at (val_type, next_address); - print_formatted (last_examine_value, format); + print_formatted (last_examine_value, format, size); } fputc ('\n', stdout); fflush (stdout); @@ -339,10 +364,11 @@ print_command (exp) else val = access_value_history (0); + if (!val) return; /* C++ */ histindex = record_latest_value (val); printf ("$%d = ", histindex); - print_formatted (val, format); + print_formatted (val, format, fmt.size); printf ("\n"); if (cleanup) @@ -372,7 +398,7 @@ output_command (exp) val = evaluate_expression (expr); - print_formatted (val, format); + print_formatted (val, format, fmt.size); do_cleanups (old_chain); } @@ -388,17 +414,41 @@ set_command (exp) do_cleanups (old_chain); } +/* C++: Modified to give useful information about variable which + hang off of `this'. */ static void address_info (exp) char *exp; { register struct symbol *sym; register CORE_ADDR val; + struct block *block, *get_selected_block (); if (exp == 0) error ("Argument required."); - sym = lookup_symbol (exp, get_selected_block (), VAR_NAMESPACE); + block = get_selected_block (); + sym = lookup_symbol_1 (exp, block, VAR_NAMESPACE); + if (! sym) + { + value v; + + /* C++: see if it hangs off of `this'. Must + not inadvertently convert from a method call + to data ref. */ + v = value_of_this (0); + if (v) + { + val = check_field (v, exp); + if (val) + { + printf ("Symbol \"%s\" is a field of the local class variable `this'\n", exp); + return; + } + } + else + sym = lookup_symbol_2 (exp, 0, VAR_NAMESPACE); + } if (sym == 0) { register int i; @@ -522,9 +572,12 @@ whatis_command (exp) else val = access_value_history (0); - printf ("type = "); - type_print (VALUE_TYPE (val), "", stdout, 1); - printf ("\n"); + if (val != 0) + { + printf ("type = "); + type_print (VALUE_TYPE (val), "", stdout, 1); + printf ("\n"); + } if (exp) do_cleanups (old_chain); @@ -586,6 +639,143 @@ ptype_command (typename) type_print (type, "", stdout, 1); printf ("\n"); } + +/* Print all the methods that correspond to the name METHOD. + Can optionally qualify the method with a CLASSNAME, as + in CLASSNAME :: METHODNAME. This routine does not call + parse_c_expression, so the input must conform to one of + these two forms. */ + +static void +pmethod_command (exp) + char *exp; +{ +# if 0 + struct expression *expr; + register value val; + register struct cleanup *old_chain; + char *classname, *methodname; + + methodname = exp; + while (*exp++ <= ' ') ; /* remove leading whitespace */ + if (exp[-1] == ':') + if (*exp == ':') + classname = (char *)1; + else error ("Invalid syntax: \"%s\"", methodname); + else + { + classname = exp-1; + while (*exp++ != ':') ; + exp[-1] = '\0'; + if (*exp == ':') + { + while (*exp++ <= ' ') ; /* remove leading 2nd whitespace */ + methodname = exp-1; + while (((*exp | 0x20) >= 'a' && ((*exp | 0x20) <= 'z')) || *exp == '_') + exp++; + if (*exp) + { + *exp++ = '\0'; + while (*exp) + if (*exp > ' ') error ("junk after method name"); + } + } + else error ("Invalid syntax: \"%s\"", methodname); + } + if (classname) + { + if (classname != (char *)1) + classtype = lookup_typename (classname); + else + { + 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; + int found_in_file; + static char *classnames[] + = {"variable", "function", "type", "method"}; + int print_count = 0; + + if (regexp) + if (val = (char *) re_comp (regexp)) + error ("Invalid regexp: %s", val); + + 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 == 0 || re_exec (SYMBOL_NAME (sym))) + && ((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) + || (class == 3 && SYMBOL_CLASS (sym) == LOC_BLOCK))) + { + if (!found_in_file) + { + printf ("\nFile %s:\n", s->filename); + print_count += 2; + } + found_in_file = 1; + MORE; + if (i == 1) + printf ("static "); + + type_print (SYMBOL_TYPE (sym), + (SYMBOL_CLASS (sym) == LOC_TYPEDEF + ? "" : SYMBOL_NAME (sym)), + stdout, 0); + printf (";\n"); + } + } + } + prev_bv = bv; + } + } + } + if (exp) + { + expr = parse_c_expression (exp); + old_chain = make_cleanup (free_current_contents, &expr); + val = evaluate_type (expr); + } + else + val = access_value_history (0); + + if (val != 0) + { + printf ("type = "); + type_print (VALUE_TYPE (val), "", stdout, 1); + printf ("\n"); + } + + if (exp) + do_cleanups (old_chain); +# endif +} struct display { @@ -767,7 +957,8 @@ do_displays () printf ("/%c ", d->format.format); print_expression (d->exp, stdout); printf (" = "); - print_formatted (evaluate_expression (d->exp), d->format.format); + print_formatted (evaluate_expression (d->exp), + d->format.format, d->format.size); printf ("\n"); } fflush (stdout); @@ -896,6 +1087,171 @@ print_frame_nameless_args (argsaddr, start, end, stream) } } +static void +printf_command (arg) + char *arg; +{ + register char *f; + register char *s = arg; + char *string; + value *val_args; + int nargs = 0; + int allocated_args = 20; + char *arg_bytes; + char *argclass; + int i; + int argindex; + int nargs_wanted; + + val_args = (value *) xmalloc (allocated_args * sizeof (value)); + + if (s == 0) + error_no_arg ("format-control string and values to print"); + + /* Skip white space before format string */ + while (*s == ' ' || *s == '\t') s++; + + /* A format string should follow, enveloped in double quotes */ + if (*s++ != '"') + error ("Bad format string, missing '\"'."); + + /* Parse the format-control string and copy it into the string STRING, + processing some kinds of escape sequence. */ + + f = string = (char *) alloca (strlen (s) + 1); + while (*s != '"') + { + int c = *s++; + switch (c) + { + case '\0': + error ("Bad format string, non-terminated '\"'."); + /* doesn't return */ + + case '\\': + switch (c = *s++) + { + case '\\': + *f++ = '\\'; + break; + case 'n': + *f++ = '\n'; + break; + case 't': + *f++ = '\t'; + break; + case 'r': + *f++ = '\r'; + break; + case '"': + *f++ = '"'; + break; + default: + /* ??? TODO: handle other escape sequences */ + error ("Unrecognized \\ escape character in format string."); + } + break; + + default: + *f++ = c; + } + } + + /* Skip over " and following space and comma. */ + s++; + *f++ = '\0'; + while (*s == ' ' || *s == '\t') s++; + + if (*s != ',' && *s != 0) + error ("Invalid argument syntax"); + + if (*s == ',') s++; + while (*s == ' ' || *s == '\t') s++; + + /* Now scan the string for %-specs and see what kinds of args they want. + argclass[I] is set to 1 if the Ith arg should be a string. */ + + argclass = (char *) alloca (strlen (s)); + nargs_wanted = 0; + f = string; + while (*f) + if (*f++ == '%') + { + while (index ("0123456789.hlL-+ #", *f)) f++; + if (*f == 's') + argclass[nargs_wanted++] = 1; + else if (*f != '%') + argclass[nargs_wanted++] = 0; + f++; + } + + /* Now, parse all arguments and evaluate them. + Store the VALUEs in VAL_ARGS. */ + + while (*s != '\0') + { + char *s1; + if (nargs == allocated_args) + val_args = (value *) xrealloc (val_args, + (allocated_args *= 2) + * sizeof (value)); + s1 = s; + val_args[nargs++] = parse_to_comma_and_eval (&s1); + s = s1; + if (*s == ',') + s++; + } + + if (nargs != nargs_wanted) + error ("Wrong number of arguments for specified format-string"); + + /* Now lay out an argument-list containing the arguments + as doubles, integers and C pointers. */ + + arg_bytes = (char *) alloca (sizeof (double) * nargs); + argindex = 0; + for (i = 0; i < nargs; i++) + { + if (argclass[i]) + { + char *str; + int tem, j; + tem = value_as_long (val_args[i]); + + /* This is a %s argument. Find the length of the string. */ + for (j = 0; ; j++) + { + char c; + QUIT; + read_memory (tem + j, &c, 1); + if (c == 0) + break; + } + + /* Copy the string contents into a string inside GDB. */ + str = (char *) alloca (j + 1); + read_memory (tem, str, j); + str[j] = 0; + + /* Pass address of internal copy as the arg to vprintf. */ + *((int *) &arg_bytes[argindex]) = (int) str; + argindex += sizeof (int); + } + else if (VALUE_TYPE (val_args[i])->code == TYPE_CODE_FLT) + { + *((double *) &arg_bytes[argindex]) = value_as_double (val_args[i]); + argindex += sizeof (double); + } + else + { + *((int *) &arg_bytes[argindex]) = value_as_long (val_args[i]); + argindex += sizeof (int); + } + } + + vprintf (string, arg_bytes); +} + static initialize () { @@ -925,6 +1281,11 @@ The selected stack frame's lexical context is used to look up the name."); add_com ("whatis", class_vars, whatis_command, "Print data type of expression EXP."); + add_com ("pmethod", class_vars, pmethod_command, + "Print definitions of method METHOD.\n\ +Argument must resolve to a method name within the containing scope.\n\ +All definitions found go into history array."); + add_info ("display", display_info, "Expressions to display when program stops, with code numbers."); add_com ("undisplay", class_vars, undisplay_command, @@ -941,6 +1302,9 @@ and examining is done as in the \"x\" command.\n\n\ With no argument, display all currently requested auto-display expressions.\n\ Use \"undisplay\" to cancel display requests previously made."); + add_com ("printf", class_vars, printf_command, + "printf \"printf format string\", arg1, arg2, arg3, ..., argn\n\ +This is useful for formatted output in user-defined commands."); add_com ("output", class_vars, output_command, "Like \"print\" but don't put in value history and don't print newline.\n\ This is useful in user-defined commands."); diff --git a/gdb/remote.c b/gdb/remote.c new file mode 100644 index 0000000..23f27df --- /dev/null +++ b/gdb/remote.c @@ -0,0 +1,607 @@ +/* Memory-access and commands for inferior process, for GDB. + Copyright (C) 1988 Free Software Foundation, Inc. + +GDB is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY. No author or distributor accepts responsibility to anyone +for the consequences of using it or for whether it serves any +particular purpose or works at all, unless he says so in writing. +Refer to the GDB General Public License for full details. + +Everyone is granted permission to copy, modify and redistribute GDB, +but only under the conditions described in the GDB General Public +License. A copy of this license is supposed to have been given to you +along with GDB so you can know your rights and responsibilities. It +should be in a file named COPYING. Among other things, the copyright +notice and this notice must be preserved on all copies. + +In other words, go ahead and share GDB, but don't try to stop +anyone else from sharing it farther. Help stamp out software hoarding! +*/ + +/* Remote communication protocol. + All values are encoded in ascii hex digits. + + Request Packet + + read registers g + reply XX....X Each byte of register data + is described by two hex digits. + Registers are in the internal order + for GDB, and the bytes in a register + are in the same order the machine uses. + or ENN for an error. + + write regs GXX..XX Each byte of register data + is described by two hex digits. + reply OK for success + ENN for an error + + read mem mAA..AA,LLLL AA..AA is address, LLLL is length. + reply XX..XX XX..XX is mem contents + or ENN NN is errno + + write mem MAA..AA,LLLL:XX..XX + AA..AA is address, + LLLL is number of bytes, + XX..XX is data + reply OK for success + ENN for an error + + cont cAA..AA AA..AA is address to resume + If AA..AA is omitted, + resume at same address. + + step sAA..AA AA..AA is address to resume + If AA..AA is omitted, + resume at same address. + + There is no immediate reply to step or cont. + The reply comes when the machine stops. + It is SAA AA is the "signal number" + + kill req k +*/ + +#include <stdio.h> +#include <signal.h> + +#include "defs.h" +#include "initialize.h" +#include "param.h" +#include "frame.h" +#include "inferior.h" + +#include <sys/wait.h> +#include <sys/ioctl.h> +#include <a.out.h> +#include <sys/file.h> +#include <sgtty.h> + +int kiodebug; + +int icache; + +/* Descriptor for I/O to remote machine. */ +int remote_desc; + +#define PBUFSIZ 300 + +static void remote_send (); +static void putpkt (); +static void getpkt (); +static void dcache_flush (); + +START_FILE + +/* Open a connection to a remote debugger. + NAME is the filename used for communication. */ + +void +remote_open (name, from_tty) + char *name; + int from_tty; +{ + struct sgttyb sg; + + remote_debugging = 0; + dcache_init (); + + remote_desc = open (name, O_RDWR); + if (remote_desc < 0) + perror_with_name (name); + + ioctl (remote_desc, TIOCGETP, &sg); + sg.sg_flags = RAW; + ioctl (remote_desc, TIOCSETP, &sg); + + if (from_tty) + printf ("Remote debugging using %s\n", name); + remote_debugging = 1; +} + +/* Convert hex digit A to a number. */ + +static int +fromhex (a) + int a; +{ + if (a >= '0' && a <= '9') + return a - '0'; + else if (a >= 'a' && a <= 'f') + return a - 'a' + 10; + else + error ("Reply contains invalid hex digit"); +} + +/* Convert number NIB to a hex digit. */ + +static int +tohex (nib) + int nib; +{ + if (nib < 10) + return '0'+nib; + else + return 'a'+nib-10; +} + +/* Tell the remote machine to resume. */ + +int +remote_resume (step, signal) + int step, signal; +{ + char buf[PBUFSIZ]; + + dcache_flush (); + + strcpy (buf, step ? "s": "c"); + + putpkt (buf); +} + +/* Wait until the remote machine stops, then return, + storing status in STATUS just as `wait' would. */ + +int +remote_wait (status) + union wait *status; +{ + char buf[PBUFSIZ]; + + status->w_status = 0; + getpkt (buf); + if (buf[0] == 'E') + error ("Remote failure reply: %s", buf); + if (buf[0] != 'S') + error ("Invalid remote reply: %s", buf); + status->w_stopval = WSTOPPED; + status->w_stopsig = (fromhex (buf[1]) << 4) + fromhex (buf[2]); +} + +/* Read the remote registers into the block REGS. */ + +void +remote_fetch_registers (regs) + char *regs; +{ + char buf[PBUFSIZ]; + int i; + char *p; + + sprintf (buf, "g"); + remote_send (buf); + + /* Reply describes registers byte by byte, + each byte encoded as two hex characters. */ + + p = buf; + for (i = 0; i < REGISTER_BYTES; i++) + { + if (p[0] == 0 || p[1] == 0) + error ("Remote reply is too short: %s", buf); + regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]); + p += 2; + } +} + +/* Store the remote registers from the contents of the block REGS. */ + +void +remote_store_registers (regs) + char *regs; +{ + char buf[PBUFSIZ]; + int i; + char *p; + + buf[0] = 'G'; + + /* Command describes registers byte by byte, + each byte encoded as two hex characters. */ + + p = buf + 1; + for (i = 0; i < REGISTER_BYTES; i++) + { + *p++ = (regs[i] > 4) & 0xf; + *p++ = regs[i] & 0xf; + } + + remote_send (buf); +} + +/* Read a word from remote address ADDR and return it. + This goes through the data cache. */ + +int +remote_fetch_word (addr) + CORE_ADDR addr; +{ + if (icache) + { + extern CORE_ADDR text_start, text_end; + + if (addr >= text_start && addr < text_end) + { + int buffer; + xfer_core_file (addr, &buffer, sizeof (int)); + return buffer; + } + } + return dcache_fetch (addr); +} + +/* Write a word WORD into remote address ADDR. + This goes through the data cache. */ + +void +remote_store_word (addr, word) + CORE_ADDR addr; + int word; +{ + dcache_poke (addr, word); +} + +/* Write memory data directly to the remote machine. + This does not inform the data cache; the data cache uses this. + MEMADDR is the address in the remote memory space. + MYADDR is the address of the buffer in our space. + LEN is the number of bytes. */ + +void +remote_write_bytes (memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + char buf[PBUFSIZ]; + int i; + char *p; + + if (len > PBUFSIZ / 2 - 20) + abort (); + + sprintf (buf, "M%x,%x:", memaddr, len); + + /* Command describes registers byte by byte, + each byte encoded as two hex characters. */ + + p = buf + strlen (buf); + for (i = 0; i < len; i++) + { + *p++ = (myaddr[i] > 4) & 0xf; + *p++ = myaddr[i] & 0xf; + } + + remote_send (buf); +} + +/* Read memory data directly from the remote machine. + This does not use the data cache; the data cache uses this. + MEMADDR is the address in the remote memory space. + MYADDR is the address of the buffer in our space. + LEN is the number of bytes. */ + +void +remote_read_bytes (memaddr, myaddr, len) + CORE_ADDR memaddr; + char *myaddr; + int len; +{ + char buf[PBUFSIZ]; + int i; + char *p; + + if (len > PBUFSIZ / 2 - 1) + abort (); + + sprintf (buf, "m%x,%x", memaddr, len); + remote_send (buf); + + /* Reply describes registers byte by byte, + each byte encoded as two hex characters. */ + + p = buf; + for (i = 0; i < REGISTER_BYTES; i++) + { + if (p[0] == 0 || p[1] == 0) + error ("Remote reply is too short: %s", buf); + myaddr[i] = fromhex (p[0]) * 16 + fromhex (p[1]); + p += 2; + } +} + +/* + +A debug packet whose contents are <data> +is encapsulated for transmission in the form: + + $ <data> # CSUM1 CSUM2 + + <data> must be ASCII alphanumeric and cannot include characters + '$' or '#' + + CSUM1 and CSUM2 are ascii hex representation of an 8-bit + checksum of <data>, the most significant nibble is sent first. + the hex digits 0-9,a-f are used. + +Receiver responds with: + + + - if CSUM is correct and ready for next packet + - - if CSUM is incorrect + +*/ + +/* Send the command in BUF to the remote machine, + and read the reply into BUF. + Report an error if we get an error reply. */ + +static void +remote_send (buf) + char *buf; +{ + int i; + putpkt (buf); + getpkt (buf); + + if (buf[0] == 'E') + error ("Remote failure reply: %s", buf); +} + +/* Send a packet to the remote machine, with error checking. + The data of the packet is in BUF. */ + +static void +putpkt (buf) + char *buf; +{ + int i; + char csum = 0; + char buf2[500]; + char buf3[1]; + int cnt = strlen (buf); + char *p; + + if (kiodebug) + fprintf (stderr, "Sending packet: %s\n", buf); + + /* Copy the packet into buffer BUF2, encapsulating it + and giving it a checksum. */ + + p = buf2; + *p++ = '$'; + + for (i = 0; i < cnt; i++) + { + csum += buf[i]; + *p++ = buf[i]; + } + *p++ = '#'; + *p++ = tohex ((csum >> 4) & 0xf); + *p++ = tohex (csum & 0xf); + + /* Send it over and over until we get a positive ack. */ + + do { + write (remote_desc, buf2, p - buf2); + read (remote_desc, buf3, 1); + } while (buf3[0] != '+'); +} + +static int +readchar () +{ + char buf[1]; + while (read (remote_desc, buf, 1) != 1) ; + return buf[0] & 0x7f; +} + +/* Read a packet from the remote machine, with error checking, + and store it in BUF. */ + +static void +getpkt (buf) + char *buf; +{ + char *bp; + char csum = 0; + int c, c1, c2; + extern kiodebug; + + while (1) + { + while ((c = readchar()) != '$'); + + bp = buf; + while (1) + { + c = readchar (); + if (c == '#') + break; + *bp++ = c; + csum += c; + } + *bp = 0; + + c1 = fromhex (readchar ()); + c2 = fromhex (readchar ()); + if (csum == (c1 << 4) + c2) + break; + printf ("Bad checksum, sentsum=0x%x, csum=0x%x, buf=%s\n", + (c1 << 4) + c2, csum, buf); + write (remote_desc, "-", 1); + } + + write (remote_desc, "+", 1); + + if (kiodebug) + fprintf (stderr,"Packet received :%s\n", buf); +} + +/* The data cache records all the data read from the remote machine + since the last time it stopped. + + Each cache block holds 16 bytes of data + starting at a multiple-of-16 address. */ + +#define DCACHE_SIZE 64 /* Number of cache blocks */ + +struct dcache_block { + struct dcache_block *next, *last; + unsigned int addr; /* Address for which data is recorded. */ + int data[4]; +}; + +struct dcache_block dcache_free, dcache_valid; + +/* Free all the data cache blocks, thus discarding all cached data. */ + +static void +dcache_flush () +{ + register struct dcache_block *db; + + while ((db = dcache_valid.next) != &dcache_valid) + { + remque (db); + insque (db, &dcache_free); + } +} + +/* + * If addr is present in the dcache, return the address of the block + * containing it. + */ + +struct dcache_block * +dcache_hit (addr) +{ + register struct dcache_block *db; + + if (addr & 3) + abort (); + + /* Search all cache blocks for one that is at this address. */ + db = dcache_valid.next; + while (db != &dcache_valid) + { + if ((addr & 0xfffffff0) == db->addr) + return db; + db = db->next; + } + return NULL; +} + +/* Return the int data at address ADDR in dcache block DC. */ + +int +dcache_value (db, addr) + struct dcache_block *db; + unsigned int addr; +{ + if (addr & 3) + abort (); + return (db->data[(addr>>2)&3]); +} + +/* Get a free cache block, put it on the valid list, + and return its address. The caller should store into the block + the address and data that it describes. */ + +struct dcache_block * +dcache_alloc () +{ + register struct dcache_block *db; + + if ((db = dcache_free.next) == &dcache_free) + /* If we can't get one from the free list, take last valid */ + db = dcache_valid.last; + + remque (db); + insque (db, &dcache_valid); + return (db); +} + +/* Return the contents of the word at address ADDR in the remote machine, + using the data cache. */ + +int +dcache_fetch (addr) + CORE_ADDR addr; +{ + register struct dcache_block *db; + + db = dcache_hit (addr); + if (db == 0) + { + db = dcache_alloc (); + remote_read_bytes (addr & ~0xf, db->data, 16); + db->addr = addr & ~0xf; + } + return (dcache_value (db, addr)); +} + +/* Write the word at ADDR both in the data cache and in the remote machine. */ + +dcache_poke (addr, data) + CORE_ADDR addr; + int data; +{ + register struct dcache_block *db; + + /* First make sure the word is IN the cache. DB is its cache block. */ + db = dcache_hit (addr); + if (db == 0) + { + db = dcache_alloc (); + remote_read_bytes (addr & ~0xf, db->data, 16); + db->addr = addr & ~0xf; + } + + /* Modify the word in the cache. */ + db->data[(addr>>2)&3] = data; + + /* Send the changed word. */ + remote_write_bytes (addr, &data, 4); +} + +/* Initialize the data cache. */ + +dcache_init () +{ + register i; + register struct dcache_block *db; + + db = (struct dcache_block *) xmalloc (sizeof (struct dcache_block) * + DCACHE_SIZE); + dcache_free.next = dcache_free.last = &dcache_free; + dcache_valid.next = dcache_valid.last = &dcache_valid; + for (i=0;i<DCACHE_SIZE;i++,db++) + insque (db, &dcache_free); +} + +static initialize () +{ +} + +END_FILE diff --git a/gdb/song b/gdb/song deleted file mode 100644 index ad65ee9..0000000 --- a/gdb/song +++ /dev/null @@ -1,44 +0,0 @@ -Date: Tue, 6 Oct 87 08:52:07 PDT -To: bug-gnu-emacs@prep.ai.mit.edu -From: Lynn Slater <silvlis!wobegon!lrs@sun.com> -Sender: silvlis!wobegon!lrs@sun.com -Organization: Silvar-Lisco, 1080 Marsh Road, Menlo Park, CA 94025-1053 -Phone.......: (415) 853-6336 (Office); (415) 796-4149 (Home) -Subject: GDB sing-along - - -Somebody asked us what was GDB. With apologies to Oscar Hemmerstein -II, Richard Rodgers, and Julie Andrews, we offered the following reply: - -Let's start at the very beginning, a very good place to start, - When you're learning to sing, its Do, Re, Mi; - When you're learning to code, its G, D, B. - (background) G, D, B. - The first three letters just happen to be, G, D, B. - (background) G, D, B. - -(Chorus) - G!, GNU!, it's Stallman's hope, - - B, a break I set myself. - - D, debug that rotten code, - - Run, a far, far way to go. - - Print, to see what you have done, - - Set, a patch that follows print. - - Quit, and recompile your code - - - - -That will bring it back to G, - D, - B, - <link> - -(Resume from the Chorus) - - -:-) Joel Bion, Mark Baushke, and Lynn Slater :-) - diff --git a/gdb/source.c b/gdb/source.c index 27ffd8f..e1d1b42 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -1,5 +1,5 @@ /* List lines of source files for GDB, the GNU debugger. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. + Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. GDB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone @@ -19,7 +19,6 @@ 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> @@ -40,9 +39,10 @@ struct symtab *current_source_symtab; int current_source_line; -/* Line for "info line" to work on if no line specified. */ +/* Line number of last line printed. Default for various commands. + current_source_line is usually, but not always, the same as this. */ -static int line_info_default_line; +static int last_line_listed; /* First line number listed by last listing command. */ @@ -59,13 +59,16 @@ select_source_symtab (s) { if (s) { + struct symtabs_and_lines sals; 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); + sals = decode_line_spec ("main", 1); + sal = sals.sals[0]; + free (sals.sals); current_source_symtab = sal.symtab; current_source_line = sal.line - 9; return; @@ -275,10 +278,7 @@ openp (path, try_cwd_first, string, mode, prot, filename_opened) *filename_opened = savestring (filename, strlen (filename)); else { - char dirname[MAXPATHLEN]; - if (getwd (dirname) == NULL) - perror_with_name ("getwd"); - *filename_opened = concat (dirname, "/", filename); + *filename_opened = concat (current_directory, "/", filename); } return fd; @@ -376,17 +376,40 @@ get_filename_and_charpos (s, line, fullname) { register int desc, linenums_changed = 0; - desc = openp (source_path, 0, s->filename, O_RDONLY, 0, fullname); + desc = openp (source_path, 0, s->filename, O_RDONLY, 0, &s->fullname); if (desc < 0) { - *fullname = NULL; + if (fullname) + *fullname = NULL; return 0; } + if (fullname) + *fullname = s->fullname; if (s->line_charpos == 0) linenums_changed = 1; if (linenums_changed) find_source_lines (s, desc); close (desc); return linenums_changed; } + +/* Print text describing the full name of the source file S + and the line number LINE and its corresponding character position. + The text starts with two Ctrl-z so that the Emacs-GDB interface + can easily find it. + + Return 1 if successful, 0 if could not find the file. */ + +int +identify_source_line (s, line) + struct symtab *s; + int line; +{ + if (s->line_charpos == 0) + get_filename_and_charpos (s, line, 0); + if (s->fullname == 0) + return 0; + printf ("\032\032%s:%d:%d\n", s->fullname, line, s->line_charpos[line - 1]); + return 1; +} /* Print source lines from the file of symtab S, starting with line number LINE and stopping before line number STOPLINE. */ @@ -401,7 +424,7 @@ print_source_lines (s, line, stopline) register FILE *stream; int nlines = stopline - line; - desc = openp (source_path, 0, s->filename, O_RDONLY, 0, (char **) 0); + desc = openp (source_path, 0, s->filename, O_RDONLY, 0, &s->fullname); if (desc < 0) perror_with_name (s->filename); @@ -432,7 +455,7 @@ print_source_lines (s, line, stopline) { c = fgetc (stream); if (c == EOF) break; - line_info_default_line = current_source_line; + last_line_listed = current_source_line; printf ("%d\t", current_source_line++); do { @@ -456,6 +479,7 @@ list_command (arg, from_tty) char *arg; int from_tty; { + struct symtabs_and_lines sals, sals_end; struct symtab_and_line sal, sal_end; struct symbol *sym; char *arg1; @@ -500,7 +524,18 @@ list_command (arg, from_tty) if (*arg1 == ',') dummy_beg = 1; else - sal = decode_line_1 (&arg1, 0, 0, 0); + { + sals = decode_line_1 (&arg1, 0, 0, 0); + + if (! sals.nelts) return; /* C++ */ + if (sals.nelts != 1) + { + error ("Unreasonable listing request"); + } + + sal = sals.sals[0]; + free (sals.sals); + } /* Record whether the BEG arg is all digits. */ @@ -517,10 +552,16 @@ list_command (arg, from_tty) 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 (dummy_beg) + sals_end = decode_line_1 (&arg1, 0, 0, 0); + else + sals_end = decode_line_1 (&arg1, 0, sal.symtab, sal.line); + if (! sals_end.nelts) return; /* C++ */ + sal_end = sals_end.sals[0]; + free (sals_end.sals); + } } if (*arg1) @@ -583,18 +624,26 @@ line_info (arg, from_tty) char *arg; int from_tty; { + struct symtabs_and_lines sals; struct symtab_and_line sal; int start_pc, end_pc; if (arg == 0) { sal.symtab = current_source_symtab; - sal.line = line_info_default_line; + sal.line = last_line_listed; } else { - sal = decode_line_spec (arg); - + sals = decode_line_spec (arg); + + if (sals.nelts == 0) + return; /* C++ */ + if (sals.nelts != 1) + error ("unreasonable line info request"); + + sal = sals.sals[0]; + free (sals.sals); /* If this command is repeated with RET, turn it into the no-arg variant. */ @@ -616,13 +665,162 @@ line_info (arg, from_tty) /* 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; + last_line_listed = sal.line + 1; } else printf ("Line number %d is out of range for \"%s\".\n", sal.line, sal.symtab->filename); } +/* Commands to search the source file for a regexp. */ + +static void +forward_search_command (regex, from_tty) + char *regex; +{ + register int c; + register int desc; + register FILE *stream; + int line = last_line_listed + 1; + char *msg; + + msg = (char *) re_comp (regex); + if (msg) + error (msg); + + if (current_source_symtab == 0) + error ("No default source file yet. Do \"help list\"."); + + /* Search from last_line_listed+1 in current_source_symtab */ + + desc = openp (source_path, 0, current_source_symtab->filename, + O_RDONLY, 0, ¤t_source_symtab->fullname); + if (desc < 0) + perror_with_name (current_source_symtab->filename); + + if (current_source_symtab->line_charpos == 0) + find_source_lines (current_source_symtab, desc); + + if (line < 1 || line >= current_source_symtab->nlines) + { + close (desc); + error ("Expression not found"); + } + + if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0) + { + close (desc); + perror_with_name (current_source_symtab->filename); + } + + stream = fdopen (desc, "r"); + clearerr (stream); + while (1) { + char buf[4096]; /* Should be reasonable??? */ + register char *p = buf; + + c = fgetc (stream); + if (c == EOF) + break; + do { + *p++ = c; + } while (c != '\n' && (c = fgetc (stream)) >= 0); + + /* we now have a source line in buf, null terminate and match */ + *p = 0; + if (re_exec (buf) > 0) + { + /* Match! */ + fclose (stream); + print_source_lines (current_source_symtab, + line, line+1); + current_source_line = max (line - 5, 1); + return; + } + line++; + } + + printf ("Expression not found\n"); + fclose (stream); +} + +static void +reverse_search_command (regex, from_tty) + char *regex; +{ + register int c; + register int desc; + register FILE *stream; + int line = last_line_listed - 1; + char *msg; + + msg = (char *) re_comp (regex); + if (msg) + error (msg); + + if (current_source_symtab == 0) + error ("No default source file yet. Do \"help list\"."); + + /* Search from last_line_listed-1 in current_source_symtab */ + + desc = openp (source_path, 0, current_source_symtab->filename, + O_RDONLY, 0, ¤t_source_symtab->fullname); + if (desc < 0) + perror_with_name (current_source_symtab->filename); + + if (current_source_symtab->line_charpos == 0) + find_source_lines (current_source_symtab, desc); + + if (line < 1 || line >= current_source_symtab->nlines) + { + close (desc); + error ("Expression not found"); + } + + if (lseek (desc, current_source_symtab->line_charpos[line - 1], 0) < 0) + { + close (desc); + perror_with_name (current_source_symtab->filename); + } + + stream = fdopen (desc, "r"); + clearerr (stream); + while (1) + { + char buf[4096]; /* Should be reasonable??? */ + register char *p = buf; + + c = fgetc (stream); + if (c == EOF) + break; + do { + *p++ = c; + } while (c != '\n' && (c = fgetc (stream)) >= 0); + + /* We now have a source line in buf; null terminate and match. */ + *p = 0; + if (re_exec (buf) > 0) + { + /* Match! */ + fclose (stream); + print_source_lines (current_source_symtab, + line, line+1); + current_source_line = max (line - 5, 1); + return; + } + line--; + if (fseek (stream, current_source_symtab->line_charpos[line - 1], 0) < 0) + { + fclose (stream); + perror_with_name (current_source_symtab->filename); + } + } + + printf ("Expression not found\n"); + fclose (stream); + return; +} + static initialize () { @@ -649,6 +847,13 @@ This sets the default address for \"x\" to the line's first instruction\n\ so that \"x/i\" suffices to start examining the machine code.\n\ The address is also stored as the value of \"$_\"."); + add_com ("forward-search", class_files, forward_search_command, + "Search for regular expression (see regex(3)) from last line listed."); + add_com_alias ("search", "forward-search", class_files, 0); + + add_com ("reverse-search", class_files, reverse_search_command, + "Search backward for regular expression (see regex(3)) from last line listed."); + add_com ("list", class_files, list_command, "List specified function or line.\n\ With no argument, lists ten more lines after or around previous listing.\n\ diff --git a/gdb/stack.c b/gdb/stack.c index 2698729..fce015b 100644 --- a/gdb/stack.c +++ b/gdb/stack.c @@ -39,6 +39,11 @@ FRAME selected_frame; int selected_frame_level; +/* Nonzero means print the full filename and linenumber + when a frame is printed, and do so in a format programs can parse. */ + +int frame_file_full_name = 0; + static void select_calling_frame (); void print_frame_info (); @@ -114,9 +119,13 @@ print_frame_info (fi, level, source, args) if (source != 0 && sal.symtab) { + int done = 0; if (source < 0 && fi->pc != sal.pc) printf ("0x%x\t", fi->pc); - print_source_lines (sal.symtab, sal.line, sal.line + 1); + if (frame_file_full_name) + done = identify_source_line (sal.symtab, sal.line); + if (!done) + print_source_lines (sal.symtab, sal.line, sal.line + 1); current_source_line = max (sal.line - 5, 1); } if (source != 0) diff --git a/gdb/symmisc.c b/gdb/symmisc.c index d17cbdd..5dcb886 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -105,11 +105,6 @@ free_symtab (s) 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. */ @@ -122,8 +117,7 @@ free_symtab (s) free (bv); /* Free the type vector. */ tv = TYPEVECTOR (s); - if (tv) /* FIXME, should this happen? It does... */ - free (tv); + free (tv); /* Also free the linetable. */ case free_linetable: @@ -177,10 +171,11 @@ static void relocate_blockvector (); static void relocate_type (); static void relocate_block (); static void relocate_symbol (); +static void relocate_source (); -/* 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. */ +/* Relocate a file's symseg so that all the pointers are valid C pointers. + Value is a `struct symtab'; but it is not suitable for direct + insertion into the `symtab_list' because it describes several files. */ static struct symtab * relocate_symtab (root) @@ -203,8 +198,6 @@ relocate_symtab (root) 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)); @@ -219,19 +212,6 @@ relocate_symtab (root) } 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; { @@ -289,6 +269,19 @@ relocate_symbol (sp) RELOCATE (SYMBOL_TYPE (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)); +} + /* 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. @@ -314,10 +307,40 @@ relocate_type (tp) RELOCATE (TYPE_FIELD_NAME (tp, i)); } } + +static void +relocate_sourcevector (svp) + register struct sourcevector *svp; +{ + register int nfiles = svp->length; + register int i; + for (i = 0; i < nfiles; i++) + RELOCATE (svp->source[i]); + for (i = 0; i < nfiles; i++) + relocate_source (svp->source[i]); +} + +static void +relocate_source (sp) + register struct source *sp; +{ + register int nitems = sp->contents.nitems; + register int i; + + RELOCATE (sp->name); + for (i = 0; i < nitems; i++) + if (sp->contents.item[i] > 0) + TEXT_RELOCATE (sp->contents.item[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, + These symtabs are not suitable for direct use in `symtab_list' + because each one describes a single object file, perhaps many source files. + `symbol_file_command' takes each of these, makes many real symtabs + from it, and then frees it. + + We assume DESC is prepositioned at the end of the string table, just before the symsegs if there are any. */ struct symtab * @@ -327,7 +350,7 @@ read_symsegs (desc, name) { struct symbol_root root; register char *data; - register struct symtab *sp, *chain = 0; + register struct symtab *sp, *sp1, *chain = 0; register int len; while (1) @@ -343,8 +366,11 @@ read_symsegs (desc, name) len = myread (desc, data + sizeof root, root.length - sizeof root); sp = relocate_symtab (data); + RELOCATE (((struct symbol_root *)data)->sourcevector); + relocate_sourcevector (((struct symbol_root *)data)->sourcevector); sp->next = chain; chain = sp; + sp->linetable = (struct linetable *) ((struct symbol_root *)data)->sourcevector; } return chain; diff --git a/gdb/symseg.h b/gdb/symseg.h index 11f4807..f5ad8ea 100644 --- a/gdb/symseg.h +++ b/gdb/symseg.h @@ -1,5 +1,6 @@ /* GDB symbol table format definitions. Copyright (C) 1986 Free Software Foundation, Inc. + Hacked by Michael Tiemann (tiemann@mcc.com) GDB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone @@ -77,15 +78,16 @@ struct symbol_root int textrel; /* Relocation for text addresses */ int datarel; /* Relocation for data addresses */ int bssrel; /* Relocation for bss addresses */ - char *filename; /* Name of source file compiled */ + char *filename; /* Name of main source file compiled */ char *filedir; /* Name of directory it was reached from */ - struct blockvector *blockvector; /* Vector of all symbol naming blocks */ + struct blockvector *blockvector; /* Vector of all symbol-naming blocks */ struct typevector *typevector; /* Vector of all data types */ enum language language; /* Code identifying the language used */ char *version; /* Version info. Not fully specified */ char *compilation; /* Compilation info. Not fully specified */ int databeg; /* Address within the file of data start */ int bssbeg; /* Address within the file of bss start */ + struct sourcevector *sourcevector; /* Vector of line-number info */ }; /* All data types of symbols in the compiled program @@ -95,7 +97,7 @@ struct symbol_root struct typevector { - int length; + int length; /* Number of types described */ struct type *type[1]; }; @@ -116,6 +118,10 @@ enum type_code TYPE_CODE_SET, /* Pascal sets */ TYPE_CODE_RANGE, /* Range (integers within spec'd bounds) */ TYPE_CODE_PASCAL_ARRAY, /* Array with explicit type of index */ + + /* C++ */ + TYPE_CODE_MPTR, /* Member pointer type */ + TYPE_CODE_REF, /* C++ Reference types */ }; /* This appears in a type's flags word for an unsigned integer type. */ @@ -143,11 +149,22 @@ struct type The debugger may add the address of such a type if it has to construct one later. */ struct type *pointer_type; + /* C++: also need a reference type. */ + struct type *reference_type; /* Type that is a function returning this type. Zero if no such function type is known here. The debugger may add the address of such a type if it has to construct one later. */ struct type *function_type; + +/* Handling of pointers to members: + TYPE_MAIN_VARIANT is used for pointer and pointer + to member types. Normally it the value of the address of its + containing type. However, for pointers to members, we must be + able to allocate pointer to member types and look them up + from some place of reference. */ + struct type *main_variant; + /* Flags about this type. */ short flags; /* Number of fields described for this type */ @@ -184,6 +201,75 @@ struct type Zero for range bounds and array domains. */ char *name; } *fields; + + /* C++ */ + int *private_field_bits; + int *protected_field_bits; + + /* Some flags to make life easier. */ + unsigned char has_constructor; + unsigned char has_destructor; + + /* Number of methods described for this type */ + short nfn_fields; + + /* Number of methods described for this type plus all the + methods that it derives from. */ + int nfn_fields_total; + + /* For classes, structures, and unions, a description of each field, + which consists of an overloaded name, followed by the types of + arguments that the method expects, and then the name after it + has been renamed to make it distinct. */ + struct fn_fieldlist + { + /* The overloaded name. */ + char *name; + /* The number of methods with this name. */ + int length; + /* The list of methods. */ + struct fn_field + { +#if 0 + /* The overloaded name */ + char *name; +#endif + /* The type of the argument */ + struct type *type; + /* The argument list */ + struct type **args; + /* The name after it has been processed */ + char *physname; + /* If this is a virtual function, the offset into the vtbl-1, + else 0. */ + int voffset; + } *fn_fields; + + int *private_fn_field_bits; + int *protected_fn_field_bits; + + } *fn_fieldlists; + + unsigned char via_protected; + unsigned char via_public; + + /* For types with virtual functions, VPTR_BASETYPE is the base class which + defined the virtual function table pointer. VPTR_FIELDNO is + the field number of that pointer in the structure. + + For types that are pointer to member types, VPTR_BASETYPE + ifs the type that this pointer is a member of. + + Unused otherwise. */ + struct type *vptr_basetype; + + int vptr_fieldno; + + /* If this type has a base class, put it here. + If this type is a pointer type, the chain of member pointer + types goes here. + Unused otherwise. */ + struct type *baseclass; }; /* All of the name-scope contours of the program @@ -321,3 +407,37 @@ struct symbol } value; }; + +/* Source-file information. + This describes the relation between source files and line numbers + and addresses in the program text. */ + +struct sourcevector +{ + int length; /* Number of source files described */ + struct source *source[1]; /* Descriptions of the files */ +}; + +/* Each item is either minus a line number, or a program counter. + If it represents a line number, that is the line described by the next + program counter value. If it is positive, it is the program + counter at which the code for the next line starts. + + Consecutive lines can be recorded by program counter entries + with no line number entries between them. Line number entries + are used when there are lines to skip with no code on them. + This is to make the table shorter. */ + +struct linetable + { + int nitems; + int item[1]; + }; + +/* All the information on one source file. */ + +struct source +{ + char *name; /* Name of file */ + struct linetable contents; +}; diff --git a/gdb/symtab.c b/gdb/symtab.c index a413bfa..5540954 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -1,5 +1,5 @@ /* Symbol table lookup for the GNU debugger, GDB. - Copyright (C) 1986, 1987 Free Software Foundation, Inc. + Copyright (C) 1986, 1987, 1988 Free Software Foundation, Inc. GDB is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to anyone @@ -26,10 +26,6 @@ anyone else from sharing it farther. Help stamp out software hoarding! #include <stdio.h> #include <obstack.h> -#ifdef mac_aux -#define REGCMP -#endif - START_FILE /* Allocate an obstack to hold objects that should be freed @@ -143,7 +139,7 @@ lookup_struct (name, block) 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); + error ("This context has class, union or enum %s, not a struct.", name); return SYMBOL_TYPE (sym); } @@ -159,7 +155,7 @@ lookup_union (name, block) 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); + error ("This context has class, struct or enum %s, not a union.", name); return SYMBOL_TYPE (sym); } @@ -175,19 +171,22 @@ lookup_enum (name, block) 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); + error ("This context has class, 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. */ + May need to construct such a type if this is the first use. + + C++: use TYPE_MAIN_VARIANT and TYPE_CHAIN to keep pointer + to member types under control. */ struct type * lookup_pointer_type (type) struct type *type; { register struct type *ptype = TYPE_POINTER_TYPE (type); - if (ptype) return ptype; + if (ptype) return TYPE_MAIN_VARIANT (ptype); /* This is the first time anyone wanted a pointer to a TYPE. */ if (TYPE_FLAGS (type) & TYPE_FLAG_PERM) @@ -197,6 +196,7 @@ lookup_pointer_type (type) sizeof (struct type)); bzero (ptype, sizeof (struct type)); + TYPE_MAIN_VARIANT (ptype) = ptype; TYPE_TARGET_TYPE (ptype) = type; TYPE_POINTER_TYPE (type) = ptype; /* New type is permanent if type pointed to is permanent. */ @@ -208,12 +208,100 @@ lookup_pointer_type (type) return ptype; } +struct type * +lookup_reference_type (type) + struct type *type; +{ + register struct type *rtype = TYPE_REFERENCE_TYPE (type); + if (rtype) return TYPE_MAIN_VARIANT (rtype); + + /* This is the first time anyone wanted a pointer to a TYPE. */ + if (TYPE_FLAGS (type) & TYPE_FLAG_PERM) + rtype = (struct type *) xmalloc (sizeof (struct type)); + else + rtype = (struct type *) obstack_alloc (symbol_obstack, + sizeof (struct type)); + + bzero (rtype, sizeof (struct type)); + TYPE_MAIN_VARIANT (rtype) = rtype; + TYPE_TARGET_TYPE (rtype) = type; + TYPE_REFERENCE_TYPE (type) = rtype; + /* New type is permanent if type pointed to is permanent. */ + if (TYPE_FLAGS (type) & TYPE_FLAG_PERM) + TYPE_FLAGS (rtype) |= TYPE_FLAG_PERM; + /* We assume the machine has only one representation for pointers! */ + TYPE_LENGTH (rtype) = sizeof (char *); + TYPE_CODE (rtype) = TYPE_CODE_REF; + return rtype; +} + + +/* 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. + The TYPE is the type of the member. The DOMAIN is the type + of the aggregate that the member belongs to. */ + +struct type * +lookup_member_pointer_type (type, domain) + struct type *type, *domain; +{ + register struct type *ptype = TYPE_POINTER_TYPE (type); + struct type *main_type; + + if (ptype) + { + ptype = TYPE_MAIN_VARIANT (ptype); + main_type = ptype; + while (ptype) + { + if (TYPE_DOMAIN_TYPE (ptype) == domain) + return ptype; + ptype = TYPE_CHAIN (ptype); + } + } + else + { + main_type = lookup_pointer_type (type); + TYPE_POINTER_TYPE (type) = main_type; + } + + /* 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_MAIN_VARIANT (ptype) = main_type; + TYPE_TARGET_TYPE (ptype) = type; + TYPE_DOMAIN_TYPE (ptype) = domain; + 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_MPTR; + + /* Now splice in the new member pointer type. */ + if (main_type) + { + /* This type was not "smashed". */ + TYPE_CHAIN (ptype) = TYPE_CHAIN (main_type); + TYPE_CHAIN (main_type) = ptype; + } + + 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) +lookup_function_type (type, argtypes) struct type *type; + struct type **argtypes; { register struct type *ptype = TYPE_FUNCTION_TYPE (type); if (ptype) return ptype; @@ -251,6 +339,8 @@ smash_to_pointer_type (type, to_type) TYPE_LENGTH (type) = sizeof (char *); TYPE_CODE (type) = TYPE_CODE_PTR; + TYPE_MAIN_VARIANT (type) = type; + if (TYPE_POINTER_TYPE (to_type) == 0 && !(TYPE_FLAGS (type) & TYPE_FLAG_PERM)) { @@ -258,6 +348,56 @@ smash_to_pointer_type (type, to_type) } } +/* 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. + + TYPE is the type of the member. DOMAIN is the type of + the aggregate that the member belongs to. */ + +void +smash_to_member_pointer_type (type, domain, to_type) + struct type *type, *domain, *to_type; +{ + bzero (type, sizeof (struct type)); + TYPE_TARGET_TYPE (type) = to_type; + TYPE_DOMAIN_TYPE (type) = domain; + /* We assume the machine has only one representation for pointers! */ + TYPE_LENGTH (type) = sizeof (char *); + TYPE_CODE (type) = TYPE_CODE_MPTR; + + TYPE_MAIN_VARIANT (type) = lookup_pointer_type (to_type); + + 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 reference to TO_TYPE. + If TO_TYPE is not permanent and has no pointer-type yet, + record TYPE as its pointer-type. */ + +void +smash_to_reference_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_REF; + + TYPE_MAIN_VARIANT (type) = type; + + if (TYPE_REFERENCE_TYPE (to_type) == 0 + && !(TYPE_FLAGS (type) & TYPE_FLAG_PERM)) + { + TYPE_REFERENCE_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. */ @@ -286,6 +426,62 @@ static struct symbol *lookup_block_symbol (); Returns the struct symbol pointer, or zero if no symbol is found. */ struct symbol * +lookup_symbol_1 (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); + } + return 0; +} + +struct symbol * +lookup_symbol_2 (name, block, namespace) + char *name; + register struct block *block; /* ignored as parameter */ + enum namespace namespace; +{ + register int i, n; + register struct symbol *sym; + register struct symtab *s; + struct blockvector *bv; + + /* 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; +} + +struct symbol * lookup_symbol (name, block, namespace) char *name; register struct block *block; @@ -558,6 +754,26 @@ find_pc_line (pc, notcurrent) } return value; } + +/* 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 index; + int dummy; + + if (symtab == 0) + return 0; + l = LINETABLE (symtab); + index = find_line_common(l, line, &dummy); + return index ? l->item[index] : 0; +} /* Find the range of pc values in a line. Store the starting pc of the line into *STARTPTR @@ -572,8 +788,8 @@ find_line_pc_range (symtab, thisline, startptr, endptr) CORE_ADDR *startptr, *endptr; { register struct linetable *l; - register int i, line, item; - int len; + register int index; + int exact_match; /* did we get an exact linenumber match */ register CORE_ADDR prev_pc; CORE_ADDR last_pc; @@ -581,78 +797,82 @@ find_line_pc_range (symtab, thisline, startptr, endptr) return 0; l = LINETABLE (symtab); - len = l->nitems; - prev_pc = -1; - for (i = 0; i < len; i++) + index = find_line_common (l, thisline, &exact_match); + if (index) { - item = l->item[i]; - if (item < 0) - line = - item - 1; + *startptr = l->item[index]; + /* If we have not seen an entry for the specified line, + assume that means the specified line has zero bytes. */ + if (!exact_match || index == l->nitems-1) + *endptr = *startptr; 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)); + /* Perhaps the following entry is for the following line. + It's worth a try. */ + if (l->item[index+1] > 0) + *endptr = l->item[index+1]; + else + *endptr = find_line_pc (symtab, thisline+1); 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. */ +/* Given a line table and a line number, return the index into the line + table for the pc of the nearest line whose number is >= the specified one. + Return 0 if none is found. The value is never zero is it is an index. -CORE_ADDR -find_line_pc (symtab, line) - struct symtab *symtab; - int line; + Set *EXACT_MATCH nonzero if the value returned is an exact match. */ + +static int +find_line_common (l, lineno, exact_match) + register struct linetable *l; + register int lineno; + int *exact_match; { - register struct linetable *l; - register int len; register int i; - register int item; - register int nextline = -1; + register int len; + + /* BEST is the smallest linenumber > LINENO so far seen, + or 0 if none has been seen so far. + BEST_INDEX identifies the item for it. */ - if (line <= 0) + int best_index = 0; + int best = 0; + + int nextline = -1; + + if (lineno <= 0) return 0; - l = LINETABLE (symtab); len = l->nitems; for (i = 0; i < len; i++) { - item = l->item[i]; + register int item = l->item[i]; + if (item < 0) nextline = - item - 1; else { nextline++; - if (line <= nextline) - return item; + if (nextline == lineno) + { + *exact_match = 1; + return i; + } + + if (nextline > lineno && (best == 0 || nextline < best)) + { + best = lineno; + best_index = i; + } } } - return 0; + + /* If we got here, we didn't get an exact match. */ + + *exact_match = 0; + return best_index; } int @@ -694,13 +914,15 @@ find_pc_line_pc_range (pc, startptr, endptr) if no file is validly specified. Callers must check that. Also, the line number returned may be invalid. */ -struct symtab_and_line +struct symtabs_and_lines decode_line_1 (argptr, funfirstline, default_symtab, default_line) char **argptr; int funfirstline; struct symtab *default_symtab; int default_line; { + struct symtabs_and_lines decode_line_2 (); + struct symtabs_and_lines values; struct symtab_and_line value; register char *p, *p1; register struct symtab *s; @@ -708,7 +930,14 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line) register CORE_ADDR pc; register int i; char *copy; - + struct symbol *sym_class; + char *class_name, *method_name, *phys_name; + int method_counter; + int i1; + struct symbol **sym_arr; + struct type *t, *field; + char **physnames; + /* Defaults have defaults. */ if (default_symtab == 0) @@ -723,9 +952,11 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line) { (*argptr)++; pc = parse_and_eval_address_1 (argptr); - value = find_pc_line (pc, 0); - value.pc = pc; - return value; + values.sals = (struct symtab_and_line *)malloc (sizeof (struct symtab_and_line)); + values.nelts = 1; + values.sals[0] = find_pc_line (pc, 0); + values.sals[0].pc = pc; + return values; } /* Maybe arg is FILE : LINENUM or FILE : FUNCTION */ @@ -741,6 +972,125 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line) if (p[0] == ':') { + + /* C++ */ + if (p[1] ==':') + { + /* Extract the class name. */ + p1 = p; + while (p != *argptr && p[-1] == ' ') --p; + copy = (char *) alloca (p - *argptr + 1); + bcopy (*argptr, copy, p - *argptr); + copy[p - *argptr] = 0; + + /* Discard the class name from the arg. */ + p = p1 + 2; + while (*p == ' ' || *p == '\t') p++; + *argptr = p; + + sym_class = lookup_symbol (copy, 0, STRUCT_NAMESPACE); + + if (sym_class && + (TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_STRUCT + || TYPE_CODE (SYMBOL_TYPE (sym_class)) == TYPE_CODE_UNION)) + { + /* 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 !=':') p++; + copy = (char *) alloca (p - *argptr + 1); + bcopy (*argptr, copy, p - *argptr); + copy[p - *argptr] = '\0'; + + /* no line number may be specified */ + while (*p == ' ' || *p == '\t') p++; + *argptr = p; + + sym = 0; + i1 = 0; /* counter for the symbol array */ + t = SYMBOL_TYPE (sym_class); + sym_arr = (struct symbol **) alloca(TYPE_NFN_FIELDS_TOTAL (t) * sizeof(struct symbol*)); + physnames = (char **) alloca (TYPE_NFN_FIELDS_TOTAL (t) * sizeof(char*)); + + if (destructor_name_p (copy, t)) + { + /* destructors are a special case. */ + struct fn_field *f = TYPE_FN_FIELDLIST1 (t, 0); + int len = TYPE_FN_FIELDLIST_LENGTH (t, 0) - 1; + phys_name = TYPE_FN_FIELD_PHYSNAME (f, len); + physnames[i1] = (char *)alloca (strlen (phys_name) + 1); + strcpy (physnames[i1], phys_name); + sym_arr[i1] = lookup_symbol (phys_name, SYMBOL_BLOCK_VALUE (sym_class), VAR_NAMESPACE); + if (sym_arr[i1]) i1++; + } + else while (t) + { + int constructor_p; + + class_name = TYPE_NAME (t); + while (*class_name++ != ' '); + + constructor_p = ! strcmp (class_name, copy); + + sym_class = lookup_symbol (class_name, 0, STRUCT_NAMESPACE); + for (method_counter = TYPE_NFN_FIELDS (SYMBOL_TYPE (sym_class)) - 1; + method_counter >= 0; + --method_counter) + { + int field_counter; + struct fn_field *f = + TYPE_FN_FIELDLIST1 (SYMBOL_TYPE (sym_class), method_counter); + + method_name = TYPE_FN_FIELDLIST_NAME (SYMBOL_TYPE (sym_class), method_counter); + if (!strcmp (copy, method_name)) + for (field_counter = TYPE_FN_FIELDLIST_LENGTH (SYMBOL_TYPE (sym_class), method_counter) - (1 + constructor_p); + field_counter >= 0; + --field_counter) + { + phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter); + physnames[i1] = (char*) alloca (strlen (phys_name) + 1); + strcpy (physnames[i1], phys_name); + sym_arr[i1] = lookup_symbol (phys_name, SYMBOL_BLOCK_VALUE (sym_class), VAR_NAMESPACE); + if (sym_arr[i1]) i1++; + } + } + t = TYPE_BASECLASS(t); + } + + if (i1 == 1) + { + sym = sym_arr[0]; + + 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); + values.sals = (struct symtab_and_line *)malloc (sizeof (struct symtab_and_line)); + values.nelts = 1; + values.sals[0] = find_pc_line (pc, 0); + values.sals[0].pc = (values.sals[0].end && values.sals[0].pc != pc) ? values.sals[0].end : pc; + } + else + { + values.nelts = 0; + } + return values; + } + if (i1 > 0) + { + return decode_line_2 (argptr, sym_arr, physnames, i1, funfirstline); + } + else + error ("that class does not have any method named %s",copy); + } + else + error("no class, struct, or union named %s", copy ); + } + /* end of C++ */ + + /* Extract the file name. */ p1 = p; while (p != *argptr && p[-1] == ' ') --p; @@ -807,7 +1157,10 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line) s = default_symtab; value.symtab = s; value.pc = 0; - return value; + values.sals = (struct symtab_and_line *)malloc (sizeof (struct symtab_and_line)); + values.sals[0] = value; + values.nelts = 1; + return values; } /* Arg token is not digits => try it as a function name @@ -834,41 +1187,157 @@ decode_line_1 (argptr, funfirstline, default_symtab, default_line) SKIP_PROLOGUE (pc); value = find_pc_line (pc, 0); value.pc = (value.end && value.pc != pc) ? value.end : pc; - return value; + values.sals = (struct symtab_and_line *)malloc (sizeof (struct symtab_and_line)); + values.sals[0] = value; + values.nelts = 1; + return values; } 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 ((i = lookup_misc_func (copy)) < 0) + error ("Function %s not defined.", copy); + else + { + value.symtab = 0; + value.line = 0; + value.pc = misc_function_vector[i].address + FUNCTION_START_OFFSET; + if (funfirstline) + SKIP_PROLOGUE (value.pc); + values.sals = (struct symtab_and_line *)malloc (sizeof (struct symtab_and_line)); + values.sals[0] = value; + values.nelts = 1; + return values; + } 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 +struct symtabs_and_lines decode_line_spec (string, funfirstline) char *string; int funfirstline; { - struct symtab_and_line sal; + struct symtabs_and_lines sals; if (string == 0) error ("Empty line specification."); - sal = decode_line_1 (&string, funfirstline, - current_source_symtab, current_source_line); + sals = decode_line_1 (&string, funfirstline, + current_source_symtab, current_source_line); if (*string) error ("Junk at end of line specification: %s", string); - return sal; + return sals; +} + +struct symtabs_and_lines +decode_line_2 (argptr, sym_arr, physnames, nelts, funfirstline) + char **argptr; + struct symbol *sym_arr[]; + char *physnames[]; + int nelts; + int funfirstline; +{ + char *getenv(); + struct symtabs_and_lines values, return_values; + register CORE_ADDR pc; + char *args, *arg1, *read_line (); + int i; + char *prompt; + + values.sals = (struct symtab_and_line *) alloca (nelts * sizeof(struct symtab_and_line)); + return_values.sals = (struct symtab_and_line *) malloc (nelts * sizeof(struct symtab_and_line)); + + i = 0; + printf("[0] cancel\n[1] all\n"); + while (i < nelts) + { + if (sym_arr[i] && SYMBOL_CLASS (sym_arr[i]) == LOC_BLOCK) + { + /* Arg is the name of a function */ + pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym_arr[i])) + + FUNCTION_START_OFFSET; + if (funfirstline) + SKIP_PROLOGUE (pc); + values.sals[i] = find_pc_line (pc, 0); + printf("[%d] file:%s; line number:%d\n", + (i+2), values.sals[i].symtab->filename, values.sals[i].line); + } + else printf ("?HERE\n"); + i++; + } + + if ((prompt = getenv ("PS2")) == NULL) + { + prompt = ">"; + } + printf("%s ",prompt); + fflush(stdout); + + args = read_line (0); + + if (args == 0) + error_no_arg ("one or more choice numbers"); + + i = 0; + while (*args) + { + int num; + + arg1 = args; + while (*arg1 >= '0' && *arg1 <= '9') arg1++; + if (*arg1 && *arg1 != ' ' && *arg1 != '\t') + error ("Arguments must be choice numbers."); + + num = atoi (args); + + if (num == 0) + error ("cancelled"); + else if (num == 1) + { + bcopy (values.sals, return_values.sals, (nelts * sizeof(struct symtab_and_line))); + return_values.nelts = nelts; + return return_values; + } + + if (num > nelts + 2) + { + printf ("No choice number %d.\n", num); + } + else + { + num -= 2; + if (values.sals[num].pc) + { + return_values.sals[i++] = values.sals[num]; + values.sals[num].pc = 0; + } + else + { + printf ("duplicate request for %d ignored.\n", num); + } + } + + args = arg1; + while (*args == ' ' || *args == '\t') args++; + } + return_values.nelts = i; + return return_values; +} + +/* Return the index of misc function named NAME. */ + +static +lookup_misc_func (name) + register char *name; +{ + register int i; + + for (i = 0; i < misc_function_count; i++) + if (!strcmp (misc_function_vector[i].name, name)) + return i; + return -1; /* not found */ } static void @@ -930,25 +1399,15 @@ list_symbols (regexp, class) register struct block *b; register int i, j; register struct symbol *sym; - char *val = 0; + char *val; int found_in_file; static char *classnames[] - = {"variable", "function", "type"}; + = {"variable", "function", "type", "method"}; 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 (regexp) if (val = (char *) re_comp (regexp)) error ("Invalid regexp: %s", val); -#endif - } printf (regexp ? "All %ss matching regular expression \"%s\":\n" @@ -973,19 +1432,12 @@ list_symbols (regexp, class) { 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 + if ((regexp == 0 || re_exec (SYMBOL_NAME (sym))) + && ((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)) + || (class == 2 && SYMBOL_CLASS (sym) == LOC_TYPEDEF) + || (class == 3 && SYMBOL_CLASS (sym) == LOC_BLOCK))) { if (!found_in_file) { @@ -1000,26 +1452,35 @@ list_symbols (regexp, class) && SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE) printf ("typedef "); - type_print (SYMBOL_TYPE (sym), - (SYMBOL_CLASS (sym) == LOC_TYPEDEF - ? "" : SYMBOL_NAME (sym)), - stdout, 0); + if (class < 3) + { + type_print (SYMBOL_TYPE (sym), + (SYMBOL_CLASS (sym) == LOC_TYPEDEF + ? "" : SYMBOL_NAME (sym)), + stdout, 0); + printf (";\n"); + } + else + { + char buf[1024]; +# if 0 + type_print_base (TYPE_FN_FIELD_TYPE(t, i), stdout, 0, 0); + type_print_varspec_prefix (TYPE_FN_FIELD_TYPE(t, i), stdout, 0); + sprintf (buf, " %s::", TYPE_NAME (t)); + type_print_method_args (TYPE_FN_FIELD_ARGS (t, i), buf, name, stdout); +# endif + } 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 @@ -1042,6 +1503,13 @@ types_info (regexp) { list_symbols (regexp, 2); } + +static void +methods_info (regexp) + char *regexp; +{ + list_symbols (regexp, 3); +} /* Initialize the standard C scalar types. */ @@ -1056,6 +1524,7 @@ init_type (code, length, uns, name) type = (struct type *) xmalloc (sizeof (struct type)); bzero (type, sizeof *type); + TYPE_MAIN_VARIANT (type) = type; TYPE_CODE (type) = code; TYPE_LENGTH (type) = length; TYPE_FLAGS (type) = uns ? TYPE_FLAG_UNSIGNED : 0; @@ -1063,6 +1532,9 @@ init_type (code, length, uns, name) TYPE_NFIELDS (type) = 0; TYPE_NAME (type) = name; + /* C++ fancies. */ + TYPE_NFN_FIELDS (type) = 0; + TYPE_BASECLASS (type) = 0; return type; } @@ -1075,6 +1547,11 @@ initialize () "All function names, or those matching REGEXP."); add_info ("types", types_info, "All types names, or those matching REGEXP."); + add_info ("methods", methods_info, + "All method names, or those matching REGEXP::REGEXP.\n\ +If the class qualifier is ommited, it is assumed to be the current scope.\n\ +If the first REGEXP is ommited, then all methods matching the second REGEXP\n\ +are listed."); add_info ("sources", sources_info, "Source files in the program."); diff --git a/gdb/symtab.h b/gdb/symtab.h index 4d93355..d184766 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -53,8 +53,8 @@ int misc_function_count; #include "symseg.h" -/* Each source file is represented by a struct symtab. - These objects are chained through the `next' field. */ +/* Each source file is represented by a struct symtab. */ +/* These objects are chained through the `next' field. */ struct symtab { @@ -70,13 +70,12 @@ struct symtab char *filename; /* This component says how to free the data we point to: free_contents => do a tree walk and free each object. - free_explicit => free what free_ptr points at, and the linetable. free_nothing => do nothing; some other symtab will free the data this one uses. free_linetable => free just the linetable. */ - enum free_code {free_nothing, free_contents, free_explicit, free_linetable} + enum free_code {free_nothing, free_contents, free_linetable} free_code; - /* Pointer to one block storage to be freed, if nonzero. */ + /* Pointer to one block of storage to be freed, if nonzero. */ char *free_ptr; /* Total number of lines found in source file. */ int nlines; @@ -91,6 +90,9 @@ struct symtab /* Offset within loader symbol table of first local symbol for this file. */ int ldsymoff; + /* Full name of file as found by searching the source path. + 0 if not yet known. */ + char *fullname; }; /* This is the list of struct symtab's that gdb considers current. */ @@ -113,24 +115,6 @@ int current_source_line; #define LINELIST(symtab) (symtab)->linetable #define LINETABLE(symtab) (symtab)->linetable -/* Recording the code addresses of source lines. */ - -struct linetable - { - int nitems; - int item[1]; - }; - -/* Each item is either minus a line number, or a program counter. - If it represents a line number, that is the line described by the next - program counter value. If it is positive, it is the program - counter at which the code for the next line starts. - - Consecutive lines can be recorded by program counter entries - with no line number entries between them. Line number entries - are used when there are lines to skip with no code on them. - This is to make the table shorter. */ - /* Macros normally used to access components of symbol table structures. */ #define BLOCKLIST_NBLOCKS(blocklist) (blocklist)->nblocks @@ -161,16 +145,34 @@ struct linetable These types are never freed. */ #define TYPE_FLAG_PERM 4 +/* Some macros for bitfields. */ +#define B_SET(a,x) (a[x>>5] |= (1 << (x&31))) +#define B_CLR(a,x) (a[x>>5] &= ~(1 << (x&31))) +#define B_TST(a,x) (a[x>>5] & (1 << (x&31))) + #define TYPE_NAME(thistype) (thistype)->name #define TYPE_TARGET_TYPE(thistype) (thistype)->target_type #define TYPE_POINTER_TYPE(thistype) (thistype)->pointer_type +#define TYPE_REFERENCE_TYPE(thistype) (thistype)->reference_type #define TYPE_FUNCTION_TYPE(thistype) (thistype)->function_type +#define TYPE_MAIN_VARIANT(thistype) (thistype)->main_variant #define TYPE_LENGTH(thistype) (thistype)->length #define TYPE_FLAGS(thistype) (thistype)->flags #define TYPE_UNSIGNED(thistype) ((thistype)->flags & TYPE_FLAG_UNSIGNED) #define TYPE_CODE(thistype) (thistype)->code #define TYPE_NFIELDS(thistype) (thistype)->nfields #define TYPE_FIELDS(thistype) (thistype)->fields +/* C++ */ +#define TYPE_VPTR_BASETYPE(thistype) (thistype)->vptr_basetype +#define TYPE_DOMAIN_TYPE(thistype) (thistype)->vptr_basetype +#define TYPE_VPTR_FIELDNO(thistype) (thistype)->vptr_fieldno +#define TYPE_FN_FIELDS(thistype) (thistype)->fn_fields +#define TYPE_NFN_FIELDS(thistype) (thistype)->nfn_fields +#define TYPE_NFN_FIELDS_TOTAL(thistype) (thistype)->nfn_fields_total +#define TYPE_BASECLASS(thistype) (thistype)->baseclass +#define TYPE_VIA_PUBLIC(thistype) (thistype)->via_public +#define TYPE_VIA_PROTECTED(thistype) (thistype)->via_protected +#define TYPE_CHAIN(thistype) (thistype)->baseclass #define TYPE_FIELD(thistype, n) (thistype)->fields[n] #define TYPE_FIELD_TYPE(thistype, n) (thistype)->fields[n].type @@ -179,11 +181,46 @@ struct linetable #define TYPE_FIELD_BITPOS(thistype, n) (thistype)->fields[n].bitpos #define TYPE_FIELD_BITSIZE(thistype, n) (thistype)->fields[n].bitsize #define TYPE_FIELD_PACKED(thistype, n) (thistype)->fields[n].bitsize + +#define TYPE_FIELD_PRIVATE_BITS(thistype) (thistype)->private_field_bits +#define TYPE_FIELD_PROTECTED_BITS(thistype) (thistype)->protected_field_bits +#define SET_TYPE_FIELD_PRIVATE(thistype, n) B_SET ((thistype)->private_field_bits, (n)) +#define SET_TYPE_FIELD_PROTECTED(thistype, n) B_SET ((thistype)->protected_field_bits, (n)) +#define TYPE_FIELD_PRIVATE(thistype, n) B_TST((thistype)->private_field_bits, (n)) +#define TYPE_FIELD_PROTECTED(thistype, n) B_TST((thistype)->protected_field_bits, (n)) + +#define TYPE_HAS_DESTRUCTOR(thistype) ((thistype)->has_destructor) +#define TYPE_HAS_CONSTRUCTOR(thistype) ((thistype)->has_constructor) + +#define TYPE_FIELD_STATIC(thistype, n) ((thistype)->fields[n].bitpos == -1) +#define TYPE_FIELD_STATIC_PHYSNAME(thistype, n) ((char *)(thistype)->fields[n].bitsize) + +#define TYPE_FN_FIELDLISTS(thistype) (thistype)->fn_fieldlists +#define TYPE_FN_FIELDLIST(thistype, n) (thistype)->fn_fieldlists[n] +#define TYPE_FN_FIELDLIST1(thistype, n) (thistype)->fn_fieldlists[n].fn_fields +#define TYPE_FN_FIELDLIST_NAME(thistype, n) (thistype)->fn_fieldlists[n].name +#define TYPE_FN_FIELDLIST_LENGTH(thistype, n) (thistype)->fn_fieldlists[n].length + +#define TYPE_FN_FIELD(thistype) (thistype)[n] +#define TYPE_FN_FIELD_NAME(thistype, n) (thistype)[n].name +#define TYPE_FN_FIELD_TYPE(thistype, n) (thistype)[n].type +#define TYPE_FN_FIELD_ARGS(thistype, n) (thistype)[n].args +#define TYPE_FN_FIELD_PHYSNAME(thistype, n) (thistype)[n].physname +#define TYPE_FN_FIELD_VIRTUAL_P(thistype, n) (thistype)[n].voffset +#define TYPE_FN_FIELD_VOFFSET(thistype, n) ((thistype)[n].voffset-1) + +#define TYPE_FN_PRIVATE_BITS(thistype) (thistype).private_fn_field_bits +#define TYPE_FN_PROTECTED_BITS(thistype) (thistype).protected_fn_field_bits +#define SET_TYPE_FN_PRIVATE(thistype, n) B_SET ((thistype).private_fn_field_bits, n) +#define SET_TYPE_FN_PROTECTED(thistype, n) B_SET ((thistype).protected_fn_field_bits, n) +#define TYPE_FN_PRIVATE(thistype, n) B_TST ((thistype).private_fn_field_bits, n) +#define TYPE_FN_PROTECTED(thistype, n) B_TST ((thistype).protected_fn_field_bits, n) /* Functions that work on the objects described above */ extern struct symtab *lookup_symtab (); extern struct symbol *lookup_symbol (); +extern struct symbol *lookup_symbol_1 (), *lookup_symbol_2 (); extern struct type *lookup_typename (); extern struct type *lookup_unsigned_typename (); extern struct type *lookup_struct (); @@ -195,6 +232,12 @@ extern struct symbol *block_function (); extern struct symbol *find_pc_function (); extern int find_pc_misc_function (); +/* C++ stuff. */ +extern struct type *lookup_reference_type (); +extern struct type *lookup_member_pointer_type (); +extern struct type *lookup_class (); +/* end of C++ stuff. */ + extern struct type *builtin_type_void; extern struct type *builtin_type_char; extern struct type *builtin_type_short; @@ -215,6 +258,12 @@ struct symtab_and_line CORE_ADDR end; }; +struct symtabs_and_lines +{ + struct symtab_and_line *sals; + int nelts; +}; + /* Given a pc value, return line number it is in. Second arg nonzero means if pc is on the boundary use the previous statement's line number. */ @@ -224,5 +273,5 @@ struct symtab_and_line find_pc_line (); /* Given a string, return the line specified by it. For commands like "list" and "breakpoint". */ -struct symtab_and_line decode_line_spec (); -struct symtab_and_line decode_line_1 (); +struct symtabs_and_lines decode_line_spec (); +struct symtabs_and_lines decode_line_1 (); diff --git a/gdb/test2.c b/gdb/test2.c deleted file mode 100644 index e6964f0..0000000 --- a/gdb/test2.c +++ /dev/null @@ -1,13 +0,0 @@ -#include <sys/param.h> -#include <sys/dir.h> -#include <sys/user.h> -#include <stdio.h> - -main () -{ - struct user u; - printf ("&u.u_ar0 - &u = %d, 0%o\n", (int) &u.u_ar0 - (int) &u, - (int) &u.u_ar0 - (int) &u); - printf ("sizeof (struct pcb) = %d, 0%o\n", - sizeof (struct pcb), sizeof (struct pcb)); -} diff --git a/gdb/test3.c b/gdb/test3.c deleted file mode 100644 index cd27cdd..0000000 --- a/gdb/test3.c +++ /dev/null @@ -1,25 +0,0 @@ -enum foo {foo1, foo2}; - -static double statdouble; - -newfun (ac) - struct haha {int a; } ac; -{ -} - -struct temp {int a; }; - -bar (a) - enum foo a; -{ - static int lose; - double happy; - typedef int myint; - - { - union wow { int a; char b; } wowvar; - static union wow wowvar1; - typedef int yourint; - char *winner; - } -} diff --git a/gdb/testattach.c b/gdb/testattach.c deleted file mode 100644 index c56a0fe..0000000 --- a/gdb/testattach.c +++ /dev/null @@ -1,10 +0,0 @@ -main () -{ - int x = 0; - - while (1) - { - sleep (1); - x++; - } -} diff --git a/gdb/testbf.c b/gdb/testbf.c deleted file mode 100644 index dd661a0..0000000 --- a/gdb/testbf.c +++ /dev/null @@ -1,13 +0,0 @@ -struct foo -{ - int a : 5, : 4, b : 5; - char c; - int : 3, d : 8, : 0, e : 5; -}; - -struct foo x; - -main () -{ - printf (x); -} diff --git a/gdb/testenum.c b/gdb/testenum.c deleted file mode 100644 index 3d85f5e..0000000 --- a/gdb/testenum.c +++ /dev/null @@ -1,25 +0,0 @@ -/* Source file for showing ENUM lossage in GDB. - Compile with "cc -o foo -g foo.c". */ - -enum bar { value1, value2, value3 }; - -struct foo { - enum bar enum_value; - int int_value; - char *pointer_value; -}; - -struct foo foo_instance; -struct foo *foo_instance_pointer; - -main () -{ - foo_instance_pointer = &foo_instance; - foo_instance.enum_value = value2; - foo_instance.int_value = 1; - foo_instance.pointer_value = "Text to make a char *"; - - /* In GDB, set a breakpoint at this line. Then try to change the - value of foo_instance.enum_value in any way. I can't do it. */ -} - diff --git a/gdb/testfb.c b/gdb/testfb.c deleted file mode 100644 index 1699471..0000000 --- a/gdb/testfb.c +++ /dev/null @@ -1,12 +0,0 @@ - -main () -{ - foo(2); - foo(3); -} - -foo (i) -{ - printf ("i is %d, ", i); - printf ("i*i is %d\n", i * i); -} diff --git a/gdb/testshort.c b/gdb/testshort.c deleted file mode 100644 index 2c60631..0000000 --- a/gdb/testshort.c +++ /dev/null @@ -1,16 +0,0 @@ -main () -{ - register int ntabs; - register short x; - short stops[30]; - - foo (); -} - -foo () -{ - register int ntabs; - register short x; - - printf (x, ntabs); -} diff --git a/gdb/testsig.c b/gdb/testsig.c deleted file mode 100644 index ded2d20..0000000 --- a/gdb/testsig.c +++ /dev/null @@ -1,17 +0,0 @@ -# include <signal.h> - -main () -{ - int handle (); - int i; - signal (SIGALRM, handle); - alarm (5); - for (i = 0; i < 100000; i++) - printf ("%d\n", i); -} - -handle () -{ - printf ("signal!\n"); - alarm (5); -} diff --git a/gdb/utils.c.OK b/gdb/utils.c index 7c52ea4..c8f5c06 100644 --- a/gdb/utils.c.OK +++ b/gdb/utils.c @@ -191,9 +191,7 @@ void quit () { fflush (stdout); -#ifdef TIOCFLUSH ioctl (fileno (stdout), TIOCFLUSH, 0); -#endif error ("Quit"); } diff --git a/gdb/valops.c b/gdb/valops.c index 9f0e3cc..c962932 100644 --- a/gdb/valops.c +++ b/gdb/valops.c @@ -17,7 +17,7 @@ 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 "initialize.h" #include "param.h" @@ -56,11 +56,19 @@ value_cast (type, arg2) return value_from_long (type, value_as_long (arg2)); else if (TYPE_LENGTH (type) == TYPE_LENGTH (VALUE_TYPE (arg2))) { + if ((code1 == TYPE_CODE_MPTR) ^ (code2 == TYPE_CODE_MPTR)) + printf ("warning: assignment between pointer-to-member and non pointer-to-member types\n"); + VALUE_TYPE (arg2) = type; return arg2; } else if (VALUE_LVAL (arg2) == lval_memory) - return value_at (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2)); + { + if ((code1 == TYPE_CODE_MPTR) ^ (code2 == TYPE_CODE_MPTR)) + printf ("warning: assignment between pointer-to-member and non pointer-to-member types\n"); + + return value_at (type, VALUE_ADDRESS (arg2) + VALUE_OFFSET (arg2)); + } else error ("Invalid cast."); } @@ -278,6 +286,9 @@ value_ind (arg1) { COERCE_ARRAY (arg1); + if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_MPTR) + error ("not implemented: member pointers in value_ind"); + /* Allow * on an integer so we can cast it to whatever we want. */ if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_INT) return value_at (builtin_type_long, @@ -285,6 +296,9 @@ value_ind (arg1) else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_PTR) return value_at (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)), (CORE_ADDR) value_as_long (arg1)); + else if (TYPE_CODE (VALUE_TYPE (arg1)) == TYPE_CODE_REF) + return value_at (TYPE_TARGET_TYPE (VALUE_TYPE (arg1)), + (CORE_ADDR) value_as_long (arg1)); error ("Attempt to take contents of a non-pointer value."); } @@ -411,6 +425,9 @@ call_function (function, nargs, args) register struct type *ftype = VALUE_TYPE (function); register enum type_code code = TYPE_CODE (ftype); + if (code == TYPE_CODE_MPTR) + error ("not implemented: member pointer to call_function"); + /* Determine address to call. */ if (code == TYPE_CODE_FUNC) { @@ -552,16 +569,24 @@ value_string (ptr, len) /* Given ARG1, a value of type (pointer to a)* structure/union, extract the component named NAME from the ultimate target structure/union and return it as a value with its appropriate type. - ERR is used in the error message if ARG1's type is wrong. */ + ERR is used in the error message if ARG1's type is wrong. + + C++: ARGS is a list of argument types to aid in the selection of + an appropriate method. Also, handle derived types. + + ERR is an error message to be printed in case the field is not found. */ value -value_struct_elt (arg1, name, err) - register value arg1; +value_struct_elt (arg1, args, name, err) + register value arg1, *args; char *name; char *err; { register struct type *t; register int i; + int found = 0; + + struct type *baseclass; COERCE_ARRAY (arg1); @@ -569,28 +594,427 @@ value_struct_elt (arg1, name, err) /* Follow pointers until we get to a non-pointer. */ - while (TYPE_CODE (t) == TYPE_CODE_PTR) + while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF) { arg1 = value_ind (arg1); COERCE_ARRAY (arg1); t = VALUE_TYPE (arg1); } + if (TYPE_CODE (t) == TYPE_CODE_MPTR) + error ("not implemented: member pointers in value_struct_elt"); + if (TYPE_CODE (t) != TYPE_CODE_STRUCT - && - TYPE_CODE (t) != TYPE_CODE_UNION) + && TYPE_CODE (t) != TYPE_CODE_UNION) error ("Attempt to extract a component of a value that is not a %s.", err); - for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--) + baseclass = t; + + if (!args) + { + /* if there are no arguments ...do this... */ + + /* Try as a variable first, because if we succeed, there + is less work to be done. */ + while (t) + { + for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--) + { + if (!strcmp (TYPE_FIELD_NAME (t, i), name)) + { + found = 1; + break; + } + } + + if (i >= 0) + return TYPE_FIELD_STATIC (t, i) + ? value_static_field (t, name, i) : value_field (arg1, i); + + t = TYPE_BASECLASS (t); + VALUE_TYPE (arg1) = t; /* side effect! */ + } + + /* C++: If it was not found as a data field, then try to + return it as a pointer to a method. */ + t = baseclass; + VALUE_TYPE (arg1) = t; /* side effect! */ + + if (destructor_name_p (name, t)) + error ("use `info method' command to print out value of destructor"); + + while (t) + { + for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i) + { + if (! strcmp (TYPE_FN_FIELDLIST_NAME (t, i), name)) + { + error ("use `info method' command to print value of method \"%s\"", name); + } + } + t = TYPE_BASECLASS (t); + } + + if (found == 0) + error("there is no field named %s", name); + return 0; + } + + if (destructor_name_p (name, t)) + { + if (!args[1]) + { + /* destructors are a special case. */ + return (value)value_fn_field (arg1, 0, TYPE_FN_FIELDLIST_LENGTH (t, 0)); + } + else + { + error ("destructor should not have any argument"); + } + } + + /* This following loop is for methods with arguments. */ + while (t) + { + /* Look up as method first, because that is where we + expect to find it first. */ + for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; i--) + { + struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i); + + if (!strcmp (TYPE_FN_FIELDLIST_NAME (t, i), name)) + { + int j; + struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i); + + found = 1; + for (j = TYPE_FN_FIELDLIST_LENGTH (t, i) - 1; j >= 0; --j) + { + if (!typecmp (TYPE_FN_FIELD_ARGS (f, j), args)) + { + if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) + { + /* First, get the virtual function table pointer. + That comes with a strange type, so cast + it to type `pointer to long' (which + should serve just fine as a function type). + Then, index into the table, and convert + final value to appropriate function type. */ + value vfn, vtbl; + value vi = value_from_long (builtin_type_int, + TYPE_FN_FIELD_VOFFSET (f, j)); + VALUE_TYPE (arg1) = TYPE_VPTR_BASETYPE (t); + + if (TYPE_VPTR_FIELDNO (t) < 0) + TYPE_VPTR_FIELDNO (t) + = fill_in_vptr_fieldno (t); + + vtbl = value_field (arg1, TYPE_VPTR_FIELDNO (t)); + vfn = value_subscript (vtbl, vi); + VALUE_TYPE (vfn) = lookup_pointer_type (TYPE_FN_FIELD_TYPE (f, j)); + return vfn; + } + else + return (value)value_fn_field (arg1, i, j); + } + } + } + } + t = TYPE_BASECLASS (t); + VALUE_TYPE (arg1) = t; /* side effect! */ + } + + if (found) + { + error ("Structure method %s not defined for arglist.", name); + return 0; + } + else + { + /* See if user tried to invoke data as function */ + t = baseclass; + while (t) + { + for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--) + { + if (!strcmp (TYPE_FIELD_NAME (t, i), name)) + { + found = 1; + break; + } + } + + if (i >= 0) + return TYPE_FIELD_STATIC (t, i) + ? value_static_field (t, name, i) : value_field (arg1, i); + + t = TYPE_BASECLASS (t); + VALUE_TYPE (arg1) = t; /* side effect! */ + } + error ("Structure has no component named %s.", name); + } +} + +/* C++: return 1 is NAME is a legitimate name for the destructor + of type TYPE. If TYPE does not have a destructor, or + if NAME is inappropriate for TYPE, an error is signaled. */ +int +destructor_name_p (name, type) + char *name; + struct type *type; +{ + /* destructors are a special case. */ + char *dname = TYPE_NAME (type); + + if (name[0] == '~') + { + if (! TYPE_HAS_DESTRUCTOR (type)) + error ("type `%s' does not have destructor defined", + TYPE_NAME (type)); + /* Skip past the "struct " at the front. */ + while (*dname++ != ' ') ; + if (strcmp (dname, name+1)) + error ("destructor specification error"); + else + return 1; + } + return 0; +} + +/* C++: Given ARG1, a value of type (pointer to a)* structure/union, + return 1 if the component named NAME from the ultimate + target structure/union is defined, otherwise, return 0. */ + +int +check_field (arg1, name) + register value arg1; + char *name; +{ + register struct type *t; + register int i; + int found = 0; + + struct type *baseclass; + + COERCE_ARRAY (arg1); + + t = VALUE_TYPE (arg1); + + /* Follow pointers until we get to a non-pointer. */ + + while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF) + { + arg1 = value_ind (arg1); + COERCE_ARRAY (arg1); + t = VALUE_TYPE (arg1); + } + + if (TYPE_CODE (t) == TYPE_CODE_MPTR) + error ("not implemented: member pointers in check_field"); + + if (TYPE_CODE (t) != TYPE_CODE_STRUCT + && TYPE_CODE (t) != TYPE_CODE_UNION) + error ("Internal error: `this' is not an aggregate"); + + baseclass = t; + + while (t) { - if (!strcmp (TYPE_FIELD_NAME (t, i), name)) - break; + for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--) + { + if (!strcmp (TYPE_FIELD_NAME (t, i), name)) + { + return 1; + } + } + t = TYPE_BASECLASS (t); + VALUE_TYPE (arg1) = t; /* side effect! */ } - if (i < 0) - error ("Structure has no component named %s.", name); + /* C++: If it was not found as a data field, then try to + return it as a pointer to a method. */ + t = baseclass; + VALUE_TYPE (arg1) = t; /* side effect! */ + + /* Destructors are a special case. */ + if (destructor_name_p (name, t)) + return 1; + + while (t) + { + for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i) + { + if (!strcmp (TYPE_FN_FIELDLIST_NAME (t, i), name)) + return 1; + } + t = TYPE_BASECLASS (t); + } + return 0; +} - return value_field (arg1, i); +/* C++: Given an aggregate type DOMAIN, and a member name NAME, + return the address of this member as a pointer to member + type. If INTYPE is non-null, then it will be the type + of the member we are looking for. This will help us resolve + pointers to member functions. */ + +value +value_struct_elt_for_address (domain, intype, name) + struct type *domain, *intype; + char *name; +{ + register struct type *t = domain; + register int i; + int found = 0; + value v; + + struct type *baseclass; + + if (TYPE_CODE (t) != TYPE_CODE_STRUCT + && TYPE_CODE (t) != TYPE_CODE_UNION) + error ("Internal error: non-aggregate type to value_struct_elt_for_address"); + + baseclass = t; + + while (t) + { + for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--) + { + if (!strcmp (TYPE_FIELD_NAME (t, i), name)) + { + if (TYPE_FIELD_PACKED (t, i)) + error ("pointers to bitfield members not allowed"); + + v = value_from_long (builtin_type_int, TYPE_FIELD_BITPOS (t, i) >> 3); + VALUE_TYPE (v) = lookup_member_pointer_type (TYPE_FIELD_TYPE (t, i), baseclass); + return v; + } + } + t = TYPE_BASECLASS (t); + } + + /* C++: If it was not found as a data field, then try to + return it as a pointer to a method. */ + t = baseclass; + + /* Destructors are a special case. */ + if (destructor_name_p (name, t)) + { + error ("pointers to destructors not implemented yet"); + } + + while (t) + { + for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; --i) + { + if (!strcmp (TYPE_FN_FIELDLIST_NAME (t, i), name)) + { + int j = TYPE_FN_FIELDLIST_LENGTH (t, i); + struct fn_field *f = TYPE_FN_FIELDLIST1 (t, i); + + if (intype == 0 && j > 1) + error ("non-unique member `%s' requires type instantiation", name); + if (intype) + { + while (j--) + if (TYPE_FN_FIELD_TYPE (f, j) == intype) + break; + if (j < 0) + error ("no member function matches that type instantiation"); + } + else + j = 0; + + if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) + { + v = value_from_long (builtin_type_long, + TYPE_FN_FIELD_VOFFSET (f, j)); + } + else + { + struct symbol *s = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, j), + 0, VAR_NAMESPACE); + v = locate_var_value (s, 0); + } + VALUE_TYPE (v) = lookup_member_pointer_type (TYPE_FN_FIELD_TYPE (f, j), baseclass); + return v; + } + } + t = TYPE_BASECLASS (t); + } + return 0; +} + +/* Compare two argument lists and return the position in which they differ, + or zero if equal. Note that we ignore the first argument, which is + the type of the instance variable. This is because we want to handle + derived classes. This is not entirely correct: we should actually + check to make sure that a requested operation is type secure, + shouldn't we? */ +int typecmp(t1, t2) + struct type *t1[]; + value t2[]; +{ + int i; + + if (t1[0]->code == TYPE_CODE_VOID) return 0; + if (!t1[1])return 0; + for (i = 1; t1[i]->code != TYPE_CODE_VOID; i++) + { + if (! t2[i] + || t1[i]->code != t2[i]->type->code + || t1[i]->target_type != t2[i]->type->target_type) + { + return i+1; + } + } + return t2[i] ? i+1 : 0; +} + +#ifndef FRAME +#include "frame.h" +#endif + +/* C++: return the value of the class instance variable, if one exists. + Flag COMPLAIN signals an error if the request is made in an + inappropriate context. */ +value +value_of_this (complain) + int complain; +{ + extern FRAME selected_frame; + struct symbol *func, *sym; + char *funname = 0; + struct block *b; + int i; + + if (selected_frame == 0) + if (complain) + error ("no frame selected"); + else return 0; + + func = get_frame_function (selected_frame); + if (func) + funname = SYMBOL_NAME (func); + else + if (complain) + error ("no `this' in nameless context"); + else return 0; + + b = SYMBOL_BLOCK_VALUE (func); + i = BLOCK_NSYMS (b); + if (i <= 0) + if (complain) + error ("no args, no `this'"); + else return 0; + + sym = BLOCK_SYM (b, 0); + if (strncmp ("$this", SYMBOL_NAME (sym), 5)) + if (complain) + error ("current stack frame not in method"); + else return 0; + + return read_var_value (sym, selected_frame); } static diff --git a/gdb/valprint.c b/gdb/valprint.c index 78c8d63..619c970 100644 --- a/gdb/valprint.c +++ b/gdb/valprint.c @@ -32,6 +32,7 @@ static int print_max; static void type_print_varspec_suffix (); static void type_print_varspec_prefix (); static void type_print_base (); +static void type_print_method_args (); START_FILE @@ -88,8 +89,10 @@ value_print (val, stream) } else { - /* A simple (nonrepeated) value */ - /* If it is a pointer, indicate what it points to. */ + /* If it is a pointer, indicate what it points to. + + C++: if it is a member pointer, we will take care + of that when we print it. */ if (TYPE_CODE (VALUE_TYPE (val)) == TYPE_CODE_PTR) { fprintf (stream, "("); @@ -192,23 +195,172 @@ val_print (type, valaddr, address, stream) } break; + case TYPE_CODE_MPTR: + { + struct type *domain = TYPE_DOMAIN_TYPE (type); + struct type *target = TYPE_TARGET_TYPE (type); + struct fn_field *f; + int j, len2; + char *kind = ""; + + val = unpack_long (builtin_type_int, valaddr); + if (TYPE_CODE (target) == TYPE_CODE_FUNC) + { + if (val < 128) + { + len = TYPE_NFN_FIELDS (domain); + for (i = 0; i < len; i++) + { + f = TYPE_FN_FIELDLIST1 (domain, i); + len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); + + for (j = 0; j < len2; j++) + { + QUIT; + if (TYPE_FN_FIELD_VOFFSET (f, j) == val) + { + kind = " virtual"; + goto common; + } + } + } + } + else + { + struct symbol *sym = find_pc_function (val); + if (sym == 0) + error ("invalid pointer to member function"); + len = TYPE_NFN_FIELDS (domain); + for (i = 0; i < len; i++) + { + f = TYPE_FN_FIELDLIST1 (domain, i); + len2 = TYPE_FN_FIELDLIST_LENGTH (domain, i); + + for (j = 0; j < len2; j++) + { + QUIT; + if (!strcmp (SYMBOL_NAME (sym), TYPE_FN_FIELD_PHYSNAME (f, j))) + goto common; + } + } + } + common: + if (i < len) + { + fprintf (stream, "& "); + type_print_base (domain, stream, 0, 0); + fprintf (stream, "::%s", kind); + type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0); + if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_' + && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$') + type_print_method_args + (TYPE_FN_FIELD_ARGS (f, j) + 1, "~", + TYPE_FN_FIELDLIST_NAME (domain, i), stream); + else + type_print_method_args + (TYPE_FN_FIELD_ARGS (f, j), "", + TYPE_FN_FIELDLIST_NAME (domain, i), stream); + break; + } + } + else + { + /* VAL is a byte offset into the structure type DOMAIN. + Find the name of the field for that offset and + print it. */ + int extra = 0; + int bits = 0; + len = TYPE_NFIELDS (domain); + val <<= 3; /* @@ Make VAL into bit offset */ + for (i = 0; i < len; i++) + { + int bitpos = TYPE_FIELD_BITPOS (domain, i); + QUIT; + if (val == bitpos) + break; + if (val < bitpos && i > 0) + { + int ptrsize = (TYPE_LENGTH (builtin_type_char) * TYPE_LENGTH (target)); + /* Somehow pointing into a field. */ + i -= 1; + extra = (val - TYPE_FIELD_BITPOS (domain, i)); + if (extra & 0x3) + bits = 1; + else + extra >>= 3; + break; + } + } + if (i < len) + { + fprintf (stream, "& "); + type_print_base (domain, stream, 0, 0); + fprintf (stream, "::"); + fprintf (stream, "%s", TYPE_FIELD_NAME (domain, i)); + if (extra) + fprintf (stream, " + %d bytes", extra); + if (bits) + fprintf (stream, " (offset in bits)"); + break; + } + } + fputc ('(', stream); + type_print (type, "", stream, -1); + fprintf (stream, ") %d", val >> 3); + break; + } + + case TYPE_CODE_REF: + fprintf (stream, "(0x%x &) = ", * (int *) valaddr); + /* De-reference the reference. */ + if (TYPE_CODE (TYPE_TARGET_TYPE (type)) != TYPE_CODE_UNDEF) + { + value val = value_at (TYPE_TARGET_TYPE (type), * (int *)valaddr); + val_print (VALUE_TYPE (val), VALUE_CONTENTS (val), + VALUE_ADDRESS (val), stream); + } + else + fprintf (stream, "???"); + break; + case TYPE_CODE_STRUCT: case TYPE_CODE_UNION: fprintf (stream, "{"); len = TYPE_NFIELDS (type); - for (i = 0; i < len; i++) + if (TYPE_BASECLASS (type)) + { + i = 1; + fprintf (stream, "<%s> = ", TYPE_NAME (TYPE_BASECLASS (type))); + val_print (TYPE_FIELD_TYPE (type, 0), + valaddr + TYPE_FIELD_BITPOS (type, 0) / 8, + 0, stream); + + } + else i = 0; + for (; i < len; i++) { if (i) fprintf (stream, ", "); fprintf (stream, "%s = ", TYPE_FIELD_NAME (type, i)); - if (TYPE_FIELD_PACKED (type, i)) + /* check if static field */ + if (TYPE_FIELD_STATIC (type, i)) + { + value v; + + v = value_static_field (type, TYPE_FIELD_NAME (type, i), i); + val_print (TYPE_FIELD_TYPE (type, i), + VALUE_CONTENTS (v), 0, stream); + } + else if (TYPE_FIELD_PACKED (type, i)) { val = unpack_field_as_long (type, valaddr, i); val_print (TYPE_FIELD_TYPE (type, i), &val, 0, stream); } else - val_print (TYPE_FIELD_TYPE (type, i), - valaddr + TYPE_FIELD_BITPOS (type, i) / 8, - 0, stream); + { + val_print (TYPE_FIELD_TYPE (type, i), + valaddr + TYPE_FIELD_BITPOS (type, i) / 8, + 0, stream); + } } fprintf (stream, "}"); break; @@ -336,13 +488,41 @@ type_print_1 (type, varstring, stream, show, level) ((show > 0 || TYPE_NAME (type) == 0) && (code == TYPE_CODE_PTR || code == TYPE_CODE_FUNC - || code == TYPE_CODE_ARRAY))) + || code == TYPE_CODE_ARRAY + || code == TYPE_CODE_MPTR + || code == TYPE_CODE_REF))) fprintf (stream, " "); type_print_varspec_prefix (type, stream, show, 0); fprintf (stream, "%s", varstring); type_print_varspec_suffix (type, stream, show, 0); } +/* Print the method arguments ARGS to the file STREAM. */ +static void +type_print_method_args (args, prefix, varstring, stream) + struct type **args; + char *prefix, *varstring; + FILE *stream; +{ + int i; + + fprintf (stream, " %s%s (", prefix, varstring); + if (args[1] && args[1]->code != TYPE_CODE_VOID) + { + i = 1; /* skip the class variable */ + while (1) + { + type_print (args[i++], "", stream, 0); + if (args[i]->code != TYPE_CODE_VOID) + { + fprintf (stream, ", "); + } + else break; + } + } + fprintf (stream, ")"); +} + /* Print any asterisks or open-parentheses needed before the variable name (to describe its type). @@ -370,12 +550,29 @@ type_print_varspec_prefix (type, stream, show, passed_a_ptr) fputc ('*', stream); break; + case TYPE_CODE_MPTR: + type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); + if (passed_a_ptr) + fputc ('(', stream); + type_print_base (TYPE_DOMAIN_TYPE (type), stream, 0, 1); + fprintf (stream, "::*"); + break; + + case TYPE_CODE_REF: + type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 1); + fputc ('&', stream); + break; + case TYPE_CODE_FUNC: - case TYPE_CODE_ARRAY: - type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, 0); + type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, + passed_a_ptr); if (passed_a_ptr) fputc ('(', stream); break; + + case TYPE_CODE_ARRAY: + type_print_varspec_prefix (TYPE_TARGET_TYPE (type), stream, 0, + passed_a_ptr); } } @@ -398,9 +595,8 @@ type_print_varspec_suffix (type, stream, show, passed_a_ptr) switch (TYPE_CODE (type)) { case TYPE_CODE_ARRAY: - type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0); - if (passed_a_ptr) - fprintf (stream, ")"); + type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, + passed_a_ptr); fprintf (stream, "["); if (TYPE_LENGTH (type) >= 0) fprintf (stream, "%d", @@ -408,12 +604,18 @@ type_print_varspec_suffix (type, stream, show, passed_a_ptr) fprintf (stream, "]"); break; + case TYPE_CODE_MPTR: + if (passed_a_ptr) + fputc (')', stream); + /* Fall through. */ case TYPE_CODE_PTR: + case TYPE_CODE_REF: type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 1); break; case TYPE_CODE_FUNC: - type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, 0); + type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, 0, + passed_a_ptr); if (passed_a_ptr) fprintf (stream, ")"); fprintf (stream, "()"); @@ -458,6 +660,8 @@ type_print_base (type, stream, show, level) { case TYPE_CODE_ARRAY: case TYPE_CODE_PTR: + case TYPE_CODE_MPTR: + case TYPE_CODE_REF: case TYPE_CODE_FUNC: type_print_base (TYPE_TARGET_TYPE (type), stream, show, level); break; @@ -478,46 +682,84 @@ type_print_base (type, stream, show, level) fprintf (stream, "{...}"); else { + struct type *basetype, *dtype; + + dtype = type; + basetype = TYPE_BASECLASS (type); + while (basetype) + { + if (TYPE_NAME (basetype) && (name = TYPE_NAME (basetype))) + { + while (*name != ' ') name++; + fprintf (stream, ": %s %s ", + TYPE_VIA_PUBLIC (dtype) ? "public" : "private", + name + 1); + } + dtype = basetype; + basetype = TYPE_BASECLASS (basetype); + } fprintf (stream, "{"); len = TYPE_NFIELDS (type); - fprintf (stream, "\n"); - for (i = 0; i < len; i++) + if (len) fprintf (stream, "\n"); + else fprintf (stream, "<no data fields>\n"); + + /* If there is a base class for this type, + do not print the field that it occupies. */ + for (i = !! TYPE_BASECLASS (type); i < len; i++) { QUIT; - print_spaces (level + 4, stream); + /* Don't print out virtual function table. */ + if (! strncmp (TYPE_FIELD_NAME (type, i), + "_vptr$", 6)) + continue; - /* If this is a bit-field and there is a gap before it, - print a nameless field to account for the gap. */ - - if (TYPE_FIELD_PACKED (type, i)) + print_spaces (level + 4, stream); + if (TYPE_FIELD_STATIC (type, i)) { - int gap = (TYPE_FIELD_BITPOS (type, i) - - (i > 0 - ? (TYPE_FIELD_BITPOS (type, i - 1) - + (TYPE_FIELD_PACKED (type, i - 1) - ? TYPE_FIELD_BITSIZE (type, i - 1) - : TYPE_LENGTH (TYPE_FIELD_TYPE (type, i - 1)) * 8)) - : 0)); - if (gap != 0) - { - fprintf (stream, "int : %d;\n", gap); - print_spaces (level + 4, stream); - } + fprintf (stream, "static "); } - - /* Print the declaration of this field. */ - type_print_1 (TYPE_FIELD_TYPE (type, i), TYPE_FIELD_NAME (type, i), stream, show - 1, level + 4); + if (!TYPE_FIELD_STATIC (type, i) + && TYPE_FIELD_PACKED (type, i)) + { + /* ??? don't know what to put here ??? */; + } + fprintf (stream, ";\n"); + } - /* Print the field width. */ - - if (TYPE_FIELD_PACKED (type, i)) - fprintf (stream, " : %d", TYPE_FIELD_BITSIZE (type, i)); + /* C++: print out the methods */ + len = TYPE_NFN_FIELDS (type); + if (len) fprintf (stream, "\n"); + for (i = 0; i < len; i++) + { + struct fn_field *f = TYPE_FN_FIELDLIST1 (type, i); + int j, len2 = TYPE_FN_FIELDLIST_LENGTH (type, i); - fprintf (stream, ";\n"); + for (j = 0; j < len2; j++) + { + QUIT; + print_spaces (level + 4, stream); + if (TYPE_FN_FIELD_VIRTUAL_P (f, j)) + fprintf (stream, "virtual "); + type_print_base (TYPE_FN_FIELD_TYPE (f, j), stream, 0, level); + type_print_varspec_prefix (TYPE_FN_FIELD_TYPE (f, j), stream, 0, 0); + if (TYPE_FN_FIELD_PHYSNAME (f, j)[0] == '_' + && TYPE_FN_FIELD_PHYSNAME (f, j)[1] == '$') + type_print_method_args + (TYPE_FN_FIELD_ARGS (f, j) + 1, "~", + TYPE_FN_FIELDLIST_NAME (type, i), stream); + else + type_print_method_args + (TYPE_FN_FIELD_ARGS (f, j), "", + TYPE_FN_FIELDLIST_NAME (type, i), stream); + + fprintf (stream, ";\n"); + } + if (len2) fprintf (stream, "\n"); } + print_spaces (level, stream); fputc ('}', stream); } diff --git a/gdb/value.h b/gdb/value.h index 9801d9a..0b21e38 100644 --- a/gdb/value.h +++ b/gdb/value.h @@ -108,7 +108,7 @@ value value_addr (); value value_assign (); value value_neg (); value value_lognot (); -value value_struct_elt (); +value value_struct_elt (), value_struct_elt_for_address (); value value_field (); value value_cast (); value value_repeat (); @@ -120,6 +120,7 @@ value value_being_returned (); value evaluate_expression (); value evaluate_type (); value parse_and_eval (); +value parse_to_comma_and_eval (); value access_value_history (); value value_of_internalvar (); @@ -128,3 +129,7 @@ struct internalvar *lookup_internalvar (); int value_equal (); int value_less (); int value_zerop (); + +/* C++ */ +value value_of_this (); +value value_static_field (); diff --git a/gdb/values.c b/gdb/values.c index 9af5d96..93d9482 100644 --- a/gdb/values.c +++ b/gdb/values.c @@ -424,7 +424,12 @@ value_as_double (val) /* Unpack raw data (copied from debugee) at VALADDR as a long, or as a double, assuming the raw data is described by type TYPE. Knows how to convert different sizes of values - and can convert between fixed and floating point. */ + and can convert between fixed and floating point. + + C++: It is assumed that the front-end has taken care of + all matters concerning pointers to members. A pointer + to member which reaches here is considered to be equivalent + to an INT (or some size). After all, it is only an offset. */ long unpack_long (type, valaddr) @@ -459,7 +464,8 @@ unpack_long (type, valaddr) if (len == sizeof (long)) return * (unsigned long *) valaddr; } - else if (code == TYPE_CODE_INT) + else if (code == TYPE_CODE_INT + || code == TYPE_CODE_MPTR) { if (len == sizeof (char)) return * (char *) valaddr; @@ -473,12 +479,12 @@ unpack_long (type, valaddr) if (len == sizeof (long)) return * (long *) valaddr; } - else if (code == TYPE_CODE_PTR) + else if (code == TYPE_CODE_PTR + || code == TYPE_CODE_REF) { if (len == sizeof (char *)) return (CORE_ADDR) * (char **) valaddr; } - error ("Value not integer or pointer."); } @@ -536,7 +542,9 @@ unpack_double (type, valaddr) /* Given a value ARG1 of a struct or union type, extract and return the value of one of its fields. - FIELDNO says which field. */ + FIELDNO says which field. + + For C++, must also be able to return values from static fields */ value value_field (arg1, fieldno) @@ -574,6 +582,96 @@ value_field (arg1, fieldno) return v; } +value +value_fn_field (arg1, fieldno, subfieldno) + register value arg1; + register int fieldno; +{ + register value v; + struct fn_field *f = TYPE_FN_FIELDLIST1 (VALUE_TYPE (arg1), fieldno); + register struct type *type = TYPE_FN_FIELD_TYPE (f, subfieldno); + struct symbol *sym; + + sym = lookup_symbol (TYPE_FN_FIELD_PHYSNAME (f, subfieldno), + 0, VAR_NAMESPACE); + if (! sym) error ("Internal error: could not find physical method named %s", + TYPE_FN_FIELD_PHYSNAME (f, subfieldno)); + + v = allocate_value (type); + VALUE_ADDRESS (v) = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); + VALUE_TYPE (v) = type; + return v; +} + +/* The value of a static class member does not depend + on its instance, only on its type. If FIELDNO >= 0, + then fieldno is a valid field number and is used directly. + Otherwise, FIELDNAME is the name of the field we are + searching for. If it is not a static field name, an + error is signaled. TYPE is the type in which we look for the + static field member. */ +value +value_static_field (type, fieldname, fieldno) + register struct type *type; + char *fieldname; + register int fieldno; +{ + register value v; + struct symbol *sym; + + if (fieldno < 0) + { + register struct type *t = type; + /* Look for static field. */ + while (t) + { + int i; + for (i = TYPE_NFIELDS (t) - 1; i >= 0; i--) + if (! strcmp (TYPE_FIELD_NAME (t, i), fieldname)) + { + if (TYPE_FIELD_STATIC (t, i)) + { + fieldno = i; + goto found; + } + else + error ("field `%s' is not static"); + } + t = TYPE_BASECLASS (t); + } + + t = type; + + if (destructor_name_p (fieldname, t)) + error ("use `info method' command to print out value of destructor"); + + while (t) + { + int i, j; + + for (i = TYPE_NFN_FIELDS (t) - 1; i >= 0; i--) + { + if (! strcmp (TYPE_FN_FIELDLIST_NAME (t, i), fieldname)) + { + error ("use `info method' command to print value of method \"%s\"", fieldname); + } + } + t = TYPE_BASECLASS (t); + } + error("there is no field named %s", fieldname); + } + + found: + + sym = lookup_symbol (TYPE_FIELD_STATIC_PHYSNAME (type, fieldno), + 0, VAR_NAMESPACE); + if (! sym) error ("Internal error: could not find physical static variable named %s", TYPE_FIELD_BITSIZE (type, fieldno)); + + type = TYPE_FIELD_TYPE (type, fieldno); + v = value_at (type, (CORE_ADDR)SYMBOL_BLOCK_VALUE (sym)); + return v; +} + long unpack_field_as_long (type, valaddr, fieldno) struct type *type; diff --git a/gdb/version.c b/gdb/version.c index 452ccd8..244d065 100644 --- a/gdb/version.c +++ b/gdb/version.c @@ -1,3 +1,3 @@ /* Define the current version number of GDB. */ -char *version = "2.4+"; +char *version = "2.5.1 (GNU C++ 1.21.0 compatible)"; |