]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
gdb/mdebug: Remove stabs support from mips inferiors
authorGuinevere Larsen <guinevere@redhat.com>
Tue, 14 Jan 2025 17:28:18 +0000 (14:28 -0300)
committerGuinevere Larsen <guinevere@redhat.com>
Tue, 28 Jan 2025 19:23:50 +0000 (16:23 -0300)
Ostensibly, the mdebugread.c is about reading debug information in the
ecoff format, but it also supports stabs-in-ecoff according to comments
in there, and also relied in some stabs facilities for ecoff reading
itself. This commit takes the first step in removing stabs support by
removing those dependencies from mdebug. And in order to support
stabs-in-ecoff, mipsread would also call stabsread_new_init.

Removing stabs-in-ecoff is trivial, as the code was well demarcated with
comments mentioning where stabs was read. Plus the call to
stabsread_new_init in mipsread can be trivially removed.

Another simple removal was the dependence on stabs_end_psymtabs: because
the local variables dependencies_used and includes_used were only touched
by stabs-reading code, they are always 0 in the new version, which means
we can find the exact code path that'd be followed in stabs_end_psymtab
and move the relevant lines to mdebug instead.

After all those, the last remaining dependency is when reading a fortran
common block from an inferior compiled by SGI fortran compilers (and
maybe more). The block could have no address, meaning it'd need to be
fixed after all the minimal symbols have been read. This was done by
adding the symbol to the stabs global_sym_chain, then calling
scan_file_globals to fix them up. This commit copies all the necessary
code for handling the fortran symbols onto mdebug, technically making
some code duplication, but since stabsread will be removed soon, this
shouldn't be too concerning.

This change was tested in the compile farm's mips64 machine (number
230), where it actually seems to have solved some 50 failures in the
testsuite, not including changes in tests from gdb.threads, as those are
often very racy. I'm not sure if these were true fixes or racy cases,
but since the new version has no newly introduced fails, only fewer of
them, I'm inclined to think this change is at least harmless.

gdb/mdebugread.c
gdb/mipsread.c

index fbfe3a70e30d9bbd633cfc3d870b145ac7cd7385..58917efdaf403575e7f71664c69c59587aac22ee 100644 (file)
@@ -46,7 +46,6 @@
 #include "objfiles.h"
 #include "gdbsupport/gdb_obstack.h"
 #include "buildsym-legacy.h"
-#include "stabsread.h"
 #include "complaints.h"
 #include "demangle.h"
 #include "gdb-demangle.h"
@@ -121,6 +120,88 @@ struct md_symloc
 #define SC_IS_BSS(sc) ((sc) == scBss)
 #define SC_IS_SBSS(sc) ((sc) == scSBss)
 #define SC_IS_UNDEF(sc) ((sc) == scUndefined || (sc) == scSUndefined)
+
+static constexpr int hashsize = 127;
+struct symbol *fortran_global_syms[hashsize];
+
+/* Calculate the hash for a fortran symbol name.  */
+static int
+hash_fortran_symbol (const char *name)
+{
+  return fast_hash (name, strlen (name)) % hashsize;
+}
+
+/* Finish up the symbols in the fortran_global_syms hashtable.  */
+static void
+finish_fortran_symbol (struct objfile *objfile)
+{
+  /* First, check if we have any fortran symbols at all.  */
+  bool found = false;
+  for (int i = 0; i < hashsize && !found; i++)
+    found = fortran_global_syms[i] != nullptr;
+
+  if (!found)
+    return;
+
+  /* We have symbols to fixup.  */
+  for (minimal_symbol *msym : objfile->msymbols ())
+    {
+      int hash = hash_fortran_symbol (msym->linkage_name ());
+      symbol *prev = nullptr;
+
+      for (symbol *sym = fortran_global_syms[hash]; sym; )
+       {
+         /* Check if the symbol in the chain is the same as the
+            minimal symbol.  If so, remove from the chain and do the
+            last bits of processing.  Otherwise, mark this symbol as
+            the last seen symbol for chain removal.  */
+         if (strcmp (msym->linkage_name (), sym->linkage_name ()) == 0)
+           {
+             /* Based on scan_file_globals, except we know the symbol is
+                LOC_STATIC, so we know the exact if branch that'd be
+                followed. */
+             sym->set_value_address (msym->value_address (objfile));
+             sym->set_section_index (msym->section_index ());
+
+             /* Update SYM to move forward through the chain, and remove
+                it from the list.  */
+             sym = sym->value_chain ();
+             if (prev)
+               prev->set_value_chain (sym);
+             else
+               fortran_global_syms[hash] = sym;
+
+             /* A symbol could have been added multiple times to
+                the hashmap, so we can't break out of the loop here.  */
+           }
+         else
+           {
+             prev = sym;
+             sym = sym->value_chain ();
+           }
+       }
+    }
+
+  /* If any symbols remain, change the address class to unresolved
+     and clear the misleading memory.  */
+  for (int hash = 0; hash < hashsize; hash++)
+    {
+      symbol *sym, *prev;
+      for (sym = fortran_global_syms[hash]; sym; )
+       {
+         prev = sym;
+         /* Zeroing the address later will overwrite the value_chain,
+            so we have to advance it now.  */
+         sym = sym->value_chain ();
+
+         prev->set_value_address (0);
+         prev->set_aclass_index (LOC_UNRESOLVED);
+       }
+    }
+
+  memset (fortran_global_syms, 0, sizeof (fortran_global_syms));
+}
+
 \f
 /* Various complaints about symbol reading that don't abort the process.  */
 static void
@@ -270,8 +351,6 @@ static void handle_psymbol_enumerators (struct objfile *, psymtab_storage *,
                                        partial_symtab *,
                                        FDR *, int, CORE_ADDR);
 
-static const char *mdebug_next_symbol_text (struct objfile *);
-\f
 /* Exported procedure: Builds a symtab from the partial symtab SELF.
    Restores the environment in effect when SELF was created, delegates
    most of the work to an ancillary procedure, and sorts
@@ -280,13 +359,11 @@ static const char *mdebug_next_symbol_text (struct objfile *);
 static void
 mdebug_read_symtab (legacy_psymtab *self, struct objfile *objfile)
 {
-  next_symbol_text_func = mdebug_next_symbol_text;
-
   self->expand_psymtab (objfile);
 
   /* 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 (objfile);
+  finish_fortran_symbol (objfile);
 }
 \f
 /* File-level interface functions.  */
