diff options
author | Per Bothner <per@bothner.com> | 1991-12-23 23:16:58 +0000 |
---|---|---|
committer | Per Bothner <per@bothner.com> | 1991-12-23 23:16:58 +0000 |
commit | 7e258d18e0112304099fbefbe910a53659b98a3d (patch) | |
tree | a1dd070cd40879a617d8cbddcf0417abf882a6af | |
parent | 3e60a6b1d3064f0e08369dbe0bae64d632fcb773 (diff) | |
download | gdb-7e258d18e0112304099fbefbe910a53659b98a3d.zip gdb-7e258d18e0112304099fbefbe910a53659b98a3d.tar.gz gdb-7e258d18e0112304099fbefbe910a53659b98a3d.tar.bz2 |
Oodles of changes. The most important is adding support for stabs
encapsulated in mips ecoff. See ChangeLog for the gory details.
-rw-r--r-- | gdb/.Sanitize | 4 | ||||
-rw-r--r-- | gdb/ChangeLog | 52 | ||||
-rw-r--r-- | gdb/buildsym.c | 58 | ||||
-rw-r--r-- | gdb/buildsym.h | 8 | ||||
-rw-r--r-- | gdb/coffread.c | 66 | ||||
-rw-r--r-- | gdb/dbxread.c | 760 | ||||
-rwxr-xr-x | gdb/depend | 19 | ||||
-rw-r--r-- | gdb/dwarfread.c | 28 | ||||
-rw-r--r-- | gdb/m68k-pinsn.c | 2 | ||||
-rw-r--r-- | gdb/mips-pinsn.c | 2 | ||||
-rw-r--r-- | gdb/mipsread.c | 1237 | ||||
-rw-r--r-- | gdb/partial-stab.h | 576 | ||||
-rw-r--r-- | gdb/sparc-pinsn.c | 2 | ||||
-rw-r--r-- | gdb/symfile.h | 76 | ||||
-rw-r--r-- | gdb/symmisc.c | 220 | ||||
-rw-r--r-- | gdb/symtab.c | 14 | ||||
-rw-r--r-- | gdb/symtab.h | 18 | ||||
-rw-r--r-- | gdb/tm-mips.h | 4 |
18 files changed, 1646 insertions, 1500 deletions
diff --git a/gdb/.Sanitize b/gdb/.Sanitize index e4e8008..96814e3 100644 --- a/gdb/.Sanitize +++ b/gdb/.Sanitize @@ -109,7 +109,6 @@ kdb-start.c language.c language.h m2-exp.y -m68k-opcode.h m68k-pinsn.c m68k-stub.c m68k-tdep.c @@ -122,7 +121,6 @@ main.c mcheck.c mem-break.c minimon.h -mips-opcode.h mips-pinsn.c mips-tdep.c mips-xdep.c @@ -138,6 +136,7 @@ ns32k-opcode.h ns32k-pinsn.c parse.c parser-defs.h +partial-stab.h pn-opcode.h printcmd.c procfs.c @@ -165,7 +164,6 @@ signame.c signame.h solib.c source.c -sparc-opcode.h sparc-pinsn.c sparc-tdep.c sparc-xdep.c diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 08c3300..925b66d 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,55 @@ +Mon Dec 23 13:54:35 1991 Per Bothner (bothner at cygnus.com) + + * m68k-opcode.h, mips-opcode.h, sparc-opcode.h: Deleted. + * m68k-pinsn.c, mips-pinsn.c, sparc-pinsn.c: + Include <opcode/FOO.h> instead of <FOO-opcode.h>. + + * symtab.h, symtab.c, coffread.c, dwarfread.c, symmisc.c, + dbxread.c: The TYPE_CPLUS_SPECIFIC structure is now only + allocated when it is needed. Until it is needed, it points + to a shared statically allocated structure. + + * buildsym.h, buildsym.c, dbxread.c: Remove the kludgy code + in read_ofile_symtab to recognize two initial N_SO stabs, + and let process_on_symbol handle it. This is cleaner, more + efficient, and lets mipsread.c share the same code. + + * symfile.h, partial-stab.h: Move ADD_PSYMBOL_VT_TO_LIST + and related macros to here ... + * dbxread.c: ... from here. + * symmisc.c: Move the "overflow" handling from + ADD_PSYMBOL_VT_TO_LIST macro into new function extend_psymbol_list. + * dwarfread.c: Re-write add_psymbol_to_list to use + ADD_PSYMBOL_VT_TO_LIST macro. + + * mipsread.c: Extend mipsread.c to handle stabs-style symbols + encapsulated in ecoff symbols. This enable full g++ debugging. + * partial-stab.h: Move the code for pre-scanning symbols + and building psymtabs to an include file, out from dbxread.c. + This way, the same code can also be used by mipsread.c. + * dbxread.c, buildsym.h: Various changes to allow some functions + to be used by mipsread.c (also some arguable stylistic changes). + + * tm-mips.h: Define BLOCK_ADDRESS_ABSOLUTE, at least for now, + since mips-tfile puts relocatable addresses into LBRAC/RBRAC + stabs. + + * mipsread.c: Replace code to handle ambiguous tag blocks. + Instead of allocating a TYPE_CODE_UNDEF, guess (by looking + at types and offsets) if a tag is a struct, union, or enum. + Still patch it later if we find out for sure. + * mipsread.c: In various ways, replace Forin's + ideo-syncratic code by code that fits better with the + rest of gdb, for both stabs-based and ecoff-based symtabs. + E.g. use end_psymtab; don't do extra passes over FDR table to + pre-partition global data; don't use external symbols to + create static/global symbols (just put them in the + misc_vector); use ADD_PSYMBOL_TO_LIST macro; don't + sort psymtabs or symtabs; use obstacks more. + + * symtab.c, mipsread.c, dbxread.c, buildsym.c: + ANSIfy: Replace bcopy by memcpy, bzero by memset. + Sun Dec 22 19:31:04 1991 Fred Fish (fnf at cygnus.com) * solib.c (locate_base): Fix uninitialized variable that was diff --git a/gdb/buildsym.c b/gdb/buildsym.c index d4dde9c..bbcaecd 100644 --- a/gdb/buildsym.c +++ b/gdb/buildsym.c @@ -808,6 +808,7 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile) last_source_file = 0; current_subfile = 0; + previous_stab_code = 0; return symtab; } @@ -1063,7 +1064,7 @@ define_symbol (valu, string, desc, type) SYMBOL_TYPE (sym) = builtin_type_double; dbl_valu = (char *) obstack_alloc (symbol_obstack, sizeof (double)); - bcopy (&d, dbl_valu, sizeof (double)); + memcpy (dbl_valu, &d, sizeof (double)); SWAP_TARGET_AND_HOST (dbl_valu, sizeof (double)); SYMBOL_VALUE_BYTES (sym) = dbl_valu; SYMBOL_CLASS (sym) = LOC_CONST_BYTES; @@ -1447,7 +1448,7 @@ cleanup_undefined_types () && (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE (*type)) && !strcmp (SYMBOL_NAME (sym), typename)) - bcopy (SYMBOL_TYPE (sym), *type, sizeof (struct type)); + memcpy (*type, SYMBOL_TYPE (sym), sizeof (struct type)); } } else @@ -1703,13 +1704,7 @@ read_type (pp) type = dbx_alloc_type (typenums); TYPE_CODE (type) = code; TYPE_NAME (type) = type_name; - if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) - { - TYPE_CPLUS_SPECIFIC (type) - = (struct cplus_struct_type *) obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type)); - bzero (TYPE_CPLUS_SPECIFIC (type), sizeof (struct cplus_struct_type)); - } - + TYPE_CPLUS_SPECIFIC(type) = &cplus_struct_default; TYPE_FLAGS (type) |= TYPE_FLAG_STUB; add_undefined_type (type); @@ -1919,15 +1914,14 @@ read_struct_type (pp, type) struct nextfield *new; register char *p; int nfields = 0; + int non_public_fields = 0; register int n; register struct next_fnfieldlist *mainlist = 0; int nfn_fields = 0; TYPE_CODE (type) = TYPE_CODE_STRUCT; - TYPE_CPLUS_SPECIFIC (type) - = (struct cplus_struct_type *) obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type)); - bzero (TYPE_CPLUS_SPECIFIC (type), sizeof (struct cplus_struct_type)); + TYPE_CPLUS_SPECIFIC(type) = &cplus_struct_default; /* First comes the total size in bytes. */ @@ -1956,6 +1950,8 @@ read_struct_type (pp, type) *pp += 1; + ALLOCATE_CPLUS_STRUCT_TYPE(type); + n_baseclasses = read_number (pp, ','); TYPE_FIELD_VIRTUAL_BITS (type) = (B_TYPE *) obstack_alloc (symbol_obstack, B_BYTES (n_baseclasses)); @@ -1984,6 +1980,7 @@ read_struct_type (pp, type) { case '0': via_public = 0; + non_public_fields++; break; case '2': via_public = 2; @@ -2081,6 +2078,8 @@ read_struct_type (pp, type) list->field.bitpos = read_number (pp, ';'); /* This field is unpacked. */ list->field.bitsize = 0; + list->visibility = 0; /* private */ + non_public_fields++; } /* GNU C++ anonymous type. */ else if (*p == '_') @@ -2108,11 +2107,13 @@ read_struct_type (pp, type) { case '0': list->visibility = 0; /* private */ + non_public_fields++; *pp += 1; break; case '1': list->visibility = 1; /* protected */ + non_public_fields++; *pp += 1; break; @@ -2209,13 +2210,18 @@ read_struct_type (pp, type) TYPE_FIELDS (type) = (struct field *) obstack_alloc (symbol_obstack, sizeof (struct field) * nfields); - TYPE_FIELD_PRIVATE_BITS (type) = - (B_TYPE *) obstack_alloc (symbol_obstack, B_BYTES (nfields)); - B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields); + if (non_public_fields) + { + ALLOCATE_CPLUS_STRUCT_TYPE (type); - TYPE_FIELD_PROTECTED_BITS (type) = - (B_TYPE *) obstack_alloc (symbol_obstack, B_BYTES (nfields)); - B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields); + TYPE_FIELD_PRIVATE_BITS (type) = + (B_TYPE *) obstack_alloc (symbol_obstack, B_BYTES (nfields)); + B_CLRALL (TYPE_FIELD_PRIVATE_BITS (type), nfields); + + TYPE_FIELD_PROTECTED_BITS (type) = + (B_TYPE *) obstack_alloc (symbol_obstack, B_BYTES (nfields)); + B_CLRALL (TYPE_FIELD_PROTECTED_BITS (type), nfields); + } /* Copy the saved-up fields into the field vector. */ @@ -2243,6 +2249,7 @@ read_struct_type (pp, type) "unread" the name that has been read, so that we can start from the top. */ + ALLOCATE_CPLUS_STRUCT_TYPE (type); /* For each list of method lists... */ do { @@ -2447,12 +2454,15 @@ read_struct_type (pp, type) *pp += 1; - TYPE_FN_FIELDLISTS (type) = - (struct fn_fieldlist *) obstack_alloc (symbol_obstack, - sizeof (struct fn_fieldlist) * nfn_fields); - TYPE_NFN_FIELDS (type) = nfn_fields; - TYPE_NFN_FIELDS_TOTAL (type) = total_length; + if (nfn_fields) + { + TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *) + obstack_alloc (symbol_obstack, + sizeof (struct fn_fieldlist) * nfn_fields); + TYPE_NFN_FIELDS (type) = nfn_fields; + TYPE_NFN_FIELDS_TOTAL (type) = total_length; + } { int i; @@ -3143,7 +3153,7 @@ read_args (pp, end) { rval = (struct type **) xmalloc (n * sizeof (struct type *)); } - bcopy (types, rval, n * sizeof (struct type *)); + memcpy (rval, types, n * sizeof (struct type *)); return rval; } diff --git a/gdb/buildsym.h b/gdb/buildsym.h index 2722d5b..80fad8e 100644 --- a/gdb/buildsym.h +++ b/gdb/buildsym.h @@ -59,6 +59,9 @@ extern struct context_stack *push_context (); extern void record_line (); extern void start_symtab (); extern struct symbol *define_symbol (); +extern struct partial_symtab *start_psymtab (); +extern void end_psymtab(); + /* Convert stab register number (from `r' declaration) to a gdb REGNUM. */ @@ -218,6 +221,11 @@ extern CORE_ADDR startup_file_end; /* From blockframe.c */ EXTERN unsigned char processing_gcc_compilation; +/* The type code that process_one_symbol saw on its previous invocation. + Used to detect pairs of N_SO symbols. */ + +EXTERN int previous_stab_code; + /* Setup a define to deal cleanly with the underscore problem */ #ifdef NAMES_HAVE_UNDERSCORE diff --git a/gdb/coffread.c b/gdb/coffread.c index f942625..bd5b0ce 100644 --- a/gdb/coffread.c +++ b/gdb/coffread.c @@ -1,6 +1,6 @@ /* Read coff symbol tables and convert to internal format, for GDB. Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu). - Copyright (C) 1987-1991 Free Software Foundation, Inc. + Copyright 1987, 1988, 1989, 1990, 1991 Free Software Foundation, Inc. This file is part of GDB. @@ -217,12 +217,20 @@ extern CORE_ADDR startup_file_end; /* From blockframe.c */ struct complaint ef_complaint = {"Unmatched .ef symbol(s) ignored starting at symnum %d", 0, 0}; -struct complaint no_aux_complaint = - {"symbol %d without one aux entry", 0, 0}; +struct complaint bf_no_aux_complaint = + {"`.bf' symbol %d has no aux entry", 0, 0}; + +struct complaint ef_no_aux_complaint = + {"`.ef' symbol %d has no aux entry", 0, 0}; struct complaint lineno_complaint = {"Line number pointer %d lower than start of line numbers", 0, 0}; +struct complaint unexpected_type_complaint = + {"Unexpected type for symbol %s", 0, 0}; + +struct complaint bad_sclass_complaint = + {"Bad n_sclass for symbol %s", 0, 0}; /* Look up a coff type-number index. Return the address of the slot where the type for that index is stored. @@ -885,7 +893,7 @@ read_coff_symtab (desc, nsyms, objfile) case C_LINE: case C_ALIAS: case C_HIDDEN: - printf ("Bad n_sclass = %d\n", cs->c_sclass); + complain (&bad_sclass_complaint, cs->c_name); break; case C_FILE: @@ -969,7 +977,7 @@ read_coff_symtab (desc, nsyms, objfile) /* main_aux.x_sym.x_misc.x_lnsz.x_lnno contains line number of '{' } */ if (cs->c_naux != 1) - complain (no_aux_complaint, cs->c_symnum); + complain (&bf_no_aux_complaint, cs->c_symnum); fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno; new = (struct context_stack *) @@ -999,7 +1007,7 @@ read_coff_symtab (desc, nsyms, objfile) break; } if (cs->c_naux != 1) { - complain (no_aux_complaint, cs->c_symnum); + complain (&ef_no_aux_complaint, cs->c_symnum); fcn_last_line = 0x7FFFFFFF; } else { fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno; @@ -1408,7 +1416,7 @@ patch_type (type, real_type) } } -/* Patch up all appropriate typdef symbols in the opaque_type_chains +/* Patch up all appropriate typedef symbols in the opaque_type_chains so that they can be used to print out opaque data structures properly */ static void @@ -1471,10 +1479,6 @@ patch_opaque_types () } } -#if defined (clipper) -#define BELIEVE_PCC_PROMOTION 1 -#endif - static struct symbol * process_coff_symbol (cs, aux) register struct coff_symbol *cs; @@ -1570,7 +1574,7 @@ process_coff_symbol (cs, aux) case C_ARG: SYMBOL_CLASS (sym) = LOC_ARG; #if 0 - /* FIXME: This has not bee tested. */ + /* FIXME: This has not been tested. */ /* Add parameter to function. */ add_param_to_type(&in_function_type,sym); #endif @@ -1578,12 +1582,12 @@ process_coff_symbol (cs, aux) #if !defined (BELIEVE_PCC_PROMOTION) /* If PCC says a parameter is a short or a char, it is really an int. */ - if (SYMBOL_TYPE (sym) == builtin_type_char - || SYMBOL_TYPE (sym) == builtin_type_short) - SYMBOL_TYPE (sym) = builtin_type_int; - else if (SYMBOL_TYPE (sym) == builtin_type_unsigned_char - || SYMBOL_TYPE (sym) == builtin_type_unsigned_short) - SYMBOL_TYPE (sym) = builtin_type_unsigned_int; + if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (builtin_type_int) + && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT) { + SYMBOL_TYPE (sym) = TYPE_UNSIGNED (SYMBOL_TYPE (sym))? + builtin_type_unsigned_int: + builtin_type_int; + } #endif break; @@ -1594,12 +1598,12 @@ process_coff_symbol (cs, aux) #if !defined (BELIEVE_PCC_PROMOTION) /* If PCC says a parameter is a short or a char, it is really an int. */ - if (SYMBOL_TYPE (sym) == builtin_type_char - || SYMBOL_TYPE (sym) == builtin_type_short) - SYMBOL_TYPE (sym) = builtin_type_int; - else if (SYMBOL_TYPE (sym) == builtin_type_unsigned_char - || SYMBOL_TYPE (sym) == builtin_type_unsigned_short) - SYMBOL_TYPE (sym) = builtin_type_unsigned_int; + if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (builtin_type_int) + && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT) { + SYMBOL_TYPE (sym) = TYPE_UNSIGNED (SYMBOL_TYPE (sym))? + builtin_type_unsigned_int: + builtin_type_int; + } #endif break; @@ -1791,9 +1795,7 @@ decode_base_type (cs, c_type, aux) type = coff_alloc_type (cs->c_symnum); TYPE_CODE (type) = TYPE_CODE_STRUCT; TYPE_NAME (type) = concat ("struct ", "<opaque>", NULL); - TYPE_CPLUS_SPECIFIC (type) - = (struct cplus_struct_type *) obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type)); - bzero (TYPE_CPLUS_SPECIFIC (type), sizeof (struct cplus_struct_type)); + TYPE_CPLUS_SPECIFIC(type) = &cplus_struct_default; TYPE_LENGTH (type) = 0; TYPE_FIELDS (type) = 0; TYPE_NFIELDS (type) = 0; @@ -1812,9 +1814,7 @@ decode_base_type (cs, c_type, aux) /* anonymous union type */ type = coff_alloc_type (cs->c_symnum); TYPE_NAME (type) = concat ("union ", "<opaque>", NULL); - TYPE_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *) - obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type)); - bzero (TYPE_CPLUS_SPECIFIC (type), sizeof (struct cplus_struct_type)); + TYPE_CPLUS_SPECIFIC(type) = &cplus_struct_default; TYPE_LENGTH (type) = 0; TYPE_LENGTH (type) = 0; TYPE_FIELDS (type) = 0; @@ -1850,7 +1850,7 @@ decode_base_type (cs, c_type, aux) case T_ULONG: return builtin_type_unsigned_long; } - printf ("unexpected type %d at symnum %d\n", c_type, cs->c_symnum); + complain (&unexpected_type_complaint, cs->c_name); return builtin_type_void; } @@ -1890,9 +1890,7 @@ read_struct_type (index, length, lastsym) type = coff_alloc_type (index); TYPE_CODE (type) = TYPE_CODE_STRUCT; - TYPE_CPLUS_SPECIFIC (type) - = (struct cplus_struct_type *) obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type)); - bzero (TYPE_CPLUS_SPECIFIC (type), sizeof (struct cplus_struct_type)); + TYPE_CPLUS_SPECIFIC(type) = &cplus_struct_default; TYPE_LENGTH (type) = length; while (!done && symnum < lastsym && symnum < nlist_nsyms_global) diff --git a/gdb/dbxread.c b/gdb/dbxread.c index 371f923..482f12c 100644 --- a/gdb/dbxread.c +++ b/gdb/dbxread.c @@ -56,8 +56,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "symfile.h" #include "buildsym.h" -#include "aout64.h" -#include "stab.gnu.h" /* We always use GNU stabs, not native, now */ +#include "aout/aout64.h" +#include "aout/stab_gnu.h" /* We always use GNU stabs, not native, now */ /* Information is passed among various dbxread routines for accessing symbol files. A pointer to this structure is kept in the sym_private @@ -98,7 +98,7 @@ extern double atof (); static void read_dbx_symtab (); static void init_psymbol_list (); -static void process_one_symbol (); +extern void process_one_symbol (); void start_subfile (); int hashname (); static struct pending *copy_pending (); @@ -560,6 +560,9 @@ fill_symbuf (sym_bfd) (a \ at the end of the text of a name) call this function to get the continuation. */ +#ifdef READ_MIPS_FORMAT +extern char *next_symbol_text (); +#else char * next_symbol_text () { @@ -569,6 +572,7 @@ next_symbol_text () SWAP_SYMBOL(&symbuf[symbuf_idx], symfile_bfd); return symbuf[symbuf_idx++].n_strx + stringtab_global; } +#endif /* Initializes storage for all of the partial symbols that will be created by read_dbx_symtab and subsidiaries. */ @@ -656,55 +660,35 @@ free_bincl_list () bincls_allocated = 0; } -static struct partial_symtab *start_psymtab (); -static void end_psymtab(); - #ifdef DEBUG /* This is normally a macro defined in read_dbx_symtab, but this is a lot easier to debug. */ -ADD_PSYMBOL_TO_PLIST(NAME, NAMELENGTH, NAMESPACE, CLASS, PLIST, VALUE) - char *NAME; - int NAMELENGTH; - enum namespace NAMESPACE; - enum address_class CLASS; - struct psymbol_allocation_list *PLIST; - unsigned long VALUE; +void +add_psymbol_to_plist(name, namelength, namespace, class, plist, value) + char *name; + int namelength; + enum namespace namespace; + enum address_class class; + struct psymbol_allocation_list *plist; + unsigned long value; { - register struct partial_symbol *psym; - -#define LIST *PLIST - do { - if ((LIST).next >= - (LIST).list + (LIST).size) - { - (LIST).list = (struct partial_symbol *) - xrealloc ((LIST).list, - ((LIST).size * 2 - * sizeof (struct partial_symbol))); - /* Next assumes we only went one over. Should be good if - program works correctly */ - (LIST).next = - (LIST).list + (LIST).size; - (LIST).size *= 2; - } - psym = (LIST).next++; -#undef LIST - - SYMBOL_NAME (psym) = (char *) obstack_alloc (psymbol_obstack, - (NAMELENGTH) + 1); - strncpy (SYMBOL_NAME (psym), (NAME), (NAMELENGTH)); - SYMBOL_NAME (psym)[(NAMELENGTH)] = '\0'; - SYMBOL_NAMESPACE (psym) = (NAMESPACE); - SYMBOL_CLASS (psym) = (CLASS); - SYMBOL_VALUE (psym) = (VALUE); - } while (0); + ADD_PSYMBOL_VT_TO_LIST(name, namelength, namespace, + class, *plist, value, SYMBOL_VALUE); } -/* Since one arg is a struct, we have to pass in a ptr and deref it (sigh) */ -#define ADD_PSYMBOL_TO_LIST(NAME, NAMELENGTH, NAMESPACE, CLASS, LIST, VALUE) \ - ADD_PSYMBOL_TO_PLIST(NAME, NAMELENGTH, NAMESPACE, CLASS, &LIST, VALUE) - +void +add_psymbol_addr_to_plist(name, namelength, namespace, class, plist, value) + char *name; + int namelength; + enum namespace namespace; + enum address_class class; + struct psymbol_allocation_list *plist; + CORE_ADDR value; +{ + ADD_PSYMBOL_VT_TO_LIST(name, namelength, namespace, + class, *plist, value, SYMBOL_VALUE_ADDRESS); +} #endif /* DEBUG */ /* Given pointers to an a.out symbol table in core containing dbx @@ -728,12 +712,10 @@ read_dbx_symtab (addr, objfile, stringtab, stringtab_size, nlistlen, { register struct internal_nlist *bufp; register char *namestring; - register struct partial_symbol *psym; int nsl; int past_first_source_file = 0; CORE_ADDR last_o_file_start = 0; struct cleanup *old_chain; - char *p; bfd *abfd; /* End of the text segment of the executable file. */ @@ -821,579 +803,27 @@ read_dbx_symtab (addr, objfile, stringtab, stringtab_size, nlistlen, } else \ namestring = bufp->n_strx + stringtab -/* Add a symbol with an integer value to a psymtab. */ -/* This is a macro unless we're debugging. See above this function. */ -#ifndef DEBUG -# define ADD_PSYMBOL_TO_LIST(NAME, NAMELENGTH, NAMESPACE, CLASS, LIST, VALUE) \ - ADD_PSYMBOL_VT_TO_LIST(NAME, NAMELENGTH, NAMESPACE, CLASS, LIST, VALUE, \ - SYMBOL_VALUE) -#endif /* DEBUG */ - -/* Add a symbol with a CORE_ADDR value to a psymtab. */ -#define ADD_PSYMBOL_ADDR_TO_LIST(NAME, NAMELENGTH, NAMESPACE, CLASS, LIST, VALUE) \ - ADD_PSYMBOL_VT_TO_LIST(NAME, NAMELENGTH, NAMESPACE, CLASS, LIST, VALUE, \ - SYMBOL_VALUE_ADDRESS) - -/* Add any kind of symbol to a psymtab. */ -#define ADD_PSYMBOL_VT_TO_LIST(NAME, NAMELENGTH, NAMESPACE, CLASS, LIST, VALUE, VT)\ - do { \ - if ((LIST).next >= \ - (LIST).list + (LIST).size) \ - { \ - (LIST).list = (struct partial_symbol *) \ - xrealloc ((LIST).list, \ - ((LIST).size * 2 \ - * sizeof (struct partial_symbol))); \ - /* Next assumes we only went one over. Should be good if \ - program works correctly */ \ - (LIST).next = \ - (LIST).list + (LIST).size; \ - (LIST).size *= 2; \ - } \ - psym = (LIST).next++; \ - \ - SYMBOL_NAME (psym) = (char *) obstack_alloc (psymbol_obstack, \ - (NAMELENGTH) + 1); \ - strncpy (SYMBOL_NAME (psym), (NAME), (NAMELENGTH)); \ - SYMBOL_NAME (psym)[(NAMELENGTH)] = '\0'; \ - SYMBOL_NAMESPACE (psym) = (NAMESPACE); \ - SYMBOL_CLASS (psym) = (CLASS); \ - VT (psym) = (VALUE); \ - } while (0); - -/* End of macro definitions, now let's handle them symbols! */ - - switch (bufp->n_type) - { - /* - * Standard, external, non-debugger, symbols - */ - - case N_TEXT | N_EXT: - case N_NBTEXT | N_EXT: - case N_NBDATA | N_EXT: - case N_NBBSS | N_EXT: - case N_SETV | N_EXT: - case N_ABS | N_EXT: - case N_DATA | N_EXT: - case N_BSS | N_EXT: - - bufp->n_value += addr; /* Relocate */ - - SET_NAMESTRING(); - - bss_ext_symbol: - record_misc_function (namestring, bufp->n_value, - bufp->n_type); /* Always */ - - continue; - - /* Standard, local, non-debugger, symbols */ - - case N_NBTEXT: - - /* We need to be able to deal with both N_FN or N_TEXT, - because we have no way of knowing whether the sys-supplied ld - or GNU ld was used to make the executable. Sequents throw - in another wrinkle -- they renumbered N_FN. */ - case N_FN: - case N_FN_SEQ: - case N_TEXT: - bufp->n_value += addr; /* Relocate */ - SET_NAMESTRING(); - if ((namestring[0] == '-' && namestring[1] == 'l') - || (namestring [(nsl = strlen (namestring)) - 1] == 'o' - && namestring [nsl - 2] == '.')) - { - if (entry_point < bufp->n_value - && entry_point >= last_o_file_start - && addr == 0) /* FIXME nogood nomore */ - { - startup_file_start = last_o_file_start; - startup_file_end = bufp->n_value; - } - if (past_first_source_file && pst - /* The gould NP1 uses low values for .o and -l symbols - which are not the address. */ - && bufp->n_value > pst->textlow) - { - end_psymtab (pst, psymtab_include_list, includes_used, - symnum * symbol_size, bufp->n_value, - dependency_list, dependencies_used, - global_psymbols.next, static_psymbols.next); - pst = (struct partial_symtab *) 0; - includes_used = 0; - dependencies_used = 0; - } - else - past_first_source_file = 1; - last_o_file_start = bufp->n_value; - } - continue; - - case N_DATA: - bufp->n_value += addr; /* Relocate */ - SET_NAMESTRING (); - /* Check for __DYNAMIC, which is used by Sun shared libraries. - Record it even if it's local, not global, so we can find it. - Same with virtual function tables, both global and static. */ - if ((namestring[8] == 'C' && (strcmp ("__DYNAMIC", namestring) == 0)) - || VTBL_PREFIX_P ((namestring+HASH_OFFSET))) - { - /* Not really a function here, but... */ - record_misc_function (namestring, bufp->n_value, - bufp->n_type); /* Always */ - } - continue; - - case N_UNDF | N_EXT: - if (bufp->n_value != 0) { - /* This is a "Fortran COMMON" symbol. See if the target - environment knows where it has been relocated to. */ - - CORE_ADDR reladdr; - - SET_NAMESTRING(); - if (target_lookup_symbol (namestring, &reladdr)) { - continue; /* Error in lookup; ignore symbol for now. */ - } - bufp->n_type ^= (N_BSS^N_UNDF); /* Define it as a bss-symbol */ - bufp->n_value = reladdr; - goto bss_ext_symbol; - } - continue; /* Just undefined, not COMMON */ - - /* Lots of symbol types we can just ignore. */ - - case N_UNDF: - case N_ABS: - case N_BSS: - case N_NBDATA: - case N_NBBSS: - continue; - - /* Keep going . . .*/ - - /* - * Special symbol types for GNU - */ - case N_INDR: - case N_INDR | N_EXT: - case N_SETA: - case N_SETA | N_EXT: - case N_SETT: - case N_SETT | N_EXT: - case N_SETD: - case N_SETD | N_EXT: - case N_SETB: - case N_SETB | N_EXT: - case N_SETV: - continue; - - /* - * Debugger symbols - */ - - case N_SO: { - unsigned long valu = bufp->n_value; - /* Symbol number of the first symbol of this file (i.e. the N_SO - if there is just one, or the first if we have a pair). */ - int first_symnum = symnum; - - /* End the current partial symtab and start a new one */ - - SET_NAMESTRING(); - - /* Peek at the next symbol. If it is also an N_SO, the - first one just indicates the directory. */ - if (symbuf_idx == symbuf_end) - fill_symbuf (abfd); - bufp = &symbuf[symbuf_idx]; - /* n_type is only a char, so swapping swapping is irrelevant. */ - if (bufp->n_type == (unsigned char)N_SO) - { - SWAP_SYMBOL (bufp, abfd); - SET_NAMESTRING (); - valu = bufp->n_value; - symbuf_idx++; - symnum++; - } - valu += addr; /* Relocate */ - - if (pst && past_first_source_file) - { - end_psymtab (pst, psymtab_include_list, includes_used, - first_symnum * symbol_size, valu, - dependency_list, dependencies_used, - global_psymbols.next, static_psymbols.next); - pst = (struct partial_symtab *) 0; - includes_used = 0; - dependencies_used = 0; +#define CUR_SYMBOL_TYPE bufp->n_type +#define CUR_SYMBOL_VALUE bufp->n_value +#define DBXREAD_ONLY +#define CHECK_SECOND_N_SO() \ + if (symbuf_idx == symbuf_end) \ + fill_symbuf (abfd);\ + bufp = &symbuf[symbuf_idx];\ + /* n_type is only a char, so swapping swapping is irrelevant. */\ + if (CUR_SYMBOL_TYPE == (unsigned char)N_SO)\ + {\ + SWAP_SYMBOL (bufp, abfd);\ + SET_NAMESTRING ();\ + valu = CUR_SYMBOL_VALUE;\ + symbuf_idx++;\ + symnum++;\ } - else - past_first_source_file = 1; - - pst = start_psymtab (objfile, addr, - namestring, valu, - first_symnum * symbol_size, - global_psymbols.next, static_psymbols.next); - continue; - } - - case N_BINCL: - /* Add this bincl to the bincl_list for future EXCLs. No - need to save the string; it'll be around until - read_dbx_symtab function returns */ - - SET_NAMESTRING(); - - add_bincl_to_list (pst, namestring, bufp->n_value); - - /* Mark down an include file in the current psymtab */ - - psymtab_include_list[includes_used++] = namestring; - if (includes_used >= includes_allocated) - { - char **orig = psymtab_include_list; - - psymtab_include_list = (char **) - alloca ((includes_allocated *= 2) * - sizeof (char *)); - bcopy (orig, psymtab_include_list, - includes_used * sizeof (char *)); - } - - continue; - - case N_SOL: - /* Mark down an include file in the current psymtab */ - - SET_NAMESTRING(); - - /* In C++, one may expect the same filename to come round many - times, when code is coming alternately from the main file - and from inline functions in other files. So I check to see - if this is a file we've seen before -- either the main - source file, or a previously included file. - - This seems to be a lot of time to be spending on N_SOL, but - things like "break c-exp.y:435" need to work (I - suppose the psymtab_include_list could be hashed or put - in a binary tree, if profiling shows this is a major hog). */ - if (pst && !strcmp (namestring, pst->filename)) - continue; - { - register int i; - for (i = 0; i < includes_used; i++) - if (!strcmp (namestring, psymtab_include_list[i])) - { - i = -1; - break; - } - if (i == -1) - continue; - } - - psymtab_include_list[includes_used++] = namestring; - if (includes_used >= includes_allocated) - { - char **orig = psymtab_include_list; - - psymtab_include_list = (char **) - alloca ((includes_allocated *= 2) * - sizeof (char *)); - bcopy (orig, psymtab_include_list, - includes_used * sizeof (char *)); - } - continue; - - case N_LSYM: /* Typedef or automatic variable. */ - case N_STSYM: /* Data seg var -- static */ - case N_LCSYM: /* BSS " */ - case N_NBSTS: /* Gould nobase. */ - case N_NBLCS: /* symbols. */ - - SET_NAMESTRING(); - - p = (char *) strchr (namestring, ':'); - - /* Skip if there is no :. */ - if (!p) continue; - - switch (p[1]) - { - case 'T': - ADD_PSYMBOL_TO_LIST (namestring, p - namestring, - STRUCT_NAMESPACE, LOC_TYPEDEF, - static_psymbols, bufp->n_value); - if (p[2] == 't') - { - /* Also a typedef with the same name. */ - ADD_PSYMBOL_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - static_psymbols, bufp->n_value); - p += 1; - } - goto check_enum; - case 't': - ADD_PSYMBOL_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - static_psymbols, bufp->n_value); - check_enum: - /* If this is an enumerated type, we need to - add all the enum constants to the partial symbol - table. This does not cover enums without names, e.g. - "enum {a, b} c;" in C, but fortunately those are - rare. There is no way for GDB to find those from the - enum type without spending too much time on it. Thus - to solve this problem, the compiler needs to put out separate - constant symbols ('c' N_LSYMS) for enum constants in - enums without names, or put out a dummy type. */ - - /* We are looking for something of the form - <name> ":" ("t" | "T") [<number> "="] "e" - {<constant> ":" <value> ","} ";". */ - - /* Skip over the colon and the 't' or 'T'. */ - p += 2; - /* This type may be given a number. Skip over it. */ - while ((*p >= '0' && *p <= '9') - || *p == '=') - p++; - - if (*p++ == 'e') - { - /* We have found an enumerated type. */ - /* According to comments in read_enum_type - a comma could end it instead of a semicolon. - I don't know where that happens. - Accept either. */ - while (*p && *p != ';' && *p != ',') - { - char *q; - - /* Check for and handle cretinous dbx symbol name - continuation! */ - if (*p == '\\') - p = next_symbol_text (); - - /* Point to the character after the name - of the enum constant. */ - for (q = p; *q && *q != ':'; q++) - ; - /* Note that the value doesn't matter for - enum constants in psymtabs, just in symtabs. */ - ADD_PSYMBOL_TO_LIST (p, q - p, - VAR_NAMESPACE, LOC_CONST, - static_psymbols, 0); - /* Point past the name. */ - p = q; - /* Skip over the value. */ - while (*p && *p != ',') - p++; - /* Advance past the comma. */ - if (*p) - p++; - } - } - - continue; - case 'c': - /* Constant, e.g. from "const" in Pascal. */ - ADD_PSYMBOL_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_CONST, - static_psymbols, bufp->n_value); - continue; - default: - /* Skip if the thing following the : is - not a letter (which indicates declaration of a local - variable, which we aren't interested in). */ - continue; - } - - case N_FUN: - case N_GSYM: /* Global (extern) variable; can be - data or bss (sigh). */ - - /* Following may probably be ignored; I'll leave them here - for now (until I do Pascal and Modula 2 extensions). */ - - case N_PC: /* I may or may not need this; I - suspect not. */ - case N_M2C: /* I suspect that I can ignore this here. */ - case N_SCOPE: /* Same. */ - - SET_NAMESTRING(); - - p = (char *) strchr (namestring, ':'); - if (!p) - continue; /* Not a debugging symbol. */ - - - - /* Main processing section for debugging symbols which - the initial read through the symbol tables needs to worry - about. If we reach this point, the symbol which we are - considering is definitely one we are interested in. - p must also contain the (valid) index into the namestring - which indicates the debugging type symbol. */ - - switch (p[1]) - { - case 'c': - ADD_PSYMBOL_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_CONST, - static_psymbols, bufp->n_value); - continue; - case 'S': - bufp->n_value += addr; /* Relocate */ - ADD_PSYMBOL_ADDR_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_STATIC, - static_psymbols, bufp->n_value); - continue; - case 'G': - bufp->n_value += addr; /* Relocate */ - /* The addresses in these entries are reported to be - wrong. See the code that reads 'G's for symtabs. */ - ADD_PSYMBOL_ADDR_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_STATIC, - global_psymbols, bufp->n_value); - continue; - - case 't': - ADD_PSYMBOL_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_TYPEDEF, - static_psymbols, bufp->n_value); - continue; - - case 'f': - ADD_PSYMBOL_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_BLOCK, - static_psymbols, bufp->n_value); - continue; - - /* Global functions were ignored here, but now they - are put into the global psymtab like one would expect. - They're also in the misc fn vector... - FIXME, why did it used to ignore these? That broke - "i fun" on these functions. */ - case 'F': - ADD_PSYMBOL_TO_LIST (namestring, p - namestring, - VAR_NAMESPACE, LOC_BLOCK, - global_psymbols, bufp->n_value); - continue; - - /* Two things show up here (hopefully); static symbols of - local scope (static used inside braces) or extensions - of structure symbols. We can ignore both. */ - case 'V': - case '(': - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - continue; - - default: - /* Unexpected symbol. Ignore it; perhaps it is an extension - that we don't know about. - - Someone says sun cc puts out symbols like - /foo/baz/maclib::/usr/local/bin/maclib, - which would get here with a symbol type of ':'. */ - continue; - } - - case N_EXCL: - - SET_NAMESTRING(); - - /* Find the corresponding bincl and mark that psymtab on the - psymtab dependency list */ - { - struct partial_symtab *needed_pst = - find_corresponding_bincl_psymtab (namestring, bufp->n_value); - - /* If this include file was defined earlier in this file, - leave it alone. */ - if (needed_pst == pst) continue; - - if (needed_pst) - { - int i; - int found = 0; - - for (i = 0; i < dependencies_used; i++) - if (dependency_list[i] == needed_pst) - { - found = 1; - break; - } - - /* If it's already in the list, skip the rest. */ - if (found) continue; - - dependency_list[dependencies_used++] = needed_pst; - if (dependencies_used >= dependencies_allocated) - { - struct partial_symtab **orig = dependency_list; - dependency_list = - (struct partial_symtab **) - alloca ((dependencies_allocated *= 2) - * sizeof (struct partial_symtab *)); - bcopy (orig, dependency_list, - (dependencies_used - * sizeof (struct partial_symtab *))); -#ifdef DEBUG_INFO - fprintf (stderr, "Had to reallocate dependency list.\n"); - fprintf (stderr, "New dependencies allocated: %d\n", - dependencies_allocated); -#endif - } - } - else - error ("Invalid symbol data: \"repeated\" header file not previously seen, at symtab pos %d.", - symnum); - } - continue; - - case N_EINCL: - case N_DSLINE: - case N_BSLINE: - case N_SSYM: /* Claim: Structure or union element. - Hopefully, I can ignore this. */ - case N_ENTRY: /* Alternate entry point; can ignore. */ - case N_MAIN: /* Can definitely ignore this. */ - case N_CATCH: /* These are GNU C++ extensions */ - case N_EHDECL: /* that can safely be ignored here. */ - case N_LENG: - case N_BCOMM: - case N_ECOMM: - case N_ECOML: - case N_FNAME: - case N_SLINE: - case N_RSYM: - case N_PSYM: - case N_LBRAC: - case N_RBRAC: - case N_NSYMS: /* Ultrix 4.0: symbol count */ - case N_DEFD: /* GNU Modula-2 */ - /* These symbols aren't interesting; don't worry about them */ - - continue; - - default: - /* If we haven't found it yet, ignore it. It's probably some - new type we don't know about yet. */ - complain (&unknown_symtype_complaint, local_hex_string(bufp->n_type)); - continue; - } +#define START_PSYMTAB(ofile,addr,fname,low,symoff,global_syms,static_syms)\ + start_psymtab(ofile, addr, fname, low, symoff, global_syms, static_syms) +#define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps)\ + end_psymtab(pst,ilist,ninc,c_off,c_text,dep_list,n_deps) +#include "partial-stab.h" } /* If there's stuff to be cleaned up, clean it up. */ @@ -1409,11 +839,7 @@ read_dbx_symtab (addr, objfile, stringtab, stringtab_size, nlistlen, { end_psymtab (pst, psymtab_include_list, includes_used, symnum * symbol_size, end_of_text_addr, - dependency_list, dependencies_used, - global_psymbols.next, static_psymbols.next); - includes_used = 0; - dependencies_used = 0; - pst = (struct partial_symtab *) 0; + dependency_list, dependencies_used); } free_bincl_list (); @@ -1428,7 +854,7 @@ read_dbx_symtab (addr, objfile, stringtab, stringtab_size, nlistlen, (normal). */ -static struct partial_symtab * +struct partial_symtab * start_psymtab (objfile, addr, filename, textlow, ldsymoff, global_syms, static_syms) struct objfile *objfile; @@ -1453,7 +879,8 @@ start_psymtab (objfile, addr, result->textlow = textlow; result->read_symtab_private = (char *) obstack_alloc (psymbol_obstack, sizeof (struct symloc)); - LDSYMOFF(result) = ldsymoff; + if (ldsymoff != -1) + LDSYMOFF(result) = ldsymoff; result->readin = 0; result->symtab = 0; @@ -1485,10 +912,9 @@ compare_psymbols (s1, s2) return st1[0] - st2[0]; if (st1[1] - st2[1]) return st1[1] - st2[1]; - return strcmp (st1 + 1, st2 + 1); + return strcmp (st1 + 2, st2 + 2); } - /* Close off the current usage of a partial_symbol table entry. This involves setting the correct number of includes (with a realloc), setting the high text mark, setting the symbol length in the @@ -1500,10 +926,9 @@ compare_psymbols (s1, s2) Then the partial symtab is put on the global list. *** List variables and peculiarities of same. *** */ -static void +void end_psymtab (pst, include_list, num_includes, capping_symbol_offset, - capping_text, dependency_list, number_dependencies, - capping_global, capping_static) + capping_text, dependency_list, number_dependencies) struct partial_symtab *pst; char **include_list; int num_includes; @@ -1511,17 +936,18 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset, CORE_ADDR capping_text; struct partial_symtab **dependency_list; int number_dependencies; - struct partial_symbol *capping_global, *capping_static; +/* struct partial_symbol *capping_global, *capping_static;*/ { int i; - LDSYMLEN(pst) = capping_symbol_offset - LDSYMOFF(pst); + if (capping_symbol_offset != -1) + LDSYMLEN(pst) = capping_symbol_offset - LDSYMOFF(pst); pst->texthigh = capping_text; pst->n_global_syms = - capping_global - (global_psymbols.list + pst->globals_offset); + global_psymbols.next - (global_psymbols.list + pst->globals_offset); pst->n_static_syms = - capping_static - (static_psymbols.list + pst->statics_offset); + static_psymbols.next - (static_psymbols.list + pst->statics_offset); pst->number_of_dependencies = number_dependencies; if (number_dependencies) @@ -1529,7 +955,7 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset, pst->dependencies = (struct partial_symtab **) obstack_alloc (psymbol_obstack, number_dependencies * sizeof (struct partial_symtab *)); - bcopy (dependency_list, pst->dependencies, + memcpy (pst->dependencies, dependency_list, number_dependencies * sizeof (struct partial_symtab *)); } else @@ -1876,46 +1302,9 @@ read_ofile_symtab (objfile, stringtab, stringtab_size, sym_offset, SET_NAMESTRING (); if (type & N_STAB) { - /* Check for a pair of N_SO symbols, which give both a new - source file name (second) and its directory (first). */ - if (type == (unsigned char)N_SO) { - /* Save the outer values */ - short bufp_n_desc = bufp->n_desc; - unsigned long valu = bufp->n_value; - - if (symbuf_idx == symbuf_end) - fill_symbuf (abfd); - bufp = &symbuf[symbuf_idx]; - if (bufp->n_type == (unsigned char)N_SO) { - char *namestring1 = namestring; - - SWAP_SYMBOL (bufp, abfd); - bufp->n_value += offset; /* Relocate */ - symbuf_idx++; - symnum++; - SET_NAMESTRING (); - - /* No need to check PCC_SOL_BROKEN, on the assumption that - such broken PCC's don't put out N_SO pairs. */ - if (last_source_file) - (void)end_symtab (bufp->n_value, 0, 0, objfile); - start_symtab (namestring, namestring1, bufp->n_value); - } else { - /* N_SO without a following N_SO */ - process_one_symbol(type, bufp_n_desc, valu, namestring); - /* our_objfile is an implicit parameter. */ - } - } else { - - /* Ordinary symbol - - HERE IS WHERE THE REAL WORK GETS DONE! - */ - process_one_symbol (type, bufp->n_desc, bufp->n_value, - namestring); - /* our_objfile is an implicit parameter. */ + process_one_symbol (type, bufp->n_desc, bufp->n_value, namestring); + /* our_objfile is an implicit parameter. */ - } } /* We skip checking for a new .o or -l file; that should never happen in this routine. */ @@ -1970,7 +1359,7 @@ hashname (name) } -static void +void process_one_symbol (type, desc, valu, name) int type, desc; CORE_ADDR valu; @@ -2151,7 +1540,22 @@ process_one_symbol (type, desc, valu, name) } #endif if (last_source_file) - (void)end_symtab (valu, 0, 0); + { + /* Check if previous symbol was also an N_SO (with some + sanity checks). If so, that one was actually the directory + name, and the current one is the real file name. + Patch things up. */ + if (previous_stab_code == N_SO + && current_subfile && current_subfile->dirname == NULL + && current_subfile->name != NULL + && current_subfile->name[strlen(current_subfile->name)-1] == '/') + { + current_subfile->dirname = current_subfile->name; + current_subfile->name = obsavestring (name, strlen (name)); + break; + } + (void)end_symtab (valu, 0, 0); + } start_symtab (name, NULL, valu); break; @@ -2226,6 +1630,8 @@ process_one_symbol (type, desc, valu, name) if (name) define_symbol (valu, name, desc, type); } + + previous_stab_code = type; } /* Copy a pending list, used to record the contents of a common @@ -52,7 +52,7 @@ cplus-dem.o : cplus-dem.c defs.h xm.h config.status tm.h config.status dbxread.o : dbxread.c defs.h xm.h config.status tm.h config.status symtab.h breakpoint.h value.h \ command.h target.h ${srcdir}/../include/bfd.h ${srcdir}/../include/ansidecl.h gdbcore.h \ ${srcdir}/../bfd/libaout.h symfile.h buildsym.h ${srcdir}/../include/aout/aout64.h \ - ${srcdir}/../include/aout/stab_gnu.h ${srcdir}/../include/aout/stab.def + ${srcdir}/../include/aout/stab_gnu.h ${srcdir}/../include/aout/stab.def partial-stab.h dwarfread.o : dwarfread.c defs.h xm.h config.status tm.h config.status ${srcdir}/../include/bfd.h \ ${srcdir}/../include/ansidecl.h ${srcdir}/../include/obstack.h symtab.h symfile.h \ ${srcdir}/../include/elf/dwarf.h ansidecl.h @@ -119,8 +119,8 @@ m2-exp.tab.o : m2-exp.tab.c ${srcdir}/defs.h xm.h config.status tm.h config.stat ${srcdir}/../include/obstack.h ${srcdir}/frame.h ${srcdir}/expression.h ${srcdir}/language.h ${srcdir}/value.h \ ${srcdir}/parser-defs.h m68k-pinsn.o : m68k-pinsn.c defs.h xm.h config.status tm.h config.status symtab.h \ - ${srcdir}/../include/obstack.h m68k-opcode.h gdbcore.h ${srcdir}/../include/bfd.h \ - ${srcdir}/../include/ansidecl.h + ${srcdir}/../include/obstack.h ${srcdir}/../include/opcode/m68k.h gdbcore.h \ + ${srcdir}/../include/bfd.h ${srcdir}/../include/ansidecl.h m68k-tdep.o : m68k-tdep.c defs.h xm.h config.status tm.h config.status ieee-float.h frame.h symtab.h \ ${srcdir}/../include/obstack.h m88k-pinsn.o : m88k-pinsn.c m88k-opcode.h defs.h xm.h config.status tm.h config.status symtab.h \ @@ -141,7 +141,7 @@ main.o : main.c defs.h xm.h config.status tm.h config.status gdbcmd.h command.h ${srcdir}/../readline/chardefs.h ${srcdir}/../readline/history.h mem-break.o : mem-break.c defs.h xm.h config.status tm.h config.status mips-pinsn.o : mips-pinsn.c defs.h xm.h config.status tm.h config.status symtab.h \ - ${srcdir}/../include/obstack.h mips-opcode.h + ${srcdir}/../include/obstack.h ${srcdir}/../include/opcode/mips.h mips-tdep.o : mips-tdep.c defs.h xm.h config.status tm.h config.status frame.h inferior.h breakpoint.h \ value.h symtab.h ${srcdir}/../include/obstack.h gdbcmd.h command.h language.h \ gdbcore.h ${srcdir}/../include/bfd.h ${srcdir}/../include/ansidecl.h @@ -149,8 +149,9 @@ mips-xdep.o : mips-xdep.c defs.h xm.h config.status tm.h config.status frame.h i value.h symtab.h ${srcdir}/../include/obstack.h gdbcore.h ${srcdir}/../include/bfd.h \ ${srcdir}/../include/ansidecl.h mipsread.o : mipsread.c defs.h xm.h config.status tm.h config.status symtab.h ${srcdir}/../include/obstack.h \ - gdbcore.h ${srcdir}/../include/bfd.h ${srcdir}/../include/ansidecl.h symfile.h \ - ${srcdir}/../include/coff/mips.h + gdbcore.h ${srcdir}/../include/bfd.h ${srcdir}/../include/ansidecl.h symfile.h buildsym.h \ + ${srcdir}/../include/coff/mips.h ${srcdir}/../bfd/libaout.h ${srcdir}/../include/aout/aout64.h \ + ${srcdir}/../include/aout/stab_gnu.h ${srcdir}/../include/aout/stab.def partial-stab.h news-xdep.o : news-xdep.c Onindy.o : ${srcdir}/nindy-share/Onindy.c ${srcdir}/nindy-share/ttycntl.h \ ${srcdir}/nindy-share/block_io.h ${srcdir}/../include/wait.h ${srcdir}/nindy-share/env.h \ @@ -181,7 +182,7 @@ remote-adapt.o : remote-adapt.c defs.h xm.h config.status tm.h config.status inf terminal.h target.h ${srcdir}/../include/bfd.h ${srcdir}/../include/ansidecl.h gdbcore.h remote-eb.o : remote-eb.c defs.h xm.h config.status tm-29k.h inferior.h breakpoint.h \ value.h symtab.h ${srcdir}/../include/obstack.h frame.h ${srcdir}/../include/wait.h \ - terminal.h target.h ${srcdir}/../include/bfd.h ${srcdir}/../include/ansidecl.h + terminal.h target.h ${srcdir}/../include/bfd.h ${srcdir}/../include/ansidecl.h gdbcore.h remote-mm.o : remote-mm.c defs.h xm.h config.status tm.h config.status inferior.h breakpoint.h value.h \ symtab.h ${srcdir}/../include/obstack.h frame.h ${srcdir}/../include/wait.h terminal.h \ minimon.h target.h ${srcdir}/../include/bfd.h ${srcdir}/../include/ansidecl.h @@ -213,8 +214,8 @@ source.o : source.c defs.h xm.h config.status tm.h config.status symtab.h ${srcd language.h command.h gdbcmd.h frame.h gdbcore.h ${srcdir}/../include/bfd.h \ ${srcdir}/../include/ansidecl.h regex.h sparc-pinsn.o : sparc-pinsn.c defs.h xm.h config.status tm.h config.status symtab.h \ - ${srcdir}/../include/obstack.h sparc-opcode.h gdbcore.h ${srcdir}/../include/bfd.h \ - ${srcdir}/../include/ansidecl.h /usr/include/string.h target.h + ${srcdir}/../include/obstack.h ${srcdir}/../include/opcode/sparc.h gdbcore.h \ + ${srcdir}/../include/bfd.h ${srcdir}/../include/ansidecl.h /usr/include/string.h target.h sparc-tdep.o : sparc-tdep.c defs.h xm.h config.status tm.h config.status frame.h inferior.h \ breakpoint.h value.h symtab.h ${srcdir}/../include/obstack.h signame.h target.h \ ${srcdir}/../include/bfd.h ${srcdir}/../include/ansidecl.h ieee-float.h gdbcore.h diff --git a/gdb/dwarfread.c b/gdb/dwarfread.c index 65a4c3f..e0c286b 100644 --- a/gdb/dwarfread.c +++ b/gdb/dwarfread.c @@ -331,11 +331,24 @@ EXFUN(start_psymtab, (struct objfile *objfile AND CORE_ADDR addr static void EXFUN(add_partial_symbol, (struct dieinfo *dip)); +#ifdef DEBUG static void -EXFUN(add_psymbol_to_list, - (struct psymbol_allocation_list *listp AND char *name - AND enum namespace space AND enum address_class class - AND CORE_ADDR value)); +DEFUN(add_psymbol_to_list, + (listp, name, space, class, value), + struct psymbol_allocation_list *listp AND + char *name AND + enum namespace space AND + enum address_class class AND + CORE_ADDR value) +{ + ADD_PSYMBOL_VT_TO_LIST(name, strlen(name), space, class, + listp, value, SYMBOL_VALUE); +} +#else +#define add_psymbol_to_list(listp, name, space, class, value) \ + ADD_PSYMBOL_VT_TO_LIST(name, strlen(name), space, class, \ + *(listp), value, SYMBOL_VALUE) +#endif static void EXFUN(init_psymbol_list, (int total_symbols)); @@ -913,10 +926,7 @@ DEFUN(struct_type, (dip, thisdie, enddie, objfile), /* No forward references created an empty type, so install one now */ type = alloc_utype (dip -> dieref, NULL); } - TYPE_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *) - obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type)); - (void) memset (TYPE_CPLUS_SPECIFIC (type), 0, - sizeof (struct cplus_struct_type)); + TYPE_CPLUS_SPECIFIC(type) = &cplus_struct_default; switch (dip -> dietag) { case TAG_structure_type: @@ -2655,6 +2665,7 @@ DEFUN(start_psymtab, return result; } +#if 0 /* LOCAL FUNCTION @@ -2696,6 +2707,7 @@ DEFUN(add_psymbol_to_list, SYMBOL_CLASS (psym) = class; SYMBOL_VALUE (psym) = value; } +#endif /* diff --git a/gdb/m68k-pinsn.c b/gdb/m68k-pinsn.c index de43af1..7fc6242 100644 --- a/gdb/m68k-pinsn.c +++ b/gdb/m68k-pinsn.c @@ -21,7 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "defs.h" #include "symtab.h" -#include "m68k-opcode.h" +#include "opcode/m68k.h" #include "gdbcore.h" /* 68k instructions are never longer than this many bytes. */ diff --git a/gdb/mips-pinsn.c b/gdb/mips-pinsn.c index a90448a..0b3391e 100644 --- a/gdb/mips-pinsn.c +++ b/gdb/mips-pinsn.c @@ -22,7 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "defs.h" #include "symtab.h" -#include "mips-opcode.h" +#include "opcode/mips.h" /* Mips instructions are never longer than this many bytes. */ #define MAXLEN 4 diff --git a/gdb/mipsread.c b/gdb/mipsread.c index f77ec4a..b98c9cb 100644 --- a/gdb/mipsread.c +++ b/gdb/mipsread.c @@ -39,6 +39,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "gdbcore.h" #include "symfile.h" #include "obstack.h" +#include "buildsym.h" #include <sys/param.h> #include <sys/file.h> #include <sys/stat.h> @@ -50,12 +51,22 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #endif /* not CMUCS */ #include "coff/mips.h" +#include "libaout.h" /* FIXME Secret internal BFD stuff for a.out */ +#include "aout/aout64.h" +#include "aout/stab_gnu.h" /* We always use GNU stabs, not native, now */ struct coff_exec { struct external_filehdr f; struct external_aouthdr a; }; +/* These must match the corresponding definition in mips-tfile.c. */ + +#define CODE_MASK 0x8F300 +#define MIPS_IS_STAB(sym) (((sym)->index & 0xFFF00) == CODE_MASK) +#define MIPS_MARK_STAB(code) ((code)+CODE_MASK) +#define MIPS_UNMARK_STAB(code) ((code)-CODE_MASK) + /* Each partial symbol table entry contains a pointer to private data for the read_symtab() function to use when expanding a partial symbol table entry to a full symbol table entry. @@ -153,6 +164,10 @@ static max_glevel; static int n_undef_symbols, n_undef_labels, n_undef_vars, n_undef_procs; +/* Pseudo symbol to use when putting stabs into the symbol table. */ + +static char stabs_symbol[] = "@stabs"; + /* Extra builtin types */ struct type *builtin_type_complex; @@ -165,7 +180,6 @@ struct type *builtin_type_string; static struct symbol *new_symbol(); static struct type *new_type(); -static struct field *new_field(); static struct block *new_block(); static struct symtab *new_symtab(); static struct linetable *new_linetable(); @@ -173,9 +187,9 @@ static struct blockvector *new_bvect(); static struct type *parse_type(); static struct type *make_type(); -static struct type *make_struct_type(); static struct symbol *mylookup_symbol(); static struct block *shrink_block(); +static void sort_blocks(); static int compare_symtabs(); static int compare_psymtabs(); @@ -189,9 +203,7 @@ static void psymtab_to_symtab_1(); static void add_block(); static void add_symbol(); static int add_line(); -static void reorder_symtabs(); -static void reorder_psymtabs(); -static void shrink_linetable(); +static struct linetable *shrink_linetable(); /* Things we export to other modules */ @@ -264,7 +276,7 @@ xzalloc(size) { char *p = xmalloc(size); - bzero(p, size); + memset(p, 0, size); return p; } @@ -292,7 +304,9 @@ mipscoff_psymtab_to_symtab(pst) psymtab_to_symtab_1(pst, pst->filename); - reorder_symtabs(); + /* Match with global symbols. This only needs to be done once, + after all of the symtabs and dependencies have been read in. */ + scan_file_globals (); if (info_verbose) printf_filtered("done.\n"); @@ -356,7 +370,7 @@ read_the_mips_symtab(abfd, fsym, end_of_text_segp) /* Allocate space for the symbol table. Read it in. */ cur_hdr = (HDRR *) xmalloc(stsize + st_hdrsize); - bcopy(&st_hdr, cur_hdr, st_hdrsize); + memcpy(cur_hdr, &st_hdr, st_hdrsize); if (read(fsym, (char *) cur_hdr + st_hdrsize, stsize) != stsize) goto readerr; @@ -422,17 +436,19 @@ fixup_symtab( hdr, data, f_ptr) fh->issBase += hdr->cbSsOffset; if (fh->rss != -1) fh->rss = (long)fh->rss + fh->issBase; + + /* Local symbols */ + fh->isymBase = (int)((SYMR*)(hdr->cbSymOffset)+fh->isymBase); + + /* FIXME! Probably don't want to do this here! */ for (s_idx = 0; s_idx < fh->csym; s_idx++) { - sh = (SYMR*)(hdr->cbSymOffset) + fh->isymBase + s_idx; + sh = (SYMR*)fh->isymBase + s_idx; sh->iss = (long) sh->iss + fh->issBase; sh->reserved = 0; } cur_fd = f_idx; - /* Local symbols */ - fh->isymBase = (int)((SYMR*)(hdr->cbSymOffset)+fh->isymBase); - /* cannot fix fh->ipdFirst because it is a short */ #define IPDFIRST(h,fh) \ ((long)h->cbPdOffset + fh->ipdFirst * sizeof(PDR)) @@ -542,6 +558,7 @@ read_mips_symtab (objfile, desc) parse_partial_symbols(end_of_text_seg, objfile); +#if 0 /* * Check to make sure file was compiled with -g. * If not, warn the user of this limitation. @@ -555,6 +572,7 @@ read_mips_symtab (objfile, desc) "You should compile with -g2 or -g3 for best debugging support.\n"); fflush(stdout); } +#endif } /* Local utilities */ @@ -563,8 +581,6 @@ read_mips_symtab (objfile, desc) static struct pst_map { struct partial_symtab *pst; /* the psymtab proper */ - int n_globals; /* globals it exports */ - int n_statics; /* statics (locals) it contains */ } * fdr_to_pst; @@ -574,14 +590,15 @@ static struct pst_map { after use. */ static struct parse_stack { - struct parse_stack *next, *prev; - struct symtab *cur_st; /* Current symtab */ - struct block *cur_block; /* Block in it */ - int blocktype; /* What are we parsing */ - int maxsyms; /* Max symbols in this block */ - struct type *cur_type; /* Type we parse fields for */ - int procadr; /* Start addres of this procedure */ - int numargs; /* Its argument count */ + struct parse_stack *next, *prev; + struct symtab *cur_st; /* Current symtab. */ + struct block *cur_block; /* Block in it. */ + int blocktype; /* What are we parsing. */ + int maxsyms; /* Max symbols in this block. */ + struct type *cur_type; /* Type we parse fields for. */ + int cur_field; /* Field number in cur_type. */ + int procadr; /* Start addres of this procedure */ + int numargs; /* Its argument count */ } *top_stack; /* Top stack ptr */ @@ -624,8 +641,8 @@ static pop_parse_stack() duplications we keep a quick fixup table, an array of lists of references indexed by file descriptor */ -static struct pending { - struct pending *next; /* link */ +static struct mips_pending { + struct mips_pending *next; /* link */ SYMR *s; /* the symbol */ struct type *t; /* its partial type descriptor */ } **pending_list; @@ -634,12 +651,12 @@ static struct pending { /* Check whether we already saw symbol SH in file FH as undefined */ static -struct pending *is_pending_symbol(fh, sh) +struct mips_pending *is_pending_symbol(fh, sh) FDR *fh; SYMR *sh; { int f_idx = fh - (FDR *) cur_hdr->cbFdOffset; - register struct pending *p; + register struct mips_pending *p; /* Linear search is ok, list is typically no more than 10 deep */ for (p = pending_list[f_idx]; p; p = p->next) @@ -651,12 +668,12 @@ struct pending *is_pending_symbol(fh, sh) /* Check whether we already saw type T in file FH as undefined */ static -struct pending *is_pending_type(fh, t) +struct mips_pending *is_pending_type(fh, t) FDR *fh; struct type *t; { int f_idx = fh - (FDR *) cur_hdr->cbFdOffset; - register struct pending *p; + register struct mips_pending *p; for (p = pending_list[f_idx]; p; p = p->next) if (p->t == t) @@ -673,11 +690,11 @@ add_pending(fh, sh, t) struct type *t; { int f_idx = fh - (FDR *) cur_hdr->cbFdOffset; - struct pending *p = is_pending_symbol(fh, sh); + struct mips_pending *p = is_pending_symbol(fh, sh); /* Make sure we do not make duplicates */ if (!p) { - p = (struct pending *) xmalloc(sizeof(*p)); + p = (struct mips_pending *) xmalloc(sizeof(*p)); p->s = sh; p->t = t; p->next = pending_list[f_idx]; @@ -691,7 +708,7 @@ add_pending(fh, sh, t) static free_pending(f_idx) { - register struct pending *p, *q; + register struct mips_pending *p, *q; for (p = pending_list[f_idx]; p; p = q) { q = p->next; @@ -755,17 +772,20 @@ free_numargs() /* Parse a single symbol. Mostly just make up a GDB symbol for it. For blocks, procedures and types we open a new lexical context. - This is basically just a big switch on the symbol's type */ + This is basically just a big switch on the symbol's type. + Return count of SYMR's handled (normally one). */ -static void +static int parse_symbol(sh, ax) SYMR *sh; AUXU *ax; { + char *name; struct symbol *s; struct block *b; struct type *t; struct field *f; + int count = 1; /* When a symbol is cross-referenced from other files/symbols we mark it explicitly */ int pend = (sh->reserved == 1); @@ -819,7 +839,13 @@ data: /* Common code for symbols describing data */ case stParam: /* arg to procedure, goes into current block */ max_gdbinfo++; top_stack->numargs++; - s = new_symbol(sh->iss); + + name = (char*)sh->iss; + /* Special GNU C++ name. */ + if (name[0] == CPLUS_MARKER && name[1] == 't' && name[2] == 0) + name = "this"; + s = new_symbol(name); + SYMBOL_NAMESPACE(s) = VAR_NAMESPACE; if (sh->sc == scRegister) { SYMBOL_CLASS(s) = LOC_REGPARM; @@ -895,6 +921,7 @@ data: /* Common code for symbols describing data */ top_stack->cur_block = b; top_stack->blocktype = sh->st; top_stack->cur_type = SYMBOL_TYPE(s); + top_stack->cur_field = -1; top_stack->procadr = sh->value; top_stack->numargs = 0; @@ -905,26 +932,91 @@ data: /* Common code for symbols describing data */ push_parse_stack(); top_stack->blocktype = stBlock; if (sh->sc == scInfo) { /* structure/union/enum def */ - s = new_symbol(sh->iss); - SYMBOL_NAMESPACE(s) = STRUCT_NAMESPACE; - SYMBOL_CLASS(s) = LOC_TYPEDEF; - SYMBOL_VALUE(s) = 0; - add_symbol(s, top_stack->cur_block); - /* If this type was expected, use its partial definition */ - if (pend) { - t = is_pending_symbol(cur_fdr, sh)->t; - } else { - /* Uhmm, can`t decide yet. Smash later */ - t = new_type(sh->iss); - TYPE_CODE(t) = TYPE_CODE_UNDEF; - add_pending(cur_fdr, sh, t); + int type_code = TYPE_CODE_UNDEF; + + s = new_symbol(sh->iss); + SYMBOL_NAMESPACE(s) = STRUCT_NAMESPACE; + SYMBOL_CLASS(s) = LOC_TYPEDEF; + SYMBOL_VALUE(s) = 0; + add_symbol(s, top_stack->cur_block); + /* If this type was expected, use its partial definition */ + if (pend) { + t = is_pending_symbol(cur_fdr, sh)->t; + } else { + int nfields = 0; + SYMR *tsym; + long max_value = 0; + struct field *f; + + /* First count the number of fields. */ + for (tsym = sh+1; tsym->st != stEnd; tsym++) + if (tsym->st == stMember) { + if (nfields == 0) + if (tsym->index == indexNil + || ax[tsym->index].ti.bt==26)/*btVoid*/ + type_code = TYPE_CODE_ENUM; + nfields++; + if (tsym->value > max_value) + max_value = tsym->value; + } + else if (tsym->st == stBlock + || tsym->st == stParsed) { + if (tsym->sc == scVariant) ; /*UNIMPLEMENTED*/ + if (tsym->index != 0) + tsym = ((SYMR*)cur_fdr->isymBase) + + tsym->index-1; + } + + t = new_type(sh->iss); + + /* Guess the type code. */ + if (type_code == TYPE_CODE_UNDEF) + if (max_value == 0) type_code = TYPE_CODE_UNION; + else type_code = TYPE_CODE_STRUCT; + + TYPE_CODE(t) = type_code; + TYPE_NFIELDS(t) = nfields; + TYPE_FIELDS(t) = f = (struct field*) + obstack_alloc (symbol_obstack, + nfields * sizeof (struct field)); + + if (type_code == TYPE_CODE_ENUM) { + /* This is a non-empty enum. */ + while (sh[1].st == stMember) { + struct symbol *enum_sym; + sh++; + f->bitpos = sh->value; + f->type = t; + f->name = (char*)sh->iss; + f->bitsize = 0; + + enum_sym = (struct symbol *) + obstack_alloc (symbol_obstack, + sizeof (struct symbol)); + memset (enum_sym, 0, sizeof (struct symbol)); + SYMBOL_NAME (enum_sym) = f->name; + SYMBOL_CLASS (enum_sym) = LOC_CONST; + SYMBOL_TYPE (enum_sym) = t; + SYMBOL_NAMESPACE (enum_sym) = VAR_NAMESPACE; + SYMBOL_VALUE (enum_sym) = sh->value; + add_symbol(enum_sym, top_stack->cur_block); + + count++; + f++; + } } - SYMBOL_TYPE(s) = t; - /* make this the current type */ - top_stack->cur_type = t; - TYPE_LENGTH(t) = sh->value; - /* Mark that symbol has a type, and say which one */ - sh->value = (long) t; + else { + /* Uhmm, can`t decide yet. Guess. */ + add_pending(cur_fdr, sh, t); + } + } + SYMBOL_TYPE(s) = t; + /* make this the current type */ + top_stack->cur_type = t; + top_stack->cur_field = 0; + TYPE_LENGTH(t) = sh->value; + /* Mark that symbol has a type, and say which one */ + sh->value = (long) t; } else { /* beginnning of (code) block. Value of symbol is the displacement from procedure start */ @@ -979,9 +1071,11 @@ data: /* Common code for symbols describing data */ pop_parse_stack(); /* restore previous lexical context */ break; - case stMember: /* member of struct/union/enum.. */ - f = new_field(top_stack->cur_type, sh->iss); + case stMember: /* member of struct or union */ + f = &TYPE_FIELDS(top_stack->cur_type)[top_stack->cur_field++]; + f->name = (char*)sh->iss; f->bitpos = sh->value; + f->bitsize = 0; f->type = parse_type(ax + sh->index, sh, &f->bitsize); break; @@ -1011,6 +1105,7 @@ data: /* Common code for symbols describing data */ error("Unknown symbol type %x.", sh->st); } sh->st = stParsed; + return count; } /* Parse the type information provided in the AX entries for @@ -1054,9 +1149,10 @@ static struct type *parse_type(ax, sh, bs) }; TIR *t; - struct type *tp = 0, *tp1; + struct type *tp = 0; char *fmt; int i; + int type_code; /* Procedures start off by one */ if (sh->st == stProc || sh->st == stStaticProc) @@ -1077,6 +1173,7 @@ static struct type *parse_type(ax, sh, bs) tp = *map_bt[t->bt]; fmt = "%s"; } else { + tp = NULL; /* Cannot use builtin types -- build our own */ switch (t->bt) { case btAdr: @@ -1084,25 +1181,26 @@ static struct type *parse_type(ax, sh, bs) fmt = "%s"; break; case btStruct: - tp = make_struct_type(TYPE_CODE_STRUCT, 0, 0, 0); + type_code = TYPE_CODE_STRUCT; fmt = "struct %s"; break; case btUnion: - tp = make_struct_type(TYPE_CODE_UNION, 0, 0, 0); + type_code = TYPE_CODE_UNION; fmt = "union %s"; break; case btEnum: - tp = make_type(TYPE_CODE_ENUM, 0, 0, 0); + type_code = TYPE_CODE_ENUM; fmt = "enum %s"; break; case btRange: - tp = make_type(TYPE_CODE_RANGE, 0, 0, 0); + type_code = TYPE_CODE_RANGE; fmt = "%s"; break; case btSet: - tp = make_type(TYPE_CODE_SET, 0, 0, 0); + type_code = TYPE_CODE_SET; fmt = "set %s"; break; + case btTypedef: default: complain (&basic_type_complaint, t->bt); return builtin_type_int; @@ -1118,15 +1216,14 @@ static struct type *parse_type(ax, sh, bs) ax++; } - /* For bitfields all we need is the width */ if (t->fBitfield) { *bs = ax->width; - return tp; + ax++; } /* All these types really point to some (common) MIPS type definition, and only the type-qualifiers fully identify - them. We`ll make the same effort at sharing */ + them. We'll make the same effort at sharing. */ if (t->bt == btIndirect || t->bt == btStruct || t->bt == btUnion || @@ -1137,54 +1234,32 @@ static struct type *parse_type(ax, sh, bs) char name[256], *pn; /* Try to cross reference this type */ - tp1 = tp; - ax += cross_ref(ax, &tp1, &pn); + ax += cross_ref(ax, &tp, type_code, &pn); + /* reading .o file ? */ + if (UNSAFE_DATA_ADDR(tp)) + tp = make_type(type_code, 0, 0, 0); /* SOMEONE OUGHT TO FIX DBXREAD TO DROP "STRUCT" */ sprintf(name, fmt, pn); - /* reading .o file ? */ - if (UNSAFE_DATA_ADDR(tp1)) - tp1 = tp; - if (TYPE_CODE(tp1) == TYPE_CODE_UNDEF) { - /* - * Type was incompletely defined, now we know. - */ - TYPE_CODE(tp1) = TYPE_CODE(tp); - TYPE_NAME(tp1) = obsavestring(name, strlen(name)); - TYPE_TYPE_SPECIFIC(tp1) = TYPE_TYPE_SPECIFIC(tp); - - /* Now do cleanup based on the final type. */ - switch (TYPE_CODE (tp1)) { - case TYPE_CODE_ENUM: - for (i = 0; i < TYPE_NFIELDS(tp1); i++) - make_enum_constant(&TYPE_FIELD(tp1,i), - tp1); - break; - } - } - if (tp1 != tp) { - /* found as cross ref, rid of our template */ - if ((TYPE_FLAGS(tp) & TYPE_FLAG_PERM) == 0) - free(tp); - tp = tp1; - /* stupid idea of prepending "struct" to type names */ - if (t->bt == btStruct && !index(TYPE_NAME(tp), ' ')) { - sprintf(name, fmt, TYPE_NAME(tp)); - TYPE_NAME(tp) = obsavestring(name, strlen(name)); - } - } else - TYPE_NAME(tp) = savestring(name, strlen(name)); + /* Usually, TYPE_CODE(tp) is already type_code. The main + exception is if we guessed wrong re struct/union/enum. */ + TYPE_CODE(tp) = type_code; + TYPE_NAME(tp) = obsavestring(pn, strlen(pn)); } /* Deal with range types */ if (t->bt == btRange) { struct field *f; - f = new_field(tp, "Low"); - f->bitpos = ax->dnLow; + TYPE_NFIELDS (tp) = 2; + TYPE_FIELDS (tp) = + (struct field *) obstack_alloc (symbol_obstack, + 2 * sizeof (struct field)); + TYPE_FIELD_NAME (tp, 0) = "Low"; + TYPE_FIELD_BITPOS (tp, 0) = ax->dnLow; ax++; - f = new_field(tp, "High"); - f->bitpos = ax->dnHigh; + TYPE_FIELD_NAME (tp, 1) = "High"; + TYPE_FIELD_BITPOS (tp, 1) = ax->dnHigh; ax++; } @@ -1255,8 +1330,21 @@ upgrade_type(tpp, tq, ax, sh) off++; } fh = get_rfd(cur_fd, rf); - f = new_field(t, (char *)0); - bzero(&ss, sizeof ss); + + /* Fields are kept in an array */ + /* FIXME - Memory leak! */ + if (TYPE_NFIELDS(t)) + TYPE_FIELDS(t) = (struct field*) + xrealloc(TYPE_FIELDS(t), + (TYPE_NFIELDS(t)+1) * sizeof(struct field)); + else + TYPE_FIELDS(t) = (struct field*) + xzalloc(sizeof(struct field)); + f = &(TYPE_FIELD(t,TYPE_NFIELDS(t))); + TYPE_NFIELDS(t)++; + memset(f, 0, sizeof(struct field)); + + memset(&ss, 0, sizeof ss); /* XXX */ f->type = parse_type(fh->iauxBase + id * sizeof(AUXU), &ss, &f->bitsize); @@ -1503,43 +1591,6 @@ parse_lines(fh, lt) } } - -/* Parse the symbols of the file described by FH, whose index is F_IDX. - BOUND is the highest core address of this file's procedures */ - -static -parse_one_file(fh, f_idx, bound) - FDR *fh; -{ - register int s_idx; - SYMR *sh; - PDR *pr; - - /* Parse local symbols first */ - - for (s_idx = 0; s_idx < fh->csym; s_idx++) { - sh = (SYMR *) (fh->isymBase) + s_idx; - cur_sdx = s_idx; - parse_symbol(sh, fh->iauxBase); - } - - /* Procedures next, note we need to look-ahead to - find out where the procedure's code ends */ - - for (s_idx = 0; s_idx < fh->cpd-1; s_idx++) { - pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + s_idx; - parse_procedure(pr, pr[1].adr); /* next proc up */ - } - if (fh->cpd) { - pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + s_idx; - parse_procedure(pr, bound); /* next file up */ - } - - /* Linenumbers. At the end, check if we can save memory */ - parse_lines(fh, LINETABLE(cur_stab)); - if (LINETABLE(cur_stab)->nitems < fh->cline) - shrink_linetable(cur_stab); -} /* Master parsing procedure for first-pass reading of file symbols into a partial_symtab. @@ -1553,7 +1604,8 @@ parse_partial_symbols(end_of_text_seg, objfile) int end_of_text_seg; struct objfile *objfile; { - int f_idx, s_idx, h_max, stat_idx; + int f_idx, s_idx; +/* int stat_idx, h_max;*/ HDRR *hdr; /* Running pointers */ FDR *fh; @@ -1562,6 +1614,30 @@ parse_partial_symbols(end_of_text_seg, objfile) register SYMR *sh; struct partial_symtab *pst; + int past_first_source_file = 0; + + /* List of current psymtab's include files */ + char **psymtab_include_list; + int includes_allocated; + int includes_used; + + /* Index within current psymtab dependency list */ + struct partial_symtab **dependency_list; + int dependencies_used, dependencies_allocated; + + includes_allocated = 30; + includes_used = 0; + psymtab_include_list = (char **) alloca (includes_allocated * + sizeof (char *)); + + dependencies_allocated = 30; + dependencies_used = 0; + dependency_list = + (struct partial_symtab **) alloca (dependencies_allocated * + sizeof (struct partial_symtab *)); + + last_source_file = 0; + /* * Big plan: * @@ -1586,70 +1662,6 @@ parse_partial_symbols(end_of_text_seg, objfile) FDR_IDX(pst) = -1; } - /* Now scan the FDRs, mostly for dependencies */ - for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) - (void) parse_fdr(f_idx, 1, objfile); - - /* Take a good guess at how many symbols we might ever need */ - h_max = hdr->iextMax; - - /* Parse externals: two passes because they can be ordered - in any way, but gdb likes to have them segregated by their - source file. */ - - /* Pass 1 over external syms: Presize and partition the list */ - for (s_idx = 0; s_idx < hdr->iextMax; s_idx++) { - esh = (EXTR *) (hdr->cbExtOffset) + s_idx; - fdr_to_pst[esh->ifd].n_globals++; - } - - if (global_psymbols.list) { - int origsize = global_psymbols.next - global_psymbols.list; - - global_psymbols.list = (struct partial_symbol *) - xrealloc (global_psymbols.list, - (h_max + origsize) * sizeof(struct partial_symbol)); - global_psymbols.next = global_psymbols.list + origsize; - global_psymbols.size = h_max + origsize; - } else { - global_psymbols.list = (struct partial_symbol *) - xmalloc (h_max * sizeof(struct partial_symbol)); - global_psymbols.next = global_psymbols.list; - global_psymbols.size = h_max; - } - - /* Pass 1.5 over files: partition out global symbol space */ - s_idx = global_psymbols.next - global_psymbols.list; - for (f_idx = -1; f_idx < hdr->ifdMax; f_idx++) { - fdr_to_pst[f_idx].pst->globals_offset = s_idx; - s_idx += fdr_to_pst[f_idx].n_globals; - } - - /* Pass 1.6 over files: partition out static symbol space. - Note that this loop starts at 0, not at -1. */ - stat_idx = static_psymbols.next - static_psymbols.list; - for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) { - fdr_to_pst[f_idx].pst->statics_offset = stat_idx; - fh = f_idx + (FDR *)(hdr->cbFdOffset); - stat_idx += fh->csym; - } - - /* Now that we know its max size, allocate static symbol list */ - if (static_psymbols.list) { - int origsize = static_psymbols.next - static_psymbols.list; - - static_psymbols.list = (struct partial_symbol *) - xrealloc (static_psymbols.list, - stat_idx * sizeof(struct partial_symbol)); - static_psymbols.next = static_psymbols.list + origsize; - static_psymbols.size = stat_idx; - } else { - static_psymbols.list = (struct partial_symbol *) - xmalloc (stat_idx * sizeof(struct partial_symbol)); - static_psymbols.next = static_psymbols.list; - static_psymbols.size = stat_idx; - } - /* Pass 2 over external syms: fill in external symbols */ for (s_idx = 0; s_idx < hdr->iextMax; s_idx++) { register struct partial_symbol *p; @@ -1659,132 +1671,185 @@ parse_partial_symbols(end_of_text_seg, objfile) if (esh->asym.sc == scUndefined || esh->asym.sc == scNil) continue; - /* Locate the psymtab and the preallocated psymbol. */ - pst = fdr_to_pst[esh->ifd].pst; - p = global_psymbols.list + pst->globals_offset + - pst->n_global_syms++; - SYMBOL_NAME(p) = (char *)(esh->asym.iss); - SYMBOL_NAMESPACE(p) = VAR_NAMESPACE; - switch (esh->asym.st) { case stProc: - SYMBOL_CLASS(p) = LOC_BLOCK; - SYMBOL_VALUE(p) = esh->asym.value; break; case stGlobal: - SYMBOL_CLASS(p) = LOC_STATIC; - SYMBOL_VALUE_ADDRESS(p) = (CORE_ADDR)esh->asym.value; misc_type = mf_data; break; case stLabel: - SYMBOL_CLASS(p) = LOC_LABEL; - SYMBOL_VALUE_ADDRESS(p) = (CORE_ADDR)esh->asym.value; break; default: misc_type = mf_unknown; complain (&unknown_ext_complaint, SYMBOL_NAME(p)); } - prim_record_misc_function (SYMBOL_NAME(p), - SYMBOL_VALUE(p), + prim_record_misc_function ((char *)(esh->asym.iss), + esh->asym.value, misc_type); } /* Pass 3 over files, over local syms: fill in static symbols */ for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) { - fh = f_idx + (FDR *)(cur_hdr->cbFdOffset); - pst = fdr_to_pst[f_idx].pst; - pst->texthigh = pst->textlow; - - for (s_idx = 0; s_idx < fh->csym; ) { - register struct partial_symbol *p; - - sh = s_idx + (SYMR *) fh->isymBase; - - if (sh->sc == scUndefined || sh->sc == scNil || - sh->index == 0xfffff) { - /* FIXME, premature? */ - s_idx++; - continue; + struct partial_symtab *save_pst; + + fh = f_idx + (FDR *)(cur_hdr->cbFdOffset); + if (fh->csym == 0) { + fdr_to_pst[f_idx].pst = NULL; + continue; + } + pst = start_psymtab (objfile, 0, (char*)fh->rss, + fh->cpd ? fh->adr : 0, + -1, + global_psymbols.next, + static_psymbols.next); + save_pst = pst; + /* Make everything point to everything. */ + FDR_IDX(pst) = f_idx; + fdr_to_pst[f_idx].pst = pst; + fh->ioptBase = (int)pst; + + CUR_HDR(pst) = cur_hdr; + + /* The way to turn this into a symtab is to call... */ + pst->read_symtab = mipscoff_psymtab_to_symtab; + + pst->texthigh = pst->textlow; + + pst->globals_offset = global_psymbols.next - global_psymbols.list; + pst->statics_offset = static_psymbols.next - static_psymbols.list; + + pst->n_global_syms = 0; + pst->n_static_syms = 0; + + + /* The second symbol must be @stab. */ + if (fh->csym >= 2 + && strcmp(((SYMR *)fh->isymBase)[1].iss, stabs_symbol) == 0) { + for (s_idx = 2; s_idx < fh->csym; s_idx++) { + int type_code; + char *namestring; + sh = s_idx + (SYMR *) fh->isymBase; + type_code = MIPS_UNMARK_STAB(sh->index); + /* TEMPORARY: */ + if (type_code == 0x84 && s_idx == 2) continue; + if (!MIPS_IS_STAB(sh)) { + if (sh->st == stProc || sh->st == stStaticProc) { + long procaddr = sh->value; + sh = (sh->index + (AUXU *)fh->iauxBase)->isym + + (SYMR *) fh->isymBase - 1; + if (sh->st == stEnd) { + long high = procaddr + sh->value; + if (high > pst->texthigh) + pst->texthigh = high; + } } + continue; + } +#define SET_NAMESTRING() namestring = (char*)sh->iss +#define CUR_SYMBOL_TYPE type_code +#define CUR_SYMBOL_VALUE sh->value +#define CHECK_SECOND_N_SO() \ + if (s_idx < fh->csym \ + && MIPS_UNMARK_STAB(((SYMR *)fh->isymBase)[s_idx+1].index) == (unsigned char)N_SO)\ + {\ + s_idx++;\ + sh = s_idx + (SYMR *) fh->isymBase;\ + SET_NAMESTRING ();\ + valu = CUR_SYMBOL_VALUE;\ + s_idx++;\ + } +#define START_PSYMTAB(ofile,addr,fname,low,symoff,global_syms,static_syms)\ + pst = save_pst +#define END_PSYMTAB(pst,ilist,ninc,c_off,c_text,dep_list,n_deps) (void)0 +#define addr 0 +#define HANDLE_RBRAC(val) \ + if ((val) > save_pst->texthigh) save_pst->texthigh = (val); +/* FIXME: Handle start_file_start and _end */ +/* FIXME: Handle enums - but must deal with next_symbol_text. */ +#include "partial-stab.h" +#undef addr + } + } + else { + for (s_idx = 0; s_idx < fh->csym; ) { + register struct partial_symbol *p; + char *name; + int class; + sh = s_idx + (SYMR *) fh->isymBase; + + if (MIPS_IS_STAB(sh)) { + s_idx++; + continue; + } - /* Locate the preallocated psymbol. */ - p = static_psymbols.list + pst->statics_offset + - pst->n_static_syms; - SYMBOL_NAME(p) = (char *)(sh->iss); - SYMBOL_VALUE(p) = sh->value; - SYMBOL_NAMESPACE(p) = VAR_NAMESPACE; - - switch (sh->st) { - case stProc: /* Asm labels apparently */ - case stStaticProc: /* Function */ - SYMBOL_CLASS(p) = LOC_BLOCK; - pst->n_static_syms++; /* Use gdb symbol */ - /* Skip over procedure to next one. */ - s_idx = (sh->index + (AUXU *)fh->iauxBase) - ->isym; - { - long high; - long procaddr = sh->value; - - sh = s_idx + (SYMR *) fh->isymBase - 1; - if (sh->st != stEnd) - continue; - high = procaddr + sh->value; - if (high > pst->texthigh) - pst->texthigh = high; - } - continue; - case stStatic: /* Variable */ - SYMBOL_CLASS(p) = LOC_STATIC; - SYMBOL_VALUE_ADDRESS(p) = (CORE_ADDR)sh->value; - break; - case stTypedef: /* Typedef */ - SYMBOL_CLASS(p) = LOC_TYPEDEF; - break; - case stConstant: /* Constant decl */ - SYMBOL_CLASS(p) = LOC_CONST; - break; - case stBlock: /* { }, str, un, enum*/ - if (sh->sc == scInfo) { - SYMBOL_NAMESPACE(p) = STRUCT_NAMESPACE; - SYMBOL_CLASS(p) = LOC_TYPEDEF; - pst->n_static_syms++; - } - /* Skip over the block */ - s_idx = sh->index; - continue; - case stFile: /* File headers */ - case stLabel: /* Labels */ - case stEnd: /* Ends of files */ - goto skip; - default: - complain (&unknown_sym_complaint, SYMBOL_NAME(p)); - complain (&unknown_st_complaint, sh->st); - s_idx++; - continue; + if (sh->sc == scUndefined || sh->sc == scNil || + sh->index == 0xfffff) { + /* FIXME, premature? */ + s_idx++; + continue; + } + + name = (char *)(sh->iss); + + switch (sh->st) { + long high; + long procaddr; + case stProc: /* Asm labels apparently */ + case stStaticProc: /* Function */ + ADD_PSYMBOL_TO_LIST(name, strlen(name), + VAR_NAMESPACE, LOC_BLOCK, + static_psymbols, sh->value); + /* Skip over procedure to next one. */ + s_idx = (sh->index + (AUXU *)fh->iauxBase)->isym; + procaddr = sh->value; + + sh = s_idx + (SYMR *) fh->isymBase - 1; + if (sh->st != stEnd) + continue; + high = procaddr + sh->value; + if (high > pst->texthigh) + pst->texthigh = high; + continue; + case stStatic: /* Variable */ + class = LOC_STATIC; + break; + case stTypedef: /* Typedef */ + class = LOC_TYPEDEF; + break; + case stConstant: /* Constant decl */ + class = LOC_CONST; + break; + case stBlock: /* { }, str, un, enum*/ + if (sh->sc == scInfo) { + ADD_PSYMBOL_TO_LIST(name, strlen(name), + STRUCT_NAMESPACE, LOC_TYPEDEF, + static_psymbols, sh->value); } - pst->n_static_syms++; /* Use this gdb symbol */ - skip: - s_idx++; /* Go to next file symbol */ -#if 0 -/* We don't usually record static syms, but some we seem to. chk dbxread. */ -/*FIXME*/ prim_record_misc_function (SYMBOL_NAME(p), - SYMBOL_VALUE(p), - misc_type); -#endif + /* Skip over the block */ + s_idx = sh->index; + continue; + case stFile: /* File headers */ + case stLabel: /* Labels */ + case stEnd: /* Ends of files */ + goto skip; + default: + complain (&unknown_sym_complaint, SYMBOL_NAME(p)); + complain (&unknown_st_complaint, sh->st); + s_idx++; + continue; + } + /* Use this gdb symbol */ + ADD_PSYMBOL_TO_LIST(name, strlen(name), + VAR_NAMESPACE, class, + static_psymbols, sh->value); + skip: + s_idx++; /* Go to next file symbol */ } - } - - /* The array (of lists) of globals must be sorted. */ - reorder_psymtabs(); - - /* Now sort the global psymbols. */ - for (f_idx = 0; f_idx < hdr->ifdMax; f_idx++) { - struct partial_symtab *pst = fdr_to_pst[f_idx].pst; - if (pst->n_global_syms > 1) - qsort (global_psymbols.list + pst->globals_offset, - pst->n_global_syms, sizeof (struct partial_symbol), - compare_psymbols); + } + end_psymtab (save_pst, psymtab_include_list, includes_used, + -1, save_pst->texthigh, + dependency_list, dependencies_used, + global_psymbols.next, static_psymbols.next); } /* Mark the last code address, and remember it for later */ @@ -1864,6 +1929,16 @@ parse_fdr(f_idx, lev, objfile) return pst; } +#ifdef READ_MIPS_FORMAT +static int s_idx; + +char* +next_symbol_text () +{ + s_idx++; + return (char*)((SYMR *)cur_fdr->isymBase)[s_idx].iss; +} +#endif /* Ancillary function to psymtab_to_symtab(). Does all the work for turning the partial symtab PST into a symtab, recurring @@ -1873,68 +1948,83 @@ parse_fdr(f_idx, lev, objfile) static void psymtab_to_symtab_1(pst, filename) - struct partial_symtab *pst; - char *filename; + struct partial_symtab *pst; + char *filename; { - int i, f_max; - struct symtab *st; - FDR *fh; - - if (pst->readin) - return; - pst->readin = 1; - - pending_list = (struct pending **) cur_hdr->cbOptOffset; + int have_stabs; + int i, f_max; + struct symtab *st; + FDR *fh; + int maxlines; + struct linetable *lines; + + if (pst->readin) + return; + pst->readin = 1; + + /* How many symbols will we need */ + /* FIXME, this does not count enum values. */ + f_max = pst->n_global_syms + pst->n_static_syms; + if (FDR_IDX(pst) == -1) { + fh = 0; + maxlines = 0; + } else { + fh = (FDR *) (cur_hdr->cbFdOffset) + FDR_IDX(pst); + f_max += fh->csym + fh->cpd; + maxlines = 2 * fh->cline; + } + + have_stabs = + fh && fh->csym >= 2 + && strcmp(((SYMR *)fh->isymBase)[1].iss, stabs_symbol) == 0; + + if (!have_stabs) { + if (fh) + st = new_symtab (pst->filename, 2 * f_max, maxlines, + pst->objfile); + else + st = new_symtab ("unknown", f_max, 0, pst->objfile); + lines = LINETABLE(st); + pending_list = (struct mips_pending **) cur_hdr->cbOptOffset; if (pending_list == 0) { - pending_list = (struct pending **) - xzalloc(cur_hdr->ifdMax * sizeof(struct pending *)); - cur_hdr->cbOptOffset = (int)pending_list; - } - - /* How many symbols will we need */ - /* FIXME, this does not count enum values. */ - f_max = pst->n_global_syms + pst->n_static_syms; - if (FDR_IDX(pst) == -1) { - fh = 0; - st = new_symtab ("unknown", f_max, 0, pst->objfile); - } else { - fh = (FDR *) (cur_hdr->cbFdOffset) + FDR_IDX(pst); - f_max += fh->csym + fh->cpd; - st = new_symtab (pst->filename, 2 * f_max, 2 * fh->cline, - pst->objfile); + pending_list = (struct mips_pending **) + xzalloc(cur_hdr->ifdMax * sizeof(struct mips_pending *)); + cur_hdr->cbOptOffset = (int)pending_list; } - - /* Read in all partial symbtabs on which this one is dependent. - NOTE that we do have circular dependencies, sigh. We solved - that by setting pst->readin before this point. */ - - for (i = 0; i < pst->number_of_dependencies; i++) - if (!pst->dependencies[i]->readin) { - /* Inform about additional files to be read in. */ - if (info_verbose) - { - fputs_filtered (" ", stdout); - wrap_here (""); - fputs_filtered ("and ", stdout); - wrap_here (""); - printf_filtered ("%s...", - pst->dependencies[i]->filename); - wrap_here (""); /* Flush output */ - fflush (stdout); - } - /* We only pass the filename for debug purposes */ - psymtab_to_symtab_1(pst->dependencies[i], - pst->dependencies[i]->filename); + } + + /* Read in all partial symbtabs on which this one is dependent. + NOTE that we do have circular dependencies, sigh. We solved + that by setting pst->readin before this point. */ + + for (i = 0; i < pst->number_of_dependencies; i++) + if (!pst->dependencies[i]->readin) { + /* Inform about additional files to be read in. */ + if (info_verbose) + { + fputs_filtered (" ", stdout); + wrap_here (""); + fputs_filtered ("and ", stdout); + wrap_here (""); + printf_filtered ("%s...", + pst->dependencies[i]->filename); + wrap_here (""); /* Flush output */ + fflush (stdout); } - - /* Now read the symbols for this symtab */ - + /* We only pass the filename for debug purposes */ + psymtab_to_symtab_1(pst->dependencies[i], + pst->dependencies[i]->filename); + } + + cur_fdr = fh; + /* Now read the symbols for this symtab */ + + if (!have_stabs) { cur_fd = FDR_IDX(pst); - cur_fdr = fh; cur_stab = st; - + /* Get a new lexical context */ - + push_parse_stack(); top_stack->cur_st = cur_stab; top_stack->cur_block = BLOCKVECTOR_BLOCK(BLOCKVECTOR(cur_stab), @@ -1946,42 +2036,102 @@ psymtab_to_symtab_1(pst, filename) top_stack->cur_type = 0; top_stack->procadr = 0; top_stack->numargs = 0; + } + + /* Parse locals and procedures */ + if (fh) { + SYMR *sh; + PDR *pr; + int f_idx = cur_fd; + char *fh_name = (char*)fh->rss; + + /* Parse local symbols first */ + + + if (have_stabs) { + if (fh->csym <= 2) + return; + for (s_idx = 2; s_idx < fh->csym; s_idx++) { + register SYMR *sh = s_idx + (SYMR *) fh->isymBase; + char *name = (char*)sh->iss; + CORE_ADDR valu = sh->value; + if (MIPS_IS_STAB(sh)) { + int type_code = MIPS_UNMARK_STAB(sh->index); + /* TEMPORARY: */ + if (type_code == 0x84 && s_idx == 2) continue; + process_one_symbol (type_code, 0, valu, name); + } + else if (sh->st == stLabel && sh->index != indexNil) { + /* Handle encoded stab line number. */ + record_line (current_subfile, sh->index, valu); + } + } + st = end_symtab (pst->texthigh, 0, 0, pst->objfile); + } + else { + /* BOUND is the highest core address of this file's procedures */ + int bound = cur_fd == cur_hdr->ifdMax - 1 ? cur_hdr->cbDnOffset + : fh[1].adr; + for (s_idx = 0; s_idx < fh->csym; ) { + sh = (SYMR *) (fh->isymBase) + s_idx; + cur_sdx = s_idx; + s_idx += parse_symbol(sh, fh->iauxBase); + } - /* Parse locals and procedures */ - if (fh) - parse_one_file(fh, cur_fd, (cur_fd == (cur_hdr->ifdMax - 1)) ? - cur_hdr->cbDnOffset : fh[1].adr); + /* Procedures next, note we need to look-ahead to + find out where the procedure's code ends */ + + for (s_idx = 0; s_idx < fh->cpd-1; s_idx++) { + pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + s_idx; + parse_procedure(pr, pr[1].adr); /* next proc up */ + } + if (fh->cpd) { + pr = (PDR *) (IPDFIRST(cur_hdr, fh)) + s_idx; + parse_procedure(pr, bound); /* next file up */ + } + /* Linenumbers. At the end, check if we can save memory */ + parse_lines(fh, lines); + if (lines->nitems < fh->cline) + lines = shrink_linetable(lines); + } + } + if (!have_stabs) { + LINETABLE(st) = lines; + /* .. and our share of externals. XXX use the global list to speed up things here. how ? FIXME, Maybe quit once we have found the right number of ext's? */ /* parse_external clobbers top_stack->cur_block and ->cur_st here. */ top_stack->blocktype = stFile; - top_stack->maxsyms = cur_hdr->isymMax + cur_hdr->ipdMax + cur_hdr->iextMax; + top_stack->maxsyms = + cur_hdr->isymMax + cur_hdr->ipdMax + cur_hdr->iextMax; + for (i = 0; i < cur_hdr->iextMax; i++) { - register EXTR *esh = (EXTR *) (cur_hdr->cbExtOffset) + i; - if (esh->ifd == cur_fd) - parse_external(esh, 1); + register EXTR *esh = (EXTR *) (cur_hdr->cbExtOffset) + i; + if (esh->ifd == cur_fd) + parse_external(esh, 1); } - + /* If there are undefined, tell the user */ if (n_undef_symbols) { - printf_filtered("File %s contains %d unresolved references:", - st->filename, n_undef_symbols); - printf_filtered("\n\t%4d variables\n\t%4d procedures\n\t%4d labels\n", - n_undef_vars, n_undef_procs, n_undef_labels); - n_undef_symbols = n_undef_labels = n_undef_vars = n_undef_procs = 0; - } + printf_filtered("File %s contains %d unresolved references:", + st->filename, n_undef_symbols); + printf_filtered("\n\t%4d variables\n\t%4d procedures\n\t%4d labels\n", + n_undef_vars, n_undef_procs, n_undef_labels); + n_undef_symbols = n_undef_labels = n_undef_vars = n_undef_procs = 0; + } pop_parse_stack(); - - /* - * Sort the symbol table now, we are done adding symbols to it. - */ - sort_symtab_syms(st); - - /* Now link the psymtab and the symtab. */ - pst->symtab = st; + } + + /* Sort the symbol table now, we are done adding symbols to it.*/ + sort_symtab_syms(st); + + sort_blocks (st); + + /* Now link the psymtab and the symtab. */ + pst->symtab = st; } /* Ancillary parsing procedures. */ @@ -1991,10 +2141,11 @@ psymtab_to_symtab_1(pst, filename) Return value says how many aux symbols we ate */ static -cross_ref(rn, tpp, pname) - RNDXR *rn; - struct type **tpp; - char **pname; +cross_ref(rn, tpp, type_code, pname) + RNDXR *rn; + struct type **tpp; + int type_code; /* Use to alloc new type if none is found. */ + char **pname; { unsigned rf; @@ -2034,15 +2185,14 @@ cross_ref(rn, tpp, pname) t = (struct type *) sh->value; *tpp = t; } else { - struct pending *p; - - /* Avoid duplicates */ - p = is_pending_symbol(fh, sh); - - if (p) - *tpp = p->t; - else - add_pending(fh, sh, *tpp); + /* Avoid duplicates */ + struct mips_pending *p = is_pending_symbol(fh, sh); + if (p) + *tpp = p->t; + else { + *tpp = make_type(type_code, 0, 0, 0); + add_pending(fh, sh, *tpp); + } } } @@ -2195,20 +2345,6 @@ compare_psymtabs( s1, s2) } -/* Partial symbols are compared lexicog by their print names */ - -static int -compare_psymbols (s1, s2) - register struct partial_symbol *s1, *s2; -{ - register char - *st1 = SYMBOL_NAME(s1), - *st2 = SYMBOL_NAME(s2); - - return (st1[0] - st2[0] ? st1[0] - st2[0] : - strcmp(st1 + 1, st2 + 1)); -} - /* Blocks with a smaller low bound should come first */ static int compare_blocks(b1,b2) @@ -2274,80 +2410,6 @@ sort_blocks(s) BLOCK_END (BLOCKVECTOR_BLOCK(bv,GLOBAL_BLOCK)); } -/* Sort the symtab list, as required by some search procedures. - We want files ordered to make them look right to users, and for - searching (see block_for_pc). */ - -static void -reorder_symtabs() -{ - register int i; - struct symtab *stab; - register struct symtab **all_symtabs; - register int symtab_count; - - if (!symtab_list) - return; - - /* Create an array of pointers to all the symtabs. */ - for (symtab_count = 0, stab = symtab_list; - stab; - symtab_count++, stab = stab->next) { - obstack_grow (psymbol_obstack, &stab, sizeof (stab)); - /* FIXME: Only sort blocks for new symtabs ??? */ - sort_blocks(stab); - } - - all_symtabs = (struct symtab **) - obstack_base (psymbol_obstack); - qsort((char *)all_symtabs, symtab_count, - sizeof(struct symtab *), compare_symtabs); - - /* Re-construct the symtab list, but now it is sorted. */ - for (i = 0; i < symtab_count-1; i++) - all_symtabs[i]->next = all_symtabs[i+1]; - all_symtabs[i]->next = 0; - symtab_list = all_symtabs[0]; - - obstack_free (psymbol_obstack, all_symtabs); -} - -/* Sort the partial symtab list, as required by some search procedures. - PC lookups stop at the first psymtab such that textlow <= PC < texthigh */ - -static void -reorder_psymtabs() -{ - register int i; - register int all_psymtabs_count; - struct partial_symtab *pstab; - struct partial_symtab **all_psymtabs; - - if (!partial_symtab_list) - return; - - /* Create an array of pointers to all the partial_symtabs. */ - - for (all_psymtabs_count = 0, pstab = partial_symtab_list; - pstab; - all_psymtabs_count++, pstab = pstab->next) - obstack_grow (psymbol_obstack, &pstab, sizeof (pstab)); - - all_psymtabs = (struct partial_symtab **) - obstack_base (psymbol_obstack); - - qsort((char *)all_psymtabs, all_psymtabs_count, - sizeof(struct partial_symtab *), compare_psymtabs); - - /* Re-construct the partial_symtab_list, but now it is sorted. */ - - for (i = 0; i < all_psymtabs_count-1; i++) - all_psymtabs[i]->next = all_psymtabs[i+1]; - all_psymtabs[i]->next = 0; - partial_symtab_list = all_psymtabs[0]; - - obstack_free (psymbol_obstack, all_psymtabs); -} /* Constructor/restructor/destructor procedures */ @@ -2390,7 +2452,7 @@ new_psymtab(name, objfile) pst = (struct partial_symtab *) obstack_alloc (psymbol_obstack, sizeof (*pst)); - bzero (pst, sizeof (*pst)); + memset (pst, 0, sizeof (*pst)); if (name == (char*)-1) /* FIXME -- why not null here? */ pst->filename = "<no name>"; @@ -2419,8 +2481,8 @@ new_psymtab(name, objfile) /* Allocate a linetable array of the given SIZE */ -static -struct linetable *new_linetable(size) +static struct linetable * +new_linetable(size) { struct linetable *l; @@ -2433,16 +2495,15 @@ struct linetable *new_linetable(size) /* Oops, too big. Shrink it. This was important with the 2.4 linetables, I am not so sure about the 3.4 ones */ -static void -shrink_linetable(s) - struct symtab *s; +static struct linetable * +shrink_linetable(lt) + struct linetable * lt; { - struct linetable *l = new_linetable(LINETABLE(s)->nitems); + struct linetable *l = new_linetable(lt->nitems); - bcopy(LINETABLE(s), l, - LINETABLE(s)->nitems * sizeof(l->item) + sizeof(struct linetable)); - free (LINETABLE(s)); - LINETABLE(s) = l; + memcpy(l, lt, lt->nitems * sizeof(l->item) + sizeof(struct linetable)); + free (lt); + return l; } /* Allocate and zero a new blockvector of NBLOCKS blocks. */ @@ -2513,7 +2574,7 @@ new_symbol(name) struct symbol *s = (struct symbol *) obstack_alloc (symbol_obstack, sizeof (struct symbol)); - bzero (s, sizeof (*s)); + memset (s, 0, sizeof (*s)); SYMBOL_NAME(s) = name; return s; } @@ -2528,9 +2589,10 @@ new_type(name) struct type *t = (struct type *) obstack_alloc (symbol_obstack, sizeof (struct type)); - bzero (t, sizeof (*t)); + memset (t, 0, sizeof (*t)); TYPE_VPTR_FIELDNO (t) = -1; TYPE_NAME(t) = name; + TYPE_CPLUS_SPECIFIC(t) = &cplus_struct_default; return t; } @@ -2545,167 +2607,26 @@ make_type(code, length, uns, name) int length, uns; char *name; { - register struct type *type; - - /* FIXME, I don't think this ever gets freed. */ - type = (struct type *) xzalloc(sizeof(struct type)); - TYPE_CODE(type) = code; - TYPE_LENGTH(type) = length; - TYPE_FLAGS(type) = uns ? TYPE_FLAG_UNSIGNED : 0; - TYPE_NAME(type) = name; - TYPE_VPTR_FIELDNO (type) = -1; - - return type; -} - -/* Create and initialize a new struct or union type, a la make_type. */ - -static -struct type * -make_struct_type(code, length, uns, name) - enum type_code code; - int length, uns; - char *name; -{ - register struct type *type; - - type = make_type (code, length, uns, name); - - /* FIXME, I don't think this ever gets freed. */ - TYPE_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *) - xzalloc (sizeof (struct cplus_struct_type)); - return type; + register struct type *type; + + /* FIXME, I don't think this ever gets freed. */ + type = (struct type *) xzalloc(sizeof(struct type)); + TYPE_CODE(type) = code; + TYPE_LENGTH(type) = length; + TYPE_FLAGS(type) = uns ? TYPE_FLAG_UNSIGNED : 0; + TYPE_NAME(type) = name; + TYPE_VPTR_FIELDNO (type) = -1; + + if (code != TYPE_CODE_METHOD && code != TYPE_CODE_FUNC) + TYPE_CPLUS_SPECIFIC(type) = &cplus_struct_default; + return type; } - -/* Allocate a new field named NAME to the type TYPE */ - -static -struct field * -new_field(type,name) - struct type *type; - char *name; -{ - struct field *f; - - /* Fields are kept in an array */ - if (TYPE_NFIELDS(type)) - TYPE_FIELDS(type) = (struct field*)xrealloc(TYPE_FIELDS(type), - (TYPE_NFIELDS(type)+1) * sizeof(struct field)); - else - TYPE_FIELDS(type) = (struct field*)xzalloc(sizeof(struct field)); - f = &(TYPE_FIELD(type,TYPE_NFIELDS(type))); - TYPE_NFIELDS(type)++; - bzero(f, sizeof(struct field)); - f->name = name; /* Whether or not NAME is zero, this works. */ - return f; -} - -/* Make an enum constant for a member F of an enumerated type T */ - -static -make_enum_constant(f,t) - struct field *f; - struct type *t; -{ - struct symbol *s; - /* - * This is awful, but that`s the way it is supposed to be - * (BTW, no need to free the real 'type', it's a builtin) - */ - f->type = (struct type *) f->bitpos; - - s = new_symbol(f->name); - SYMBOL_NAMESPACE(s) = VAR_NAMESPACE; - SYMBOL_CLASS(s) = LOC_CONST; - SYMBOL_TYPE(s) = t; - SYMBOL_VALUE(s) = f->bitpos; - add_symbol(s, top_stack->cur_block); -} - - /* Things used for calling functions in the inferior. These functions are exported to our companion - mips-dep.c file and are here because they play + mips-tdep.c file and are here because they play with the symbol-table explicitly. */ -#if 0 -/* Need to make a new symbol on the fly for the dummy - frame we put on the stack. Which goes in the.. */ - -static struct symtab *dummy_symtab; - -/* Make up a dummy symbol for the code we put at END_PC, - of size SIZE, invoking a function with NARGS arguments - and using a frame of FRAMESIZE bytes */ - -mips_create_dummy_symbol(end_pc, size, nargs, framesize) -{ - struct block *bl; - struct symbol *g; - struct mips_extra_func_info *gdbinfo; - - /* Allocate symtab if not done already */ - if (dummy_symtab == 0) - dummy_symtab = new_symtab(".dummy_symtab.", 100, 0); - - /* Make a new block. Only needs one symbol */ - bl = new_block(1); - BLOCK_START(bl) = end_pc - size; - BLOCK_END(bl) = end_pc; - - BLOCK_SUPERBLOCK(bl) = - BLOCKVECTOR_BLOCK(BLOCKVECTOR(dummy_symtab),GLOBAL_BLOCK); - add_block(bl, dummy_symtab); - sort_blocks(dummy_symtab); - - BLOCK_FUNCTION(bl) = new_symbol("??"); - SYMBOL_BLOCK_VALUE(BLOCK_FUNCTION(bl)) = bl; - g = new_symbol(".gdbinfo."); - BLOCK_SYM(bl,BLOCK_NSYMS(bl)++) = g; - - SYMBOL_NAMESPACE(g) = LABEL_NAMESPACE; - SYMBOL_CLASS(g) = LOC_CONST; - SYMBOL_TYPE(g) = builtin_type_void; - gdbinfo = (struct mips_extra_func_info *) - xzalloc(sizeof(struct mips_extra_func_info)); - - SYMBOL_VALUE(g) = (long) gdbinfo; - - gdbinfo->numargs = nargs; - gdbinfo->framesize = framesize; - gdbinfo->framereg = 29; - gdbinfo->pcreg = 31; - gdbinfo->regmask = -2; - gdbinfo->regoffset = -4; - gdbinfo->fregmask = 0; /* XXX */ - gdbinfo->fregoffset = 0; /* XXX */ -} - -/* We just returned from the dummy code at END_PC, drop its symbol */ - -mips_destroy_dummy_symbol(end_pc) -{ - struct block *bl; - struct blockvector *bv = BLOCKVECTOR(dummy_symtab); - int i; - - bl = block_for_pc(end_pc); - free(BLOCK_FUNCTION(bl)); - free(SYMBOL_VALUE(BLOCK_SYM(bl,0))); - free(BLOCK_SYM(bl,0)); - - for (i = FIRST_LOCAL_BLOCK; i < BLOCKVECTOR_NBLOCKS(bv); i++) - if (BLOCKVECTOR_BLOCK(bv,i) == bl) - break; - for (; i < BLOCKVECTOR_NBLOCKS(bv) - 1; i++) - BLOCKVECTOR_BLOCK(bv,i) = BLOCKVECTOR_BLOCK(bv,i+1); - BLOCKVECTOR_NBLOCKS(bv)--; - sort_blocks(dummy_symtab); - free(bl); -} -#endif - /* Sigtramp: make sure we have all the necessary information about the signal trampoline code. Since the official code from MIPS does not do so, we make up that information ourselves. diff --git a/gdb/partial-stab.h b/gdb/partial-stab.h new file mode 100644 index 0000000..d901795 --- /dev/null +++ b/gdb/partial-stab.h @@ -0,0 +1,576 @@ +/* Shared code to pre-read a stab (dbx-style), when building a psymtab. + Copyright (C) 1986-1991 Free Software Foundation, Inc. + +This file is part of GDB. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* The following need to be defined: + SET_NAMESTRING() --Set namestring to name of symbol. + CUR_SYMBOL_TYPE --Type code of current symbol. + CUR_SYMBOL_VALUE --Value field of current symbol. May be adjusted here. + */ + +#ifdef DEBUG +/* Since one arg is a struct, we have to pass in a ptr and deref it (sigh) */ +#define ADD_PSYMBOL_TO_LIST(NAME, NAMELENGTH, NAMESPACE, CLASS, LIST, VALUE) \ + add_psymbol_to_plist(NAME, NAMELENGTH, NAMESPACE, CLASS, &LIST, VALUE) +#define ADD_PSYMBOL_ADDR_TO_LIST(NAME, NAMELENGTH, NAMESPACE, CLASS, LIST, VALUE) \ + add_psymbol_to_plist(NAME, NAMELENGTH, NAMESPACE, CLASS, &LIST, VALUE) +#else +/* Add a symbol with an integer value to a psymtab. */ +#define ADD_PSYMBOL_TO_LIST(NAME, NAMELENGTH, NAMESPACE, CLASS, LIST, VALUE) \ + ADD_PSYMBOL_VT_TO_LIST(NAME, NAMELENGTH, NAMESPACE, CLASS, LIST, VALUE, SYMBOL_VALUE) + +/* Add a symbol with a CORE_ADDR value to a psymtab. */ +#define ADD_PSYMBOL_ADDR_TO_LIST(NAME,NAMELENGTH, NAMESPACE,CLASS, LIST,VALUE)\ + ADD_PSYMBOL_VT_TO_LIST(NAME, NAMELENGTH, NAMESPACE, CLASS, LIST, VALUE, SYMBOL_VALUE_ADDRESS) +#endif + +/* End of macro definitions, now let's handle them symbols! */ + + switch (CUR_SYMBOL_TYPE) + { + char *p; + /* + * Standard, external, non-debugger, symbols + */ + +#ifdef DBXREAD_ONLY + case N_TEXT | N_EXT: + case N_NBTEXT | N_EXT: + case N_NBDATA | N_EXT: + case N_NBBSS | N_EXT: + case N_SETV | N_EXT: + case N_ABS | N_EXT: + case N_DATA | N_EXT: + case N_BSS | N_EXT: + + CUR_SYMBOL_VALUE += addr; /* Relocate */ + + SET_NAMESTRING(); + + bss_ext_symbol: + record_misc_function (namestring, CUR_SYMBOL_VALUE, + CUR_SYMBOL_TYPE); /* Always */ + + continue; + + /* Standard, local, non-debugger, symbols */ + + case N_NBTEXT: + + /* We need to be able to deal with both N_FN or N_TEXT, + because we have no way of knowing whether the sys-supplied ld + or GNU ld was used to make the executable. Sequents throw + in another wrinkle -- they renumbered N_FN. */ + + case N_FN: + case N_FN_SEQ: + case N_TEXT: + CUR_SYMBOL_VALUE += addr; /* Relocate */ + SET_NAMESTRING(); + if ((namestring[0] == '-' && namestring[1] == 'l') + || (namestring [(nsl = strlen (namestring)) - 1] == 'o' + && namestring [nsl - 2] == '.')) + { + if (entry_point < CUR_SYMBOL_VALUE + && entry_point >= last_o_file_start + && addr == 0) /* FIXME nogood nomore */ + { + startup_file_start = last_o_file_start; + startup_file_end = CUR_SYMBOL_VALUE; + } + if (past_first_source_file && pst + /* The gould NP1 uses low values for .o and -l symbols + which are not the address. */ + && CUR_SYMBOL_VALUE > pst->textlow) + { + END_PSYMTAB (pst, psymtab_include_list, includes_used, + symnum * symbol_size, CUR_SYMBOL_VALUE, + dependency_list, dependencies_used); + pst = (struct partial_symtab *) 0; + includes_used = 0; + dependencies_used = 0; + } + else + past_first_source_file = 1; + last_o_file_start = CUR_SYMBOL_VALUE; + } + continue; + + case N_DATA: + CUR_SYMBOL_VALUE += addr; /* Relocate */ + SET_NAMESTRING (); + /* Check for __DYNAMIC, which is used by Sun shared libraries. + Record it even if it's local, not global, so we can find it. + Same with virtual function tables, both global and static. */ + if ((namestring[8] == 'C' && (strcmp ("__DYNAMIC", namestring) == 0)) + || VTBL_PREFIX_P ((namestring+HASH_OFFSET))) + { + /* Not really a function here, but... */ + record_misc_function (namestring, CUR_SYMBOL_VALUE, + CUR_SYMBOL_TYPE); /* Always */ + } + continue; + + case N_UNDF | N_EXT: + if (CUR_SYMBOL_VALUE != 0) { + /* This is a "Fortran COMMON" symbol. See if the target + environment knows where it has been relocated to. */ + + CORE_ADDR reladdr; + + SET_NAMESTRING(); + if (target_lookup_symbol (namestring, &reladdr)) { + continue; /* Error in lookup; ignore symbol for now. */ + } + CUR_SYMBOL_TYPE ^= (N_BSS^N_UNDF); /* Define it as a bss-symbol */ + CUR_SYMBOL_VALUE = reladdr; + goto bss_ext_symbol; + } + continue; /* Just undefined, not COMMON */ +#endif + + /* Lots of symbol types we can just ignore. */ + + case N_UNDF: + case N_ABS: + case N_BSS: + case N_NBDATA: + case N_NBBSS: + continue; + + /* Keep going . . .*/ + + /* + * Special symbol types for GNU + */ + case N_INDR: + case N_INDR | N_EXT: + case N_SETA: + case N_SETA | N_EXT: + case N_SETT: + case N_SETT | N_EXT: + case N_SETD: + case N_SETD | N_EXT: + case N_SETB: + case N_SETB | N_EXT: + case N_SETV: + continue; + + /* + * Debugger symbols + */ + + case N_SO: { + unsigned long valu = CUR_SYMBOL_VALUE; + /* Symbol number of the first symbol of this file (i.e. the N_SO + if there is just one, or the first if we have a pair). */ + int first_symnum = symnum; + + /* End the current partial symtab and start a new one */ + + SET_NAMESTRING(); + + /* Peek at the next symbol. If it is also an N_SO, the + first one just indicates the directory. */ + CHECK_SECOND_N_SO(); + valu += addr; /* Relocate */ + + if (pst && past_first_source_file) + { + END_PSYMTAB (pst, psymtab_include_list, includes_used, + first_symnum * symbol_size, valu, + dependency_list, dependencies_used); + pst = (struct partial_symtab *) 0; + includes_used = 0; + dependencies_used = 0; + } + else + past_first_source_file = 1; + + pst = START_PSYMTAB (objfile, addr, + namestring, valu, + first_symnum * symbol_size, + global_psymbols.next, static_psymbols.next); + continue; + } + +#ifdef DBXREAD_ONLY + case N_BINCL: + /* Add this bincl to the bincl_list for future EXCLs. No + need to save the string; it'll be around until + read_dbx_symtab function returns */ + + SET_NAMESTRING(); + + add_bincl_to_list (pst, namestring, CUR_SYMBOL_VALUE); + + /* Mark down an include file in the current psymtab */ + + psymtab_include_list[includes_used++] = namestring; + if (includes_used >= includes_allocated) + { + char **orig = psymtab_include_list; + + psymtab_include_list = (char **) + alloca ((includes_allocated *= 2) * + sizeof (char *)); + bcopy (orig, psymtab_include_list, + includes_used * sizeof (char *)); + } + + continue; +#endif + + case N_SOL: + /* Mark down an include file in the current psymtab */ + + SET_NAMESTRING(); + + /* In C++, one may expect the same filename to come round many + times, when code is coming alternately from the main file + and from inline functions in other files. So I check to see + if this is a file we've seen before -- either the main + source file, or a previously included file. + + This seems to be a lot of time to be spending on N_SOL, but + things like "break c-exp.y:435" need to work (I + suppose the psymtab_include_list could be hashed or put + in a binary tree, if profiling shows this is a major hog). */ + if (pst && !strcmp (namestring, pst->filename)) + continue; + { + register int i; + for (i = 0; i < includes_used; i++) + if (!strcmp (namestring, psymtab_include_list[i])) + { + i = -1; + break; + } + if (i == -1) + continue; + } + + psymtab_include_list[includes_used++] = namestring; + if (includes_used >= includes_allocated) + { + char **orig = psymtab_include_list; + + psymtab_include_list = (char **) + alloca ((includes_allocated *= 2) * + sizeof (char *)); + bcopy (orig, psymtab_include_list, + includes_used * sizeof (char *)); + } + continue; + case N_LSYM: /* Typedef or automatic variable. */ + case N_STSYM: /* Data seg var -- static */ + case N_LCSYM: /* BSS " */ + case N_NBSTS: /* Gould nobase. */ + case N_NBLCS: /* symbols. */ + + SET_NAMESTRING(); + + p = (char *) strchr (namestring, ':'); + + /* Skip if there is no :. */ + if (!p) continue; + + switch (p[1]) + { + case 'T': + ADD_PSYMBOL_TO_LIST (namestring, p - namestring, + STRUCT_NAMESPACE, LOC_TYPEDEF, + static_psymbols, CUR_SYMBOL_VALUE); + if (p[2] == 't') + { + /* Also a typedef with the same name. */ + ADD_PSYMBOL_TO_LIST (namestring, p - namestring, + VAR_NAMESPACE, LOC_TYPEDEF, + static_psymbols, CUR_SYMBOL_VALUE); + p += 1; + } + goto check_enum; + case 't': + ADD_PSYMBOL_TO_LIST (namestring, p - namestring, + VAR_NAMESPACE, LOC_TYPEDEF, + static_psymbols, CUR_SYMBOL_VALUE); + check_enum: +#ifdef DBXREAD_ONLY + /* If this is an enumerated type, we need to + add all the enum constants to the partial symbol + table. This does not cover enums without names, e.g. + "enum {a, b} c;" in C, but fortunately those are + rare. There is no way for GDB to find those from the + enum type without spending too much time on it. Thus + to solve this problem, the compiler needs to put out separate + constant symbols ('c' N_LSYMS) for enum constants in + enums without names, or put out a dummy type. */ + + /* We are looking for something of the form + <name> ":" ("t" | "T") [<number> "="] "e" + {<constant> ":" <value> ","} ";". */ + + /* Skip over the colon and the 't' or 'T'. */ + p += 2; + /* This type may be given a number. Also, numbers can come + in pairs like (0,26). Skip over it. */ + while ((*p >= '0' && *p <= '9') + || *p == '(' || *p == ',' || *p == ')' + || *p == '=') + p++; + + if (*p++ == 'e') + { + /* We have found an enumerated type. */ + /* According to comments in read_enum_type + a comma could end it instead of a semicolon. + I don't know where that happens. + Accept either. */ + while (*p && *p != ';' && *p != ',') + { + char *q; + + /* Check for and handle cretinous dbx symbol name + continuation! */ + if (*p == '\\') + p = next_symbol_text (); + + /* Point to the character after the name + of the enum constant. */ + for (q = p; *q && *q != ':'; q++) + ; + /* Note that the value doesn't matter for + enum constants in psymtabs, just in symtabs. */ + ADD_PSYMBOL_TO_LIST (p, q - p, + VAR_NAMESPACE, LOC_CONST, + static_psymbols, 0); + /* Point past the name. */ + p = q; + /* Skip over the value. */ + while (*p && *p != ',') + p++; + /* Advance past the comma. */ + if (*p) + p++; + } + } +#endif + continue; + case 'c': + /* Constant, e.g. from "const" in Pascal. */ + ADD_PSYMBOL_TO_LIST (namestring, p - namestring, + VAR_NAMESPACE, LOC_CONST, + static_psymbols, CUR_SYMBOL_VALUE); + continue; + default: + /* Skip if the thing following the : is + not a letter (which indicates declaration of a local + variable, which we aren't interested in). */ + continue; + } + + case N_FUN: + case N_GSYM: /* Global (extern) variable; can be + data or bss (sigh). */ + + /* Following may probably be ignored; I'll leave them here + for now (until I do Pascal and Modula 2 extensions). */ + + case N_PC: /* I may or may not need this; I + suspect not. */ + case N_M2C: /* I suspect that I can ignore this here. */ + case N_SCOPE: /* Same. */ + + SET_NAMESTRING(); + + p = (char *) strchr (namestring, ':'); + if (!p) + continue; /* Not a debugging symbol. */ + + + + /* Main processing section for debugging symbols which + the initial read through the symbol tables needs to worry + about. If we reach this point, the symbol which we are + considering is definitely one we are interested in. + p must also contain the (valid) index into the namestring + which indicates the debugging type symbol. */ + + switch (p[1]) + { + case 'c': + ADD_PSYMBOL_TO_LIST (namestring, p - namestring, + VAR_NAMESPACE, LOC_CONST, + static_psymbols, CUR_SYMBOL_VALUE); + continue; + case 'S': + CUR_SYMBOL_VALUE += addr; /* Relocate */ + ADD_PSYMBOL_ADDR_TO_LIST (namestring, p - namestring, + VAR_NAMESPACE, LOC_STATIC, + static_psymbols, CUR_SYMBOL_VALUE); + continue; + case 'G': + CUR_SYMBOL_VALUE += addr; /* Relocate */ + /* The addresses in these entries are reported to be + wrong. See the code that reads 'G's for symtabs. */ + ADD_PSYMBOL_ADDR_TO_LIST (namestring, p - namestring, + VAR_NAMESPACE, LOC_STATIC, + global_psymbols, CUR_SYMBOL_VALUE); + continue; + + case 't': + ADD_PSYMBOL_TO_LIST (namestring, p - namestring, + VAR_NAMESPACE, LOC_TYPEDEF, + static_psymbols, CUR_SYMBOL_VALUE); + continue; + + case 'f': + ADD_PSYMBOL_TO_LIST (namestring, p - namestring, + VAR_NAMESPACE, LOC_BLOCK, + static_psymbols, CUR_SYMBOL_VALUE); + continue; + + /* Global functions were ignored here, but now they + are put into the global psymtab like one would expect. + They're also in the misc fn vector... + FIXME, why did it used to ignore these? That broke + "i fun" on these functions. */ + case 'F': + ADD_PSYMBOL_TO_LIST (namestring, p - namestring, + VAR_NAMESPACE, LOC_BLOCK, + global_psymbols, CUR_SYMBOL_VALUE); + continue; + + /* Two things show up here (hopefully); static symbols of + local scope (static used inside braces) or extensions + of structure symbols. We can ignore both. */ + case 'V': + case '(': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + continue; + + default: + /* Unexpected symbol. Ignore it; perhaps it is an extension + that we don't know about. + + Someone says sun cc puts out symbols like + /foo/baz/maclib::/usr/local/bin/maclib, + which would get here with a symbol type of ':'. */ + continue; + } + +#ifdef DBXREAD_ONLY + case N_EXCL: + + SET_NAMESTRING(); + + /* Find the corresponding bincl and mark that psymtab on the + psymtab dependency list */ + { + struct partial_symtab *needed_pst = + find_corresponding_bincl_psymtab (namestring, CUR_SYMBOL_VALUE); + + /* If this include file was defined earlier in this file, + leave it alone. */ + if (needed_pst == pst) continue; + + if (needed_pst) + { + int i; + int found = 0; + + for (i = 0; i < dependencies_used; i++) + if (dependency_list[i] == needed_pst) + { + found = 1; + break; + } + + /* If it's already in the list, skip the rest. */ + if (found) continue; + + dependency_list[dependencies_used++] = needed_pst; + if (dependencies_used >= dependencies_allocated) + { + struct partial_symtab **orig = dependency_list; + dependency_list = + (struct partial_symtab **) + alloca ((dependencies_allocated *= 2) + * sizeof (struct partial_symtab *)); + bcopy (orig, dependency_list, + (dependencies_used + * sizeof (struct partial_symtab *))); +#ifdef DEBUG_INFO + fprintf (stderr, "Had to reallocate dependency list.\n"); + fprintf (stderr, "New dependencies allocated: %d\n", + dependencies_allocated); +#endif + } + } + else + error ("Invalid symbol data: \"repeated\" header file not previously seen, at symtab pos %d.", + symnum); + } + continue; +#endif + + case N_RBRAC: +#ifdef HANDLE_RBRAC + HANDLE_RBRAC(CUR_SYMBOL_VALUE); +#endif + case N_EINCL: + case N_DSLINE: + case N_BSLINE: + case N_SSYM: /* Claim: Structure or union element. + Hopefully, I can ignore this. */ + case N_ENTRY: /* Alternate entry point; can ignore. */ + case N_MAIN: /* Can definitely ignore this. */ + case N_CATCH: /* These are GNU C++ extensions */ + case N_EHDECL: /* that can safely be ignored here. */ + case N_LENG: + case N_BCOMM: + case N_ECOMM: + case N_ECOML: + case N_FNAME: + case N_SLINE: + case N_RSYM: + case N_PSYM: + case N_LBRAC: + case N_NSYMS: /* Ultrix 4.0: symbol count */ + case N_DEFD: /* GNU Modula-2 */ + /* These symbols aren't interesting; don't worry about them */ + + continue; + + default: +#ifdef DBXREAD_ONLY + /* If we haven't found it yet, ignore it. It's probably some + new type we don't know about yet. */ + complain (&unknown_symtype_complaint, local_hex_string(CUR_SYMBOL_TYPE)); +#endif + continue; + } diff --git a/gdb/sparc-pinsn.c b/gdb/sparc-pinsn.c index a8cdb08..7fed7e9 100644 --- a/gdb/sparc-pinsn.c +++ b/gdb/sparc-pinsn.c @@ -21,7 +21,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "defs.h" #include "symtab.h" -#include "sparc-opcode.h" +#include "opcode/sparc.h" #include "gdbcore.h" #include "string.h" #include "target.h" diff --git a/gdb/symfile.h b/gdb/symfile.h index 5d1c1c6..67226b9 100644 --- a/gdb/symfile.h +++ b/gdb/symfile.h @@ -1,5 +1,5 @@ /* Definitions for reading symbol files into GDB. - Copyright (C) 1990 Free Software Foundation, Inc. + Copyright (C) 1990, 1991 Free Software Foundation, Inc. This file is part of GDB. @@ -19,8 +19,36 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* This file requires that you first include "bfd.h". */ -/* Data structures and function definitions for dealing with - symbol table reading from files. */ + +/* Structure for keeping track of object files. + + One of these is allocated for each object file we access, e.g. the + exec_file, symbol_file, and any shared library object files. */ + +struct objfile { + /* All struct objfile's are chained together by their next pointers. */ + struct objfile *next; + + /* Each objfile points to a chain of struct symtabs derived from this + object file. They are chained by their objfile_chain pointers, and + each one points back to this struct objfile. */ + struct symtab *symtabs; + + /* Ditto for psymtabs. */ + struct partial_symtab *psymtabs; + + /* The object file's name. Malloc'd; free it if you free this struct. */ + char *name; + + /* The object file's BFD. Can be null, in which case bfd_open (name) and + put the result here. */ + bfd *obfd; + + /* The modification timestamp of the object file, as of the last time + we read its symbols. */ + long mtime; +}; + /* Structure to keep track of symbol reading functions for various object file types. */ @@ -83,14 +111,41 @@ struct sym_fns { in whatever module implements the functions pointed to; an initializer calls add_symtab_fns to add them to the global chain. */ struct sym_fns *next; + + /* objfile + is the "struct objfile" for the object file being read. */ + struct objfile *objfile; }; +extern void extend_psymbol_list(); + +/* Add any kind of symbol to a psymbol_allocation_list. */ + +#define ADD_PSYMBOL_VT_TO_LIST(NAME, NAMELENGTH, NAMESPACE, CLASS, LIST, VALUE, VT)\ + do { \ + register struct partial_symbol *psym; \ + if ((LIST).next >= (LIST).list + (LIST).size) \ + extend_psymbol_list(&(LIST)); \ + psym = (LIST).next++; \ + \ + SYMBOL_NAME (psym) = (char *) obstack_alloc (psymbol_obstack, \ + (NAMELENGTH) + 1); \ + strncpy (SYMBOL_NAME (psym), (NAME), (NAMELENGTH)); \ + SYMBOL_NAME (psym)[(NAMELENGTH)] = '\0'; \ + SYMBOL_NAMESPACE (psym) = (NAMESPACE); \ + SYMBOL_CLASS (psym) = (CLASS); \ + VT (psym) = (VALUE); \ + } while (0); + /* Functions */ extern struct symtab *allocate_symtab (); +extern struct objfile *allocate_objfile (); +extern void free_objfile (); extern int free_named_symtabs (); extern void fill_in_vptr_fieldno (); extern void add_symtab_fns (); +extern void syms_from_objfile (); /* Functions for dealing with the misc "function" vector, really a misc address<->symbol mapping vector for things we don't have debug symbols @@ -121,13 +176,18 @@ extern char *obconcat (); /* Variables */ -/* File name symbols were loaded from. */ +/* The object file that the main symbol table was loaded from (e.g. the + argument to the "symbol-file" or "file" command). */ + +extern struct objfile *symfile_objfile; + +/* Where execution starts in symfile */ -extern char *symfile; +CORE_ADDR entry_point; -/* The modification date of the file when they were loaded. */ +/* Root of object file struct chain. */ -extern long /* really time_t */ symfile_mtime; +struct objfile *object_files; /* Vectors of all partial symbols read in from file. */ @@ -156,5 +216,5 @@ extern struct complaint complaint_root[1]; /* Functions that handle complaints. (in symfile.c) */ -int complain(); +void complain(); void clear_complaints(); diff --git a/gdb/symmisc.c b/gdb/symmisc.c index 04d3759..507ec18 100644 --- a/gdb/symmisc.c +++ b/gdb/symmisc.c @@ -1,5 +1,5 @@ -/* Do various things to symbol tables (other than lookup)), for GDB. - Copyright (C) 1986, 1987, 1989 Free Software Foundation, Inc. +/* Do various things to symbol tables (other than lookup), for GDB. + Copyright 1986, 1987, 1989, 1991 Free Software Foundation, Inc. This file is part of GDB. @@ -20,52 +20,15 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <stdio.h> #include "defs.h" -#include "param.h" #include "symtab.h" #include "bfd.h" #include "symfile.h" #include "breakpoint.h" #include "command.h" +#include "obstack.h" -#include <obstack.h> +#include <string.h> -/* 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 (); -#if defined (CLEAR_SOLIB) - CLEAR_SOLIB (); -#endif - 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; - clear_pc_function_cache(); -} - /* Free a struct block <- B and all the symbols defined in that block. */ static void @@ -119,9 +82,10 @@ free_symtab (s) case free_linetable: /* Everything will be freed either by our `free_ptr' - or by some other symbatb, except for our linetable. + or by some other symtab, except for our linetable. Free that now. */ - free (LINETABLE (s)); + if (LINETABLE (s)) + free (LINETABLE (s)); break; } @@ -142,7 +106,7 @@ static void print_symbol (); static void print_partial_symbol (); void -print_symtabs (filename) +printsyms_command (filename) char *filename; { FILE *outfile; @@ -155,10 +119,16 @@ print_symtabs (filename) int depth; struct cleanup *cleanups; extern int fclose(); + char *symname; if (filename == 0) error_no_arg ("file to write symbol data in"); + /* If a second arg is supplied, it is a source file name to match on */ + symname = strchr (filename, ' '); + if (symname) + *symname++ = '\0'; + filename = tilde_expand (filename); make_cleanup (free, filename); @@ -171,8 +141,16 @@ print_symtabs (filename) for (s = symtab_list; s; s = s->next) { - /* First print the line table. */ + /* If source file name is specified, reject all but that one. */ + if (symname) + if (0 != strncmp (symname, s->filename, strlen (symname))) + continue; + fprintf (outfile, "Symtab for file %s\n", s->filename); + fprintf (outfile, "Read from object file %s (%x)\n", s->objfile->name, + s->objfile); + + /* First print the line table. */ l = LINETABLE (s); if (l) { fprintf (outfile, "\nLine table:\n\n"); @@ -324,17 +302,23 @@ print_symbol (symbol, depth, outfile) } void -print_partial_symtabs (filename) +printpsyms_command (filename) char *filename; { FILE *outfile; struct partial_symtab *p; struct cleanup *cleanups; extern int fclose(); + char *symname; if (filename == 0) error_no_arg ("file to write partial symbol data in"); + /* If a second arg is supplied, it is a source file name to match on */ + symname = strchr (filename, ' '); + if (symname) + *symname++ = '\0'; + filename = tilde_expand (filename); make_cleanup (free, filename); @@ -347,14 +331,19 @@ print_partial_symtabs (filename) for (p = partial_symtab_list; p; p = p->next) { + /* If source file name is specified, reject all but that one. */ + if (symname) + if (0 != strncmp (symname, p->filename, strlen (symname))) + continue; + fprintf_filtered (outfile, "Partial symtab for source file %s ", p->filename); fprintf_filtered (outfile, "(object 0x%x)\n\n", p); - fprintf_filtered (outfile, " Full symbol table %s been read from %s\n", - p->readin ? "has" : "has not yet", - p->symfile_name); + fprintf (outfile, " Read from object file %s (0x%x)\n", p->objfile->name, + p->objfile); + if (p->readin) - fprintf_filtered (outfile, " Was read into symtab at 0x%x by function at 0x%x\n", + fprintf_filtered (outfile, " Full symtab was read (at 0x%x by function at 0x%x)\n", p->symtab, p->read_symtab); fprintf_filtered (outfile, " Relocate symbols by 0x%x\n", p->addr); fprintf_filtered (outfile, " Symbols cover text addresses 0x%x-0x%x\n", @@ -381,8 +370,6 @@ int count; char *what; FILE *outfile; { - char *space; - char *class; fprintf_filtered (outfile, " %s partial symbols:\n", what); while (count-- > 0) @@ -468,26 +455,131 @@ block_depth (block) return i; } -/* - * Free all partial_symtab storage. - */ -void -free_all_psymtabs() +static void +printobjfiles_command () { - obstack_free (psymbol_obstack, 0); - obstack_init (psymbol_obstack); - partial_symtab_list = (struct partial_symtab *) 0; + struct objfile *objfile; + struct symtab *symtab; + struct partial_symtab *psymtab; + int first; + + for (objfile = object_files; objfile; objfile = objfile->next) { + printf_filtered ("\nObject file %s: ", objfile->name); + printf_filtered ("Objfile at %x, bfd at %x\n\n", objfile, objfile->obfd); + + if (objfile->psymtabs) { + printf_filtered ("Psymtabs:\n"); + for (psymtab = objfile->psymtabs; + psymtab; + psymtab = psymtab->objfile_chain) { + printf_filtered ("%s at %x, ", psymtab->filename, psymtab); + if (psymtab->objfile != objfile) + printf_filtered ("NOT ON CHAIN! "); + wrap_here (" "); + } + printf_filtered ("\n\n"); + } + + if (objfile->symtabs) { + printf_filtered ("Symtabs:\n"); + for (symtab = objfile->symtabs; + symtab; + symtab = symtab->objfile_chain) { + printf_filtered ("%s at %x, ", symtab->filename, symtab); + if (symtab->objfile != objfile) + printf_filtered ("NOT ON CHAIN! "); + wrap_here (" "); + } + printf_filtered ("\n\n"); + } + } + + /* Now check for psymtabs that aren't owned by an objfile. */ + + first = 1; + for (psymtab = partial_symtab_list; psymtab; psymtab = psymtab->next) { + for (objfile = object_files; objfile; objfile = objfile->next) { + if (psymtab->objfile == objfile) + goto next; + } + if (first) + printf_filtered ("Psymtabs that aren't owned by any objfile:\n"); + first = 0; + printf_filtered (" %s at %x, psymtab->objfile %x\n", psymtab->filename, + psymtab, psymtab->objfile); + next: ; + } + + /* Now check for symtabs that aren't owned by an objfile. */ + + first = 1; + for (symtab = symtab_list; symtab; symtab = symtab->next) { + for (objfile = object_files; objfile; objfile = objfile->next) { + if (symtab->objfile == objfile) + goto next2; + } + if (first) + printf_filtered ("Symtabs that aren't owned by any objfile:\n"); + first = 0; + printf_filtered (" %s at %x, symtab->objfile %x\n", symtab->filename, + symtab, symtab->objfile); + next2: ; + } } +struct cplus_struct_type cplus_struct_default; + +void +allocate_cplus_struct_type (type) + struct type *type; +{ + if (!HAVE_CPLUS_STRUCT (type)) + { + int nfields = TYPE_NFIELDS (type); + TYPE_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *) + obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type)); + *(TYPE_CPLUS_SPECIFIC(type)) = cplus_struct_default; + } +} + +/* Increase the space allocated for LISTP. */ + +void +extend_psymbol_list(listp) + register struct psymbol_allocation_list *listp; +{ + int new_size; + if (listp->size == 0) + { + new_size = 255; + listp->list = (struct partial_symbol *) + xmalloc (new_size * sizeof (struct partial_symbol)); + } + else + { + new_size = listp->size * 2; + listp->list = (struct partial_symbol *) + xrealloc (listp->list, new_size * sizeof (struct partial_symbol)); + } + /* Next assumes we only went one over. Should be good if + program works correctly */ + listp->next = listp->list + listp->size; + listp->size = new_size; +} + void _initialize_symmisc () { symtab_list = (struct symtab *) 0; partial_symtab_list = (struct partial_symtab *) 0; - add_com ("printsyms", class_obscure, print_symtabs, - "Print dump of current symbol definitions to file OUTFILE."); - add_com ("printpsyms", class_obscure, print_partial_symtabs, - "Print dump of current partial symbol definitions to file OUTFILE."); + add_com ("printsyms", class_obscure, printsyms_command, + "Print dump of current symbol definitions to file OUTFILE.\n\ +If a SOURCE file is specified, dump only that file's symbols."); + add_com ("printpsyms", class_obscure, printpsyms_command, + "Print dump of current partial symbol definitions to file OUTFILE.\n\ +If a SOURCE file is specified, dump only that file's partial symbols."); + add_com ("printobjfiles", class_obscure, printobjfiles_command, + "Print dump of current object file definitions."); } diff --git a/gdb/symtab.c b/gdb/symtab.c index cd5c289..c05a9e1 100644 --- a/gdb/symtab.c +++ b/gdb/symtab.c @@ -218,7 +218,7 @@ check_stub_type(type) sym = lookup_symbol (name, 0, STRUCT_NAMESPACE, 0, (struct symtab **)NULL); if (sym) - bcopy (SYMBOL_TYPE(sym), type, sizeof (struct type)); + memcpy (type, SYMBOL_TYPE(sym), sizeof (struct type)); } } @@ -636,6 +636,7 @@ check_stub_method (type, i, j) TYPE_DOMAIN_TYPE (mtype) = type; TYPE_ARG_TYPES (mtype) = argtypes; TYPE_FLAGS (mtype) &= ~TYPE_FLAG_STUB; + TYPE_FN_FIELD_STUB (f, j) = 0; } /* Given a type TYPE, return a type of functions that return that type. @@ -1704,7 +1705,7 @@ operator_chars (p, end) */ int -find_methods(t, name, physnames, sym_arr) +find_methods (t, name, physnames, sym_arr) struct type *t; char *name; char **physnames; @@ -1756,7 +1757,7 @@ find_methods(t, name, physnames, sym_arr) --field_counter) { char *phys_name; - if (TYPE_FLAGS (TYPE_FN_FIELD_TYPE (f, field_counter)) & TYPE_FLAG_STUB) + if (TYPE_FN_FIELD_STUB (f, field_counter)) check_stub_method (t, method_counter, field_counter); phys_name = TYPE_FN_FIELD_PHYSNAME (f, field_counter); physnames[i1] = (char*) alloca (strlen (phys_name) + 1); @@ -2685,12 +2686,7 @@ init_type (code, length, uns, name) /* C++ fancies. */ if (code == TYPE_CODE_STRUCT || code == TYPE_CODE_UNION) - { - TYPE_CPLUS_SPECIFIC (type) - = (struct cplus_struct_type *) xmalloc (sizeof (struct cplus_struct_type)); - TYPE_NFN_FIELDS (type) = 0; - TYPE_N_BASECLASSES (type) = 0; - } + TYPE_CPLUS_SPECIFIC(type) = &cplus_struct_default; return type; } diff --git a/gdb/symtab.h b/gdb/symtab.h index 97b8800..bd7e050 100644 --- a/gdb/symtab.h +++ b/gdb/symtab.h @@ -197,7 +197,7 @@ struct type /* Slot to point to additional language-specific fields of this type. */ union type_specific { - /* ARG_TYPES is for TYPE_CODE_METHOD and TYPE_CODE_FUNCTION. */ + /* ARG_TYPES is for TYPE_CODE_METHOD and TYPE_CODE_FUNC. */ struct type **arg_types; /* CPLUS_STUFF is for TYPE_CODE_STRUCT. */ struct cplus_struct_type *cplus_stuff; @@ -262,6 +262,16 @@ struct cplus_struct_type unsigned char via_protected; unsigned char via_public; }; +/* The default value of TYPE_CPLUS_SPECIFIC(T) points to the + this shared static structure. */ + +extern struct cplus_struct_type cplus_struct_default; + +extern void allocate_cplus_struct_type (); +#define ALLOCATE_CPLUS_STRUCT_TYPE(type) allocate_cplus_struct_type (type) +#define HAVE_CPLUS_STRUCT(type) \ + (TYPE_CPLUS_SPECIFIC(type) != &cplus_struct_default) + /* All of the name-scope contours of the program are represented by `struct block' objects. @@ -710,9 +720,11 @@ int current_source_line; #define SET_TYPE_FIELD_VIRTUAL(thistype, n) \ B_SET (TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n)) #define TYPE_FIELD_PRIVATE(thistype, n) \ - B_TST(TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits, (n)) + (TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits == NULL ? 0 \ + : B_TST(TYPE_CPLUS_SPECIFIC(thistype)->private_field_bits, (n))) #define TYPE_FIELD_PROTECTED(thistype, n) \ -B_TST(TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits, (n)) + (TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits == NULL ? 0 \ + : B_TST(TYPE_CPLUS_SPECIFIC(thistype)->protected_field_bits, (n))) #define TYPE_FIELD_VIRTUAL(thistype, n) \ B_TST(TYPE_CPLUS_SPECIFIC(thistype)->virtual_field_bits, (n)) diff --git a/gdb/tm-mips.h b/gdb/tm-mips.h index dc5af0d..af451ef 100644 --- a/gdb/tm-mips.h +++ b/gdb/tm-mips.h @@ -31,6 +31,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /*#define NAMES_HAVE_UNDERSCORE*/ +/* Address of blocks in N_LBRAC and N_RBRAC symbols are absolute addresses, + not relative to start of source address. */ +#define BLOCK_ADDRESS_ABSOLUTE + /* Debugger information will be in mips' format */ #define READ_MIPS_FORMAT |