Oodles of changes. The most important is adding support for stabs
authorPer Bothner <per@bothner.com>
Mon, 23 Dec 1991 23:16:58 +0000 (23:16 +0000)
committerPer Bothner <per@bothner.com>
Mon, 23 Dec 1991 23:16:58 +0000 (23:16 +0000)
encapsulated in mips ecoff.  See ChangeLog for the gory details.

18 files changed:
gdb/.Sanitize
gdb/ChangeLog
gdb/buildsym.c
gdb/buildsym.h
gdb/coffread.c
gdb/dbxread.c
gdb/depend
gdb/dwarfread.c
gdb/m68k-pinsn.c
gdb/mips-pinsn.c
gdb/mipsread.c
gdb/partial-stab.h [new file with mode: 0644]
gdb/sparc-pinsn.c
gdb/symfile.h
gdb/symmisc.c
gdb/symtab.c
gdb/symtab.h
gdb/tm-mips.h

index e4e8008b0d96f144ff2c3cb8b65e4988cb264398..96814e369fbecfacc1b294c30cbb9ccdc1c1d3ae 100644 (file)
@@ -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
index 08c3300ca34ee6e068066f3b621040ef9a59478d..925b66d9fdd22338c255358dec98e92232df4b1b 100644 (file)
@@ -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 
index d4dde9c07ca10cd9b49491829dbc6eb94d2095cc..bbcaecdbbb8c07b9563790d545213284b4833dad 100644 (file)
@@ -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;
 }
 
index 2722d5b0b951bdd4f60192cbbf2c46e62dc39bb1..80fad8e432d655bde69105ee4625bf4dd045eab7 100644 (file)
@@ -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
index f942625a646c2e0acf4cdc0cca5da862bbfbbd12..bd5b0ce559b1637973d14042a01db0508ba59209 100644 (file)
@@ -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};
 \f
 /* 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 ()
     }
 }
 \f
-#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;
 }
 \f
@@ -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)
index 371f923560cdf85a1778569725afdda289c0d905..482f12c91047461278de079011633b12e1bd6db3 100644 (file)
@@ -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
 \f
 /* 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)
 }
 
 \f
-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;
 }
 \f
 /* Copy a pending list, used to record the contents of a common
index 511c2040b5ee4bed93eb526b0758eb3a85081b30..f0c0faa7e48526ad3de91a1807a1249f4d06f250 100755 (executable)
@@ -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 
index 65a4c3f7dd34054110aa315b3f21217df3ce7edf..e0c286bdc9684a766f114552104ad847dc770fb4 100644 (file)
@@ -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
 
 /*
 
index de43af111461bf3e3c06a5b55f53cf4a450b7936..7fc6242b78d2f902109b4bc15232387009e4e437 100644 (file)
@@ -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.  */
index a90448ae04d23d9c075f78b73a63926533001fe6..0b3391e07b27777f4d70fc8b0fe82ced9b32fcc2 100644 (file)
@@ -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
index f77ec4a07565c21415f31c031f46791fd2f58da4..b98c9cb391e57d7a23cdb253b79df76835cb05a8 100644 (file)
@@ -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();
 \f
 /* 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
 }
 \f
 /* 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);
-}
 \f
 /* 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;
 }
 \f
 /* 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);
-}
 \f
 /* 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);
-}
-
-
 \f
 /* 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 (file)
index 0000000..d901795
--- /dev/null
@@ -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;
+       }
index a8cdb08e7f231d140dbd4d10dda4a5be7a2defd1..7fed7e976085e92a3478c70360e9784e58e974c6 100644 (file)
@@ -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"
index 5d1c1c666ec3b616dbd0265e46db546be6706e13..67226b94ddefe74e5b10373cf50113388b694141 100644 (file)
@@ -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();
index 04d375957b0b7a807e4b047b2f350e82f8aa4b67..507ec1825f30e5026e20171414ac27f61e33af02 100644 (file)
@@ -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>
 \f
-/* 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;
 }
 \f
-/*
- * 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: ;
+  }
 }
 \f
+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.");
 }
 
index cd5c28932c41152e555bcedb27beb97b1503d45f..c05a9e1730a80e01a78c96579f6f21bd3ecb5e6b 100644 (file)
@@ -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;
 }
 
index 97b88003af66e4dcd2600ea55b78cfd3404624e1..bd7e050ac456eeb07ea1f52f6bf4447d02b44254 100644 (file)
@@ -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)
+
 \f
 /* 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))
 
index dc5af0dc4f634450b6a01bdfb93cbf7bc71918f3..af451efaaa59c2aa8fbd823f3b99f6e5236e4021 100644 (file)
@@ -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