@@ -339,10 +416,8 @@ mdebug_build_psymtabs (minimal_symbol_reader &reader,
   debug_swap = swap;
   debug_info = info;
 
-  stabsread_new_init ();
-  free_header_files ();
-  init_header_files ();
-       
+  memset (fortran_global_syms, 0, sizeof (fortran_global_syms));
+
   /* Make sure all the FDR information is swapped in.  */
   if (info->fdr == NULL)
     {
@@ -647,9 +722,10 @@ parse_symbol (SYMR *sh, union aux_ext *ax, char *ext_sh, int bigend,
          /* It is a FORTRAN common block.  At least for SGI Fortran the
             address is not in the symbol; we need to fix it later in
             scan_file_globals.  */
-         int bucket = hashname (s->linkage_name ());
-         s->set_value_chain (global_sym_chain[bucket]);
-         global_sym_chain[bucket] = s;
+
+         int bucket = hash_fortran_symbol (s->linkage_name ());
+         s->set_value_chain (fortran_global_syms[bucket]);
+         fortran_global_syms[bucket] = s;
        }
       else
        {
@@ -2049,8 +2125,7 @@ parse_procedure (PDR *pr, struct compunit_symtab *search_symtab,
      function is adjusted accordingly if no debugging info was found in the
      compilation unit.  */
 
-  if (processing_gcc_compilation == 0
-      && found_ecoff_debugging_info == 0
+  if (found_ecoff_debugging_info == 0
       && s->type ()->target_type ()->code () == TYPE_CODE_VOID)
     s->set_type (builtin_type (mdebugread_objfile)->nodebug_text_symbol);
 }
@@ -2216,14 +2291,6 @@ parse_lines (FDR *fh, PDR *pr, struct linetable *lt, int maxlines,
        }
     }
 }
-\f
-static void
-function_outside_compilation_unit_complaint (const char *arg1)
-{
-  complaint (_("function `%s' appears to be defined "
-              "outside of all compilation units"),
-            arg1);
-}
 
 /* Use the STORAGE_CLASS to compute which section the given symbol
    belongs to, and then records this new minimal symbol.  */
@@ -2297,7 +2364,6 @@ parse_partial_symbols (minimal_symbol_reader &reader,
                       psymtab_storage *partial_symtabs,
                       struct objfile *objfile)
 {
-  struct gdbarch *gdbarch = objfile->arch ();
   const bfd_size_type external_sym_size = debug_swap->external_sym_size;
   const bfd_size_type external_rfd_size = debug_swap->external_rfd_size;
   const bfd_size_type external_ext_size = debug_swap->external_ext_size;
@@ -2314,17 +2380,11 @@ parse_partial_symbols (minimal_symbol_reader &reader,
   EXTR *ext_in_end;
   SYMR sh;
   legacy_psymtab *pst;
-  int textlow_not_set = 1;
 
   /* List of current psymtab's include files.  */
-  const char **psymtab_include_list;
-  int includes_allocated;
-  int includes_used;
   EXTR *extern_tab;
   struct pst_map *fdr_to_pst;
   /* Index within current psymtab dependency list.  */
-  legacy_psymtab **dependency_list;
-  int dependencies_used, dependencies_allocated;
   char *name;
   enum language prev_language;
   asection *text_sect;
@@ -2343,18 +2403,6 @@ parse_partial_symbols (minimal_symbol_reader &reader,
 
   extern_tab = XOBNEWVEC (&objfile->objfile_obstack, EXTR, hdr->iextMax);
 
-  includes_allocated = 30;
-  includes_used = 0;
-  psymtab_include_list = (const char **) alloca (includes_allocated *
-                                                sizeof (const char *));
-  next_symbol_text_func = mdebug_next_symbol_text;
-
-  dependencies_allocated = 30;
-  dependencies_used = 0;
-  dependency_list =
-    (legacy_psymtab **) alloca (dependencies_allocated *
-                               sizeof (legacy_psymtab *));
-
   set_last_source_file (NULL);
 
   /*
@@ -2662,7 +2710,6 @@ parse_partial_symbols (minimal_symbol_reader &reader,
         ecoff for local symbols.  (It is the second symbol because
         the first symbol is the stFile used to signal the start of a
         file).  */
-      processing_gcc_compilation = 0;
       if (fh->csym >= 2)
        {
          (*swap_sym_in) (cur_bfd,
@@ -2671,1031 +2718,345 @@ parse_partial_symbols (minimal_symbol_reader &reader,
                          &sh);
          if (strcmp (debug_info->ss + fh->issBase + sh.iss,
                      stabs_symbol) == 0)
-           processing_gcc_compilation = 2;
+           error ("GDB no longer supports stabs debug information.");
        }
 
-      if (processing_gcc_compilation != 0)
+      for (cur_sdx = 0; cur_sdx < fh->csym;)
        {
-         for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++)
-           {
-             int type_code;
-             const char *namestring;
+         char *sym_name;
+         enum address_class theclass;
+         unrelocated_addr minsym_value;
+         int section = -1;
 
-             (*swap_sym_in) (cur_bfd,
-                             (((char *) debug_info->external_sym)
-                           + (fh->isymBase + cur_sdx) * external_sym_size),
-                             &sh);
-             type_code = ECOFF_UNMARK_STAB (sh.index);
-             if (!ECOFF_IS_STAB (&sh))
-               {
-                 if (sh.st == stProc || sh.st == stStaticProc)
-                   {
-                     unrelocated_addr procaddr;
-                     long isym;
+         (*swap_sym_in) (cur_bfd,
+                         ((char *) debug_info->external_sym
+                          + ((fh->isymBase + cur_sdx)
+                             * external_sym_size)),
+                         &sh);
 
-                     if (sh.st == stStaticProc)
-                       {
-                         namestring = debug_info->ss + fh->issBase + sh.iss;
-                         record_minimal_symbol (reader, namestring,
-                                                unrelocated_addr (sh.value),
-                                                mst_file_text, sh.sc,
-                                                objfile);
-                       }
-                     procaddr = unrelocated_addr (sh.value);
-
-                     isym = AUX_GET_ISYM (fh->fBigendian,
-                                          (debug_info->external_aux
-                                           + fh->iauxBase
-                                           + sh.index));
-                     (*swap_sym_in) (cur_bfd,
-                                     ((char *) debug_info->external_sym
-                                      + ((fh->isymBase + isym - 1)
-                                         * external_sym_size)),
-                                     &sh);
-                     if (sh.st == stEnd)
-                       {
-                         unrelocated_addr high
-                           = unrelocated_addr (CORE_ADDR (procaddr)
-                                               + sh.value);
-
-                         /* Kludge for Irix 5.2 zero fh->adr.  */
-                         if (!relocatable
-                             && (!pst->text_low_valid
-                                 || procaddr < pst->unrelocated_text_low ()))
-                           pst->set_text_low (procaddr);
-                         if (high > pst->unrelocated_text_high ())
-                           pst->set_text_high (high);
-                       }
-                   }
-                 else if (sh.st == stStatic)
-                   {
-                     switch (sh.sc)
-                       {
-                       case scUndefined:
-                       case scSUndefined:
-                       case scNil:
-                       case scAbs:
-                         break;
-
-                       case scData:
-                       case scSData:
-                       case scRData:
-                       case scPData:
-                       case scXData:
-                         namestring = debug_info->ss + fh->issBase + sh.iss;
-                         record_minimal_symbol (reader, namestring,
-                                                unrelocated_addr (sh.value),
-                                                mst_file_data, sh.sc,
-                                                objfile);
-                         break;
-
-                       default:
-                         /* FIXME!  Shouldn't this use cases for bss, 
-                            then have the default be abs?  */
-                         namestring = debug_info->ss + fh->issBase + sh.iss;
-                         record_minimal_symbol (reader, namestring,
-                                                unrelocated_addr (sh.value),
-                                                mst_file_bss, sh.sc,
-                                                objfile);
-                         break;
-                       }
-                   }
-                 continue;
-               }
-             /* Handle stabs continuation.  */
-             {
-               char *stabstring = debug_info->ss + fh->issBase + sh.iss;
-               /* If we need to heap-allocate STABSTRING, this owns
-                  it.  */
-               gdb::unique_xmalloc_ptr<char> stabstring_storage;
-               int len = strlen (stabstring);
+         if (ECOFF_IS_STAB (&sh))
+           {
+             cur_sdx++;
+             continue;
+           }
 
-               while (stabstring[len - 1] == '\\')
-                 {
-                   SYMR sh2;
-                   char *stabstring1 = stabstring;
-                   char *stabstring2;
-                   int len2;
-
-                   /* Ignore continuation char from 1st string.  */
-                   len--;
-
-                   /* Read next stabstring.  */
-                   cur_sdx++;
-                   (*swap_sym_in) (cur_bfd,
-                                   (((char *) debug_info->external_sym)
-                                    + (fh->isymBase + cur_sdx)
-                                    * external_sym_size),
-                                   &sh2);
-                   stabstring2 = debug_info->ss + fh->issBase + sh2.iss;
-                   len2 = strlen (stabstring2);
-
-                   /* Concatenate stabstring2 with stabstring1.  */
-                   if (stabstring_storage != nullptr)
-                     {
-                       stabstring_storage.reset
-                         ((char *) xrealloc (stabstring_storage.release (),
-                                             len + len2 + 1));
-                       stabstring = stabstring_storage.get ();
-                     }
-                   else
-                     {
-                       stabstring_storage.reset
-                         ((char *) xmalloc (len + len2 + 1));
-                       stabstring = stabstring_storage.get ();
-                       strcpy (stabstring, stabstring1);
-                     }
-                   strcpy (stabstring + len, stabstring2);
-                   len += len2;
-                 }
+         /* Non absolute static symbols go into the minimal table.  */
+         if (SC_IS_UNDEF (sh.sc) || sh.sc == scNil
+             || (sh.index == indexNil
+                 && (sh.st != stStatic || sh.sc == scAbs)))
+           {
+             /* FIXME, premature?  */
+             cur_sdx++;
+             continue;
+           }
 
-               switch (type_code)
-                 {
-                   const char *p;
-
-                   /* Standard, external, non-debugger, symbols.  */
-
-                 case N_TEXT | N_EXT:
-                 case N_NBTEXT | N_EXT:
-                   goto record_it;
-
-                 case N_DATA | N_EXT:
-                 case N_NBDATA | N_EXT:
-                   goto record_it;
-
-                 case N_BSS:
-                 case N_BSS | N_EXT:
-                 case N_NBBSS | N_EXT:
-                 case N_SETV | N_EXT:          /* FIXME, is this in BSS?  */
-                   goto record_it;
-
-                 case N_ABS | N_EXT:
-                 record_it:
-                   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:
-                   continue;
-
-                 case N_DATA:
-                   goto record_it;
-
-                 case N_UNDF | N_EXT:
-                   continue;           /* Just undefined, not COMMON.  */
-
-                 case N_UNDF:
-                   continue;
-
-                   /* Lots of symbol types we can just ignore.  */
-
-                 case N_ABS:
-                 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:
-                   {
-                     static int prev_so_symnum = -10;
-                     const char *basename;
-
-                     /* A zero value is probably an indication for the
-                        SunPRO 3.0 compiler.  stabs_end_psymtab explicitly tests
-                        for zero, so don't relocate it.  */
-
-                     if (sh.value == 0
-                         && gdbarch_sofun_address_maybe_missing (gdbarch))
-                       textlow_not_set = 1;
-                     else
-                       textlow_not_set = 0;
-
-                     if (prev_so_symnum != symnum - 1)
-                       {               /* Here if prev stab wasn't N_SO.  */
-                         if (pst)
-                           {
-                             pst = (legacy_psymtab *) 0;
-                             includes_used = 0;
-                             dependencies_used = 0;
-                           }
-                       }
+         sym_name = debug_info->ss + fh->issBase + sh.iss;
 
-                     prev_so_symnum = symnum;
-
-                     /* End the current partial symtab and start a
-                        new one.  */
-
-                     /* SET_NAMESTRING ();*/
-                     namestring = stabstring;
-
-                     /* Null name means end of .o file.  Don't start a new
-                        one.  */
-                     if (*namestring == '\000')
-                       continue;
-
-                     /* Some compilers (including gcc) emit a pair of
-                        initial N_SOs.  The first one is a directory name;
-                        the second the file name.  If pst exists, is
-                        empty, and has a filename ending in '/', we assume
-                        the previous N_SO was a directory name.  */
-                     basename = lbasename (namestring);
-                     if (basename != namestring && *basename == '\000')
-                       continue;               /* Simply ignore directory
-                                                  name SOs.  */
-
-                     /* Some other compilers (C++ ones in particular) emit
-                        useless SOs for non-existant .c files.  We ignore
-                        all subsequent SOs that immediately follow the
-                        first.  */
-
-                     if (!pst)
-                       pst = save_pst;
-                     continue;
-                   }
+         minsym_value = unrelocated_addr (sh.value);
 
-                 case N_BINCL:
-                   continue;
+         switch (sh.sc)
+           {
+           case scText:
+           case scRConst:
+             /* The value of a stEnd symbol is the displacement from the
+                corresponding start symbol value, do not relocate it.  */
+             if (sh.st != stEnd)
+               section = SECT_OFF_TEXT (objfile);
+             break;
+           case scData:
+           case scSData:
+           case scRData:
+           case scPData:
+           case scXData:
+             section = SECT_OFF_DATA (objfile);
+             break;
+           case scBss:
+           case scSBss:
+             section = SECT_OFF_BSS (objfile);
+             break;
+           }
 
-                 case N_SOL:
-                   {
-                     enum language tmp_language;
-
-                     /* Mark down an include file in the current psymtab.  */
-
-                     /* SET_NAMESTRING (); */
-                     namestring = stabstring;
-
-                     tmp_language
-                       = deduce_language_from_filename (namestring);
-
-                     /* Only change the psymtab's language if we've
-                        learned something useful (eg. tmp_language is not
-                        language_unknown).  In addition, to match what
-                        start_subfile does, never change from C++ to
-                        C.  */
-                     if (tmp_language != language_unknown
-                         && (tmp_language != language_c
-                             || psymtab_language != language_cplus))
-                       psymtab_language = tmp_language;
-
-                     /* 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 && filename_cmp (namestring, pst->filename) == 0)
-                       continue;
+         switch (sh.st)
+           {
+             unrelocated_addr high;
+             unrelocated_addr procaddr;
+             int new_sdx;
 
-                     {
-                       int i;
-
-                       for (i = 0; i < includes_used; i++)
-                         if (filename_cmp (namestring,
-                                           psymtab_include_list[i]) == 0)
-                           {
-                             i = -1;
-                             break;
-                           }
-                       if (i == -1)
-                         continue;
-                     }
+           case stStaticProc:
+             reader.record_with_info (sym_name, minsym_value,
+                                      mst_file_text,
+                                      SECT_OFF_TEXT (objfile));
 
-                     psymtab_include_list[includes_used++] = namestring;
-                     if (includes_used >= includes_allocated)
-                       {
-                         const char **orig = psymtab_include_list;
+             [[fallthrough]];
 
-                         psymtab_include_list = (const char **)
-                           alloca ((includes_allocated *= 2) *
-                                   sizeof (const char *));
-                         memcpy (psymtab_include_list, orig,
-                                 includes_used * sizeof (const char *));
-                       }
-                     continue;
-                   }
-                 case N_LSYM:      /* Typedef or automatic variable.  */
-                 case N_STSYM:     /* Data seg var -- static  */
-                 case N_LCSYM:     /* BSS      "  */
-                 case N_ROSYM:     /* Read-only data seg var -- static.  */
-                 case N_NBSTS:     /* Gould nobase.  */
-                 case N_NBLCS:     /* symbols.  */
-                 case N_FUN:
-                 case N_GSYM:      /* Global (extern) variable; can be
-                                      data or bss (sigh FIXME).  */
-
-                   /* 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 (); */
-                   namestring = stabstring;
-                   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 'S':
-                       pst->add_psymbol (std::string_view (namestring,
-                                                           p - namestring),
-                                         true, VAR_DOMAIN, LOC_STATIC,
-                                         SECT_OFF_DATA (objfile),
-                                         psymbol_placement::STATIC,
-                                         unrelocated_addr (sh.value),
-                                         psymtab_language,
-                                         partial_symtabs, objfile);
-                       continue;
-                     case 'G':
-                       /* The addresses in these entries are reported
-                          to be wrong.  See the code that reads 'G's
-                          for symtabs.  */
-                       pst->add_psymbol (std::string_view (namestring,
-                                                           p - namestring),
-                                         true, VAR_DOMAIN, LOC_STATIC,
-                                         SECT_OFF_DATA (objfile),
-                                         psymbol_placement::GLOBAL,
-                                         unrelocated_addr (sh.value),
-                                         psymtab_language,
-                                         partial_symtabs, objfile);
-                       continue;
-
-                     case 'T':
-                       /* When a 'T' entry is defining an anonymous enum, it
-                          may have a name which is the empty string, or a
-                          single space.  Since they're not really defining a
-                          symbol, those shouldn't go in the partial symbol
-                          table.  We do pick up the elements of such enums at
-                          'check_enum:', below.  */
-                       if (p >= namestring + 2
-                           || (p == namestring + 1
-                               && namestring[0] != ' '))
-                         {
-                           pst->add_psymbol
-                             (std::string_view (namestring, p - namestring),
-                              true, STRUCT_DOMAIN, LOC_TYPEDEF, -1,
-                              psymbol_placement::STATIC,
-                              unrelocated_addr (0),
-                              psymtab_language,
-                              partial_symtabs, objfile);
-                           if (p[2] == 't')
-                             {
-                               /* Also a typedef with the same name.  */
-                               pst->add_psymbol
-                                 (std::string_view (namestring,
-                                                    p - namestring),
-                                  true, VAR_DOMAIN, LOC_TYPEDEF, -1,
-                                  psymbol_placement::STATIC,
-                                  unrelocated_addr (0),
-                                  psymtab_language,
-                                  partial_symtabs, objfile);
-                               p += 1;
-                             }
-                         }
-                       goto check_enum;
-                     case 't':
-                       if (p != namestring)    /* a name is there, not
-                                                  just :T...  */
-                         {
-                           pst->add_psymbol
-                             (std::string_view (namestring,
-                                                p - namestring),
-                              true, VAR_DOMAIN, LOC_TYPEDEF, -1,
-                              psymbol_placement::STATIC,
-                              unrelocated_addr (0),
-                              psymtab_language,
-                              partial_symtabs, objfile);
-                         }
-                     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 the enum in a
-                          nameless type.  GCC2 does this.  */
-
-                       /* 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')
-                         {
-                           /* The aix4 compiler emits extra crud before
-                              the members.  */
-                           if (*p == '-')
-                             {
-                               /* Skip over the type (?).  */
-                               while (*p != ':')
-                                 p++;
-
-                               /* Skip over the colon.  */
-                               p++;
-                             }
-
-                           /* 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 != ',')
-                             {
-                               const char *q;
-
-                               /* Check for and handle cretinous dbx
-                                  symbol name continuation!  */
-                               if (*p == '\\' || (*p == '?' && p[1] == '\0'))
-                                 p = next_symbol_text (objfile);
-
-                               /* 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.  */
-                               pst->add_psymbol (std::string_view (p,
-                                                                   q - p),
-                                                 true, VAR_DOMAIN,
-                                                 LOC_CONST, -1,
-                                                 psymbol_placement::STATIC,
-                                                 unrelocated_addr (0),
-                                                 psymtab_language,
-                                                 partial_symtabs, objfile);
-                               /* 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.  */
-                       pst->add_psymbol (std::string_view (namestring,
-                                                           p - namestring),
-                                         true, VAR_DOMAIN, LOC_CONST, -1,
-                                         psymbol_placement::STATIC,
-                                         unrelocated_addr (0),
-                                         psymtab_language,
-                                         partial_symtabs, objfile);
-                       continue;
-
-                     case 'f':
-                       if (! pst)
-                         {
-                           std::string copy (namestring, p);
-                           function_outside_compilation_unit_complaint
-                             (copy.c_str ());
-                         }
-                       pst->add_psymbol (std::string_view (namestring,
-                                                           p - namestring),
-                                         true, VAR_DOMAIN, LOC_BLOCK,
-                                         SECT_OFF_TEXT (objfile),
-                                         psymbol_placement::STATIC,
-                                         unrelocated_addr (sh.value),
-                                         psymtab_language,
-                                         partial_symtabs, objfile);
-                       continue;
-
-                       /* Global functions were ignored here, but now they
-                          are put into the global psymtab like one would
-                          expect.  They're also in the minimal symbol
-                          table.  */
-                     case 'F':
-                       if (! pst)
-                         {
-                           std::string copy (namestring, p);
-                           function_outside_compilation_unit_complaint
-                             (copy.c_str ());
-                         }
-                       pst->add_psymbol (std::string_view (namestring,
-                                                           p - namestring),
-                                         true, VAR_DOMAIN, LOC_BLOCK,
-                                         SECT_OFF_TEXT (objfile),
-                                         psymbol_placement::GLOBAL,
-                                         unrelocated_addr (sh.value),
-                                         psymtab_language,
-                                         partial_symtabs, objfile);
-                       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':
-                     case '-':
-                     case '#':         /* For symbol identification (used
-                                          in live ranges).  */
-                       continue;
-
-                     case ':':
-                       /* It is a C++ nested symbol.  We don't need to
-                          record it (I don't think); if we try to look up
-                          foo::bar::baz, then symbols for the symtab
-                          containing foo should get read in, I think.  */
-                       /* 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;
-
-                     default:
-                       /* Unexpected symbol descriptor.  The second and
-                          subsequent stabs of a continued stab can show up
-                          here.  The question is whether they ever can
-                          mimic a normal stab--it would be nice if not,
-                          since we certainly don't want to spend the time
-                          searching to the end of every string looking for
-                          a backslash.  */
-
-                       complaint (_("unknown symbol descriptor `%c'"), p[1]);
-
-                       /* Ignore it; perhaps it is an extension that we don't
-                          know about.  */
-                       continue;
-                     }
+           case stProc:
+             /* Ignore all parameter symbol records.  */
+             if (sh.index >= hdr->iauxMax)
+               {
+                 /* Should not happen, but does when cross-compiling
+                    with the MIPS compiler.  FIXME -- pull later.  */
+                 index_complaint (sym_name);
+                 new_sdx = cur_sdx + 1;        /* Don't skip at all.  */
+               }
+             else
+               new_sdx = AUX_GET_ISYM (fh->fBigendian,
+                                       (debug_info->external_aux
+                                        + fh->iauxBase
+                                        + sh.index));
 
-                 case N_EXCL:
-                   continue;
-
-                 case N_ENDM:
-                   /* Solaris 2 end of module, finish current partial
-                      symbol table.  stabs_end_psymtab will set the
-                      high text address of PST to the proper value,
-                      which is necessary if a module compiled without
-                      debugging info follows this module.  */
-                   if (pst
-                       && gdbarch_sofun_address_maybe_missing (gdbarch))
-                     {
-                       pst = (legacy_psymtab *) 0;
-                       includes_used = 0;
-                       dependencies_used = 0;
-                     }
-                   continue;
+             if (new_sdx <= cur_sdx)
+               {
+                 /* This should not happen either... FIXME.  */
+                 complaint (_("bad proc end in aux found from symbol %s"),
+                            sym_name);
+                 new_sdx = cur_sdx + 1;        /* Don't skip backward.  */
+               }
 
-                 case N_RBRAC:
-                   {
-                     unrelocated_addr unrel_value
-                       = unrelocated_addr (sh.value);
-                     if (unrel_value > save_pst->unrelocated_text_high ())
-                       save_pst->set_text_high (unrel_value);
-                   }
-                   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_NSYMS:         /* Ultrix 4.0: symbol count */
-                 case N_DEFD:                  /* GNU Modula-2 */
-                 case N_ALIAS:         /* SunPro F77: alias name, ignore
-                                          for now.  */
-
-                 case N_OBJ:           /* Useless types from Solaris.  */
-                 case N_OPT:
-                   /* These symbols aren't interesting; don't worry about
-                      them.  */
-
-                   continue;
+             /* For stProc symbol records, we need to check the
+                storage class as well, as only (stProc, scText)
+                entries represent "real" procedures - See the
+                Compaq document titled "Object File / Symbol Table
+                Format Specification" for more information.  If the
+                storage class is not scText, we discard the whole
+                block of symbol records for this stProc.  */
+             if (sh.st == stProc && sh.sc != scText)
+               goto skip;
+
+             /* Usually there is a local and a global stProc symbol
+                for a function.  This means that the function name
+                has already been entered into the minimal symbol table
+                while processing the global symbols in pass 2 above.
+                One notable exception is the PROGRAM name from
+                f77 compiled executables, it is only put out as
+                local stProc symbol, and a global MAIN__ stProc symbol
+                points to it.  It doesn't matter though, as gdb is
+                still able to find the PROGRAM name via the partial
+                symbol table, and the MAIN__ symbol via the minimal
+                symbol table.  */
+             if (sh.st == stProc)
+               pst->add_psymbol (sym_name, true,
+                                 VAR_DOMAIN, LOC_BLOCK,
+                                 section,
+                                 psymbol_placement::GLOBAL,
+                                 unrelocated_addr (sh.value),
+                                 psymtab_language,
+                                 partial_symtabs, objfile);
+             else
+               pst->add_psymbol (sym_name, true,
+                                 VAR_DOMAIN, LOC_BLOCK,
+                                 section,
+                                 psymbol_placement::STATIC,
+                                 unrelocated_addr (sh.value),
+                                 psymtab_language,
+                                 partial_symtabs, objfile);
 
-                 default:
-                   /* If we haven't found it yet, ignore it.  It's
-                      probably some new type we don't know about yet.  */
-                   complaint (_("unknown symbol type %s"),
-                              hex_string (type_code)); /* CUR_SYMBOL_TYPE */
-                   continue;
-                 }
-             }
-             /* end - Handle continuation */
-           }
-       }
-      else
-       {
-         for (cur_sdx = 0; cur_sdx < fh->csym;)
-           {
-             char *sym_name;
-             enum address_class theclass;
-             unrelocated_addr minsym_value;
-             int section = -1;
+             procaddr = unrelocated_addr (sh.value);
 
+             cur_sdx = new_sdx;
              (*swap_sym_in) (cur_bfd,
                              ((char *) debug_info->external_sym
-                              + ((fh->isymBase + cur_sdx)
+                              + ((fh->isymBase + cur_sdx - 1)
                                  * external_sym_size)),
                              &sh);
+             if (sh.st != stEnd)
+               continue;
 
-             if (ECOFF_IS_STAB (&sh))
-               {
-                 cur_sdx++;
-                 continue;
-               }
+             /* Kludge for Irix 5.2 zero fh->adr.  */
+             if (!relocatable
+                 && (!pst->text_low_valid
+                     || procaddr < pst->unrelocated_text_low ()))
+               pst->set_text_low (procaddr);
 
-             /* Non absolute static symbols go into the minimal table.  */
-             if (SC_IS_UNDEF (sh.sc) || sh.sc == scNil
-                 || (sh.index == indexNil
-                     && (sh.st != stStatic || sh.sc == scAbs)))
-               {
-                 /* FIXME, premature?  */
-                 cur_sdx++;
-                 continue;
-               }
+             high = unrelocated_addr (CORE_ADDR (procaddr) + sh.value);
+             if (high > pst->unrelocated_text_high ())
+               pst->set_text_high (high);
+             continue;
 
-             sym_name = debug_info->ss + fh->issBase + sh.iss;
+           case stStatic:      /* Variable */
+             if (SC_IS_DATA (sh.sc))
+               reader.record_with_info (sym_name, minsym_value,
+                                        mst_file_data,
+                                        SECT_OFF_DATA (objfile));
+             else
+               reader.record_with_info (sym_name, minsym_value,
+                                        mst_file_bss,
+                                        SECT_OFF_BSS (objfile));
+             theclass = LOC_STATIC;
+             break;
+
+           case stIndirect:    /* Irix5 forward declaration */
+             /* Skip forward declarations from Irix5 cc.  */
+             goto skip;
+
+           case stTypedef:     /* Typedef */
+             /* Skip typedefs for forward declarations and opaque
+                structs from alpha and mips cc.  */
+             if (sh.iss == 0 || has_opaque_xref (fh, &sh))
+               goto skip;
+             theclass = LOC_TYPEDEF;
+             break;
 
-             minsym_value = unrelocated_addr (sh.value);
+           case stConstant:    /* Constant decl */
+             theclass = LOC_CONST;
+             break;
 
-             switch (sh.sc)
+           case stUnion:
+           case stStruct:
+           case stEnum:
+           case stBlock:       /* { }, str, un, enum */
+             /* Do not create a partial symbol for cc unnamed aggregates
+                and gcc empty aggregates.  */
+             if ((sh.sc == scInfo
+                  || SC_IS_COMMON (sh.sc))
+                 && sh.iss != 0
+                 && sh.index != cur_sdx + 2)
                {
-               case scText:
-               case scRConst:
-                 /* The value of a stEnd symbol is the displacement from the
-                    corresponding start symbol value, do not relocate it.  */
-                 if (sh.st != stEnd)
-                   section = SECT_OFF_TEXT (objfile);
-                 break;
-               case scData:
-               case scSData:
-               case scRData:
-               case scPData:
-               case scXData:
-                 section = SECT_OFF_DATA (objfile);
-                 break;
-               case scBss:
-               case scSBss:
-                 section = SECT_OFF_BSS (objfile);
-                 break;
+                 pst->add_psymbol (sym_name, true,
+                                   STRUCT_DOMAIN, LOC_TYPEDEF, -1,
+                                   psymbol_placement::STATIC,
+                                   unrelocated_addr (0),
+                                   psymtab_language,
+                                   partial_symtabs, objfile);
                }
+             handle_psymbol_enumerators (objfile, partial_symtabs,
+                                         pst, fh, sh.st, sh.value);
 
-             switch (sh.st)
+             /* Skip over the block.  */
+             new_sdx = sh.index;
+             if (new_sdx <= cur_sdx)
                {
-                 unrelocated_addr high;
-                 unrelocated_addr procaddr;
-                 int new_sdx;
-
-               case stStaticProc:
-                 reader.record_with_info (sym_name, minsym_value,
-                                          mst_file_text,
-                                          SECT_OFF_TEXT (objfile));
+                 /* This happens with the Ultrix kernel.  */
+                 complaint (_("bad aux index at block symbol %s"),
+                            sym_name);
+                 new_sdx = cur_sdx + 1;        /* Don't skip backward.  */
+               }
+             cur_sdx = new_sdx;
+             continue;
 
-                 [[fallthrough]];
+           case stFile:        /* File headers */
+           case stLabel:       /* Labels */
+           case stEnd: /* Ends of files */
+             goto skip;
 
-               case stProc:
-                 /* Ignore all parameter symbol records.  */
-                 if (sh.index >= hdr->iauxMax)
-                   {
-                     /* Should not happen, but does when cross-compiling
-                        with the MIPS compiler.  FIXME -- pull later.  */
-                     index_complaint (sym_name);
-                     new_sdx = cur_sdx + 1;    /* Don't skip at all.  */
-                   }
-                 else
-                   new_sdx = AUX_GET_ISYM (fh->fBigendian,
-                                           (debug_info->external_aux
-                                            + fh->iauxBase
-                                            + sh.index));
+           case stLocal:       /* Local variables */
+             /* Normally these are skipped because we skip over
+                all blocks we see.  However, these can occur
+                as visible symbols in a .h file that contains code.  */
+             goto skip;
 
-                 if (new_sdx <= cur_sdx)
-                   {
-                     /* This should not happen either... FIXME.  */
-                     complaint (_("bad proc end in aux found from symbol %s"),
-                                sym_name);
-                     new_sdx = cur_sdx + 1;    /* Don't skip backward.  */
-                   }
-
-                 /* For stProc symbol records, we need to check the
-                    storage class as well, as only (stProc, scText)
-                    entries represent "real" procedures - See the
-                    Compaq document titled "Object File / Symbol Table
-                    Format Specification" for more information.  If the
-                    storage class is not scText, we discard the whole
-                    block of symbol records for this stProc.  */
-                 if (sh.st == stProc && sh.sc != scText)
-                   goto skip;
-
-                 /* Usually there is a local and a global stProc symbol
-                    for a function.  This means that the function name
-                    has already been entered into the minimal symbol table
-                    while processing the global symbols in pass 2 above.
-                    One notable exception is the PROGRAM name from
-                    f77 compiled executables, it is only put out as
-                    local stProc symbol, and a global MAIN__ stProc symbol
-                    points to it.  It doesn't matter though, as gdb is
-                    still able to find the PROGRAM name via the partial
-                    symbol table, and the MAIN__ symbol via the minimal
-                    symbol table.  */
-                 if (sh.st == stProc)
-                   pst->add_psymbol (sym_name, true,
-                                     VAR_DOMAIN, LOC_BLOCK,
-                                     section,
-                                     psymbol_placement::GLOBAL,
-                                     unrelocated_addr (sh.value),
-                                     psymtab_language,
-                                     partial_symtabs, objfile);
-                 else
-                   pst->add_psymbol (sym_name, true,
-                                     VAR_DOMAIN, LOC_BLOCK,
-                                     section,
-                                     psymbol_placement::STATIC,
-                                     unrelocated_addr (sh.value),
-                                     psymtab_language,
-                                     partial_symtabs, objfile);
-
-                 procaddr = unrelocated_addr (sh.value);
-
-                 cur_sdx = new_sdx;
-                 (*swap_sym_in) (cur_bfd,
-                                 ((char *) debug_info->external_sym
-                                  + ((fh->isymBase + cur_sdx - 1)
-                                     * external_sym_size)),
-                                 &sh);
-                 if (sh.st != stEnd)
-                   continue;
-
-                 /* Kludge for Irix 5.2 zero fh->adr.  */
-                 if (!relocatable
-                     && (!pst->text_low_valid
-                         || procaddr < pst->unrelocated_text_low ()))
-                   pst->set_text_low (procaddr);
-
-                 high = unrelocated_addr (CORE_ADDR (procaddr) + sh.value);
-                 if (high > pst->unrelocated_text_high ())
-                   pst->set_text_high (high);
-                 continue;
-
-               case stStatic:  /* Variable */
-                 if (SC_IS_DATA (sh.sc))
-                   reader.record_with_info (sym_name, minsym_value,
-                                            mst_file_data,
-                                            SECT_OFF_DATA (objfile));
-                 else
-                   reader.record_with_info (sym_name, minsym_value,
-                                            mst_file_bss,
-                                            SECT_OFF_BSS (objfile));
-                 theclass = LOC_STATIC;
-                 break;
+           default:
+             /* Both complaints are valid:  one gives symbol sym_name,
+                the other the offending symbol type.  */
+             complaint (_("unknown local symbol %s"),
+                        sym_name);
+             complaint (_("with type %d"), sh.st);
+             cur_sdx++;
+             continue;
+           }
+         /* Use this gdb symbol.  */
+         pst->add_psymbol (sym_name, true,
+                           VAR_DOMAIN, theclass, section,
+                           psymbol_placement::STATIC,
+                           unrelocated_addr (sh.value),
+                           psymtab_language,
+                           partial_symtabs, objfile);
+       skip:
+         cur_sdx++;    /* Go to next file symbol.  */
+       }
 
-               case stIndirect:        /* Irix5 forward declaration */
-                 /* Skip forward declarations from Irix5 cc.  */
-                 goto skip;
+      /* Now do enter the external symbols.  */
+      ext_ptr = &extern_tab[fdr_to_pst[f_idx].globals_offset];
+      cur_sdx = fdr_to_pst[f_idx].n_globals;
+      PST_PRIVATE (save_pst)->extern_count = cur_sdx;
+      PST_PRIVATE (save_pst)->extern_tab = ext_ptr;
+      for (; --cur_sdx >= 0; ext_ptr++)
+       {
+         enum address_class theclass;
+         SYMR *psh;
+         CORE_ADDR svalue;
+         int section;
 
-               case stTypedef: /* Typedef */
-                 /* Skip typedefs for forward declarations and opaque
-                    structs from alpha and mips cc.  */
-                 if (sh.iss == 0 || has_opaque_xref (fh, &sh))
-                   goto skip;
-                 theclass = LOC_TYPEDEF;
-                 break;
+         gdb_assert (ext_ptr->ifd == f_idx);
 
-               case stConstant:        /* Constant decl */
-                 theclass = LOC_CONST;
-                 break;
+         psh = &ext_ptr->asym;
 
-               case stUnion:
-               case stStruct:
-               case stEnum:
-               case stBlock:   /* { }, str, un, enum */
-                 /* Do not create a partial symbol for cc unnamed aggregates
-                    and gcc empty aggregates.  */
-                 if ((sh.sc == scInfo
-                      || SC_IS_COMMON (sh.sc))
-                     && sh.iss != 0
-                     && sh.index != cur_sdx + 2)
-                   {
-                     pst->add_psymbol (sym_name, true,
-                                       STRUCT_DOMAIN, LOC_TYPEDEF, -1,
-                                       psymbol_placement::STATIC,
-                                       unrelocated_addr (0),
-                                       psymtab_language,
-                                       partial_symtabs, objfile);
-                   }
-                 handle_psymbol_enumerators (objfile, partial_symtabs,
-                                             pst, fh, sh.st, sh.value);
+         /* Do not add undefined symbols to the partial symbol table.  */
+         if (SC_IS_UNDEF (psh->sc) || psh->sc == scNil)
+           continue;
 
-                 /* Skip over the block.  */
-                 new_sdx = sh.index;
-                 if (new_sdx <= cur_sdx)
-                   {
-                     /* This happens with the Ultrix kernel.  */
-                     complaint (_("bad aux index at block symbol %s"),
-                                sym_name);
-                     new_sdx = cur_sdx + 1;    /* Don't skip backward.  */
-                   }
-                 cur_sdx = new_sdx;
-                 continue;
-
-               case stFile:    /* File headers */
-               case stLabel:   /* Labels */
-               case stEnd:     /* Ends of files */
-                 goto skip;
-
-               case stLocal:   /* Local variables */
-                 /* Normally these are skipped because we skip over
-                    all blocks we see.  However, these can occur
-                    as visible symbols in a .h file that contains code.  */
-                 goto skip;
-
-               default:
-                 /* Both complaints are valid:  one gives symbol sym_name,
-                    the other the offending symbol type.  */
-                 complaint (_("unknown local symbol %s"),
-                            sym_name);
-                 complaint (_("with type %d"), sh.st);
-                 cur_sdx++;
-                 continue;
-               }
-             /* Use this gdb symbol.  */
-             pst->add_psymbol (sym_name, true,
-                               VAR_DOMAIN, theclass, section,
-                               psymbol_placement::STATIC,
-                               unrelocated_addr (sh.value),
-                               psymtab_language,
-                               partial_symtabs, objfile);
-           skip:
-             cur_sdx++;        /* Go to next file symbol.  */
+         svalue = psh->value;
+         switch (psh->sc)
+           {
+           default:
+           case scText:
+           case scRConst:
+             section = SECT_OFF_TEXT (objfile);
+             break;
+           case scData:
+           case scSData:
+           case scRData:
+           case scPData:
+           case scXData:
+             section = SECT_OFF_DATA (objfile);
+             break;
+           case scBss:
+           case scSBss:
+             section = SECT_OFF_BSS (objfile);
+             break;
            }
 
-         /* Now do enter the external symbols.  */
-         ext_ptr = &extern_tab[fdr_to_pst[f_idx].globals_offset];
-         cur_sdx = fdr_to_pst[f_idx].n_globals;
-         PST_PRIVATE (save_pst)->extern_count = cur_sdx;
-         PST_PRIVATE (save_pst)->extern_tab = ext_ptr;
-         for (; --cur_sdx >= 0; ext_ptr++)
+         switch (psh->st)
            {
-             enum address_class theclass;
-             SYMR *psh;
-             CORE_ADDR svalue;
-             int section;
-
-             gdb_assert (ext_ptr->ifd == f_idx);
-
-             psh = &ext_ptr->asym;
-
-             /* Do not add undefined symbols to the partial symbol table.  */
-             if (SC_IS_UNDEF (psh->sc) || psh->sc == scNil)
+           case stNil:
+             /* These are generated for static symbols in .o files,
+                ignore them.  */
+             continue;
+           case stProc:
+           case stStaticProc:
+             /* External procedure symbols have been entered
+                into the minimal symbol table in pass 2 above.
+                Ignore them, as parse_external will ignore them too.  */
+             continue;
+           case stLabel:
+             theclass = LOC_LABEL;
+             break;
+           default:
+             unknown_ext_complaint (debug_info->ssext + psh->iss);
+             /* Pretend it's global.  */
+             [[fallthrough]];
+           case stGlobal:
+             /* Global common symbols are resolved by the runtime loader,
+                ignore them.  */
+             if (SC_IS_COMMON (psh->sc))
                continue;
 
-             svalue = psh->value;
-             switch (psh->sc)
-               {
-               default:
-               case scText:
-               case scRConst:
-                 section = SECT_OFF_TEXT (objfile);
-                 break;
-               case scData:
-               case scSData:
-               case scRData:
-               case scPData:
-               case scXData:
-                 section = SECT_OFF_DATA (objfile);
-                 break;
-               case scBss:
-               case scSBss:
-                 section = SECT_OFF_BSS (objfile);
-                 break;
-               }
-
-             switch (psh->st)
-               {
-               case stNil:
-                 /* These are generated for static symbols in .o files,
-                    ignore them.  */
-                 continue;
-               case stProc:
-               case stStaticProc:
-                 /* External procedure symbols have been entered
-                    into the minimal symbol table in pass 2 above.
-                    Ignore them, as parse_external will ignore them too.  */
-                 continue;
-               case stLabel:
-                 theclass = LOC_LABEL;
-                 break;
-               default:
-                 unknown_ext_complaint (debug_info->ssext + psh->iss);
-                 /* Pretend it's global.  */
-                 [[fallthrough]];
-               case stGlobal:
-                 /* Global common symbols are resolved by the runtime loader,
-                    ignore them.  */
-                 if (SC_IS_COMMON (psh->sc))
-                   continue;
-
-                 theclass = LOC_STATIC;
-                 break;
-               }
-             char *sym_name = debug_info->ssext + psh->iss;
-             pst->add_psymbol (sym_name, true,
-                               VAR_DOMAIN, theclass,
-                               section,
-                               psymbol_placement::GLOBAL,
-                               unrelocated_addr (svalue),
-                               psymtab_language,
-                               partial_symtabs, objfile);
+             theclass = LOC_STATIC;
+             break;
            }
+         char *sym_name = debug_info->ssext + psh->iss;
+         pst->add_psymbol (sym_name, true,
+                           VAR_DOMAIN, theclass,
+                           section,
+                           psymbol_placement::GLOBAL,
+                           unrelocated_addr (svalue),
+                           psymtab_language,
+                           partial_symtabs, objfile);
        }
 
-      /* Link pst to FDR.  stabs_end_psymtab returns NULL if the psymtab was
-        empty and put on the free list.  */
-      fdr_to_pst[f_idx].pst
-       = stabs_end_psymtab (objfile, partial_symtabs, save_pst,
-                            psymtab_include_list, includes_used,
-                            -1, save_pst->unrelocated_text_high (),
-                            dependency_list, dependencies_used,
-                            textlow_not_set);
-      includes_used = 0;
-      dependencies_used = 0;
+      /* Link pst to FDR.  Link NULL if the psymtab was empty and put on
+        the free list.  */
+      if (save_pst->empty ())
+       {
+         partial_symtabs->discard_psymtab (save_pst);
+         save_pst = nullptr;
+       }
+      else
+       {
+         save_pst->end ();
+         save_pst->number_of_dependencies = 0;
+         save_pst->dependencies = nullptr;
+       }
+      fdr_to_pst[f_idx].pst = save_pst;
     }
 
   /* Now scan the FDRs for dependencies.  */
@@ -3822,22 +3183,6 @@ handle_psymbol_enumerators (struct objfile *objfile,
     }
 }
 
-/* Get the next symbol.  OBJFILE is unused.  */
-
-static const char *
-mdebug_next_symbol_text (struct objfile *objfile)
-{
-  SYMR sh;
-
-  cur_sdx++;
-  (*debug_swap->swap_sym_in) (cur_bfd,
-                             ((char *) debug_info->external_sym
-                              + ((cur_fdr->isymBase + cur_sdx)
-                                 * debug_swap->external_sym_size)),
-                             &sh);
-  return debug_info->ss + cur_fdr->issBase + sh.iss;
-}
-
 /* Ancillary function to psymtab_to_symtab().  Does all the work
    for turning the partial symtab PST into a symtab, recurring
    first on all dependent psymtabs.  The argument FILENAME is
@@ -3860,7 +3205,6 @@ mdebug_expand_psymtab (legacy_psymtab *pst, struct objfile *objfile)
   FDR *fh;
   struct linetable *lines;
   CORE_ADDR lowest_pdr_addr = 0;
-  int last_symtab_ended = 0;
   const section_offsets &section_offsets = objfile->section_offsets;
 
   if (pst->readin)
@@ -3895,7 +3239,6 @@ mdebug_expand_psymtab (legacy_psymtab *pst, struct objfile *objfile)
   cur_fdr = fh;
 
   /* See comment in parse_partial_symbols about the @stabs sentinel.  */
-  processing_gcc_compilation = 0;
   if (fh != NULL && fh->csym >= 2)
     {
       SYMR sh;
@@ -3907,132 +3250,77 @@ mdebug_expand_psymtab (legacy_psymtab *pst, struct objfile *objfile)
       if (strcmp (debug_info->ss + fh->issBase + sh.iss,
                  stabs_symbol) == 0)
        {
-         /* We indicate that this is a GCC compilation so that certain
-            features will be enabled in stabsread/dbxread.  */
-         processing_gcc_compilation = 2;
+         /* This file contains stabs debuginfo, so we can't read it.  */
+         error ("GDB no longer supports stabs debug information.");
        }
     }
 
-  if (processing_gcc_compilation != 0)
+  /* This symbol table contains ordinary ecoff entries.  */
+
+  int maxlines, size;
+  EXTR *ext_ptr;
+
+  if (fh == 0)
+    {
+      maxlines = 0;
+      cust = new_symtab ("unknown", 0, objfile);
+    }
+  else
     {
-      struct gdbarch *gdbarch = objfile->arch ();
+      maxlines = 2 * fh->cline;
+      cust = new_symtab (pst->filename, maxlines, objfile);
 
-      /* This symbol table contains stabs-in-ecoff entries.  */
+      /* The proper language was already determined when building
+        the psymtab, use it.  */
+      cust->primary_filetab ()->set_language
+       (PST_PRIVATE (pst)->pst_language);
+    }
 
-      /* Parse local symbols first.  */
+  psymtab_language = cust->primary_filetab ()->language ();
 
-      if (fh->csym <= 2)       /* FIXME, this blows psymtab->symtab ptr.  */
-       {
-         mdebugread_objfile = NULL;
-         return;
-       }
-      for (cur_sdx = 2; cur_sdx < fh->csym; cur_sdx++)
-       {
-         SYMR sh;
-         char *name;
-         CORE_ADDR valu;
+  /* This code allocates the line table on the heap and then later
+     copies it to the obstack.  So, while casting away const here
+     is ugly, it's not incorrect.  */
+  lines = const_cast<linetable *> (cust->primary_filetab ()->linetable ());
 
-         (*swap_sym_in) (cur_bfd,
-                         (((char *) debug_info->external_sym)
-                          + (fh->isymBase + cur_sdx) * external_sym_size),
-                         &sh);
-         name = debug_info->ss + fh->issBase + sh.iss;
-         valu = sh.value;
-         /* XXX This is a hack.  It will go away!  */
-         if (ECOFF_IS_STAB (&sh) || (name[0] == '#'))
-           {
-             int type_code = ECOFF_UNMARK_STAB (sh.index);
-             enum language language = PST_PRIVATE (pst)->pst_language;
+  /* Get a new lexical context.  */
 
-             /* We should never get non N_STAB symbols here, but they
-                should be harmless, so keep process_one_symbol from
-                complaining about them.  */
-             if (type_code & N_STAB)
-               {
-                 /* If we found a trailing N_SO with no name, process
-                    it here instead of in process_one_symbol, so we
-                    can keep a handle to its symtab.  The symtab
-                    would otherwise be ended twice, once in
-                    process_one_symbol, and once after this loop.  */
-                 if (type_code == N_SO
-                     && get_last_source_file ()
-                     && previous_stab_code != (unsigned char) N_SO
-                     && *name == '\000')
-                   {
-                     valu += section_offsets[SECT_OFF_TEXT (objfile)];
-                     previous_stab_code = N_SO;
-                     cust = end_compunit_symtab (valu);
-                     end_stabs ();
-                     last_symtab_ended = 1;
-                   }
-                 else
-                   {
-                     last_symtab_ended = 0;
-                     process_one_symbol (type_code, 0, valu, name,
-                                         section_offsets, objfile, language);
-                   }
-               }
-             /* Similarly a hack.  */
-             else if (name[0] == '#')
-               {
-                 process_one_symbol (N_SLINE, 0, valu, name,
-                                     section_offsets, objfile, language);
-               }
-             if (type_code == N_FUN)
-               {
-                 /* Make up special symbol to contain
-                    procedure specific info.  */
-                 mdebug_extra_func_info *e
-                   = OBSTACK_ZALLOC (&mdebugread_objfile->objfile_obstack,
-                                     mdebug_extra_func_info);
-                 struct symbol *s = new_symbol (MDEBUG_EFI_SYMBOL_NAME);
-
-                 s->set_domain (LABEL_DOMAIN);
-                 s->set_aclass_index (LOC_CONST);
-                 s->set_type (builtin_type (objfile)->builtin_void);
-                 s->set_value_bytes ((gdb_byte *) e);
-                 e->pdr.framereg = -1;
-                 add_symbol_to_list (s, get_local_symbols ());
-               }
-           }
-         else if (sh.st == stLabel)
-           {
-             if (sh.index == indexNil)
-               {
-                 /* This is what the gcc2_compiled and __gnu_compiled_*
-                    show up as.  So don't complain.  */
-                 ;
-               }
-             else
-               {
-                 /* Handle encoded stab line number.  */
-                 record_line
-                   (get_current_subfile (), sh.index,
-                    unrelocated_addr (gdbarch_addr_bits_remove (gdbarch,
-                                                                valu)));
-               }
-           }
-         else if (sh.st == stProc || sh.st == stStaticProc
-                  || sh.st == stStatic || sh.st == stEnd)
-           /* These are generated by gcc-2.x, do not complain.  */
-           ;
-         else
-           complaint (_("unknown stabs symbol %s"), name);
-       }
+  push_parse_stack ();
+  top_stack->cur_st = cust->primary_filetab ();
+  top_stack->cur_block = cust->blockvector ()->static_block ();
+  top_stack->cur_block->set_start (pst->text_low (objfile));
+  top_stack->cur_block->set_end (0);
+  top_stack->blocktype = stFile;
+  top_stack->cur_type = 0;
+  top_stack->procadr = 0;
+  top_stack->numargs = 0;
+  found_ecoff_debugging_info = 0;
 
-      if (! last_symtab_ended)
+  if (fh)
+    {
+      char *sym_ptr;
+      char *sym_end;
+
+      /* Parse local symbols first.  */
+      sym_ptr = ((char *) debug_info->external_sym
+                + fh->isymBase * external_sym_size);
+      sym_end = sym_ptr + fh->csym * external_sym_size;
+      while (sym_ptr < sym_end)
        {
-         cust = end_compunit_symtab (pst->text_high (objfile));
-         end_stabs ();
+         SYMR sh;
+         int c;
+
+         (*swap_sym_in) (cur_bfd, sym_ptr, &sh);
+         c = parse_symbol (&sh,
+                           debug_info->external_aux + fh->iauxBase,
+                           sym_ptr, fh->fBigendian,
+                           section_offsets, objfile);
+         sym_ptr += c * external_sym_size;
        }
 
-      /* There used to be a call to sort_blocks here, but this should not
-        be necessary for stabs symtabs.  And as sort_blocks modifies the
-        start address of the GLOBAL_BLOCK to the FIRST_LOCAL_BLOCK,
-        it did the wrong thing if the first procedure in a file was
-        generated via asm statements.  */
-
-      /* Fill in procedure info next.  */
+      /* Linenumbers.  At the end, check if we can save memory.
+        parse_lines has to look ahead an arbitrary number of PDR
+        structures, so we swap them all first.  */
       if (fh->cpd > 0)
        {
          char *pdr_ptr;
@@ -4060,162 +3348,60 @@ mdebug_expand_psymtab (legacy_psymtab *pst, struct objfile *objfile)
                lowest_pdr_addr = pdr_in->adr;
            }
 
+         parse_lines (fh, pr_block.data (), lines, maxlines,
+                      lowest_pdr_addr);
+         if (lines->nitems < fh->cline)
+           lines = shrink_linetable (lines);
+
+         /* Fill in procedure info next.  */
          pdr_in = pr_block.data ();
          pdr_in_end = pdr_in + fh->cpd;
          for (; pdr_in < pdr_in_end; pdr_in++)
-           parse_procedure (pdr_in, cust, pst);
+           parse_procedure (pdr_in, NULL, pst);
        }
     }
-  else
-    {
-      /* This symbol table contains ordinary ecoff entries.  */
 
-      int maxlines, size;
-      EXTR *ext_ptr;
-
-      if (fh == 0)
-       {
-         maxlines = 0;
-         cust = new_symtab ("unknown", 0, objfile);
-       }
-      else
-       {
-         maxlines = 2 * fh->cline;
-         cust = new_symtab (pst->filename, maxlines, objfile);
-
-         /* The proper language was already determined when building
-            the psymtab, use it.  */
-         cust->primary_filetab ()->set_language
-           (PST_PRIVATE (pst)->pst_language);
-       }
-
-      psymtab_language = cust->primary_filetab ()->language ();
-
-      /* This code allocates the line table on the heap and then later
-        copies it to the obstack.  So, while casting away const here
-        is ugly, it's not incorrect.  */
-      lines = const_cast<linetable *> (cust->primary_filetab ()->linetable ());
-
-      /* Get a new lexical context.  */
-
-      push_parse_stack ();
-      top_stack->cur_st = cust->primary_filetab ();
-      top_stack->cur_block = cust->blockvector ()->static_block ();
-      top_stack->cur_block->set_start (pst->text_low (objfile));
-      top_stack->cur_block->set_end (0);
-      top_stack->blocktype = stFile;
-      top_stack->cur_type = 0;
-      top_stack->procadr = 0;
-      top_stack->numargs = 0;
-      found_ecoff_debugging_info = 0;
-
-      if (fh)
-       {
-         char *sym_ptr;
-         char *sym_end;
-
-         /* Parse local symbols first.  */
-         sym_ptr = ((char *) debug_info->external_sym
-                    + fh->isymBase * external_sym_size);
-         sym_end = sym_ptr + fh->csym * external_sym_size;
-         while (sym_ptr < sym_end)
-           {
-             SYMR sh;
-             int c;
-
-             (*swap_sym_in) (cur_bfd, sym_ptr, &sh);
-             c = parse_symbol (&sh,
-                               debug_info->external_aux + fh->iauxBase,
-                               sym_ptr, fh->fBigendian,
-                               section_offsets, objfile);
-             sym_ptr += c * external_sym_size;
-           }
-
-         /* Linenumbers.  At the end, check if we can save memory.
-            parse_lines has to look ahead an arbitrary number of PDR
-            structures, so we swap them all first.  */
-         if (fh->cpd > 0)
-           {
-             char *pdr_ptr;
-             char *pdr_end;
-             PDR *pdr_in;
-             PDR *pdr_in_end;
-
-             gdb::def_vector<PDR> pr_block (fh->cpd);
-
-             pdr_ptr = ((char *) debug_info->external_pdr
-                        + fh->ipdFirst * external_pdr_size);
-             pdr_end = pdr_ptr + fh->cpd * external_pdr_size;
-             pdr_in = pr_block.data ();
-             for (;
-                  pdr_ptr < pdr_end;
-                  pdr_ptr += external_pdr_size, pdr_in++)
-               {
-                 (*swap_pdr_in) (cur_bfd, pdr_ptr, pdr_in);
-
-                 /* Determine lowest PDR address, the PDRs are not always
-                    sorted.  */
-                 if (pdr_in == pr_block.data ())
-                   lowest_pdr_addr = pdr_in->adr;
-                 else if (pdr_in->adr < lowest_pdr_addr)
-                   lowest_pdr_addr = pdr_in->adr;
-               }
-
-             parse_lines (fh, pr_block.data (), lines, maxlines,
-                          lowest_pdr_addr);
-             if (lines->nitems < fh->cline)
-               lines = shrink_linetable (lines);
-
-             /* Fill in procedure info next.  */
-             pdr_in = pr_block.data ();
-             pdr_in_end = pdr_in + fh->cpd;
-             for (; pdr_in < pdr_in_end; pdr_in++)
-               parse_procedure (pdr_in, NULL, pst);
-           }
-       }
-
-      size = lines->nitems;
-      if (size > 1)
-       --size;
-      cust->primary_filetab ()->set_linetable
-       ((struct linetable *)
-        obstack_copy (&mdebugread_objfile->objfile_obstack,
-                      lines, (sizeof (struct linetable)
-                              + size * sizeof (lines->item))));
-      xfree (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?  */
-      top_stack->cur_st = cust->primary_filetab ();
-      top_stack->cur_block
-       = top_stack->cur_st->compunit ()->blockvector ()->global_block ();
-      top_stack->blocktype = stFile;
-
-      ext_ptr = PST_PRIVATE (pst)->extern_tab;
-      for (i = PST_PRIVATE (pst)->extern_count; --i >= 0; ext_ptr++)
-       parse_external (ext_ptr, fh->fBigendian,
-                       section_offsets, objfile);
-
-      /* If there are undefined symbols, tell the user.
-        The alpha has an undefined symbol for every symbol that is
-        from a shared library, so tell the user only if verbose is on.  */
-      if (info_verbose && n_undef_symbols)
-       {
-         gdb_printf (_("File %s contains %d unresolved references:"),
-                     symtab_to_filename_for_display
-                     (cust->primary_filetab ()),
-                     n_undef_symbols);
-         gdb_printf ("\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 ();
+  size = lines->nitems;
+  if (size > 1)
+    --size;
+  cust->primary_filetab ()->set_linetable
+    ((struct linetable *)
+     obstack_copy (&mdebugread_objfile->objfile_obstack,
+                  lines, (sizeof (struct linetable)
+                          + size * sizeof (lines->item))));
+  xfree (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?  */
+  top_stack->cur_st = cust->primary_filetab ();
+  top_stack->cur_block
+    = top_stack->cur_st->compunit ()->blockvector ()->global_block ();
+  top_stack->blocktype = stFile;
+
+  ext_ptr = PST_PRIVATE (pst)->extern_tab;
+  for (i = PST_PRIVATE (pst)->extern_count; --i >= 0; ext_ptr++)
+    parse_external (ext_ptr, fh->fBigendian,
+                   section_offsets, objfile);
+
+  /* If there are undefined symbols, tell the user.
+     The alpha has an undefined symbol for every symbol that is
+     from a shared library, so tell the user only if verbose is on.  */
+  if (info_verbose && n_undef_symbols)
+    {
+      gdb_printf (_("File %s contains %d unresolved references:"),
+                 symtab_to_filename_for_display
+                 (cust->primary_filetab ()),
+                 n_undef_symbols);
+      gdb_printf ("\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;
 
-      sort_blocks (cust->primary_filetab ());
     }
+  pop_parse_stack ();
+
+  sort_blocks (cust->primary_filetab ());
 
   /* Now link the psymtab and the symtab.  */
   pst->compunit_symtab = cust;
index 53def129be70fbe8e043694e157958eabfd50eaf..0389545f7feb5e18f0c19e0ae00dce12a7f75693 100644 (file)
@@ -26,7 +26,6 @@
 #include "bfd.h"
 #include "symtab.h"
 #include "objfiles.h"
-#include "stabsread.h"
 #include "mdebugread.h"
 
 #include "coff/sym.h"
@@ -49,7 +48,6 @@ read_alphacoff_dynamic_symtab (minimal_symbol_reader &,
 static void
 mipscoff_new_init (struct objfile *ignore)
 {
-  stabsread_new_init ();
 }
 
 /* Initialize to read a symbol file (nothing to do).  */