Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [PATCH v2 0/8] Remove stabs support from GDB
@ 2025-10-20 15:28 Guinevere Larsen
  2025-10-20 15:28 ` [PATCH v2 1/8] gdb: move some stabs functions to gdb/buildsym-legacy.h Guinevere Larsen
                   ` (10 more replies)
  0 siblings, 11 replies; 24+ messages in thread
From: Guinevere Larsen @ 2025-10-20 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Guinevere Larsen

Now that GDB 17 has branched, I think we're ready to remov stabs from
GDB entirely, and the sooner this is merged, the earlier we'll spot any
problems and the more time will be there to fix them.

This series does just that.

Guinevere Larsen (8):
  gdb: move some stabs functions to gdb/buildsym-legacy.h
  gdb/mdebug: Remove stabs support from mips inferiors
  gdb: Remove stabs support from ELF files
  gdb: Remove stabs support from dbx
  gdb: Remove stabs support for COFF files
  gdb: Remove stabs support from XCOFF inferiors
  gdb: Fully remove stabs code from GDB
  gdb: remove support for dbx from GDB

 gdb/Makefile.in                      |    8 +-
 gdb/NEWS                             |    4 +
 gdb/arch-utils.c                     |    6 -
 gdb/arch-utils.h                     |    3 -
 gdb/buildsym-legacy.h                |   10 +
 gdb/buildsym.c                       |   18 -
 gdb/coffread.c                       |  133 +-
 gdb/configure                        |    6 +-
 gdb/configure.ac                     |    4 +-
 gdb/dbxread.c                        |  254 -
 gdb/doc/Makefile.in                  |   46 +-
 gdb/doc/gdb.texinfo                  |   23 +-
 gdb/doc/stabs.texinfo                | 4130 ---------------
 gdb/elfread.c                        |  146 +-
 gdb/gdb-stabs.h                      |  176 -
 gdb/gdbarch-gen.c                    |   22 -
 gdb/gdbarch-gen.h                    |    4 -
 gdb/gdbarch_components.py            |    8 -
 gdb/mdebugread.c                     | 1781 ++-----
 gdb/microblaze-tdep.c                |    8 -
 gdb/mipsread.c                       |    2 -
 gdb/objfiles.h                       |    3 -
 gdb/rs6000-aix-nat.c                 |    1 -
 gdb/sparc-tdep.c                     |   10 -
 gdb/sparc64-tdep.c                   |    2 -
 gdb/stabsread.c                      | 7217 --------------------------
 gdb/stabsread.h                      |  314 --
 gdb/symmisc.c                        |    3 -
 gdb/testsuite/gdb.stabs/aout.sed     |   16 -
 gdb/testsuite/gdb.stabs/ecoff.sed    |   17 -
 gdb/testsuite/gdb.stabs/exclfwd.exp  |   57 -
 gdb/testsuite/gdb.stabs/exclfwd.h    |   21 -
 gdb/testsuite/gdb.stabs/exclfwd1.c   |   34 -
 gdb/testsuite/gdb.stabs/exclfwd2.c   |   29 -
 gdb/testsuite/gdb.stabs/gdb11479.c   |   76 -
 gdb/testsuite/gdb.stabs/gdb11479.exp |   59 -
 gdb/testsuite/gdb.stabs/hppa.sed     |   20 -
 gdb/testsuite/gdb.stabs/weird.def    |  900 ----
 gdb/testsuite/gdb.stabs/weird.exp    |  309 --
 gdb/testsuite/gdb.stabs/xcoff.sed    |   17 -
 gdb/testsuite/lib/gdb.exp            |    6 +
 gdb/xcoffread.c                      | 2014 +------
 42 files changed, 544 insertions(+), 17373 deletions(-)
 delete mode 100644 gdb/dbxread.c
 delete mode 100644 gdb/doc/stabs.texinfo
 delete mode 100644 gdb/gdb-stabs.h
 delete mode 100644 gdb/stabsread.c
 delete mode 100644 gdb/stabsread.h
 delete mode 100644 gdb/testsuite/gdb.stabs/aout.sed
 delete mode 100644 gdb/testsuite/gdb.stabs/ecoff.sed
 delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd.exp
 delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd.h
 delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd1.c
 delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd2.c
 delete mode 100644 gdb/testsuite/gdb.stabs/gdb11479.c
 delete mode 100644 gdb/testsuite/gdb.stabs/gdb11479.exp
 delete mode 100644 gdb/testsuite/gdb.stabs/hppa.sed
 delete mode 100644 gdb/testsuite/gdb.stabs/weird.def
 delete mode 100644 gdb/testsuite/gdb.stabs/weird.exp
 delete mode 100644 gdb/testsuite/gdb.stabs/xcoff.sed


base-commit: b9e48061e06ec0c181757c9e80cc4dc72d614f4f
-- 
2.51.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v2 1/8] gdb: move some stabs functions to gdb/buildsym-legacy.h
  2025-10-20 15:28 [PATCH v2 0/8] Remove stabs support from GDB Guinevere Larsen
@ 2025-10-20 15:28 ` Guinevere Larsen
  2025-10-20 16:25   ` Tom Tromey
  2025-10-20 15:28 ` [PATCH v2 2/8] gdb/mdebug: Remove stabs support from mips inferiors Guinevere Larsen
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 24+ messages in thread
From: Guinevere Larsen @ 2025-10-20 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Guinevere Larsen

The gdb/stabsread.h and .c files define 2 things that, while originally
intended only for stabs reading, actually end up being used for coff,
ecoff and maybe more debuginfo formats. That is the function "hashname",
and the macro HASHSIZE.  Both are used for small hashtables when reading
some symbols with incomplete information.

With the upcoming removal of stabs code, this code should be moved
somewhere, and the location that looked most reasonable was
gdb/buildsym-legacy.  No change in behavior is expected after this
commit.
---
 gdb/buildsym-legacy.h | 10 ++++++++++
 gdb/stabsread.c       |  8 --------
 gdb/stabsread.h       |  9 ++-------
 3 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/gdb/buildsym-legacy.h b/gdb/buildsym-legacy.h
index 4ae8e1a7b66..06d39e8529f 100644
--- a/gdb/buildsym-legacy.h
+++ b/gdb/buildsym-legacy.h
@@ -21,6 +21,16 @@
 
 #include "buildsym.h"
 
+/* Legacy hash for symbol names used for several debuginfo formats.  */
+
+#define HASHSIZE 127
+
+static inline int
+hashname (const char *name)
+{
+  return fast_hash (name, strlen (name)) % HASHSIZE;
+}
+
 /* This module provides definitions used for creating and adding to
    the symbol table.  These routines are called from various symbol-
    file-reading routines.  This file holds the legacy API, which
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
index 733fc9e6ddc..60cd5702396 100644
--- a/gdb/stabsread.c
+++ b/gdb/stabsread.c
@@ -7190,14 +7190,6 @@ find_name_end (const char *name)
     }
 }
 
-/* See stabsread.h.  */
-
-int
-hashname (const char *name)
-{
-  return fast_hash (name, strlen (name)) % HASHSIZE;
-}
-
 /* Initializer for this module.  */
 
 INIT_GDB_FILE (stabsread)
diff --git a/gdb/stabsread.h b/gdb/stabsread.h
index 15f73266e1c..1c9ce854dff 100644
--- a/gdb/stabsread.h
+++ b/gdb/stabsread.h
@@ -19,6 +19,8 @@
 #ifndef GDB_STABSREAD_H
 #define GDB_STABSREAD_H
 
+#include "buildsym-legacy.h"
+
 struct objfile;
 struct legacy_psymtab;
 enum language;
@@ -26,13 +28,6 @@ enum language;
 /* Definitions, prototypes, etc for stabs debugging format support
    functions.  */
 
-#define HASHSIZE 127		/* Size of things hashed via
-				   hashname().  */
-
-/* Compute a small integer hash code for the given name.  */
-
-extern int hashname (const char *name);
-
 /* Count symbols as they are processed, for error messages.  */
 
 extern unsigned int symnum;
-- 
2.51.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v2 2/8] gdb/mdebug: Remove stabs support from mips inferiors
  2025-10-20 15:28 [PATCH v2 0/8] Remove stabs support from GDB Guinevere Larsen
  2025-10-20 15:28 ` [PATCH v2 1/8] gdb: move some stabs functions to gdb/buildsym-legacy.h Guinevere Larsen
@ 2025-10-20 15:28 ` Guinevere Larsen
  2025-10-20 15:28 ` [PATCH v2 3/8] gdb: Remove stabs support from ELF files Guinevere Larsen
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 24+ messages in thread
From: Guinevere Larsen @ 2025-10-20 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Guinevere Larsen, Tom Tromey

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.

Acked-By: Tom Tromey <tom@tromey.com>
---
 gdb/mdebugread.c | 1781 +++++++++++++---------------------------------
 gdb/mipsread.c   |    2 -
 2 files changed, 478 insertions(+), 1305 deletions(-)

diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c
index 9504e5e1670..849191b1bfe 100644
--- a/gdb/mdebugread.c
+++ b/gdb/mdebugread.c
@@ -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,80 @@ 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)
+
+struct symbol *fortran_global_syms[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 = hashname (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_loc_class_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 +343,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 +351,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 +408,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 +714,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;
+	  s->set_value_chain (fortran_global_syms[bucket]);
+	  fortran_global_syms[bucket] = s;
 	}
       else
 	{
@@ -2049,8 +2117,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 +2283,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 +2356,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 +2372,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 +2395,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 +2702,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,1034 +2710,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;
-	      stabs_deprecated_warning ();
-	    }
+	    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 location_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-existent .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;
-	      location_class loc_class;
-	      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;
 
-	      minsym_value = unrelocated_addr (sh.value);
+	    case stIndirect:	/* Irix5 forward declaration */
+	      /* Skip forward declarations from Irix5 cc.  */
+	      goto skip;
 
-	      switch (sh.sc)
+	    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;
+
+	    case stConstant:	/* Constant decl */
+	      theclass = LOC_CONST;
+	      break;
+
+	    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));
-
-		  [[fallthrough]];
+		  /* 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 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 stFile:	/* File headers */
+	    case stLabel:	/* Labels */
+	    case stEnd:	/* Ends of files */
+	      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.  */
-		    }
+	    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;
 
-		  /* 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));
-		  loc_class = 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 location_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;
-		  loc_class = LOC_TYPEDEF;
-		  break;
+	  gdb_assert (ext_ptr->ifd == f_idx);
 
-		case stConstant:	/* Constant decl */
-		  loc_class = 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, loc_class, 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)
 	    {
-	      location_class loc_class;
-	      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:
-		  loc_class = 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;
-
-		  loc_class = LOC_STATIC;
-		  break;
-		}
-	      char *sym_name = debug_info->ssext + psh->iss;
-	      pst->add_psymbol (sym_name, true,
-				VAR_DOMAIN, loc_class,
-				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.  */
@@ -3825,22 +3175,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
@@ -3863,7 +3197,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)
@@ -3898,7 +3231,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;
@@ -3910,132 +3242,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_loc_class_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 (fh)
+    {
+      char *sym_ptr;
+      char *sym_end;
 
-      if (! last_symtab_ended)
+      /* 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;
@@ -4063,162 +3340,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;
diff --git a/gdb/mipsread.c b/gdb/mipsread.c
index 1d76b8f4eda..943ed9afc5c 100644
--- a/gdb/mipsread.c
+++ b/gdb/mipsread.c
@@ -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).  */
-- 
2.51.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v2 3/8] gdb: Remove stabs support from ELF files
  2025-10-20 15:28 [PATCH v2 0/8] Remove stabs support from GDB Guinevere Larsen
  2025-10-20 15:28 ` [PATCH v2 1/8] gdb: move some stabs functions to gdb/buildsym-legacy.h Guinevere Larsen
  2025-10-20 15:28 ` [PATCH v2 2/8] gdb/mdebug: Remove stabs support from mips inferiors Guinevere Larsen
@ 2025-10-20 15:28 ` Guinevere Larsen
  2025-10-20 15:28 ` [PATCH v2 4/8] gdb: Remove stabs support from dbx Guinevere Larsen
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 24+ messages in thread
From: Guinevere Larsen @ 2025-10-20 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Guinevere Larsen, Tom Tromey

This commit makes it so that GDB won't read stabs information from ELF
files.  If stabs is detected in an ELF file, the reader now warns the user
that stabs is not supported.

This test would cause two new failures in the test gdb.stabs/weird.exp
(that surprisingly didn't happen in the mips commit).  Rather than fixing
the test that'll be removed soon, I just removed the test instead.

Approved-By: Tom Tromey <tom@tromey.com>
---
 gdb/elfread.c                     | 146 +-------------
 gdb/testsuite/gdb.stabs/weird.exp | 309 ------------------------------
 2 files changed, 1 insertion(+), 454 deletions(-)
 delete mode 100644 gdb/testsuite/gdb.stabs/weird.exp

diff --git a/gdb/elfread.c b/gdb/elfread.c
index 152576d3523..2302dcf1ae6 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -28,7 +28,6 @@
 #include "symtab.h"
 #include "symfile.h"
 #include "objfiles.h"
-#include "stabsread.h"
 #include "probe.h"
 #include "arch-utils.h"
 #include "gdbtypes.h"
@@ -45,7 +44,6 @@
 #include <string_view>
 #include "dwarf2/public.h"
 #include "cli/cli-cmds.h"
-#include "gdb-stabs.h"
 
 /* Whether ctf should always be read, or only if no dwarf is present.  */
 static bool always_read_ctf;
@@ -1207,134 +1205,6 @@ elf_symfile_read_dwarf2 (struct objfile *objfile,
   return has_dwarf2;
 }
 
-/* find_text_range --- find start and end of loadable code sections
-
-   The find_text_range function finds the shortest address range that
-   encloses all sections containing executable code, and stores it in
-   objfile's text_addr and text_size members.
-
-   dbx_symfile_read will use this to finish off the partial symbol
-   table, in some cases.  */
-
-static void
-find_text_range (bfd * sym_bfd, struct objfile *objfile)
-{
-  asection *sec;
-  int found_any = 0;
-  CORE_ADDR start = 0;
-  CORE_ADDR end = 0;
-
-  for (sec = sym_bfd->sections; sec; sec = sec->next)
-    if (bfd_section_flags (sec) & SEC_CODE)
-      {
-	CORE_ADDR sec_start = bfd_section_vma (sec);
-	CORE_ADDR sec_end = sec_start + bfd_section_size (sec);
-
-	if (found_any)
-	  {
-	    if (sec_start < start)
-	      start = sec_start;
-	    if (sec_end > end)
-	      end = sec_end;
-	  }
-	else
-	  {
-	    start = sec_start;
-	    end = sec_end;
-	  }
-
-	found_any = 1;
-      }
-
-  if (!found_any)
-    error (_("Can't find any code sections in symbol file"));
-
-  DBX_TEXT_ADDR (objfile) = start;
-  DBX_TEXT_SIZE (objfile) = end - start;
-}
-
-/* Scan and build partial symbols for an ELF symbol file.
-   This ELF file has already been processed to get its minimal symbols.
-
-   This routine is the equivalent of dbx_symfile_init and dbx_symfile_read
-   rolled into one.
-
-   OBJFILE is the object file we are reading symbols from.
-   ADDR is the address relative to which the symbols are (e.g.
-   the base address of the text segment).
-   STABSECT is the BFD section information for the .stab section.
-   STABSTROFFSET and STABSTRSIZE define the location in OBJFILE where the
-   .stabstr section exists.
-
-   This routine is mostly copied from dbx_symfile_init and dbx_symfile_read,
-   adjusted for elf details.  */
-
-void
-elfstab_build_psymtabs (struct objfile *objfile, asection *stabsect,
-			file_ptr stabstroffset, unsigned int stabstrsize)
-{
-  int val;
-  bfd *sym_bfd = objfile->obfd.get ();
-  const char *name = bfd_get_filename (sym_bfd);
-
-  stabsread_new_init ();
-
-  /* Allocate struct to keep track of stab reading.  */
-  dbx_objfile_data_key.emplace (objfile);
-  dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
-  /* Find the first and last text address.  dbx_symfile_read seems to
-     want this.  */
-  find_text_range (sym_bfd, objfile);
-
-#define	ELF_STABS_SYMBOL_SIZE	12	/* XXX FIXME XXX */
-  DBX_SYMBOL_SIZE (objfile) = ELF_STABS_SYMBOL_SIZE;
-  DBX_SYMCOUNT (objfile)
-    = bfd_section_size (stabsect) / DBX_SYMBOL_SIZE (objfile);
-  DBX_STRINGTAB_SIZE (objfile) = stabstrsize;
-  DBX_SYMTAB_OFFSET (objfile) = stabsect->filepos;
-  DBX_STAB_SECTION (objfile) = stabsect;
-
-  if (stabstrsize > bfd_get_size (sym_bfd))
-    error (_("ridiculous string table size: %d bytes"), stabstrsize);
-  DBX_STRINGTAB (objfile) = (char *)
-    obstack_alloc (&objfile->objfile_obstack, stabstrsize + 1);
-  OBJSTAT (objfile, sz_strtab += stabstrsize + 1);
-
-  /* Now read in the string table in one big gulp.  */
-
-  val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
-  if (val < 0)
-    perror_with_name (name);
-  val = bfd_read (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
-  if (val != stabstrsize)
-    perror_with_name (name);
-
-  stabsread_new_init ();
-  free_header_files ();
-  init_header_files ();
-
-  key->ctx.processing_acc_compilation = 1;
-
-  key->ctx.symbuf_read = 0;
-  key->ctx.symbuf_left = bfd_section_size (stabsect);
-
-  scoped_restore restore_stabs_data = make_scoped_restore (&key->ctx.stabs_data);
-  gdb::unique_xmalloc_ptr<gdb_byte> data_holder;
-
-  key->ctx.stabs_data = symfile_relocate_debug_section (objfile, stabsect, NULL);
-  if (key->ctx.stabs_data)
-    data_holder.reset (key->ctx.stabs_data);
-
-  /* In an elf file, we've already installed the minimal symbols that came
-     from the elf (non-stab) symbol table, so always act like an
-     incremental load here.  dbx_symfile_read should not generate any new
-     minimal symbols, since we will have already read the ELF dynamic symbol
-     table and normal symbol entries won't be in the ".stab" section; but in
-     case it does, it will install them itself.  */
-  read_stabs_symtab (objfile, 0);
-}
-
 /* Scan and build partial symbols for a symbol file.
    We have been initialized by a call to elf_symfile_init, which
    currently does nothing.
@@ -1350,7 +1220,6 @@ elfstab_build_psymtabs (struct objfile *objfile, asection *stabsect,
    We look for sections with specific names, to tell us what debug
    format to look for:  FIXME!!!
 
-   elfstab_build_psymtabs() handles STABS symbols;
    mdebug_build_psymtabs() handles ECOFF debugging information.
 
    Note that ELF files have a "minimal" symbol table, which looks a lot
@@ -1397,20 +1266,7 @@ elf_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
 	elfmdebug_build_psymtabs (objfile, swap, ei.mdebugsect);
     }
   if (ei.stabsect)
-    {
-      asection *str_sect;
-
-      /* Stab sections have an associated string table that looks like
-	 a separate section.  */
-      str_sect = bfd_get_section_by_name (abfd, ".stabstr");
-
-      /* FIXME should probably warn about a stab section without a stabstr.  */
-      if (str_sect)
-	elfstab_build_psymtabs (objfile,
-				ei.stabsect,
-				str_sect->filepos,
-				bfd_section_size (str_sect));
-    }
+    warning ("stabs debug information is not supported.");
 
   /* Read the CTF section only if there is no DWARF info.  */
   if (always_read_ctf && ei.ctfsect)
diff --git a/gdb/testsuite/gdb.stabs/weird.exp b/gdb/testsuite/gdb.stabs/weird.exp
deleted file mode 100644
index 3bc6e0d8ac9..00000000000
--- a/gdb/testsuite/gdb.stabs/weird.exp
+++ /dev/null
@@ -1,309 +0,0 @@
-# Copyright 1997-2025 Free Software Foundation, Inc.
-
-# 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 3 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, see <http://www.gnu.org/licenses/>.
-
-# Test that GDB properly ignores invalid stabs.
-# Also test that GDB can debug a .o file, and that it doesn't mind
-# a file that's more minimal than what a compiler normally puts out.
-
-set testfile weird
-set srcfile [standard_output_file weird.s]
-set binfile [standard_output_file weirdx.o]
-
-proc do_tests {} {
-	global binfile
-	global gdb_prompt
-
-	# Mips/alpha targets that use gcc with mips-tfile put out the stabs
-	# assembler directives embedded in comments. If the assembler
-	# file is then processed with native cc, all stabs directives
-	# will be lost.
-	# Skip the rest of the stabs tests for this case.
-	send_gdb "ptype inttype\n"
-	gdb_expect {
-		-re "^ptype inttype\r*\ntype = inttype.*$gdb_prompt $" {
-			pass "stabs found"
-		}
-		-re ".*$gdb_prompt $" {
-			setup_xfail "mips-*-*"
-			setup_xfail "alpha-*-*"
-			fail "stabs not found"
-			return
-		}
-		default { fail "checking for stabs" }
-	}
-
-	print_weird_var var0
-	print_weird_var var1
-	print_weird_var var2
-	print_weird_var var3
-
-	print_weird_var attr32
-	print_weird_var attr33
-	print_weird_var attr35
-	print_weird_var attr36
-	print_weird_var attr37
-	print_weird_var attr38
-	print_weird_var attr39
-	print_weird_var attr41
-	print_weird_var attr42
-	print_weird_var attr43
-	print_weird_var attr44
-	print_weird_var attr46
-	print_weird_var attr47
-	print_weird_var attr58
-	print_weird_var attr59
-	print_weird_var attr60
-	print_weird_var attr61
-	print_weird_var attr62
-	print_weird_var attr63
-	print_weird_var attr64
-	print_weird_var attr65
-	print_weird_var attr66
-	print_weird_var attr67
-	print_weird_var attr68
-	print_weird_var attr69
-	print_weird_var attr70
-	print_weird_var attr71
-	print_weird_var attr72
-	print_weird_var attr73
-	print_weird_var attr74
-	print_weird_var attr75
-	print_weird_var attr76
-	print_weird_var attr77
-	print_weird_var attr78
-	print_weird_var attr79
-	print_weird_var attr80
-	print_weird_var attr81
-	print_weird_var attr82
-	print_weird_var attr83
-	print_weird_var attr84
-	print_weird_var attr85
-	print_weird_var attr86
-	print_weird_var attr87
-	print_weird_var attr88
-	print_weird_var attr89
-	print_weird_var attr90
-	print_weird_var attr91
-	print_weird_var attr92
-	print_weird_var attr93
-	print_weird_var attr94
-	print_weird_var attr95
-	print_weird_var attr96
-	print_weird_var attr97
-	print_weird_var attr98
-	print_weird_var attr99
-	print_weird_var attr100
-	print_weird_var attr101
-	print_weird_var attr102
-	print_weird_var attr103
-	print_weird_var attr104
-	print_weird_var attr105
-	print_weird_var attr106
-	print_weird_var attr107
-	print_weird_var attr108
-	print_weird_var attr109
-	print_weird_var attr110
-	print_weird_var attr111
-	print_weird_var attr112
-	print_weird_var attr113
-	print_weird_var attr114
-	print_weird_var attr115
-	print_weird_var attr116
-	print_weird_var attr117
-	print_weird_var attr118
-	print_weird_var attr119
-	print_weird_var attr120
-	print_weird_var attr121
-	print_weird_var attr122
-	print_weird_var attr123
-	print_weird_var attr124
-	print_weird_var attr125
-	print_weird_var attr126
-
-	gdb_test "p const69" " = 69" "'e' constant on non-enum type"
-	gdb_test "whatis const69" "type = (unsigned int|inttype)"
-
-	gdb_test "p sizeof (const70)" " = 2" "'e' constant with embedded type"
-
-	gdb_test "p constchar" " = 97 'a'" "char constant"
-        gdb_test "p constString1" " = \"Single quote String1\"" "string constant 1"
-        gdb_test "p constString2" " = \"Double quote String2\"" "string constant 2"
-
-        gdb_test "p constString3" " = \"String3 with embedded quote ' in the middle\"" "string constant 3"
-        gdb_test "p constString4" { = "String4 with embedded quote \\" in the middle"} "string constant 4"
-	gdb_test "p bad_neg0" " = \{field0 = 42, field2 =.*field3 = 45\}"
-
-	gdb_test "ptype inttype" "type = (unsigned int|inttype)" "ptype on inttype"
-	gdb_test "p sizeof (float72type)" " = 9" "unrecognized floating point type"
-
-	# This big number needs to be kept as one piece
-	gdb_test "p/x int256var" " = 0x0*2a0000002b0000002c0000002d0000002d0000002c0000002b0000002a" "print very big integer"
-
-	gdb_test "whatis consth" "type = inttype"
-	gdb_test "whatis consth2" "type = inttype"
-
-	# GDB does not yet understand S constants
-	setup_xfail "*-*-*"
-	gdb_test "p/x bad_neg0const" " = \{field0 = 0x11222211, field2 =.*\
-field3 = 0x77888877\}" "print struct constant"
-
-	gdb_test "ptype bad_type0" "type = .*" "print bad_type0"
-	gdb_test "ptype bad_type1" "type = .*" "print bad_type1"
-
-	# GDB does not yet support arrays indexed by anything at all unusual
-	setup_xfail "*-*-*"
-	gdb_test "p array0" " = \\{42, 43, 44, 45, 46, 47\\}" "array0 with strange index"
-	setup_xfail "*-*-*"
-	gdb_test "p array1" " = \\{42, 43, 44\\}" "array1 with strange index"
-
-	# GDB does not yet support this feature
-	gdb_test "whatis one_var" "type = inttype_one" \
-	    "whatis one_var (known failure in gdb 4.10)"
-	# But do make sure that it prints as something reasonable
-	gdb_test "whatis one_var" "type = inttype(|_one)" \
-	    "whatis one_var test 2"
-
-	gdb_test "whatis two_var" "type = inttype_two" \
-	    "whatis two_var (known failure in gdb 4.10)"
-	# But do make sure that it prints as something reasonable
-	gdb_test "whatis two_var" "type = inttype(|_two)" \
-	    "whatis two_var test 2"
-
-	setup_xfail "*-*-*"
-	gdb_test "whatis pointer_to_int_var" "type = int \[*\]"
-	setup_xfail "*-*-*"
-	gdb_test "whatis intp_var" "type = intp"
-
-	gdb_test "p common0var0" "= 42"
-	# GDB seems to only understand common blocks local to a function.
-	# These variables never get relocated to be relative to the common 
-	# block.
-	# I'm not sure whether it is valid to have a common block which
-	# is not local to a function.
-	setup_xfail "*-*-*"
-	gdb_test "p common0var1" "= 24"
-	setup_xfail "*-*-*"
-	gdb_test "p common0var2" "= 22"
-}
-
-proc print_weird_var { var } {
-	global gdb_prompt
-
-	# Make sure that the variable gets printed out correctly, without
-	# any sort of warning message.
-        gdb_test_multiple "print $var" "variable $var printed property" {  
-		-re "^print $var\r*\n.\[0-9\]* = 42.*$gdb_prompt $" {
-			pass "variable $var printed properly"
-		}
-		-re ".*$gdb_prompt $" {
-			fail "variable $var printed properly"
-		}
-	}
-
-	# Make sure that the stabs did get loaded in a sensible way.
-	# If somehow the stabs got skipped, then the above test can
-	# pass because GDB assumes int for variables without a stab.
-
-	# This doesn't work because 32=45 doesn't preserve the name in
-	# gdb (as of 14 Sep 93 anyway).
-	#gdb_test "whatis $var" "type = (unsigned int|inttype)"
-
-	# But the size should be right.
-	gdb_test "print sizeof ($var)" "= 4"
-}
-
-
-# Don't use gdb_load; it doesn't bitch if the loading produced some
-# error messages during symbol reading.
-
-global target_os
-set sedscript ${srcdir}/${subdir}/aout.sed
-set sedoptions ""
-
-switch -glob ${target_triplet} {
-    "hppa*-*-*" {
-	set sedscript ${srcdir}/${subdir}/hppa.sed
-    }
-    "mips-*-ecoff" {
-	set sedscript ${srcdir}/${subdir}/ecoff.sed
-    }
-    "powerpc-*-aix*" {
-	set sedscript ${srcdir}/${subdir}/xcoff.sed
-	set sedoptions "-r"
-    }
-    "rs6000-*-aix*" {
-	set sedscript ${srcdir}/${subdir}/xcoff.sed
-	set sedoptions "-r"
-    }
-    "*-*-aout" {
-	set sedscript ${srcdir}/${subdir}/aout.sed
-    }
-    "*-*-xcoff" {
-	set sedscript ${srcdir}/${subdir}/xcoff.sed
-	set sedoptions "-r"
-    }
-    "alpha-*-*" {
-	set sedscript ${srcdir}/${subdir}/ecoff.sed
-    }
-}
-
-# Hope this is a Unix box.
-set exec_output [remote_exec build "sed" "${sedoptions} -f ${sedscript}" "${srcdir}/${subdir}/weird.def" "${srcfile}"]
-if { [lindex $exec_output 0] != 0 } {
-    perror "Couldn't make test case. $exec_output"
-    return -1
-}
-
-if  { [gdb_compile "${srcfile}" "${binfile}" object ""] != "" } {
-     untested "failed to compile"
-     return -1
-}
-
-remote_file build delete ${srcfile}
-
-clean_restart
-
-set binfile_host [gdb_remote_download host $binfile]
-set binfile_re [string_to_regexp $binfile_host]
-send_gdb "file $binfile_host\n"
-# If $binfile is very long, a \r (but not a \n) will echo in the
-# middle of the echo of the command.  So to match the echo, we
-# would like to match anything not containing \n
-# (we would prefer to be sure not to match any warning message).
-# But \[^\n\]* doesn't seem to work, so instead use the heuristic
-# that a filename won't contain a space and a warning message will.
-# But spaces following by backspaces aren't really spaces.
-gdb_expect 60 {
-    -re "^file (\[^ \]| +\008)*\r*\n" {
-	exp_continue
-    }
-    -re "A program is being debugged already.\[\r\n\]+Are you sure you want to change the file\\? \\(y or n\\)" {
-	send_gdb "y\n"
-	exp_continue
-    }
-    -re "^Reading symbols from .*$binfile_re\\.\\.\\.(|\r\nUsing host libthread_db library .*libthread_db.so.*\\.)\r\n(\[^\\n\]*\n)?$gdb_prompt $" {
-	pass "weirdx.o read without error"
-    }
-    -re ".*$gdb_prompt $" {
-	fail "errors reading weirdx.o"
-    }
-    timeout {
-	perror "couldn't load $binfile into $GDB (timed out)."
-	return -1
-    }
-    eof { fail "(eof) cannot read weirdx.o" }
-}
-
-do_tests
-- 
2.51.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v2 4/8] gdb: Remove stabs support from dbx
  2025-10-20 15:28 [PATCH v2 0/8] Remove stabs support from GDB Guinevere Larsen
                   ` (2 preceding siblings ...)
  2025-10-20 15:28 ` [PATCH v2 3/8] gdb: Remove stabs support from ELF files Guinevere Larsen
@ 2025-10-20 15:28 ` Guinevere Larsen
  2025-10-20 15:28 ` [PATCH v2 5/8] gdb: Remove stabs support for COFF files Guinevere Larsen
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 24+ messages in thread
From: Guinevere Larsen @ 2025-10-20 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Guinevere Larsen, Tom Tromey

This commit makes it so reading dbx inferiors will not read stabs
debuginfo from the inferiors.

This has the side effect of making reading DBX inferiors a noop.  It
will be removed in a future commit, however, the present series of
commit is focused on just removing stabs.

Approved-By: Tom Tromey <tom@tromey.com>
---
 gdb/dbxread.c | 15 ++++++---------
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index 260f5838494..de3f7c6a45b 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -36,12 +36,14 @@
 #include "target.h"
 #include "libaout.h"
 #include "objfiles.h"
-#include "stabsread.h"
+#include "buildsym-legacy.h"
 #include "gdb-stabs.h"
 #include "cp-support.h"
-
-/* Required for the following registry.  */
-#include "gdb-stabs.h"
+#include "c-lang.h"
+#include "psymtab.h"
+#include "block.h"
+#include "aout/aout64.h"
+#include "aout/stab_gnu.h"
 
 /* Local function prototypes.  */
 
@@ -80,7 +82,6 @@ explicit_lookup_type (int real_filenum, int index)
 static void
 dbx_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
 {
-  read_stabs_symtab (objfile, symfile_flags);
 }
 
 /* Initialize anything that needs initializing when a completely new
@@ -90,9 +91,6 @@ dbx_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
 static void
 dbx_new_init (struct objfile *ignore)
 {
-  stabsread_new_init ();
-  init_header_files ();
-  warning (_("The a.out file format is deprecated and will be removed soon."));
 }
 
 
@@ -227,7 +225,6 @@ dbx_symfile_init (struct objfile *objfile)
 static void
 dbx_symfile_finish (struct objfile *objfile)
 {
-  free_header_files ();
 }
 
 \f
-- 
2.51.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v2 5/8] gdb: Remove stabs support for COFF files
  2025-10-20 15:28 [PATCH v2 0/8] Remove stabs support from GDB Guinevere Larsen
                   ` (3 preceding siblings ...)
  2025-10-20 15:28 ` [PATCH v2 4/8] gdb: Remove stabs support from dbx Guinevere Larsen
@ 2025-10-20 15:28 ` Guinevere Larsen
  2025-10-20 15:28 ` [PATCH v2 6/8] gdb: Remove stabs support from XCOFF inferiors Guinevere Larsen
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 24+ messages in thread
From: Guinevere Larsen @ 2025-10-20 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Guinevere Larsen, Tom Tromey

This commit continues the removal of stabs by removing support from coff
inferiors.  This is trivial for the most part, just a removal of code
setting things only relevant for stabs, with one exception.

The global variables symnum and within_function were introduced to
coffread.c (and within_function was converted to boolean).  I looked into
making them parameters to the relevant function, but this would require
changes to several otherwise untouched functions, so I kept them as globals
instead.

Approved-By: Tom Tromey <tom@tromey.com>
---
 gdb/coffread.c | 133 +++++--------------------------------------------
 1 file changed, 12 insertions(+), 121 deletions(-)

diff --git a/gdb/coffread.c b/gdb/coffread.c
index 0a3be97c8d8..e8ed1e6b8ee 100644
--- a/gdb/coffread.c
+++ b/gdb/coffread.c
@@ -30,13 +30,11 @@
 #include "libcoff.h"
 #include "objfiles.h"
 #include "buildsym-legacy.h"
-#include "stabsread.h"
 #include "complaints.h"
 #include "target.h"
 #include "block.h"
 #include "dictionary.h"
 #include "dwarf2/public.h"
-#include "gdb-stabs.h"
 
 #include "coff-pe-read.h"
 
@@ -159,6 +157,10 @@ static file_ptr linetab_size;
 static char *stringtab = NULL;
 static long stringtab_length = 0;
 
+/* Used when reading coff symbols.  */
+static int symnum;
+static bool within_function;
+
 extern void stabsread_clear_cache (void);
 
 static struct type *coff_read_struct_type (int, int, int,
@@ -204,99 +206,6 @@ static void read_one_sym (struct coff_symbol *,
 static void coff_symtab_read (minimal_symbol_reader &,
 			      file_ptr, unsigned int, struct objfile *);
 
-/* Scan and build partial symbols for an coff symbol file.
-   The coff file has already been processed to get its minimal symbols.
-
-   This routine is the equivalent of dbx_symfile_init and dbx_symfile_read
-   rolled into one.
-
-   OBJFILE is the object file we are reading symbols from.
-   ADDR is the address relative to which the symbols are (e.g.
-   the base address of the text segment).
-   TEXTADDR is the address of the text section.
-   TEXTSIZE is the size of the text section.
-   STABSECTS is the list of .stab sections in OBJFILE.
-   STABSTROFFSET and STABSTRSIZE define the location in OBJFILE where the
-   .stabstr section exists.
-
-   This routine is mostly copied from dbx_symfile_init and dbx_symfile_read,
-   adjusted for coff details.  */
-
-void
-coffstab_build_psymtabs (struct objfile *objfile,
-			 CORE_ADDR textaddr, unsigned int textsize,
-			 const std::vector<asection *> &stabsects,
-			 file_ptr stabstroffset, unsigned int stabstrsize)
-{
-  int val;
-  bfd *sym_bfd = objfile->obfd.get ();
-  const char *name = bfd_get_filename (sym_bfd);
-  unsigned int stabsize;
-
-  stabs_deprecated_warning ();
-  /* Allocate struct to keep track of stab reading.  */
-  dbx_objfile_data_key.emplace (objfile);
-  dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
-  DBX_TEXT_ADDR (objfile) = textaddr;
-  DBX_TEXT_SIZE (objfile) = textsize;
-
-#define	COFF_STABS_SYMBOL_SIZE	12	/* XXX FIXME XXX */
-  DBX_SYMBOL_SIZE (objfile) = COFF_STABS_SYMBOL_SIZE;
-  DBX_STRINGTAB_SIZE (objfile) = stabstrsize;
-
-  if (stabstrsize > bfd_get_size (sym_bfd))
-    error (_("ridiculous string table size: %d bytes"), stabstrsize);
-  DBX_STRINGTAB (objfile) = (char *)
-    obstack_alloc (&objfile->objfile_obstack, stabstrsize + 1);
-  OBJSTAT (objfile, sz_strtab += stabstrsize + 1);
-
-  /* Now read in the string table in one big gulp.  */
-
-  val = bfd_seek (sym_bfd, stabstroffset, SEEK_SET);
-  if (val < 0)
-    perror_with_name (name);
-  val = bfd_read (DBX_STRINGTAB (objfile), stabstrsize, sym_bfd);
-  if (val != stabstrsize)
-    perror_with_name (name);
-
-  stabsread_new_init ();
-  free_header_files ();
-  init_header_files ();
-
-  key->ctx.processing_acc_compilation = 1;
-
-  /* In a coff file, we've already installed the minimal symbols that came
-     from the coff (non-stab) symbol table, so always act like an
-     incremental load here.  */
-  scoped_restore save_symbuf_sections
-    = make_scoped_restore (&key->ctx.symbuf_sections);
-  if (stabsects.size () == 1)
-    {
-      stabsize = bfd_section_size (stabsects[0]);
-      DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile);
-      DBX_SYMTAB_OFFSET (objfile) = stabsects[0]->filepos;
-    }
-  else
-    {
-      DBX_SYMCOUNT (objfile) = 0;
-      for (asection *section : stabsects)
-	{
-	  stabsize = bfd_section_size (section);
-	  DBX_SYMCOUNT (objfile) += stabsize / DBX_SYMBOL_SIZE (objfile);
-	}
-
-      DBX_SYMTAB_OFFSET (objfile) = stabsects[0]->filepos;
-
-      key->ctx.sect_idx = 1;
-      key->ctx.symbuf_sections = &stabsects;
-      key->ctx.symbuf_left = bfd_section_size (stabsects[0]);
-      key->ctx.symbuf_read = 0;
-    }
-
-  read_stabs_symtab (objfile, 0);
-}
-
 /* We are called once per section from coff_symfile_read.  We
    need to examine each section we are passed, check to see
    if it is something we are interested in processing, and
@@ -458,7 +367,6 @@ coff_alloc_type (int index)
 static void
 coff_start_compunit_symtab (struct objfile *objfile, const char *name)
 {
-  within_function = 0;
   start_compunit_symtab (objfile,
 			 name,
   /* We never know the directory name for COFF.  */
@@ -705,7 +613,6 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
   unsigned int num_symbols;
   file_ptr symtab_offset;
   file_ptr stringtab_offset;
-  unsigned int stabstrsize;
   
   info = coff_objfile_data_key.get (objfile);
   symfile_bfd = abfd;		/* Kludge for swap routines.  */
@@ -793,23 +700,7 @@ coff_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
     bfd_map_over_sections (abfd, coff_locate_sections, (void *) info);
 
   if (!info->stabsects->empty())
-    {
-      if (!info->stabstrsect)
-	{
-	  error (_("The debugging information in `%s' is corrupted.\nThe "
-		   "file has a `.stabs' section, but no `.stabstr' section."),
-		 filename);
-	}
-
-      /* FIXME: dubious.  Why can't we use something normal like
-	 bfd_get_section_contents?  */
-      stabstrsize = bfd_section_size (info->stabstrsect);
-
-      coffstab_build_psymtabs (objfile,
-			       info->textaddr, info->textsize,
-			       *info->stabsects,
-			       info->stabstrsect->filepos, stabstrsize);
-    }
+    warning (_("stabs debug information is not supported."));
 
   if (dwarf2_initialize_objfile (objfile))
     {
@@ -840,8 +731,6 @@ coff_new_init (struct objfile *ignore)
 static void
 coff_symfile_finish (struct objfile *objfile)
 {
-  /* Let stabs reader clean up.  */
-  stabsread_clear_cache ();
 }
 \f
 
@@ -881,6 +770,9 @@ coff_symtab_read (minimal_symbol_reader &reader,
 
   scoped_free_pendings free_pending;
 
+  within_function = false;
+  symnum = 0;
+
   /* Position to read the symbol table.  */
   val = bfd_seek (objfile->obfd.get (), symtab_offset, 0);
   if (val < 0)
@@ -899,7 +791,6 @@ coff_symtab_read (minimal_symbol_reader &reader,
 
   coff_start_compunit_symtab (objfile, "");
 
-  symnum = 0;
   while (symnum < nsyms)
     {
       QUIT;			/* Make this command interruptible.  */
@@ -1122,7 +1013,7 @@ coff_symtab_read (minimal_symbol_reader &reader,
 	case C_FCN:
 	  if (strcmp (cs->c_name, ".bf") == 0)
 	    {
-	      within_function = 1;
+	      within_function = true;
 
 	      /* Value contains address of first non-init type
 		 code.  */
@@ -1158,7 +1049,7 @@ coff_symtab_read (minimal_symbol_reader &reader,
 		  complaint (_("`.ef' symbol without matching `.bf' "
 			       "symbol ignored starting at symnum %d"),
 			     cs->c_symnum);
-		  within_function = 0;
+		  within_function = false;
 		  break;
 		}
 
@@ -1169,7 +1060,7 @@ coff_symtab_read (minimal_symbol_reader &reader,
 		  complaint (_("Unmatched .ef symbol(s) ignored "
 			       "starting at symnum %d"),
 			     cs->c_symnum);
-		  within_function = 0;
+		  within_function = false;
 		  break;
 		}
 	      if (cs->c_naux != 1)
@@ -1203,7 +1094,7 @@ coff_symtab_read (minimal_symbol_reader &reader,
 			    fcn_cs_saved.c_value
 			    + fcn_aux_saved.x_sym.x_misc.x_fsize
 			    + objfile->text_section_offset ());
-	      within_function = 0;
+	      within_function = false;
 	    }
 	  break;
 
-- 
2.51.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v2 6/8] gdb: Remove stabs support from XCOFF inferiors
  2025-10-20 15:28 [PATCH v2 0/8] Remove stabs support from GDB Guinevere Larsen
                   ` (4 preceding siblings ...)
  2025-10-20 15:28 ` [PATCH v2 5/8] gdb: Remove stabs support for COFF files Guinevere Larsen
@ 2025-10-20 15:28 ` Guinevere Larsen
  2025-11-07 10:46   ` Andrew Burgess
  2025-10-20 15:28 ` [PATCH v2 7/8] gdb: Fully remove stabs code from GDB Guinevere Larsen
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 24+ messages in thread
From: Guinevere Larsen @ 2025-10-20 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Guinevere Larsen

This commit is the second to last in the series fully removing support
for stabs in GDB, removing it from XCOFF inferiors.  According to IBM's
AIX documentation[1], xcoff binaries can only have stabs or DWARF debug
info, meaning removing stabs seems pretty trivial, as anything that
isn't related to setting base information on the objfile or reading
dwarf can be removed.

The unfortunate part of this removal is that XCOFF minimal symbols are
encoded in stabs, so if an inferior has not been compiled with dwarf
debuginfo, GDB will only be able to do assembly-level debugging.  Due to
this, the xcoff reader now emits a warning if no dwarf is read, saying:
"No usable debug information found".  This change would also add a lot of
regressions to to AIX, so the gdb_compile proc has been changed to not
work when a test tries to compile a test with nodebug.

As a sidenote, gdb-stabs.h can just be removed from rs6000-aix-nat, as
none of the structs or macros defined in the header are used in the nat
file, so that is an unnecessary include.

This commit introduces some known regressions when testing GDB in AIX
systems.  The main ones are:
* inferior function calls now crash with a corrupted stack.  This seems
  to be some fault of dwarf in explaining how to correctly set the frame
  for a function.
* fortran tests can't runto_main: the fortran compiler does not add any
  symbol for MAIN__ in the dwarf information, only in stabs, so the
  fortran_runto_main proc can't set the breakpoint correctly.
* When dealing with c++ class methods, there are cases when we fail to
  properly recognize a method call as a new function.
* When dealing with c++ virtual inheritance, GDB has issues finding a
  derived class's members when it has been downcast to a base class.

[1] https://www.ibm.com/docs/en/aix/7.3?topic=formats-xcoff-object-file-format
---
 gdb/rs6000-aix-nat.c      |    1 -
 gdb/testsuite/lib/gdb.exp |    6 +
 gdb/xcoffread.c           | 2014 +------------------------------------
 3 files changed, 14 insertions(+), 2007 deletions(-)

diff --git a/gdb/rs6000-aix-nat.c b/gdb/rs6000-aix-nat.c
index 213f197a420..2b0cf8577fa 100644
--- a/gdb/rs6000-aix-nat.c
+++ b/gdb/rs6000-aix-nat.c
@@ -23,7 +23,6 @@
 #include "symfile.h"
 #include "objfiles.h"
 #include "bfd.h"
-#include "gdb-stabs.h"
 #include "regcache.h"
 #include "arch-utils.h"
 #include "inf-child.h"
diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp
index ef6a8f859ef..856c96771c6 100644
--- a/gdb/testsuite/lib/gdb.exp
+++ b/gdb/testsuite/lib/gdb.exp
@@ -6132,6 +6132,12 @@ proc gdb_compile {source dest type options} {
 
     set outdir [file dirname $dest]
 
+    # GDB doesn't support minimal symbols in AIX, so fail the compilation
+    # if nodebug is requested for an AIX target.
+    if { [istarget *-*-aix*] && [lsearch -exact $options nodebug] != -1} {
+	return "minsyms not supported in AIX"
+    }
+
     # If this is set, calling test_compiler_info will cause recursion.
     if { [lsearch -exact $options getting_compiler_info] == -1 } {
 	set getting_compiler_info false
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
index d8b99a05911..2e63ab73132 100644
--- a/gdb/xcoffread.c
+++ b/gdb/xcoffread.c
@@ -42,18 +42,12 @@
 #include "symfile.h"
 #include "objfiles.h"
 #include "buildsym-legacy.h"
-#include "stabsread.h"
 #include "expression.h"
 #include "complaints.h"
 #include "psymtab.h"
 #include "dwarf2/sect-names.h"
 #include "dwarf2/public.h"
 
-#include "gdb-stabs.h"
-
-/* For interface with stabsread.c.  */
-#include "aout/stab_gnu.h"
-
 \f
 /* We put a pointer to this structure in the read_symtab_private field
    of the psymtab.  */
@@ -78,10 +72,6 @@ struct xcoff_symloc
     unsigned int lineno_off;
   };
 
-/* Remember what we deduced to be the source language of this psymtab.  */
-
-static enum language psymtab_language = language_unknown;
-\f
 
 /* Simplified internal version of coff symbol table information.  */
 
@@ -96,10 +86,6 @@ struct xcoff_symbol
     unsigned int c_type;
   };
 
-/* Last function's saved coff symbol `cs'.  */
-
-static struct xcoff_symbol fcn_cs_saved;
-
 static bfd *symfile_bfd;
 
 /* Core address of start and end of text of current source file.
@@ -109,10 +95,6 @@ static bfd *symfile_bfd;
 
 static CORE_ADDR cur_src_end_addr;
 
-/* Core address of the end of the first object file.  */
-
-static CORE_ADDR first_object_file_end;
-
 /* Initial symbol-table-debug-string vector length.  */
 
 #define	INITIAL_STABVECTOR_LENGTH	40
@@ -187,28 +169,8 @@ bf_notfound_complaint (void)
   complaint (_("line numbers off, `.bf' symbol not found"));
 }
 
-static void
-ef_complaint (int arg1)
-{
-  complaint (_("Mismatched .ef symbol ignored starting at symnum %d"), arg1);
-}
-
-static void
-eb_complaint (int arg1)
-{
-  complaint (_("Mismatched .eb symbol ignored starting at symnum %d"), arg1);
-}
-
 static void xcoff_initial_scan (struct objfile *, symfile_add_flags);
 
-static void scan_xcoff_symtab (minimal_symbol_reader &,
-			       psymtab_storage *partial_symtabs,
-			       struct objfile *);
-
-static const char *xcoff_next_symbol_text (struct objfile *);
-
-static void record_include_begin (struct xcoff_symbol *);
-
 static void
 enter_line_range (struct subfile *, unsigned, unsigned,
 		  CORE_ADDR, CORE_ADDR, unsigned *);
@@ -221,32 +183,13 @@ static void xcoff_new_init (struct objfile *);
 
 static void xcoff_symfile_finish (struct objfile *);
 
-static char *coff_getfilename (union internal_auxent *, struct objfile *);
-
 static void read_symbol (struct internal_syment *, int);
 
 static int read_symbol_lineno (int);
 
 static CORE_ADDR read_symbol_nvalue (int);
 
-static struct symbol *process_xcoff_symbol (struct xcoff_symbol *,
-					    struct objfile *);
-
-static void read_xcoff_symtab (struct objfile *, legacy_psymtab *);
-
-#if 0
-static void add_stab_to_list (char *, struct pending_stabs **);
-#endif
-
-static void record_include_end (struct xcoff_symbol *);
-
 static void process_linenos (CORE_ADDR, CORE_ADDR);
-\f
-
-/* Translate from a COFF section number (target_index) to a SECT_OFF_*
-   code.  */
-static int secnum_to_section (int, struct objfile *);
-static asection *secnum_to_bfd_section (int, struct objfile *);
 
 struct xcoff_find_targ_sec_arg
   {
@@ -256,104 +199,6 @@ struct xcoff_find_targ_sec_arg
     struct objfile *objfile;
   };
 
-static void find_targ_sec (bfd *, asection *, void *);
-
-static void
-find_targ_sec (bfd *abfd, asection *sect, void *obj)
-{
-  struct xcoff_find_targ_sec_arg *args
-    = (struct xcoff_find_targ_sec_arg *) obj;
-  struct objfile *objfile = args->objfile;
-
-  if (sect->target_index == args->targ_index)
-    {
-      /* This is the section.  Figure out what SECT_OFF_* code it is.  */
-      if (bfd_section_flags (sect) & SEC_CODE)
-	*args->resultp = SECT_OFF_TEXT (objfile);
-      else if (bfd_section_flags (sect) & SEC_LOAD)
-	*args->resultp = SECT_OFF_DATA (objfile);
-      else
-	*args->resultp = gdb_bfd_section_index (abfd, sect);
-      *args->bfd_sect = sect;
-    }
-}
-
-/* Search all BFD sections for the section whose target_index is
-   equal to N_SCNUM.  Set *BFD_SECT to that section.  The section's
-   associated index in the objfile's section_offset table is also
-   stored in *SECNUM.
-
-   If no match is found, *BFD_SECT is set to NULL, and *SECNUM
-   is set to the text section's number.  */
-
-static void
-xcoff_secnum_to_sections (int n_scnum, struct objfile *objfile,
-			  asection **bfd_sect, int *secnum)
-{
-  struct xcoff_find_targ_sec_arg args;
-
-  args.targ_index = n_scnum;
-  args.resultp = secnum;
-  args.bfd_sect = bfd_sect;
-  args.objfile = objfile;
-
-  *bfd_sect = NULL;
-  *secnum = SECT_OFF_TEXT (objfile);
-
-  bfd_map_over_sections (objfile->obfd.get (), find_targ_sec, &args);
-}
-
-/* Return the section number (SECT_OFF_*) that N_SCNUM points to.  */
-
-static int
-secnum_to_section (int n_scnum, struct objfile *objfile)
-{
-  int secnum;
-  asection *ignored;
-
-  xcoff_secnum_to_sections (n_scnum, objfile, &ignored, &secnum);
-  return secnum;
-}
-
-/* Return the BFD section that N_SCNUM points to.  */
-
-static asection *
-secnum_to_bfd_section (int n_scnum, struct objfile *objfile)
-{
-  int ignored;
-  asection *bfd_sect;
-
-  xcoff_secnum_to_sections (n_scnum, objfile, &bfd_sect, &ignored);
-  return bfd_sect;
-}
-\f
-/* add a given stab string into given stab vector.  */
-
-#if 0
-
-static void
-add_stab_to_list (char *stabname, struct pending_stabs **stabvector)
-{
-  if (*stabvector == NULL)
-    {
-      *stabvector = (struct pending_stabs *)
-	xmalloc (sizeof (struct pending_stabs) +
-		 INITIAL_STABVECTOR_LENGTH * sizeof (char *));
-      (*stabvector)->count = 0;
-      (*stabvector)->length = INITIAL_STABVECTOR_LENGTH;
-    }
-  else if ((*stabvector)->count >= (*stabvector)->length)
-    {
-      (*stabvector)->length += INITIAL_STABVECTOR_LENGTH;
-      *stabvector = (struct pending_stabs *)
-	xrealloc ((char *) *stabvector, sizeof (struct pending_stabs) +
-		  (*stabvector)->length * sizeof (char *));
-    }
-  (*stabvector)->stab[(*stabvector)->count++] = stabname;
-}
-
-#endif
-\f
 /* Linenos are processed on a file-by-file basis.
 
    Two reasons:
@@ -500,67 +345,6 @@ static int inclDepth;		/* nested include depth */
 /* subfile structure for the main compilation unit.  */
 static subfile *main_subfile;
 
-static void allocate_include_entry (void);
-
-static void
-record_include_begin (struct xcoff_symbol *cs)
-{
-  if (inclDepth)
-    {
-      /* In xcoff, we assume include files cannot be nested (not in .c files
-	 of course, but in corresponding .s files.).  */
-
-      /* This can happen with old versions of GCC.
-	 GCC 2.3.3-930426 does not exhibit this on a test case which
-	 a user said produced the message for him.  */
-      complaint (_("Nested C_BINCL symbols"));
-    }
-  ++inclDepth;
-
-  allocate_include_entry ();
-
-  inclTable[inclIndx].name = cs->c_name;
-  inclTable[inclIndx].begin = cs->c_value;
-}
-
-static void
-record_include_end (struct xcoff_symbol *cs)
-{
-  InclTable *pTbl;
-
-  if (inclDepth == 0)
-    {
-      complaint (_("Mismatched C_BINCL/C_EINCL pair"));
-    }
-
-  allocate_include_entry ();
-
-  pTbl = &inclTable[inclIndx];
-  pTbl->end = cs->c_value;
-
-  --inclDepth;
-  ++inclIndx;
-}
-
-static void
-allocate_include_entry (void)
-{
-  if (inclTable == NULL)
-    {
-      inclTable = XCNEWVEC (InclTable, INITIAL_INCLUDE_TABLE_LENGTH);
-      inclLength = INITIAL_INCLUDE_TABLE_LENGTH;
-      inclIndx = 0;
-      main_subfile = new subfile;
-    }
-  else if (inclIndx >= inclLength)
-    {
-      inclLength += INITIAL_INCLUDE_TABLE_LENGTH;
-      inclTable = XRESIZEVEC (InclTable, inclTable, inclLength);
-      memset (inclTable + inclLength - INITIAL_INCLUDE_TABLE_LENGTH,
-	      '\0', sizeof (InclTable) * INITIAL_INCLUDE_TABLE_LENGTH);
-    }
-}
-
 /* Global variable to pass the psymtab down to all the routines involved
    in psymtab to symtab processing.  */
 static legacy_psymtab *this_symtab_psymtab;
@@ -817,794 +601,10 @@ enter_line_range (struct subfile *subfile, unsigned beginoffset,
 }
 
 
-/* Refill the symbol table input buffer
-   and set the variables that control fetching entries from it.
-   Reports an error if no data available.
-   This function can read past the end of the symbol table
-   (into the string table) but this does no harm.  */
-
-/* Create a new minimal symbol (using record_with_info).
-
-   Creation of all new minimal symbols should go through this function
-   rather than calling the various record functions in order
-   to make sure that all symbol addresses get properly relocated.
-
-   Arguments are:
-
-   NAME - the symbol's name (but if NAME starts with a period, that
-   leading period is discarded).
-   ADDRESS - the symbol's address, prior to relocation.  This function
-      relocates the address before recording the minimal symbol.
-   MS_TYPE - the symbol's type.
-   N_SCNUM - the symbol's XCOFF section number.
-   OBJFILE - the objfile associated with the minimal symbol.  */
-
-static void
-record_minimal_symbol (minimal_symbol_reader &reader,
-		       const char *name, unrelocated_addr address,
-		       enum minimal_symbol_type ms_type,
-		       int n_scnum,
-		       struct objfile *objfile)
-{
-  if (name[0] == '.')
-    ++name;
-
-  reader.record_with_info (name, address, ms_type,
-			   secnum_to_section (n_scnum, objfile));
-}
-
-/* xcoff has static blocks marked in `.bs', `.es' pairs.  They cannot be
-   nested.  At any given time, a symbol can only be in one static block.
-   This is the base address of current static block, zero if non exists.  */
-
-static int static_block_base = 0;
-
-/* Section number for the current static block.  */
-
-static int static_block_section = -1;
-
-/* true if space for symbol name has been allocated.  */
-
-static int symname_alloced = 0;
-
-/* Next symbol to read.  Pointer into raw seething symbol table.  */
-
-static char *raw_symbol;
-
-/* This is the function which stabsread.c calls to get symbol
-   continuations.  */
-
-static const char *
-xcoff_next_symbol_text (struct objfile *objfile)
-{
-  struct internal_syment symbol;
-  const char *retval;
-
-  /* FIXME: is this the same as the passed arg?  */
-  if (this_symtab_objfile)
-    objfile = this_symtab_objfile;
-
-  bfd_coff_swap_sym_in (objfile->obfd.get (), raw_symbol, &symbol);
-  if (symbol.n_zeroes)
-    {
-      complaint (_("Unexpected symbol continuation"));
-
-      /* Return something which points to '\0' and hope the symbol reading
-	 code does something reasonable.  */
-      retval = "";
-    }
-  else if (symbol.n_sclass & 0x80)
-    {
-      retval = XCOFF_DATA (objfile)->debugsec + symbol.n_offset;
-      raw_symbol += coff_data (objfile->obfd)->local_symesz;
-      ++symnum;
-    }
-  else
-    {
-      complaint (_("Unexpected symbol continuation"));
-
-      /* Return something which points to '\0' and hope the symbol reading
-	 code does something reasonable.  */
-      retval = "";
-    }
-  return retval;
-}
-
-/* Read symbols for a given partial symbol table.  */
-
-static void
-read_xcoff_symtab (struct objfile *objfile, legacy_psymtab *pst)
-{
-  bfd *abfd = objfile->obfd.get ();
-  char *raw_auxptr;		/* Pointer to first raw aux entry for sym.  */
-  struct xcoff_symfile_info *xcoff = XCOFF_DATA (objfile);
-  char *strtbl = xcoff->strtbl;
-  char *debugsec = xcoff->debugsec;
-  const char *debugfmt = bfd_xcoff_is_xcoff64 (abfd) ? "XCOFF64" : "XCOFF";
-
-  struct internal_syment symbol[1];
-  union internal_auxent main_aux;
-  struct xcoff_symbol cs[1];
-  CORE_ADDR file_start_addr = 0;
-  CORE_ADDR file_end_addr = 0;
-
-  int next_file_symnum = -1;
-  unsigned int max_symnum;
-  int just_started = 1;
-  int depth = 0;
-  CORE_ADDR fcn_start_addr = 0;
-  enum language pst_symtab_language;
-
-  struct xcoff_symbol fcn_stab_saved = { 0 };
-
-  /* fcn_cs_saved is global because process_xcoff_symbol needs it.  */
-  union internal_auxent fcn_aux_saved {};
-  struct context_stack *newobj;
-
-  const char *filestring = pst->filename;	/* Name of the current file.  */
-
-  const char *last_csect_name;	/* Last seen csect's name.  */
-
-  this_symtab_psymtab = pst;
-  this_symtab_objfile = objfile;
-
-  /* Get the appropriate COFF "constants" related to the file we're
-     handling.  */
-  local_symesz = coff_data (abfd)->local_symesz;
-
-  set_last_source_file (NULL);
-  last_csect_name = 0;
-  pst_symtab_language = deduce_language_from_filename (filestring);
-
-  start_stabs ();
-  start_compunit_symtab (objfile, filestring, NULL, file_start_addr,
-			 pst_symtab_language);
-  record_debugformat (debugfmt);
-  symnum = ((struct xcoff_symloc *) pst->read_symtab_private)->first_symnum;
-  max_symnum =
-    symnum + ((struct xcoff_symloc *) pst->read_symtab_private)->numsyms;
-  first_object_file_end = 0;
-
-  raw_symbol = xcoff->symtbl + symnum * local_symesz;
-
-  while (symnum < max_symnum)
-    {
-      QUIT;			/* make this command interruptible.  */
-
-      /* READ_ONE_SYMBOL (symbol, cs, symname_alloced); */
-      /* read one symbol into `cs' structure.  After processing the
-	 whole symbol table, only string table will be kept in memory,
-	 symbol table and debug section of xcoff will be freed.  Thus
-	 we can mark symbols with names in string table as
-	 `alloced'.  */
-      {
-	int ii;
-
-	/* Swap and align the symbol into a reasonable C structure.  */
-	bfd_coff_swap_sym_in (abfd, raw_symbol, symbol);
-
-	cs->c_symnum = symnum;
-	cs->c_naux = symbol->n_numaux;
-	if (symbol->n_zeroes)
-	  {
-	    symname_alloced = 0;
-	    /* We must use the original, unswapped, name here so the name field
-	       pointed to by cs->c_name will persist throughout xcoffread.  If
-	       we use the new field, it gets overwritten for each symbol.  */
-	    cs->c_name = ((struct external_syment *) raw_symbol)->e.e_name;
-	    /* If it's exactly E_SYMNMLEN characters long it isn't
-	       '\0'-terminated.  */
-	    if (cs->c_name[E_SYMNMLEN - 1] != '\0')
-	      {
-		char *p;
-
-		p = (char *) obstack_alloc (&objfile->objfile_obstack,
-					    E_SYMNMLEN + 1);
-		strncpy (p, cs->c_name, E_SYMNMLEN);
-		p[E_SYMNMLEN] = '\0';
-		cs->c_name = p;
-		symname_alloced = 1;
-	      }
-	  }
-	else if (symbol->n_sclass & 0x80)
-	  {
-	    cs->c_name = debugsec + symbol->n_offset;
-	    symname_alloced = 0;
-	  }
-	else
-	  {
-	    /* in string table */
-	    cs->c_name = strtbl + (int) symbol->n_offset;
-	    symname_alloced = 1;
-	  }
-	cs->c_value = symbol->n_value;
-	cs->c_sclass = symbol->n_sclass;
-	cs->c_secnum = symbol->n_scnum;
-	cs->c_type = (unsigned) symbol->n_type;
-
-	raw_symbol += local_symesz;
-	++symnum;
-
-	/* Save addr of first aux entry.  */
-	raw_auxptr = raw_symbol;
-
-	/* Skip all the auxents associated with this symbol.  */
-	for (ii = symbol->n_numaux; ii; --ii)
-	  {
-	    raw_symbol += coff_data (abfd)->local_auxesz;
-	    ++symnum;
-	  }
-      }
-
-      /* if symbol name starts with ".$" or "$", ignore it.  */
-      if (cs->c_name[0] == '$'
-	  || (cs->c_name[1] == '$' && cs->c_name[0] == '.'))
-	continue;
-
-      if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)
-	{
-	  if (get_last_source_file ())
-	    {
-	      pst->compunit_symtab = end_compunit_symtab (cur_src_end_addr);
-	      end_stabs ();
-	    }
-
-	  start_stabs ();
-	  start_compunit_symtab (objfile, "_globals_", NULL,
-				 0, pst_symtab_language);
-	  record_debugformat (debugfmt);
-	  cur_src_end_addr = first_object_file_end;
-	  /* Done with all files, everything from here on is globals.  */
-	}
-
-      if (cs->c_sclass == C_EXT || cs->c_sclass == C_HIDEXT ||
-	  cs->c_sclass == C_WEAKEXT)
-	{
-	  /* Dealing with a symbol with a csect entry.  */
-
-#define	CSECT(PP) ((PP)->x_csect)
-#define	CSECT_LEN(PP) (CSECT(PP).x_scnlen.u64)
-#define	CSECT_ALIGN(PP) (SMTYP_ALIGN(CSECT(PP).x_smtyp))
-#define	CSECT_SMTYP(PP) (SMTYP_SMTYP(CSECT(PP).x_smtyp))
-#define	CSECT_SCLAS(PP) (CSECT(PP).x_smclas)
-
-	  /* Convert the auxent to something we can access.
-	     XCOFF can have more than one auxiliary entries.
-
-	     Actual functions will have two auxiliary entries, one to have the
-	     function size and other to have the smtype/smclass (LD/PR).
-
-	     c_type value of main symbol table will be set only in case of
-	     C_EXT/C_HIDEEXT/C_WEAKEXT storage class symbols.
-	     Bit 10 of type is set if symbol is a function, ie the value is set
-	     to 32(0x20). So we need to read the first function auxiliary entry
-	     which contains the size. */
-	  if (cs->c_naux > 1 && ISFCN (cs->c_type))
-	    {
-	      /* a function entry point.  */
-
-	      fcn_start_addr = cs->c_value;
-
-	      /* save the function header info, which will be used
-		 when `.bf' is seen.  */
-	      fcn_cs_saved = *cs;
-
-	      /* Convert the auxent to something we can access.  */
-	      bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
-				    0, cs->c_naux, &fcn_aux_saved);
-	      continue;
-	    }
-	  /* Read the csect auxiliary header, which is always the last by
-	     convention. */
-	  bfd_coff_swap_aux_in (abfd,
-			       raw_auxptr
-			       + ((coff_data (abfd)->local_symesz)
-			       * (cs->c_naux - 1)),
-			       cs->c_type, cs->c_sclass,
-			       cs->c_naux - 1, cs->c_naux,
-			       &main_aux);
-
-	  switch (CSECT_SMTYP (&main_aux))
-	    {
-
-	    case XTY_ER:
-	      /* Ignore all external references.  */
-	      continue;
-
-	    case XTY_SD:
-	      /* A section description.  */
-	      {
-		switch (CSECT_SCLAS (&main_aux))
-		  {
-
-		  case XMC_PR:
-		    {
-
-		      /* A program csect is seen.  We have to allocate one
-			 symbol table for each program csect.  Normally gdb
-			 prefers one symtab for each source file.  In case
-			 of AIX, one source file might include more than one
-			 [PR] csect, and they don't have to be adjacent in
-			 terms of the space they occupy in memory.  Thus, one
-			 single source file might get fragmented in the
-			 memory and gdb's file start and end address
-			 approach does not work!  GCC (and I think xlc) seem
-			 to put all the code in the unnamed program csect.  */
-
-		      if (last_csect_name)
-			{
-			  complete_symtab (filestring, file_start_addr);
-			  cur_src_end_addr = file_end_addr;
-			  end_compunit_symtab (file_end_addr);
-			  end_stabs ();
-			  start_stabs ();
-			  /* Give all csects for this source file the same
-			     name.  */
-			  start_compunit_symtab (objfile, filestring, NULL,
-						 0, pst_symtab_language);
-			  record_debugformat (debugfmt);
-			}
-
-		      /* If this is the very first csect seen,
-			 basically `__start'.  */
-		      if (just_started)
-			{
-			  first_object_file_end
-			    = cs->c_value + CSECT_LEN (&main_aux);
-			  just_started = 0;
-			}
-
-		      file_start_addr =
-			cs->c_value + objfile->text_section_offset ();
-		      file_end_addr = file_start_addr + CSECT_LEN (&main_aux);
-
-		      if (cs->c_name && (cs->c_name[0] == '.' || cs->c_name[0] == '@'))
-			last_csect_name = cs->c_name;
-		    }
-		    continue;
-
-		    /* All other symbols are put into the minimal symbol
-		       table only.  */
-
-		  case XMC_RW:
-		    continue;
-
-		  case XMC_TC0:
-		    continue;
-
-		  case XMC_TC:
-		    continue;
-
-		  default:
-		    /* Ignore the symbol.  */
-		    continue;
-		  }
-	      }
-	      break;
-
-	    case XTY_LD:
-
-	      switch (CSECT_SCLAS (&main_aux))
-		{
-		/* We never really come to this part as this case has been
-		   handled in ISFCN check above.
-		   This and other cases of XTY_LD are kept just for
-		   reference. */
-		case XMC_PR:
-		  continue;
-
-		case XMC_GL:
-		  /* shared library function trampoline code entry point.  */
-		  continue;
-
-		case XMC_DS:
-		  /* The symbols often have the same names as debug symbols for
-		     functions, and confuse lookup_symbol.  */
-		  continue;
-
-		default:
-		  /* xlc puts each variable in a separate csect, so we get
-		     an XTY_SD for each variable.  But gcc puts several
-		     variables in a csect, so that each variable only gets
-		     an XTY_LD.  This will typically be XMC_RW; I suspect
-		     XMC_RO and XMC_BS might be possible too.
-		     These variables are put in the minimal symbol table
-		     only.  */
-		  continue;
-		}
-	      break;
-
-	    case XTY_CM:
-	      /* Common symbols are put into the minimal symbol table only.  */
-	      continue;
-
-	    default:
-	      break;
-	    }
-	}
-
-      switch (cs->c_sclass)
-	{
-	case C_FILE:
-
-	  /* c_value field contains symnum of next .file entry in table
-	     or symnum of first global after last .file.  */
-
-	  next_file_symnum = cs->c_value;
-
-	  /* Complete symbol table for last object file containing
-	     debugging information.  */
-
-	  /* Whether or not there was a csect in the previous file, we
-	     have to call `end_stabs' and `start_stabs' to reset
-	     type_vector, line_vector, etc. structures.  */
-
-	  complete_symtab (filestring, file_start_addr);
-	  cur_src_end_addr = file_end_addr;
-	  end_compunit_symtab (file_end_addr);
-	  end_stabs ();
-
-	  /* XCOFF, according to the AIX 3.2 documentation, puts the
-	     filename in cs->c_name.  But xlc 1.3.0.2 has decided to
-	     do things the standard COFF way and put it in the auxent.
-	     We use the auxent if the symbol is ".file" and an auxent
-	     exists, otherwise use the symbol itself.  Simple
-	     enough.  */
-	  if (!strcmp (cs->c_name, ".file") && cs->c_naux > 0)
-	    {
-	      bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
-				    0, cs->c_naux, &main_aux);
-	      filestring = coff_getfilename (&main_aux, objfile);
-	    }
-	  else
-	    filestring = cs->c_name;
-
-	  start_stabs ();
-	  start_compunit_symtab (objfile, filestring, NULL, 0,
-				 pst_symtab_language);
-	  record_debugformat (debugfmt);
-	  last_csect_name = 0;
-
-	  /* reset file start and end addresses.  A compilation unit
-	     with no text (only data) should have zero file
-	     boundaries.  */
-	  file_start_addr = file_end_addr = 0;
-	  break;
-
-	case C_FUN:
-	  fcn_stab_saved = *cs;
-	  break;
-
-	case C_FCN:
-	  if (strcmp (cs->c_name, ".bf") == 0)
-	    {
-	      CORE_ADDR off = objfile->text_section_offset ();
-
-	      bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
-				    0, cs->c_naux, &main_aux);
-
-	      within_function = 1;
-
-	      newobj = push_context (0, fcn_start_addr + off);
-
-	      newobj->name = define_symbol
-		(fcn_cs_saved.c_value + off,
-		 fcn_stab_saved.c_name, 0, 0, objfile);
-	      if (newobj->name != NULL)
-		newobj->name->set_section_index (SECT_OFF_TEXT (objfile));
-	    }
-	  else if (strcmp (cs->c_name, ".ef") == 0)
-	    {
-	      bfd_coff_swap_aux_in (abfd, raw_auxptr, cs->c_type, cs->c_sclass,
-				    0, cs->c_naux, &main_aux);
-
-	      /* The value of .ef is the address of epilogue code;
-		 not useful for gdb.  */
-	      /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
-		 contains number of lines to '}' */
-
-	      if (outermost_context_p ())
-		{	/* We attempted to pop an empty context stack.  */
-		  ef_complaint (cs->c_symnum);
-		  within_function = 0;
-		  break;
-		}
-	      struct context_stack cstk = pop_context ();
-	      /* Stack must be empty now.  */
-	      if (!outermost_context_p ())
-		{
-		  ef_complaint (cs->c_symnum);
-		  within_function = 0;
-		  break;
-		}
-
-	      finish_block (cstk.name, cstk.old_blocks,
-			    NULL, cstk.start_addr,
-			    (fcn_cs_saved.c_value
-			     + fcn_aux_saved.x_sym.x_misc.x_fsize
-			     + objfile->text_section_offset ()));
-	      within_function = 0;
-	    }
-	  break;
-
-	case C_BSTAT:
-	  /* Begin static block.  */
-	  {
-	    struct internal_syment static_symbol;
-
-	    read_symbol (&static_symbol, cs->c_value);
-	    static_block_base = static_symbol.n_value;
-	    static_block_section =
-	      secnum_to_section (static_symbol.n_scnum, objfile);
-	  }
-	  break;
-
-	case C_ESTAT:
-	  /* End of static block.  */
-	  static_block_base = 0;
-	  static_block_section = -1;
-	  break;
-
-	case C_ARG:
-	case C_REGPARM:
-	case C_REG:
-	case C_TPDEF:
-	case C_STRTAG:
-	case C_UNTAG:
-	case C_ENTAG:
-	  {
-	    complaint (_("Unrecognized storage class %d."),
-		       cs->c_sclass);
-	  }
-	  break;
-
-	case C_LABEL:
-	case C_NULL:
-	  /* Ignore these.  */
-	  break;
-
-	case C_HIDEXT:
-	case C_STAT:
-	  break;
-
-	case C_BINCL:
-	  /* beginning of include file */
-	  /* In xlc output, C_BINCL/C_EINCL pair doesn't show up in sorted
-	     order.  Thus, when we see them, we might not know enough info
-	     to process them.  Thus, we'll be saving them into a table 
-	     (inclTable) and postpone their processing.  */
-
-	  record_include_begin (cs);
-	  break;
-
-	case C_EINCL:
-	  /* End of include file.  */
-	  /* See the comment after case C_BINCL.  */
-	  record_include_end (cs);
-	  break;
-
-	case C_BLOCK:
-	  if (strcmp (cs->c_name, ".bb") == 0)
-	    {
-	      depth++;
-	      newobj = push_context (depth,
-				  (cs->c_value
-				   + objfile->text_section_offset ()));
-	    }
-	  else if (strcmp (cs->c_name, ".eb") == 0)
-	    {
-	      if (outermost_context_p ())
-		{	/* We attempted to pop an empty context stack.  */
-		  eb_complaint (cs->c_symnum);
-		  break;
-		}
-	      struct context_stack cstk = pop_context ();
-	      if (depth-- != cstk.depth)
-		{
-		  eb_complaint (cs->c_symnum);
-		  break;
-		}
-	      if (*get_local_symbols () && !outermost_context_p ())
-		{
-		  /* Make a block for the local symbols within.  */
-		  finish_block (cstk.name,
-				cstk.old_blocks, NULL,
-				cstk.start_addr,
-				(cs->c_value
-				 + objfile->text_section_offset ()));
-		}
-	      *get_local_symbols () = cstk.locals;
-	    }
-	  break;
-
-	default:
-	  process_xcoff_symbol (cs, objfile);
-	  break;
-	}
-    }
-
-  if (get_last_source_file ())
-    {
-      struct compunit_symtab *cust;
-
-      complete_symtab (filestring, file_start_addr);
-      cur_src_end_addr = file_end_addr;
-      cust = end_compunit_symtab (file_end_addr);
-      /* When reading symbols for the last C_FILE of the objfile, try
-	 to make sure that we set pst->compunit_symtab to the symtab for the
-	 file, not to the _globals_ symtab.  I'm not sure whether this
-	 actually works right or when/if it comes up.  */
-      if (pst->compunit_symtab == NULL)
-	pst->compunit_symtab = cust;
-      end_stabs ();
-    }
-}
-
 #define	SYMNAME_ALLOC(NAME, ALLOCED)	\
   ((ALLOCED) ? (NAME) : obstack_strdup (&objfile->objfile_obstack, \
 					(NAME)))
 
-
-/* process one xcoff symbol.  */
-
-static struct symbol *
-process_xcoff_symbol (struct xcoff_symbol *cs, struct objfile *objfile)
-{
-  struct symbol onesymbol;
-  struct symbol *sym = &onesymbol;
-  struct symbol *sym2 = NULL;
-  char *name, *pp;
-
-  int sec;
-  CORE_ADDR off;
-
-  if (cs->c_secnum < 0)
-    {
-      /* The value is a register number, offset within a frame, etc.,
-	 and does not get relocated.  */
-      off = 0;
-      sec = -1;
-    }
-  else
-    {
-      sec = secnum_to_section (cs->c_secnum, objfile);
-      off = objfile->section_offsets[sec];
-    }
-
-  name = cs->c_name;
-  if (name[0] == '.')
-    ++name;
-
-  /* default assumptions */
-  sym->set_value_address (cs->c_value + off);
-  sym->set_domain (VAR_DOMAIN);
-  sym->set_section_index (secnum_to_section (cs->c_secnum, objfile));
-
-  if (ISFCN (cs->c_type))
-    {
-      /* At this point, we don't know the type of the function.  This
-	 will be patched with the type from its stab entry later on in
-	 patch_block_stabs (), unless the file was compiled without -g.  */
-
-      sym->set_linkage_name (SYMNAME_ALLOC (name, symname_alloced));
-      sym->set_type (builtin_type (objfile)->nodebug_text_symbol);
-
-      sym->set_domain (FUNCTION_DOMAIN);
-      sym->set_loc_class_index (LOC_BLOCK);
-      sym2 = new (&objfile->objfile_obstack) symbol (*sym);
-
-      if (cs->c_sclass == C_EXT || C_WEAKEXT)
-	add_symbol_to_list (sym2, get_global_symbols ());
-      else if (cs->c_sclass == C_HIDEXT || cs->c_sclass == C_STAT)
-	add_symbol_to_list (sym2, get_file_symbols ());
-    }
-  else
-    {
-      /* In case we can't figure out the type, provide default.  */
-      sym->set_type (builtin_type (objfile)->nodebug_data_symbol);
-
-      switch (cs->c_sclass)
-	{
-#if 0
-	  /* The values of functions and global symbols are now resolved
-	     via the global_sym_chain in stabsread.c.  */
-	case C_FUN:
-	  if (fcn_cs_saved.c_sclass == C_EXT)
-	    add_stab_to_list (name, &global_stabs);
-	  else
-	    add_stab_to_list (name, &file_stabs);
-	  break;
-
-	case C_GSYM:
-	  add_stab_to_list (name, &global_stabs);
-	  break;
-#endif
-
-	case C_BCOMM:
-	  common_block_start (cs->c_name, objfile);
-	  break;
-
-	case C_ECOMM:
-	  common_block_end (objfile);
-	  break;
-
-	default:
-	  complaint (_("Unexpected storage class: %d"),
-		     cs->c_sclass);
-	  [[fallthrough]];
-
-	case C_DECL:
-	case C_PSYM:
-	case C_RPSYM:
-	case C_ECOML:
-	case C_LSYM:
-	case C_RSYM:
-	case C_GSYM:
-
-	  {
-	    sym = define_symbol (cs->c_value + off, cs->c_name, 0, 0, objfile);
-	    if (sym != NULL)
-	      {
-		sym->set_section_index (sec);
-	      }
-	    return sym;
-	  }
-
-	case C_STSYM:
-
-	  /* For xlc (not GCC), the 'V' symbol descriptor is used for
-	     all statics and we need to distinguish file-scope versus
-	     function-scope using within_function.  We do this by
-	     changing the string we pass to define_symbol to use 'S'
-	     where we need to, which is not necessarily super-clean,
-	     but seems workable enough.  */
-
-	  if (*name == ':')
-	    return NULL;
-
-	  pp = strchr (name, ':');
-	  if (pp == NULL)
-	    return NULL;
-
-	  ++pp;
-	  if (*pp == 'V' && !within_function)
-	    *pp = 'S';
-	  sym = define_symbol ((cs->c_value
-				+ objfile->section_offsets[static_block_section]),
-			       cs->c_name, 0, 0, objfile);
-	  if (sym != NULL)
-	    {
-	      sym->set_value_address
-		(sym->value_address () + static_block_base);
-	      sym->set_section_index (static_block_section);
-	    }
-	  return sym;
-
-	}
-    }
-  return sym2;
-}
-
-/* Extract the file name from the aux entry of a C_FILE symbol.
-   Result is in static storage and is only good for temporary use.  */
-
-static char *
-coff_getfilename (union internal_auxent *aux_entry, struct objfile *objfile)
-{
-  static char buffer[BUFSIZ];
-
-  if (aux_entry->x_file.x_n.x_n.x_zeroes == 0)
-    strcpy (buffer, (XCOFF_DATA (objfile)->strtbl
-		     + aux_entry->x_file.x_n.x_n.x_offset));
-  else
-    {
-      size_t x_fname_len = sizeof (aux_entry->x_file.x_n.x_fname);
-      strncpy (buffer, aux_entry->x_file.x_n.x_fname, x_fname_len);
-      buffer[x_fname_len] = '\0';
-    }
-  return (buffer);
-}
-
 /* Set *SYMBOL to symbol number symno in symtbl.  */
 static void
 read_symbol (struct internal_syment *symbol, int symno)
@@ -1732,52 +732,10 @@ find_linenos (struct bfd *abfd, struct bfd_section *asect, void *vpinfo)
   if (maxoff > info->max_lineno_offset)
     info->max_lineno_offset = maxoff;
 }
-\f
-static void
-xcoff_expand_psymtab (legacy_psymtab *pst, struct objfile *objfile)
-{
-  gdb_assert (!pst->readin);
 
-  /* Read in all partial symtabs on which this one is dependent.  */
-  pst->expand_dependencies (objfile);
-
-  if (((struct xcoff_symloc *) pst->read_symtab_private)->numsyms != 0)
-    {
-      /* Init stuff necessary for reading in symbols.  */
-      stabsread_init ();
-
-      scoped_free_pendings free_pending;
-      read_xcoff_symtab (objfile, pst);
-    }
-
-  pst->readin = true;
-}
-
-/* Read in all of the symbols for a given psymtab for real.
-   Be verbose about it if the user wants that.  SELF is not NULL.  */
-
-static void
-xcoff_read_symtab (legacy_psymtab *self, struct objfile *objfile)
-{
-  gdb_assert (!self->readin);
-
-  if (((struct xcoff_symloc *) self->read_symtab_private)->numsyms != 0
-      || self->number_of_dependencies)
-    {
-      next_symbol_text_func = xcoff_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);
-    }
-}
-\f
 static void
 xcoff_new_init (struct objfile *objfile)
 {
-  stabsread_new_init ();
 }
 
 /* Do initialization in preparation for reading symbols from OBJFILE.
@@ -1859,906 +817,6 @@ init_stringtab (bfd *abfd, file_ptr offset, struct objfile *objfile)
 
   return;
 }
-\f
-/* If we have not yet seen a function for this psymtab, this is 0.  If we
-   have seen one, it is the offset in the line numbers of the line numbers
-   for the psymtab.  */
-static unsigned int first_fun_line_offset;
-
-/* Allocate and partially fill a partial symtab.  It will be
-   completely filled at the end of the symbol list.
-
-   SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR
-   is the address relative to which its symbols are (incremental) or 0
-   (normal).  */
-
-static legacy_psymtab *
-xcoff_start_psymtab (psymtab_storage *partial_symtabs,
-		     struct objfile *objfile,
-		     const char *filename, int first_symnum)
-{
-  /* We fill in textlow later.  */
-  legacy_psymtab *result = new legacy_psymtab (filename, partial_symtabs,
-					       objfile->per_bfd,
-					       unrelocated_addr (0));
-
-  result->read_symtab_private =
-    XOBNEW (&objfile->objfile_obstack, struct xcoff_symloc);
-  ((struct xcoff_symloc *) result->read_symtab_private)->first_symnum = first_symnum;
-  result->legacy_read_symtab = xcoff_read_symtab;
-  result->legacy_expand_psymtab = xcoff_expand_psymtab;
-
-  /* Deduce the source language from the filename for this psymtab.  */
-  psymtab_language = deduce_language_from_filename (filename);
-
-  return result;
-}
-
-/* Close off the current usage of PST.
-   Returns PST, or NULL if the partial symtab was empty and thrown away.
-
-   CAPPING_SYMBOL_NUMBER is the end of pst (exclusive).
-
-   INCLUDE_LIST, NUM_INCLUDES, DEPENDENCY_LIST, and NUMBER_DEPENDENCIES
-   are the information for includes and dependencies.  */
-
-static legacy_psymtab *
-xcoff_end_psymtab (struct objfile *objfile, psymtab_storage *partial_symtabs,
-		   legacy_psymtab *pst,
-		   const char **include_list, int num_includes,
-		   int capping_symbol_number,
-		   legacy_psymtab **dependency_list,
-		   int number_dependencies, int textlow_not_set)
-{
-  int i;
-
-  if (capping_symbol_number != -1)
-    ((struct xcoff_symloc *) pst->read_symtab_private)->numsyms =
-      capping_symbol_number
-      - ((struct xcoff_symloc *) pst->read_symtab_private)->first_symnum;
-  ((struct xcoff_symloc *) pst->read_symtab_private)->lineno_off =
-    first_fun_line_offset;
-  first_fun_line_offset = 0;
-
-  pst->end ();
-
-  pst->number_of_dependencies = number_dependencies;
-  if (number_dependencies)
-    {
-      pst->dependencies
-	= partial_symtabs->allocate_dependencies (number_dependencies);
-      memcpy (pst->dependencies, dependency_list,
-	      number_dependencies * sizeof (legacy_psymtab *));
-    }
-  else
-    pst->dependencies = 0;
-
-  for (i = 0; i < num_includes; i++)
-    {
-      legacy_psymtab *subpst =
-	new legacy_psymtab (include_list[i], partial_symtabs, objfile->per_bfd);
-
-      subpst->read_symtab_private = XOBNEW (&objfile->objfile_obstack, xcoff_symloc);
-      ((struct xcoff_symloc *) subpst->read_symtab_private)->first_symnum = 0;
-      ((struct xcoff_symloc *) subpst->read_symtab_private)->numsyms = 0;
-
-      /* We could save slight bits of space by only making one of these,
-	 shared by the entire set of include files.  FIXME-someday.  */
-      subpst->dependencies =
-	partial_symtabs->allocate_dependencies (1);
-      subpst->dependencies[0] = pst;
-      subpst->number_of_dependencies = 1;
-
-      subpst->legacy_read_symtab = pst->legacy_read_symtab;
-      subpst->legacy_expand_psymtab = pst->legacy_expand_psymtab;
-    }
-
-  if (num_includes == 0
-      && number_dependencies == 0
-      && pst->empty ())
-    {
-      /* Throw away this psymtab, it's empty.  */
-      /* Empty psymtabs happen as a result of header files which don't have
-	 any symbols in them.  There can be a lot of them.  */
-
-      partial_symtabs->discard_psymtab (pst);
-
-      /* Indicate that psymtab was thrown away.  */
-      pst = NULL;
-    }
-  return pst;
-}
-
-/* Swap raw symbol at *RAW and put the name in *NAME, the symbol in
-   *SYMBOL, the first auxent in *AUX.  Advance *RAW and *SYMNUMP over
-   the symbol and its auxents.  */
-
-static void
-swap_sym (struct internal_syment *symbol, union internal_auxent *aux,
-	  const char **name, char **raw, unsigned int *symnump,
-	  struct objfile *objfile)
-{
-  bfd_coff_swap_sym_in (objfile->obfd.get (), *raw, symbol);
-  if (symbol->n_zeroes)
-    {
-      /* If it's exactly E_SYMNMLEN characters long it isn't
-	 '\0'-terminated.  */
-      if (symbol->n_name[E_SYMNMLEN - 1] != '\0')
-	{
-	  /* FIXME: wastes memory for symbols which we don't end up putting
-	     into the minimal symbols.  */
-	  char *p;
-
-	  p = (char *) obstack_alloc (&objfile->objfile_obstack,
-				      E_SYMNMLEN + 1);
-	  strncpy (p, symbol->n_name, E_SYMNMLEN);
-	  p[E_SYMNMLEN] = '\0';
-	  *name = p;
-	}
-      else
-	/* Point to the unswapped name as that persists as long as the
-	   objfile does.  */
-	*name = ((struct external_syment *) *raw)->e.e_name;
-    }
-  else if (symbol->n_sclass & 0x80)
-    {
-      *name = XCOFF_DATA (objfile)->debugsec + symbol->n_offset;
-    }
-  else
-    {
-      *name = XCOFF_DATA (objfile)->strtbl + symbol->n_offset;
-    }
-  ++*symnump;
-  *raw += coff_data (objfile->obfd)->local_symesz;
-  if (symbol->n_numaux > 0)
-    {
-      bfd_coff_swap_aux_in (objfile->obfd.get (), *raw, symbol->n_type,
-			    symbol->n_sclass, 0, symbol->n_numaux, aux);
-
-      *symnump += symbol->n_numaux;
-      *raw += coff_data (objfile->obfd)->local_symesz * symbol->n_numaux;
-    }
-}
-
-static void
-function_outside_compilation_unit_complaint (const char *arg1)
-{
-  complaint (_("function `%s' appears to be defined "
-	       "outside of all compilation units"),
-	     arg1);
-}
-
-static void
-scan_xcoff_symtab (minimal_symbol_reader &reader,
-		   psymtab_storage *partial_symtabs,
-		   struct objfile *objfile)
-{
-  CORE_ADDR toc_offset = 0;	/* toc offset value in data section.  */
-  const char *filestring = NULL;
-
-  const char *namestring;
-  bfd *abfd;
-  asection *bfd_sect;
-  unsigned int nsyms;
-
-  /* Current partial symtab */
-  legacy_psymtab *pst;
-
-  /* List of current psymtab's include files.  */
-  const char **psymtab_include_list;
-  int includes_allocated;
-  int includes_used;
-
-  /* Index within current psymtab dependency list.  */
-  legacy_psymtab **dependency_list;
-  int dependencies_used, dependencies_allocated;
-
-  char *sraw_symbol;
-  struct internal_syment symbol;
-  union internal_auxent main_aux[5];
-  unsigned int ssymnum;
-
-  const char *last_csect_name = NULL; /* Last seen csect's name and value.  */
-  unrelocated_addr last_csect_val = unrelocated_addr (0);
-  int last_csect_sec = 0;
-  int misc_func_recorded = 0;	/* true if any misc. function.  */
-  int textlow_not_set = 1;
-
-  pst = (legacy_psymtab *) 0;
-
-  includes_allocated = 30;
-  includes_used = 0;
-  psymtab_include_list = (const char **) alloca (includes_allocated *
-						 sizeof (const char *));
-
-  dependencies_allocated = 30;
-  dependencies_used = 0;
-  dependency_list =
-    (legacy_psymtab **) alloca (dependencies_allocated *
-				       sizeof (legacy_psymtab *));
-
-  set_last_source_file (NULL);
-
-  abfd = objfile->obfd.get ();
-  next_symbol_text_func = xcoff_next_symbol_text;
-
-  sraw_symbol = XCOFF_DATA (objfile)->symtbl;
-  nsyms = XCOFF_DATA (objfile)->symtbl_num_syms;
-  ssymnum = 0;
-  while (ssymnum < nsyms)
-    {
-      int sclass;
-
-      QUIT;
-
-      bfd_coff_swap_sym_in (abfd, sraw_symbol, &symbol);
-      sclass = symbol.n_sclass;
-
-      switch (sclass)
-	{
-	case C_EXT:
-	case C_HIDEXT:
-	case C_WEAKEXT:
-	  {
-	    /* The CSECT auxent--always the last auxent.  */
-	    union internal_auxent csect_aux;
-	    unsigned int symnum_before = ssymnum;
-
-	    swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
-		      &ssymnum, objfile);
-	    if (symbol.n_numaux > 1)
-	      {
-		bfd_coff_swap_aux_in
-		  (objfile->obfd.get (),
-		   sraw_symbol - coff_data (abfd)->local_symesz,
-		   symbol.n_type,
-		   symbol.n_sclass,
-		   symbol.n_numaux - 1,
-		   symbol.n_numaux,
-		   &csect_aux);
-	      }
-	    else
-	      csect_aux = main_aux[0];
-
-	    /* If symbol name starts with ".$" or "$", ignore it.  */
-	    if (namestring[0] == '$'
-		|| (namestring[0] == '.' && namestring[1] == '$'))
-	      break;
-
-	    switch (csect_aux.x_csect.x_smtyp & 0x7)
-	      {
-	      case XTY_SD:
-		switch (csect_aux.x_csect.x_smclas)
-		  {
-		  case XMC_PR:
-		    if (last_csect_name)
-		      {
-			/* If no misc. function recorded in the last
-			   seen csect, enter it as a function.  This
-			   will take care of functions like strcmp()
-			   compiled by xlc.  */
-
-			if (!misc_func_recorded)
-			  {
-			    record_minimal_symbol
-			      (reader, last_csect_name, last_csect_val,
-			       mst_text, last_csect_sec, objfile);
-			    misc_func_recorded = 1;
-			  }
-
-			if (pst != NULL)
-			  {
-			    /* We have to allocate one psymtab for
-			       each program csect, because their text
-			       sections need not be adjacent.  */
-			    xcoff_end_psymtab
-			      (objfile, partial_symtabs, pst, psymtab_include_list,
-			       includes_used, symnum_before, dependency_list,
-			       dependencies_used, textlow_not_set);
-			    includes_used = 0;
-			    dependencies_used = 0;
-			    /* Give all psymtabs for this source file the same
-			       name.  */
-			    pst = xcoff_start_psymtab
-			      (partial_symtabs, objfile,
-			       filestring,
-			       symnum_before);
-			  }
-		      }
-		    /* Activate the misc_func_recorded mechanism for
-		       compiler- and linker-generated CSECTs like ".strcmp"
-		       and "@FIX1".  */ 
-		    if (namestring && (namestring[0] == '.'
-				       || namestring[0] == '@'))
-		      {
-			last_csect_name = namestring;
-			last_csect_val = unrelocated_addr (symbol.n_value);
-			last_csect_sec = symbol.n_scnum;
-		      }
-		    if (pst != NULL)
-		      {
-			unrelocated_addr highval
-			  = unrelocated_addr (symbol.n_value
-					      + CSECT_LEN (&csect_aux));
-
-			if (highval > pst->unrelocated_text_high ())
-			  pst->set_text_high (highval);
-			unrelocated_addr loval
-			  = unrelocated_addr (symbol.n_value);
-			if (!pst->text_low_valid
-			    || loval < pst->unrelocated_text_low ())
-			  pst->set_text_low (loval);
-		      }
-		    misc_func_recorded = 0;
-		    break;
-
-		  case XMC_RW:
-		  case XMC_TD:
-		    /* Data variables are recorded in the minimal symbol
-		       table, except for section symbols.  */
-		    if (*namestring != '.')
-		      record_minimal_symbol
-			(reader, namestring, unrelocated_addr (symbol.n_value),
-			 sclass == C_HIDEXT ? mst_file_data : mst_data,
-			 symbol.n_scnum, objfile);
-		    break;
-
-		  case XMC_TC0:
-		    if (toc_offset)
-		      warning (_("More than one XMC_TC0 symbol found."));
-		    toc_offset = symbol.n_value;
-
-		    /* Make TOC offset relative to start address of
-		       section.  */
-		    bfd_sect = secnum_to_bfd_section (symbol.n_scnum, objfile);
-		    if (bfd_sect)
-		      toc_offset -= bfd_section_vma (bfd_sect);
-		    break;
-
-		  case XMC_TC:
-		    /* These symbols tell us where the TOC entry for a
-		       variable is, not the variable itself.  */
-		    break;
-
-		  default:
-		    break;
-		  }
-		break;
-
-	      case XTY_LD:
-		switch (csect_aux.x_csect.x_smclas)
-		  {
-		  case XMC_PR:
-		    /* A function entry point.  */
-
-		    if (first_fun_line_offset == 0 && symbol.n_numaux > 1)
-		      first_fun_line_offset =
-			main_aux[0].x_sym.x_fcnary.x_fcn.x_lnnoptr;
-
-		    record_minimal_symbol
-		      (reader, namestring, unrelocated_addr (symbol.n_value),
-		       sclass == C_HIDEXT ? mst_file_text : mst_text,
-		       symbol.n_scnum, objfile);
-		    misc_func_recorded = 1;
-		    break;
-
-		  case XMC_GL:
-		    /* shared library function trampoline code entry
-		       point.  */
-
-		    /* record trampoline code entries as
-		       mst_solib_trampoline symbol.  When we lookup mst
-		       symbols, we will choose mst_text over
-		       mst_solib_trampoline.  */
-		    record_minimal_symbol
-		      (reader, namestring, unrelocated_addr (symbol.n_value),
-		       mst_solib_trampoline, symbol.n_scnum, objfile);
-		    misc_func_recorded = 1;
-		    break;
-
-		  case XMC_DS:
-		    /* The symbols often have the same names as
-		       debug symbols for functions, and confuse
-		       lookup_symbol.  */
-		    break;
-
-		  default:
-
-		    /* xlc puts each variable in a separate csect,
-		       so we get an XTY_SD for each variable.  But
-		       gcc puts several variables in a csect, so
-		       that each variable only gets an XTY_LD.  We
-		       still need to record them.  This will
-		       typically be XMC_RW; I suspect XMC_RO and
-		       XMC_BS might be possible too.  */
-		    if (*namestring != '.')
-		      record_minimal_symbol
-			(reader, namestring, unrelocated_addr (symbol.n_value),
-			 sclass == C_HIDEXT ? mst_file_data : mst_data,
-			 symbol.n_scnum, objfile);
-		    break;
-		  }
-		break;
-
-	      case XTY_CM:
-		switch (csect_aux.x_csect.x_smclas)
-		  {
-		  case XMC_RW:
-		  case XMC_BS:
-		    /* Common variables are recorded in the minimal symbol
-		       table, except for section symbols.  */
-		    if (*namestring != '.')
-		      record_minimal_symbol
-			(reader, namestring, unrelocated_addr (symbol.n_value),
-			 sclass == C_HIDEXT ? mst_file_bss : mst_bss,
-			 symbol.n_scnum, objfile);
-		    break;
-		  }
-		break;
-
-	      default:
-		break;
-	      }
-	  }
-	  break;
-	case C_FILE:
-	  {
-	    unsigned int symnum_before;
-
-	    symnum_before = ssymnum;
-	    swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
-		      &ssymnum, objfile);
-
-	    /* See if the last csect needs to be recorded.  */
-
-	    if (last_csect_name && !misc_func_recorded)
-	      {
-		/* If no misc. function recorded in the last seen csect, enter
-		   it as a function.  This will take care of functions like
-		   strcmp() compiled by xlc.  */
-
-		record_minimal_symbol (reader, last_csect_name, last_csect_val,
-				       mst_text, last_csect_sec, objfile);
-		misc_func_recorded = 1;
-	      }
-
-	    if (pst)
-	      {
-		xcoff_end_psymtab (objfile, partial_symtabs,
-				   pst, psymtab_include_list,
-				   includes_used, symnum_before,
-				   dependency_list, dependencies_used,
-				   textlow_not_set);
-		includes_used = 0;
-		dependencies_used = 0;
-	      }
-	    first_fun_line_offset = 0;
-
-	    /* XCOFF, according to the AIX 3.2 documentation, puts the
-	       filename in cs->c_name.  But xlc 1.3.0.2 has decided to
-	       do things the standard COFF way and put it in the auxent.
-	       We use the auxent if the symbol is ".file" and an auxent
-	       exists, otherwise use the symbol itself.  */
-	    if (!strcmp (namestring, ".file") && symbol.n_numaux > 0)
-	      {
-		filestring = coff_getfilename (&main_aux[0], objfile);
-	      }
-	    else
-	      filestring = namestring;
-
-	    pst = xcoff_start_psymtab (partial_symtabs, objfile,
-				       filestring,
-				       symnum_before);
-	    last_csect_name = NULL;
-	  }
-	  break;
-
-	default:
-	  {
-	    complaint (_("Storage class %d not recognized during scan"),
-		       sclass);
-	  }
-	  [[fallthrough]];
-
-	case C_FCN:
-	  /* C_FCN is .bf and .ef symbols.  I think it is sufficient
-	     to handle only the C_FUN and C_EXT.  */
-
-	case C_BSTAT:
-	case C_ESTAT:
-	case C_ARG:
-	case C_REGPARM:
-	case C_REG:
-	case C_TPDEF:
-	case C_STRTAG:
-	case C_UNTAG:
-	case C_ENTAG:
-	case C_LABEL:
-	case C_NULL:
-
-	  /* C_EINCL means we are switching back to the main file.  But there
-	     is no reason to care; the only thing we want to know about
-	     includes is the names of all the included (.h) files.  */
-	case C_EINCL:
-
-	case C_BLOCK:
-
-	  /* I don't think C_STAT is used in xcoff; C_HIDEXT appears to be
-	     used instead.  */
-	case C_STAT:
-
-	  /* I don't think the name of the common block (as opposed to the
-	     variables within it) is something which is user visible
-	     currently.  */
-	case C_BCOMM:
-	case C_ECOMM:
-
-	case C_PSYM:
-	case C_RPSYM:
-
-	  /* I think we can ignore C_LSYM; types on xcoff seem to use C_DECL
-	     so C_LSYM would appear to be only for locals.  */
-	case C_LSYM:
-
-	case C_AUTO:
-	case C_RSYM:
-	  {
-	    /* We probably could save a few instructions by assuming that
-	       C_LSYM, C_PSYM, etc., never have auxents.  */
-	    int naux1 = symbol.n_numaux + 1;
-
-	    ssymnum += naux1;
-	    sraw_symbol += bfd_coff_symesz (abfd) * naux1;
-	  }
-	  break;
-
-	case C_BINCL:
-	  {
-	    /* Mark down an include file in the current psymtab.  */
-	    enum language tmp_language;
-
-	    swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
-		      &ssymnum, objfile);
-
-	    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 && strcmp (namestring, pst->filename) == 0)
-	      continue;
-
-	    {
-	      int i;
-
-	      for (i = 0; i < includes_used; i++)
-		if (strcmp (namestring, psymtab_include_list[i]) == 0)
-		  {
-		    i = -1;
-		    break;
-		  }
-	      if (i == -1)
-		continue;
-	    }
-	    psymtab_include_list[includes_used++] = namestring;
-	    if (includes_used >= includes_allocated)
-	      {
-		const char **orig = psymtab_include_list;
-
-		psymtab_include_list = (const char **)
-		  alloca ((includes_allocated *= 2) *
-			  sizeof (const char *));
-		memcpy (psymtab_include_list, orig,
-			includes_used * sizeof (const char *));
-	      }
-	    continue;
-	  }
-	case C_FUN:
-	  /* The value of the C_FUN is not the address of the function (it
-	     appears to be the address before linking), but as long as it
-	     is smaller than the actual address, then find_pc_partial_function
-	     will use the minimal symbols instead.  I hope.  */
-
-	case C_GSYM:
-	case C_ECOML:
-	case C_DECL:
-	case C_STSYM:
-	  {
-	    const char *p;
-
-	    swap_sym (&symbol, &main_aux[0], &namestring, &sraw_symbol,
-		      &ssymnum, objfile);
-
-	    p = 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 (symbol.n_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 (symbol.n_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, TYPE_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, TYPE_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 name (namestring, (p - namestring));
-		    function_outside_compilation_unit_complaint (name.c_str ());
-		  }
-		pst->add_psymbol (std::string_view (namestring,
-						    p - namestring),
-				  true, FUNCTION_DOMAIN, LOC_BLOCK,
-				  SECT_OFF_TEXT (objfile),
-				  psymbol_placement::STATIC,
-				  unrelocated_addr (symbol.n_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 name (namestring, (p - namestring));
-		    function_outside_compilation_unit_complaint (name.c_str ());
-		  }
-
-		/* We need only the minimal symbols for these
-		   loader-generated definitions.  Keeping the global
-		   symbols leads to "in psymbols but not in symbols"
-		   errors.  */
-		if (startswith (namestring, "@FIX"))
-		  continue;
-
-		pst->add_psymbol (std::string_view (namestring,
-						    p - namestring),
-				  true, FUNCTION_DOMAIN, LOC_BLOCK,
-				  SECT_OFF_TEXT (objfile),
-				  psymbol_placement::GLOBAL,
-				  unrelocated_addr (symbol.n_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;
-	      }
-	  }
-	}
-    }
-
-  if (pst)
-    {
-      xcoff_end_psymtab (objfile, partial_symtabs,
-			 pst, psymtab_include_list, includes_used,
-			 ssymnum, dependency_list,
-			 dependencies_used, textlow_not_set);
-    }
-
-  /* Record the toc offset value of this symbol table into objfile
-     structure.  If no XMC_TC0 is found, toc_offset should be zero.
-     Another place to obtain this information would be file auxiliary
-     header.  */
-
-  XCOFF_DATA (objfile)->toc_offset = toc_offset;
-}
 
 /* Return the toc offset value for a given objfile.  */
 
@@ -2783,17 +841,13 @@ static void
 xcoff_initial_scan (struct objfile *objfile, symfile_add_flags symfile_flags)
 {
   bfd *abfd;
-  int val;
   int num_symbols;		/* # of symbols */
   file_ptr symtab_offset;	/* symbol table and */
   file_ptr stringtab_offset;	/* string table file offsets */
   struct xcoff_symfile_info *info;
-  const char *name;
-  unsigned int size;
 
   info = XCOFF_DATA (objfile);
   symfile_bfd = abfd = objfile->obfd.get ();
-  name = objfile_name (objfile);
 
   num_symbols = bfd_get_symcount (abfd);	/* # of symbols */
   symtab_offset = obj_sym_filepos (abfd);	/* symbol table file offset */
@@ -2802,76 +856,24 @@ xcoff_initial_scan (struct objfile *objfile, symfile_add_flags symfile_flags)
 
   info->min_lineno_offset = 0;
   info->max_lineno_offset = 0;
+  info->debugsec = nullptr;
   bfd_map_over_sections (abfd, find_linenos, info);
 
   if (num_symbols > 0)
     {
-      stabs_deprecated_warning ();
       /* Read the string table.  */
       init_stringtab (abfd, stringtab_offset, objfile);
-
-      /* Read the .debug section, if present and if we're not ignoring
-	 it.  */
-      if (!(objfile->flags & OBJF_READNEVER))
-	{
-	  struct bfd_section *secp;
-	  bfd_size_type length;
-	  bfd_byte *debugsec = NULL;
-
-	  secp = bfd_get_section_by_name (abfd, ".debug");
-	  if (secp)
-	    {
-	      length = bfd_section_size (secp);
-	      if (length)
-		{
-		  debugsec
-		    = (bfd_byte *) obstack_alloc (&objfile->objfile_obstack,
-						  length);
-
-		  if (!bfd_get_full_section_contents (abfd, secp, &debugsec))
-		    {
-		      error (_("Error reading .debug section of `%s': %s"),
-			     name, bfd_errmsg (bfd_get_error ()));
-		    }
-		}
-	    }
-	  info->debugsec = (char *) debugsec;
-	}
     }
 
-  /* Read the symbols.  We keep them in core because we will want to
-     access them randomly in read_symbol*.  */
-  val = bfd_seek (abfd, symtab_offset, SEEK_SET);
-  if (val < 0)
-    error (_("Error reading symbols from %s: %s"),
-	   name, bfd_errmsg (bfd_get_error ()));
-  size = coff_data (abfd)->local_symesz * num_symbols;
-  info->symtbl = (char *) obstack_alloc (&objfile->objfile_obstack, size);
-  info->symtbl_num_syms = num_symbols;
-
-  val = bfd_read (info->symtbl, size, abfd);
-  if (val != size)
-    perror_with_name (_("reading symbol table"));
-
-  scoped_free_pendings free_pending;
-  minimal_symbol_reader reader (objfile);
-
-  /* Now that the symbol table data of the executable file are all in core,
-     process them and define symbols accordingly.  */
-
-  psymbol_functions *psf = new psymbol_functions ();
-  psymtab_storage *partial_symtabs = psf->get_partial_symtabs ().get ();
-  objfile->qf.emplace_front (psf);
-  scan_xcoff_symtab (reader, partial_symtabs, objfile);
-
-  /* Install any minimal symbols that have been collected as the current
-     minimal symbols for this objfile.  */
-
-  reader.install ();
-
   /* DWARF2 sections.  */
 
-  dwarf2_initialize_objfile (objfile, &dwarf2_xcoff_names);
+  if (!(objfile->flags & OBJF_READNEVER))
+    {
+      /* If we can't read dwarf from an inferior, it will only have
+	 stabs debuginfo, which we don't support anymore.  */
+      if (!dwarf2_initialize_objfile (objfile, &dwarf2_xcoff_names))
+	  warning (_("No usable debug information found."));
+    }
 }
 \f
 static void
-- 
2.51.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v2 7/8] gdb: Fully remove stabs code from GDB
  2025-10-20 15:28 [PATCH v2 0/8] Remove stabs support from GDB Guinevere Larsen
                   ` (5 preceding siblings ...)
  2025-10-20 15:28 ` [PATCH v2 6/8] gdb: Remove stabs support from XCOFF inferiors Guinevere Larsen
@ 2025-10-20 15:28 ` Guinevere Larsen
  2025-10-20 16:39   ` Eli Zaretskii
  2025-10-20 15:28 ` [PATCH v2 8/8] gdb: remove support for dbx " Guinevere Larsen
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 24+ messages in thread
From: Guinevere Larsen @ 2025-10-20 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Guinevere Larsen, Tom Tromey

This commit is the last in the series removing GDB's support for stabs.
It removes the stabsread.{c|h} files, and removes the last usage of
stabsread stuff in buildsym.  Notably, the header file gdb-stabs.h
remains in the tree as it is misnamed at this point - it is used for
reading dbx objfiles.  It (and dbxread) will be removed in a future
commit.

Approved-By: Tom Tromey <tom@tromey.com>
---
 gdb/Makefile.in                      |    2 -
 gdb/NEWS                             |    2 +
 gdb/arch-utils.c                     |    6 -
 gdb/arch-utils.h                     |    3 -
 gdb/buildsym.c                       |   18 -
 gdb/dbxread.c                        |    9 +
 gdb/doc/Makefile.in                  |   46 +-
 gdb/doc/gdb.texinfo                  |   23 +-
 gdb/doc/stabs.texinfo                | 4130 ---------------
 gdb/gdbarch-gen.c                    |   22 -
 gdb/gdbarch-gen.h                    |    4 -
 gdb/gdbarch_components.py            |    8 -
 gdb/microblaze-tdep.c                |    8 -
 gdb/objfiles.h                       |    3 -
 gdb/sparc-tdep.c                     |   10 -
 gdb/sparc64-tdep.c                   |    2 -
 gdb/stabsread.c                      | 7209 --------------------------
 gdb/stabsread.h                      |  309 --
 gdb/symmisc.c                        |    3 -
 gdb/testsuite/gdb.stabs/aout.sed     |   16 -
 gdb/testsuite/gdb.stabs/ecoff.sed    |   17 -
 gdb/testsuite/gdb.stabs/exclfwd.exp  |   57 -
 gdb/testsuite/gdb.stabs/exclfwd.h    |   21 -
 gdb/testsuite/gdb.stabs/exclfwd1.c   |   34 -
 gdb/testsuite/gdb.stabs/exclfwd2.c   |   29 -
 gdb/testsuite/gdb.stabs/gdb11479.c   |   76 -
 gdb/testsuite/gdb.stabs/gdb11479.exp |   59 -
 gdb/testsuite/gdb.stabs/hppa.sed     |   20 -
 gdb/testsuite/gdb.stabs/weird.def    |  900 ----
 gdb/testsuite/gdb.stabs/xcoff.sed    |   17 -
 30 files changed, 27 insertions(+), 13036 deletions(-)
 delete mode 100644 gdb/doc/stabs.texinfo
 delete mode 100644 gdb/stabsread.c
 delete mode 100644 gdb/stabsread.h
 delete mode 100644 gdb/testsuite/gdb.stabs/aout.sed
 delete mode 100644 gdb/testsuite/gdb.stabs/ecoff.sed
 delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd.exp
 delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd.h
 delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd1.c
 delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd2.c
 delete mode 100644 gdb/testsuite/gdb.stabs/gdb11479.c
 delete mode 100644 gdb/testsuite/gdb.stabs/gdb11479.exp
 delete mode 100644 gdb/testsuite/gdb.stabs/hppa.sed
 delete mode 100644 gdb/testsuite/gdb.stabs/weird.def
 delete mode 100644 gdb/testsuite/gdb.stabs/xcoff.sed

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 29b4efa58e9..381c064bc4e 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1199,7 +1199,6 @@ COMMON_SFILES = \
 	source.c \
 	source-cache.c \
 	split-name.c \
-	stabsread.c \
 	stack.c \
 	std-regs.c \
 	symfile.c \
@@ -1674,7 +1673,6 @@ HFILES_NO_SRCDIR = \
 	sparc-ravenscar-thread.h \
 	sparc-tdep.h \
 	split-name.h \
-	stabsread.h \
 	stack.h \
 	stap-probe.h \
 	svr4-tls-tdep.h \
diff --git a/gdb/NEWS b/gdb/NEWS
index b0146852c5c..2c94e786f41 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -31,6 +31,8 @@
   subsequent runs of the inferior will use the same arguments as the
   first run.
 
+* Support for stabs debug information has been removed.
+
 * New targets
 
 GNU/Linux/MicroBlaze (gdbserver) microblazeel-*linux*
diff --git a/gdb/arch-utils.c b/gdb/arch-utils.c
index 377694537bd..49955494791 100644
--- a/gdb/arch-utils.c
+++ b/gdb/arch-utils.c
@@ -324,12 +324,6 @@ generic_convert_register_p (struct gdbarch *gdbarch, int regnum,
   return 0;
 }
 
-int
-default_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
-{
-  return 0;
-}
-
 int
 generic_instruction_nullified (struct gdbarch *gdbarch,
 			       struct regcache *regcache)
diff --git a/gdb/arch-utils.h b/gdb/arch-utils.h
index 14a84b74733..6aa4270a118 100644
--- a/gdb/arch-utils.h
+++ b/gdb/arch-utils.h
@@ -261,9 +261,6 @@ extern int default_code_of_frame_writable (struct gdbarch *gdbarch,
 extern int generic_convert_register_p (struct gdbarch *gdbarch, int regnum,
 				       struct type *type);
 
-extern int default_stabs_argument_has_addr (struct gdbarch *gdbarch,
-					    struct type *type);
-
 extern int generic_instruction_nullified (struct gdbarch *gdbarch,
 					  struct regcache *regcache);
 
diff --git a/gdb/buildsym.c b/gdb/buildsym.c
index 2a8e95e078b..b240a1ca45a 100644
--- a/gdb/buildsym.c
+++ b/gdb/buildsym.c
@@ -34,11 +34,6 @@
 #include "dictionary.h"
 #include <algorithm>
 
-/* For cleanup_undefined_stabs_types and finish_global_stabs (somewhat
-   questionable--see comment where we call them).  */
-
-#include "stabsread.h"
-
 /* List of blocks already made (lexical contexts already closed).
    This is used at the end to make the blockvector.  */
 
@@ -806,19 +801,6 @@ buildsym_compunit::end_compunit_symtab_get_static_block (CORE_ADDR end_addr,
 	pb->block = barray[i++];
     }
 
-  /* Cleanup any undefined types that have been left hanging around
-     (this needs to be done before the finish_blocks so that
-     file_symbols is still good).
-
-     Both cleanup_undefined_stabs_types and finish_global_stabs are stabs
-     specific, but harmless for other symbol readers, since on gdb
-     startup or when finished reading stabs, the state is set so these
-     are no-ops.  FIXME: Is this handled right in case of QUIT?  Can
-     we make this cleaner?  */
-
-  cleanup_undefined_stabs_types (m_objfile);
-  finish_global_stabs (m_objfile);
-
   if (!required
       && m_pending_blocks == NULL
       && m_file_symbols == NULL
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index de3f7c6a45b..e003a909fe8 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -74,6 +74,15 @@ explicit_lookup_type (int real_filenum, int index)
 }
 #endif
 \f
+
+const registry<objfile>::key<dbx_symfile_info> dbx_objfile_data_key;
+
+/* This could leak memory, but it will be removed soon, so it
+   shouldn't have a large impact.  */
+dbx_symfile_info::~dbx_symfile_info ()
+{
+}
+
 /* Scan and build partial symbols for a symbol file.
    We have been initialized by a call to dbx_symfile_init, which 
    put all the relevant info into a "struct dbx_symfile_info",
diff --git a/gdb/doc/Makefile.in b/gdb/doc/Makefile.in
index b9c79b95e8a..4c9f8642fd9 100644
--- a/gdb/doc/Makefile.in
+++ b/gdb/doc/Makefile.in
@@ -94,15 +94,15 @@ SET_TEXINPUTS = \
    TEXINPUTS=${TEXIDIR}:.:$(srcdir):$(READLINE_DIR):$(GDBMI_DIR):$$TEXINPUTS
 
 # Files which should be generated via 'info' and installed by 'install-info'
-INFO_DEPS = gdb.info stabs.info annotate.info
+INFO_DEPS = gdb.info annotate.info
 
 # Files which should be generated via 'dvi' and installed by 'install-dvi'
-DVIFILES = gdb.dvi stabs.dvi refcard.dvi annotate.dvi
+DVIFILES = gdb.dvi refcard.dvi annotate.dvi
 # Files which should be generated via 'pdf' and installed by 'install-pdf'
-PDFFILES = gdb.pdf stabs.pdf refcard.pdf annotate.pdf
+PDFFILES = gdb.pdf refcard.pdf annotate.pdf
 # Files which should be generated via 'html' and installed by 'install-html'
-HTMLFILES =  gdb/index.html stabs/index.html annotate/index.html
-HTMLFILES_INSTALL = gdb stabs annotate
+HTMLFILES =  gdb/index.html annotate/index.html
+HTMLFILES_INSTALL = gdb annotate
 
 # There may be alternate predefined collections of switches to configure
 # the GDB manual.  Normally this is not done in synch with the software
@@ -156,17 +156,6 @@ GDB_DOC_FILES = \
 	$(GDB_DOC_SOURCE_INCLUDES) \
 	$(GDB_DOC_BUILD_INCLUDES)
 
-# Stabs manual: All files
-STABS_DOC_SOURCE_INCLUDES = \
-	$(srcdir)/fdl.texi
-STABS_DOC_BUILD_INCLUDES = \
-	gdb-cfg.texi \
-	GDBvn.texi
-STABS_DOC_FILES = \
-	$(srcdir)/stabs.texinfo \
-	$(STABS_DOC_SOURCE_INCLUDES) \
-	$(STABS_DOC_BUILD_INCLUDES)
-
 # Annotate migration document
 ANNOTATE_DOC_SOURCE_INCLUDES = \
 	$(srcdir)/fdl.texi
@@ -207,7 +196,7 @@ all: info
 
 info: $(INFO_DEPS)
 dvi: $(DVIFILES)
-ps: gdb.ps stabs.ps refcard.ps annotate.ps
+ps: gdb.ps refcard.ps annotate.ps
 html: $(HTMLFILES)
 pdf: $(PDFFILES)
 man: $(MANS)
@@ -593,29 +582,6 @@ gdb/index.html: ${GDB_DOC_FILES}
 		$(READLINE_TEXI_INCFLAG) -I ${GDBMI_DIR} -I $(srcdir) \
 		$(srcdir)/gdb.texinfo
 
-stabs.info: $(STABS_DOC_FILES)
-	$(ECHO_MAKEINFO) $(MAKEINFO_CMD) -I $(srcdir) -o stabs.info $(srcdir)/stabs.texinfo
-
-# STABS DOCUMENTATION: HTML file
-
-stabs/index.html: $(STABS_DOC_FILES)
-	$(ECHO_GEN) $(MAKEHTML) $(MAKEHTMLFLAGS) \
-		-o stabs \
-		-I $(srcdir) \
-		$(srcdir)/stabs.texinfo
-
-# STABS DOCUMENTATION: TeX dvi file
-stabs.dvi : $(STABS_DOC_FILES)
-	$(ECHO_TEXI2DVI) $(TEXI2DVI_CMD) $(SILENT_Q_FLAG) -I $(srcdir) \
-		$(srcdir)/stabs.texinfo
-
-stabs.ps: stabs.dvi
-	$(ECHO_DVIPS) $(DVIPS) $(SILENT_Q_FLAG) -o $@ $?
-
-stabs.pdf: $(STABS_DOC_FILES)
-	$(ECHO_TEXI2DVI) $(TEXI2DVI_CMD) $(SILENT_Q_FLAG) --pdf -I $(srcdir) \
-		$(srcdir)/stabs.texinfo
-
 # ANNOTATE DOCUMENTATION: TeX dvi file
 annotate.dvi : $(ANNOTATE_DOC_FILES)
 	$(ECHO_TEXI2DVI) $(TEXI2DVI_CMD) $(SILENT_Q_FLAG) -I $(srcdir) \
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index e0fc0ff98ab..da211d9c8d6 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -20453,7 +20453,7 @@ if the debug information provides it, the program that compiled the file
 (which may include, e.g., the compiler version and command line arguments),
 @item
 whether the executable includes debugging information for that file, and
-if so, what format the information is in (e.g., STABS, Dwarf 2, etc.), and
+if so, what format the information is in (e.g., Dwarf 2), and
 @item
 whether the debugging information includes information about
 preprocessor macros.
@@ -22038,9 +22038,7 @@ Warnings and Messages}.)
 
 We have not implemented the two-stage strategy for COFF yet.  When the
 symbol table is stored in COFF format, @code{symbol-file} reads the
-symbol table data in full right away.  Note that ``stabs-in-COFF''
-still does the two-stage strategy, since the debug info is actually
-in stabs format.
+symbol table data in full right away.
 
 @kindex readnow
 @cindex reading symbols immediately
@@ -23148,7 +23146,7 @@ Instead you must do, for example,
 $ gdb -iex "set use-deprecated-index-sections on" <program>
 @end smallexample
 
-Indices only work when using DWARF debugging information, not stabs.
+Indices only work when using DWARF debugging information.
 
 @subsection Automatic symbol index cache
 
@@ -42476,14 +42474,13 @@ and the full path if known.
 This command prints, for each object file in the program, various data
 about that object file followed by the byte cache (@dfn{bcache})
 statistics for the object file.  The objfile data includes the number
-of minimal, partial, full, and stabs symbols, the number of types
-defined by the objfile, the number of as yet unexpanded psym tables,
-the number of line tables and string tables, and the amount of memory
-used by the various tables.  The bcache statistics include the counts,
-sizes, and counts of duplicates of all and unique objects, max,
-average, and median entry size, total memory used and its overhead and
-savings, and various measures of the hash table size and chain
-lengths.
+of minimal, partial, and full, the number of types defined by the
+objfile, the number of as yet unexpanded psym tables, the number of
+line tables and string tables, and the amount of memory used by the
+various tables.  The bcache statistics include the counts, sizes, and
+counts of duplicates of all and unique objects, max, average, and
+median entry size, total memory used and its overhead and savings,
+and various measures of the hash table size and chain lengths.
 
 @kindex maint print target-stack
 @cindex target stack description
diff --git a/gdb/doc/stabs.texinfo b/gdb/doc/stabs.texinfo
deleted file mode 100644
index eac342a6f73..00000000000
--- a/gdb/doc/stabs.texinfo
+++ /dev/null
@@ -1,4130 +0,0 @@
-\input texinfo
-@setfilename stabs.info
-@setchapternewpage odd
-@settitle STABS
-
-@c man begin INCLUDE
-@include gdb-cfg.texi
-@c man end
-
-@c @finalout
-
-@c This is a dir.info fragment to support semi-automated addition of
-@c manuals to an info tree.
-@dircategory Software development
-@direntry
-* Stabs: (stabs).                 The "stabs" debugging information format.   
-@end direntry
-
-@copying
-Copyright @copyright{} 1992--2025 Free Software Foundation, Inc.
-Contributed by Cygnus Support.  Written by Julia Menapace, Jim Kingdon,
-and David MacKenzie.
-
-Permission is granted to copy, distribute and/or modify this document
-under the terms of the GNU Free Documentation License, Version 1.3 or
-any later version published by the Free Software Foundation; with no
-Invariant Sections, with no Front-Cover Texts, and with no Back-Cover
-Texts.  A copy of the license is included in the section entitled ``GNU
-Free Documentation License''.
-@end copying
-
-@ifnottex
-This document describes the stabs debugging symbol tables.
-
-@insertcopying
-@end ifnottex
-
-@titlepage
-@title The ``stabs'' debug format
-@author Julia Menapace, Jim Kingdon, David MacKenzie
-@author Cygnus Support
-@page
-@tex
-\def\$#1${{#1}}  % Kludge: collect RCS revision info without $...$
-\xdef\manvers{\$Revision$}  % For use in headers, footers too
-{\parskip=0pt
-\hfill Cygnus Support\par
-\hfill \manvers\par
-\hfill \TeX{}info \texinfoversion\par
-}
-@end tex
-
-@vskip 0pt plus 1filll
-@insertcopying
-@end titlepage
-
-@ifnottex
-@node Top
-@top The "stabs" representation of debugging information
-
-This document describes the stabs debugging format.
-
-@menu
-* Overview::			Overview of stabs
-* Program Structure::		Encoding of the structure of the program
-* Constants::			Constants
-* Variables::
-* Types::			Type definitions
-* Macro define and undefine::	Representation of #define and #undef
-* Symbol Tables::		Symbol information in symbol tables
-* Cplusplus::			Stabs specific to C++
-* Stab Types::			Symbol types in a.out files
-* Symbol Descriptors::		Table of symbol descriptors
-* Type Descriptors::		Table of type descriptors
-* Expanded Reference::		Reference information by stab type
-* Questions::			Questions and anomalies
-* Stab Sections::		In some object file formats, stabs are
-                                in sections.
-* GNU Free Documentation License::  The license for this documentation
-* Symbol Types Index::          Index of symbolic stab symbol type names.
-@end menu
-@end ifnottex
-
-@contents
-
-@node Overview
-@chapter Overview of Stabs
-
-@dfn{Stabs} refers to a format for information that describes a program
-to a debugger.  This format was apparently invented by
-Peter Kessler at
-the University of California at Berkeley, for the @code{pdx} Pascal
-debugger; the format has spread widely since then.
-
-This document is one of the few published sources of documentation on
-stabs.  It is believed to be comprehensive for stabs used by C.  The
-lists of symbol descriptors (@pxref{Symbol Descriptors}) and type
-descriptors (@pxref{Type Descriptors}) are believed to be completely
-comprehensive.  Stabs for COBOL-specific features and for variant
-records (used by Pascal and Modula-2) are poorly documented here.
-
-@c FIXME: Need to document all OS9000 stuff in GDB; see all references
-@c to os9k_stabs in stabsread.c.
-
-Other sources of information on stabs are @cite{Dbx and Dbxtool
-Interfaces}, 2nd edition, by Sun, 1988, and @cite{AIX Version 3.2 Files
-Reference}, Fourth Edition, September 1992, "dbx Stabstring Grammar" in
-the a.out section, page 2-31.  This document is believed to incorporate
-the information from those two sources except where it explicitly directs
-you to them for more information.
-
-@menu
-* Flow::			Overview of debugging information flow
-* Stabs Format::		Overview of stab format
-* String Field::		The string field
-* C Example::			A simple example in C source
-* Assembly Code::		The simple example at the assembly level
-@end menu
-
-@node Flow
-@section Overview of Debugging Information Flow
-
-The GNU C compiler compiles C source in a @file{.c} file into assembly
-language in a @file{.s} file, which the assembler translates into
-a @file{.o} file, which the linker combines with other @file{.o} files and
-libraries to produce an executable file.
-
-With the @samp{-g} option, GCC puts in the @file{.s} file additional
-debugging information, which is slightly transformed by the assembler
-and linker, and carried through into the final executable.  This
-debugging information describes features of the source file like line
-numbers, the types and scopes of variables, and function names,
-parameters, and scopes.
-
-For some object file formats, the debugging information is encapsulated
-in assembler directives known collectively as @dfn{stab} (symbol table)
-directives, which are interspersed with the generated code.  Stabs are
-the native format for debugging information in the a.out and XCOFF
-object file formats.  The GNU tools can also emit stabs in the COFF and
-ECOFF object file formats.
-
-The assembler adds the information from stabs to the symbol information
-it places by default in the symbol table and the string table of the
-@file{.o} file it is building.  The linker consolidates the @file{.o}
-files into one executable file, with one symbol table and one string
-table.  Debuggers use the symbol and string tables in the executable as
-a source of debugging information about the program.
-
-@node Stabs Format
-@section Overview of Stab Format
-
-There are three overall formats for stab assembler directives,
-differentiated by the first word of the stab.  The name of the directive
-describes which combination of four possible data fields follows.  It is
-either @code{.stabs} (string), @code{.stabn} (number), or @code{.stabd}
-(dot).  IBM's XCOFF assembler uses @code{.stabx} (and some other
-directives such as @code{.file} and @code{.bi}) instead of
-@code{.stabs}, @code{.stabn} or @code{.stabd}.
-
-The overall format of each class of stab is:
-
-@example
-.stabs "@var{string}",@var{type},@var{other},@var{desc},@var{value}
-.stabn @var{type},@var{other},@var{desc},@var{value}
-.stabd @var{type},@var{other},@var{desc}
-.stabx "@var{string}",@var{value},@var{type},@var{sdb-type}
-@end example
-
-@c what is the correct term for "current file location"?  My AIX
-@c assembler manual calls it "the value of the current location counter".
-For @code{.stabn} and @code{.stabd}, there is no @var{string} (the
-@code{n_strx} field is zero; see @ref{Symbol Tables}).  For
-@code{.stabd}, the @var{value} field is implicit and has the value of
-the current file location.  For @code{.stabx}, the @var{sdb-type} field
-is unused for stabs and can always be set to zero.  The @var{other}
-field is almost always unused and can be set to zero.
-
-The number in the @var{type} field gives some basic information about
-which type of stab this is (or whether it @emph{is} a stab, as opposed
-to an ordinary symbol).  Each valid type number defines a different stab
-type; further, the stab type defines the exact interpretation of, and
-possible values for, any remaining @var{string}, @var{desc}, or
-@var{value} fields present in the stab.  @xref{Stab Types}, for a list
-in numeric order of the valid @var{type} field values for stab directives.
-
-@node String Field
-@section The String Field
-
-For most stabs the string field holds the meat of the
-debugging information.  The flexible nature of this field
-is what makes stabs extensible.  For some stab types the string field
-contains only a name.  For other stab types the contents can be a great
-deal more complex.
-
-The overall format of the string field for most stab types is:
-
-@example
-"@var{name}:@var{symbol-descriptor} @var{type-information}"
-@end example
-
-@var{name} is the name of the symbol represented by the stab; it can
-contain a pair of colons (@pxref{Nested Symbols}).  @var{name} can be
-omitted, which means the stab represents an unnamed object.  For
-example, @samp{:t10=*2} defines type 10 as a pointer to type 2, but does
-not give the type a name.  Omitting the @var{name} field is supported by
-AIX dbx and GDB after about version 4.8, but not other debuggers.  GCC
-sometimes uses a single space as the name instead of omitting the name
-altogether; apparently that is supported by most debuggers.
-
-The @var{symbol-descriptor} following the @samp{:} is an alphabetic
-character that tells more specifically what kind of symbol the stab
-represents. If the @var{symbol-descriptor} is omitted, but type
-information follows, then the stab represents a local variable.  For a
-list of symbol descriptors, see @ref{Symbol Descriptors}.  The @samp{c}
-symbol descriptor is an exception in that it is not followed by type
-information.  @xref{Constants}.
-
-@var{type-information} is either a @var{type-number}, or
-@samp{@var{type-number}=}.  A @var{type-number} alone is a type
-reference, referring directly to a type that has already been defined.
-
-The @samp{@var{type-number}=} form is a type definition, where the
-number represents a new type which is about to be defined.  The type
-definition may refer to other types by number, and those type numbers
-may be followed by @samp{=} and nested definitions.  Also, the Lucid
-compiler will repeat @samp{@var{type-number}=} more than once if it
-wants to define several type numbers at once.
-
-In a type definition, if the character that follows the equals sign is
-non-numeric then it is a @var{type-descriptor}, and tells what kind of
-type is about to be defined.  Any other values following the
-@var{type-descriptor} vary, depending on the @var{type-descriptor}.
-@xref{Type Descriptors}, for a list of @var{type-descriptor} values.  If
-a number follows the @samp{=} then the number is a @var{type-reference}.
-For a full description of types, @ref{Types}.
-
-A @var{type-number} is often a single number.  The GNU and Sun tools
-additionally permit a @var{type-number} to be a pair
-(@var{file-number},@var{filetype-number}) (the parentheses appear in the
-string, and serve to distinguish the two cases).  The @var{file-number}
-is 0 for the base source file, 1 for the first included file, 2 for the
-next, and so on.  The @var{filetype-number} is a number starting with
-1 which is incremented for each new type defined in the file.
-(Separating the file number and the type number permits the
-@code{N_BINCL} optimization to succeed more often; see @ref{Include
-Files}).
-
-There is an AIX extension for type attributes.  Following the @samp{=}
-are any number of type attributes.  Each one starts with @samp{@@} and
-ends with @samp{;}.  Debuggers, including AIX's dbx and GDB 4.10, skip
-any type attributes they do not recognize.  GDB 4.9 and other versions
-of dbx may not do this.  Because of a conflict with C@t{++}
-(@pxref{Cplusplus}), new attributes should not be defined which begin
-with a digit, @samp{(}, or @samp{-}; GDB may be unable to distinguish
-those from the C@t{++} type descriptor @samp{@@}.  The attributes are:
-
-@table @code
-@item a@var{boundary}
-@var{boundary} is an integer specifying the alignment.  I assume it
-applies to all variables of this type.
-
-@item p@var{integer}
-Pointer class (for checking).  Not sure what this means, or how
-@var{integer} is interpreted.
-
-@item P
-Indicate this is a packed type, meaning that structure fields or array
-elements are placed more closely in memory, to save memory at the
-expense of speed.
-
-@item s@var{size}
-Size in bits of a variable of this type.  This is fully supported by GDB
-4.11 and later.
-
-@item S
-Indicate that this type is a string instead of an array of characters,
-or a bitstring instead of a set.  It doesn't change the layout of the
-data being represented, but does enable the debugger to know which type
-it is.
-
-@item V
-Indicate that this type is a vector instead of an array.  The only 
-major difference between vectors and arrays is that vectors are
-passed by value instead of by reference (vector coprocessor extension).
-
-@end table
-
-All of this can make the string field quite long.  All versions of GDB,
-and some versions of dbx, can handle arbitrarily long strings.  But many
-versions of dbx (or assemblers or linkers, I'm not sure which)
-cretinously limit the strings to about 80 characters, so compilers which
-must work with such systems need to split the @code{.stabs} directive
-into several @code{.stabs} directives.  Each stab duplicates every field
-except the string field.  The string field of every stab except the last
-is marked as continued with a backslash at the end (in the assembly code
-this may be written as a double backslash, depending on the assembler).
-Removing the backslashes and concatenating the string fields of each
-stab produces the original, long string.  Just to be incompatible (or so
-they don't have to worry about what the assembler does with
-backslashes), AIX can use @samp{?} instead of backslash.
-
-@node C Example
-@section A Simple Example in C Source
-
-To get the flavor of how stabs describe source information for a C
-program, let's look at the simple program:
-
-@example
-main()
-@{
-        printf("Hello world");
-@}
-@end example
-
-When compiled with @samp{-g}, the program above yields the following
-@file{.s} file.  Line numbers have been added to make it easier to refer
-to parts of the @file{.s} file in the description of the stabs that
-follows.
-
-@node Assembly Code
-@section The Simple Example at the Assembly Level
-
-This simple ``hello world'' example demonstrates several of the stab
-types used to describe C language source files.
-
-@example
-1  gcc2_compiled.:
-2  .stabs "/cygint/s1/users/jcm/play/",100,0,0,Ltext0
-3  .stabs "hello.c",100,0,0,Ltext0
-4  .text
-5  Ltext0:
-6  .stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0
-7  .stabs "char:t2=r2;0;127;",128,0,0,0
-8  .stabs "long int:t3=r1;-2147483648;2147483647;",128,0,0,0
-9  .stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
-10 .stabs "long unsigned int:t5=r1;0;-1;",128,0,0,0
-11 .stabs "short int:t6=r1;-32768;32767;",128,0,0,0
-12 .stabs "long long int:t7=r1;0;-1;",128,0,0,0
-13 .stabs "short unsigned int:t8=r1;0;65535;",128,0,0,0
-14 .stabs "long long unsigned int:t9=r1;0;-1;",128,0,0,0
-15 .stabs "signed char:t10=r1;-128;127;",128,0,0,0
-16 .stabs "unsigned char:t11=r1;0;255;",128,0,0,0
-17 .stabs "float:t12=r1;4;0;",128,0,0,0
-18 .stabs "double:t13=r1;8;0;",128,0,0,0
-19 .stabs "long double:t14=r1;8;0;",128,0,0,0
-20 .stabs "void:t15=15",128,0,0,0
-21      .align 4
-22 LC0:
-23      .ascii "Hello, world!\12\0"
-24      .align 4
-25      .global _main
-26      .proc 1
-27 _main:
-28 .stabn 68,0,4,LM1
-29 LM1:
-30      !#PROLOGUE# 0
-31      save %sp,-136,%sp
-32      !#PROLOGUE# 1
-33      call ___main,0
-34      nop
-35 .stabn 68,0,5,LM2
-36 LM2:
-37 LBB2:
-38      sethi %hi(LC0),%o1
-39      or %o1,%lo(LC0),%o0
-40      call _printf,0
-41      nop
-42 .stabn 68,0,6,LM3
-43 LM3:
-44 LBE2:
-45 .stabn 68,0,6,LM4
-46 LM4:
-47 L1:
-48      ret
-49      restore
-50 .stabs "main:F1",36,0,0,_main
-51 .stabn 192,0,0,LBB2
-52 .stabn 224,0,0,LBE2
-@end example
-
-@node Program Structure
-@chapter Encoding the Structure of the Program
-
-The elements of the program structure that stabs encode include the name
-of the main function, the names of the source and include files, the
-line numbers, procedure names and types, and the beginnings and ends of
-blocks of code.
-
-@menu
-* Main Program::		Indicate what the main program is
-* Source Files::		The path and name of the source file
-* Include Files::               Names of include files
-* Line Numbers::
-* Procedures::
-* Nested Procedures::
-* Block Structure::
-* Alternate Entry Points::      Entering procedures except at the beginning.
-@end menu
-
-@node Main Program
-@section Main Program
-
-@findex N_MAIN
-Most languages allow the main program to have any name.  The
-@code{N_MAIN} stab type tells the debugger the name that is used in this
-program.  Only the string field is significant; it is the name of
-a function which is the main program.  Most C compilers do not use this
-stab (they expect the debugger to assume that the name is @code{main}),
-but some C compilers emit an @code{N_MAIN} stab for the @code{main}
-function.  I'm not sure how XCOFF handles this.
-
-@node Source Files
-@section Paths and Names of the Source Files
-
-@findex N_SO
-Before any other stabs occur, there must be a stab specifying the source
-file.  This information is contained in a symbol of stab type
-@code{N_SO}; the string field contains the name of the file.  The
-value of the symbol is the start address of the portion of the
-text section corresponding to that file.
-
-Some compilers use the desc field to indicate the language of the
-source file.  Sun's compilers started this usage, and the first
-constants are derived from their documentation.  Languages added
-by gcc/gdb start at 0x32 to avoid conflict with languages Sun may
-add in the future.  A desc field with a value 0 indicates that no
-language has been specified via this mechanism.
-
-@table @asis
-@item @code{N_SO_AS} (0x1)
-Assembly language
-@item @code{N_SO_C}  (0x2)
-K&R traditional C
-@item @code{N_SO_ANSI_C} (0x3)
-ANSI C
-@item @code{N_SO_CC}  (0x4)
-C++
-@item @code{N_SO_FORTRAN} (0x5)
-Fortran
-@item @code{N_SO_PASCAL} (0x6)
-Pascal
-@item @code{N_SO_FORTRAN90} (0x7)
-Fortran90
-@item @code{N_SO_OBJC} (0x32)
-Objective-C
-@item @code{N_SO_OBJCPLUS} (0x33)
-Objective-C++
-@end table
-
-Some compilers (for example, GCC2 and SunOS4 @file{/bin/cc}) also
-include the directory in which the source was compiled, in a second
-@code{N_SO} symbol preceding the one containing the file name.  This
-symbol can be distinguished by the fact that it ends in a slash.  Code
-from the @code{cfront} C@t{++} compiler can have additional @code{N_SO} symbols for
-nonexistent source files after the @code{N_SO} for the real source file;
-these are believed to contain no useful information.
-
-For example:
-
-@example
-.stabs "/cygint/s1/users/jcm/play/",100,0,0,Ltext0     # @r{100 is N_SO}
-.stabs "hello.c",100,0,0,Ltext0
-        .text
-Ltext0:
-@end example
-
-@findex C_FILE
-Instead of @code{N_SO} symbols, XCOFF uses a @code{.file} assembler
-directive which assembles to a @code{C_FILE} symbol; explaining this in
-detail is outside the scope of this document.
-
-@c FIXME: Exactly when should the empty N_SO be used?  Why?
-If it is useful to indicate the end of a source file, this is done with
-an @code{N_SO} symbol with an empty string for the name.  The value is
-the address of the end of the text section for the file.  For some
-systems, there is no indication of the end of a source file, and you
-just need to figure it ended when you see an @code{N_SO} for a different
-source file, or a symbol ending in @code{.o} (which at least some
-linkers insert to mark the start of a new @code{.o} file).
-
-@node Include Files
-@section Names of Include Files
-
-There are several schemes for dealing with include files: the
-traditional @code{N_SOL} approach, Sun's @code{N_BINCL} approach, and the
-XCOFF @code{C_BINCL} approach (which despite the similar name has little in
-common with @code{N_BINCL}).
-
-@findex N_SOL
-An @code{N_SOL} symbol specifies which include file subsequent symbols
-refer to.  The string field is the name of the file and the value is the
-text address corresponding to the end of the previous include file and
-the start of this one.  To specify the main source file again, use an
-@code{N_SOL} symbol with the name of the main source file.
-
-@findex N_BINCL
-@findex N_EINCL
-@findex N_EXCL
-The @code{N_BINCL} approach works as follows.  An @code{N_BINCL} symbol
-specifies the start of an include file.  In an object file, only the
-string is significant; the linker puts data into some of the other
-fields.  The end of the include file is marked by an @code{N_EINCL}
-symbol (which has no string field).  In an object file, there is no
-significant data in the @code{N_EINCL} symbol.  @code{N_BINCL} and
-@code{N_EINCL} can be nested.
-
-If the linker detects that two source files have identical stabs between
-an @code{N_BINCL} and @code{N_EINCL} pair (as will generally be the case
-for a header file), then it only puts out the stabs once.  Each
-additional occurrence is replaced by an @code{N_EXCL} symbol.  I believe
-the GNU linker and the Sun (both SunOS4 and Solaris) linker are the only
-ones which supports this feature.
-
-A linker which supports this feature will set the value of a
-@code{N_BINCL} symbol to the total of all the characters in the stabs
-strings included in the header file, omitting any file numbers.  The
-value of an @code{N_EXCL} symbol is the same as the value of the
-@code{N_BINCL} symbol it replaces.  This information can be used to
-match up @code{N_EXCL} and @code{N_BINCL} symbols which have the same
-filename.  The @code{N_EINCL} value, and the values of the other and
-description fields for all three, appear to always be zero.
-
-@findex C_BINCL
-@findex C_EINCL
-For the start of an include file in XCOFF, use the @file{.bi} assembler
-directive, which generates a @code{C_BINCL} symbol.  A @file{.ei}
-directive, which generates a @code{C_EINCL} symbol, denotes the end of
-the include file.  Both directives are followed by the name of the
-source file in quotes, which becomes the string for the symbol.
-The value of each symbol, produced automatically by the assembler
-and linker, is the offset into the executable of the beginning
-(inclusive, as you'd expect) or end (inclusive, as you would not expect)
-of the portion of the COFF line table that corresponds to this include
-file.  @code{C_BINCL} and @code{C_EINCL} do not nest.
-
-@node Line Numbers
-@section Line Numbers
-
-@findex N_SLINE
-An @code{N_SLINE} symbol represents the start of a source line.  The
-desc field contains the line number and the value contains the code
-address for the start of that source line.  On most machines the address
-is absolute; for stabs in sections (@pxref{Stab Sections}), it is
-relative to the function in which the @code{N_SLINE} symbol occurs.
-
-@findex N_DSLINE
-@findex N_BSLINE
-GNU documents @code{N_DSLINE} and @code{N_BSLINE} symbols for line
-numbers in the data or bss segments, respectively.  They are identical
-to @code{N_SLINE} but are relocated differently by the linker.  They
-were intended to be used to describe the source location of a variable
-declaration, but I believe that GCC2 actually puts the line number in
-the desc field of the stab for the variable itself.  GDB has been
-ignoring these symbols (unless they contain a string field) since
-at least GDB 3.5.
-
-For single source lines that generate discontiguous code, such as flow
-of control statements, there may be more than one line number entry for
-the same source line.  In this case there is a line number entry at the
-start of each code range, each with the same line number.
-
-XCOFF does not use stabs for line numbers.  Instead, it uses COFF line
-numbers (which are outside the scope of this document).  Standard COFF
-line numbers cannot deal with include files, but in XCOFF this is fixed
-with the @code{C_BINCL} method of marking include files (@pxref{Include
-Files}).
-
-@node Procedures
-@section Procedures
-
-@findex N_FUN, for functions
-@findex N_FNAME
-@findex N_STSYM, for functions (Sun acc)
-@findex N_GSYM, for functions (Sun acc)
-All of the following stabs normally use the @code{N_FUN} symbol type.
-However, Sun's @code{acc} compiler on SunOS4 uses @code{N_GSYM} and
-@code{N_STSYM}, which means that the value of the stab for the function
-is useless and the debugger must get the address of the function from
-the non-stab symbols instead.  On systems where non-stab symbols have
-leading underscores, the stabs will lack underscores and the debugger
-needs to know about the leading underscore to match up the stab and the
-non-stab symbol.  BSD Fortran is said to use @code{N_FNAME} with the
-same restriction; the value of the symbol is not useful (I'm not sure it
-really does use this, because GDB doesn't handle this and no one has
-complained).
-
-@findex C_FUN
-A function is represented by an @samp{F} symbol descriptor for a global
-(extern) function, and @samp{f} for a static (local) function.  For
-a.out, the value of the symbol is the address of the start of the
-function; it is already relocated.  For stabs in ELF, the SunPRO
-compiler version 2.0.1 and GCC put out an address which gets relocated
-by the linker.  In a future release SunPRO is planning to put out zero,
-in which case the address can be found from the ELF (non-stab) symbol.
-Because looking things up in the ELF symbols would probably be slow, I'm
-not sure how to find which symbol of that name is the right one, and
-this doesn't provide any way to deal with nested functions, it would
-probably be better to make the value of the stab an address relative to
-the start of the file, or just absolute.  See @ref{ELF Linker
-Relocation} for more information on linker relocation of stabs in ELF
-files.  For XCOFF, the stab uses the @code{C_FUN} storage class and the
-value of the stab is meaningless; the address of the function can be
-found from the csect symbol (XTY_LD/XMC_PR).
-
-The type information of the stab represents the return type of the
-function; thus @samp{foo:f5} means that foo is a function returning type
-5.  There is no need to try to get the line number of the start of the
-function from the stab for the function; it is in the next
-@code{N_SLINE} symbol.
-
-@c FIXME: verify whether the "I suspect" below is true or not.
-Some compilers (such as Sun's Solaris compiler) support an extension for
-specifying the types of the arguments.  I suspect this extension is not
-used for old (non-prototyped) function definitions in C.  If the
-extension is in use, the type information of the stab for the function
-is followed by type information for each argument, with each argument
-preceded by @samp{;}.  An argument type of 0 means that additional
-arguments are being passed, whose types and number may vary (@samp{...}
-in ANSI C).  GDB has tolerated this extension (parsed the syntax, if not
-necessarily used the information) since at least version 4.8; I don't
-know whether all versions of dbx tolerate it.  The argument types given
-here are not redundant with the symbols for the formal parameters
-(@pxref{Parameters}); they are the types of the arguments as they are
-passed, before any conversions might take place.  For example, if a C
-function which is declared without a prototype takes a @code{float}
-argument, the value is passed as a @code{double} but then converted to a
-@code{float}.  Debuggers need to use the types given in the arguments
-when printing values, but when calling the function they need to use the
-types given in the symbol defining the function.
-
-If the return type and types of arguments of a function which is defined
-in another source file are specified (i.e., a function prototype in ANSI
-C), traditionally compilers emit no stab; the only way for the debugger
-to find the information is if the source file where the function is
-defined was also compiled with debugging symbols.  As an extension the
-Solaris compiler uses symbol descriptor @samp{P} followed by the return
-type of the function, followed by the arguments, each preceded by
-@samp{;}, as in a stab with symbol descriptor @samp{f} or @samp{F}.
-This use of symbol descriptor @samp{P} can be distinguished from its use
-for register parameters (@pxref{Register Parameters}) by the fact that it has
-symbol type @code{N_FUN}.
-
-The AIX documentation also defines symbol descriptor @samp{J} as an
-internal function.  I assume this means a function nested within another
-function.  It also says symbol descriptor @samp{m} is a module in
-Modula-2 or extended Pascal.
-
-Procedures (functions which do not return values) are represented as
-functions returning the @code{void} type in C.  I don't see why this couldn't
-be used for all languages (inventing a @code{void} type for this purpose if
-necessary), but the AIX documentation defines @samp{I}, @samp{P}, and
-@samp{Q} for internal, global, and static procedures, respectively.
-These symbol descriptors are unusual in that they are not followed by
-type information.
-
-The following example shows a stab for a function @code{main} which
-returns type number @code{1}.  The @code{_main} specified for the value
-is a reference to an assembler label which is used to fill in the start
-address of the function.
-
-@example
-.stabs "main:F1",36,0,0,_main      # @r{36 is N_FUN}
-@end example
-
-The stab representing a procedure is located immediately following the
-code of the procedure.  This stab is in turn directly followed by a
-group of other stabs describing elements of the procedure.  These other
-stabs describe the procedure's parameters, its block local variables, and
-its block structure.
-
-If functions can appear in different sections, then the debugger may not
-be able to find the end of a function.  Recent versions of GCC will mark
-the end of a function with an @code{N_FUN} symbol with an empty string
-for the name.  The value is the address of the end of the current
-function.  Without such a symbol, there is no indication of the address
-of the end of a function, and you must assume that it ended at the
-starting address of the next function or at the end of the text section
-for the program.
-
-@node Nested Procedures
-@section Nested Procedures
-
-For any of the symbol descriptors representing procedures, after the
-symbol descriptor and the type information is optionally a scope
-specifier.  This consists of a comma, the name of the procedure, another
-comma, and the name of the enclosing procedure.  The first name is local
-to the scope specified, and seems to be redundant with the name of the
-symbol (before the @samp{:}).  This feature is used by GCC, and
-presumably Pascal, Modula-2, etc., compilers, for nested functions.
-
-If procedures are nested more than one level deep, only the immediately
-containing scope is specified.  For example, this code:
-
-@example
-int
-foo (int x)
-@{
-  int bar (int y)
-    @{
-      int baz (int z)
-        @{
-          return x + y + z;
-        @}
-      return baz (x + 2 * y);
-    @}
-  return x + bar (3 * x);
-@}
-@end example
-
-@noindent
-produces the stabs:
-
-@example
-.stabs "baz:f1,baz,bar",36,0,0,_baz.15         # @r{36 is N_FUN}
-.stabs "bar:f1,bar,foo",36,0,0,_bar.12
-.stabs "foo:F1",36,0,0,_foo
-@end example
-
-@node Block Structure
-@section Block Structure
-
-@findex N_LBRAC
-@findex N_RBRAC
-@c For GCC 2.5.8 or so stabs-in-coff, these are absolute instead of
-@c function relative (as documented below).  But GDB has never been able
-@c to deal with that (it had wanted them to be relative to the file, but
-@c I just fixed that (between GDB 4.12 and 4.13)), so it is function
-@c relative just like ELF and SOM and the below documentation.
-The program's block structure is represented by the @code{N_LBRAC} (left
-brace) and the @code{N_RBRAC} (right brace) stab types.  The variables
-defined inside a block precede the @code{N_LBRAC} symbol for most
-compilers, including GCC.  Other compilers, such as the Convex, Acorn
-RISC machine, and Sun @code{acc} compilers, put the variables after the
-@code{N_LBRAC} symbol.  The values of the @code{N_LBRAC} and
-@code{N_RBRAC} symbols are the start and end addresses of the code of
-the block, respectively.  For most machines, they are relative to the
-starting address of this source file.  For the Gould NP1, they are
-absolute.  For stabs in sections (@pxref{Stab Sections}), they are
-relative to the function in which they occur.
-
-The @code{N_LBRAC} and @code{N_RBRAC} stabs that describe the block
-scope of a procedure are located after the @code{N_FUN} stab that
-represents the procedure itself.
-
-Sun documents the desc field of @code{N_LBRAC} and
-@code{N_RBRAC} symbols as containing the nesting level of the block.
-However, dbx seems to not care, and GCC always sets desc to
-zero.
-
-@findex .bb
-@findex .be
-@findex C_BLOCK
-For XCOFF, block scope is indicated with @code{C_BLOCK} symbols.  If the
-name of the symbol is @samp{.bb}, then it is the beginning of the block;
-if the name of the symbol is @samp{.be}; it is the end of the block.
-
-@node Alternate Entry Points
-@section Alternate Entry Points
-
-@findex N_ENTRY
-@findex C_ENTRY
-Some languages, like Fortran, have the ability to enter procedures at
-some place other than the beginning.  One can declare an alternate entry
-point.  The @code{N_ENTRY} stab is for this; however, the Sun FORTRAN
-compiler doesn't use it.  According to AIX documentation, only the name
-of a @code{C_ENTRY} stab is significant; the address of the alternate
-entry point comes from the corresponding external symbol.  A previous
-revision of this document said that the value of an @code{N_ENTRY} stab
-was the address of the alternate entry point, but I don't know the
-source for that information.
-
-@node Constants
-@chapter Constants
-
-The @samp{c} symbol descriptor indicates that this stab represents a
-constant.  This symbol descriptor is an exception to the general rule
-that symbol descriptors are followed by type information.  Instead, it
-is followed by @samp{=} and one of the following:
-
-@table @code
-@item b @var{value}
-Boolean constant.  @var{value} is a numeric value; I assume it is 0 for
-false or 1 for true.
-
-@item c @var{value}
-Character constant.  @var{value} is the numeric value of the constant.
-
-@item e @var{type-information} , @var{value}
-Constant whose value can be represented as integral.
-@var{type-information} is the type of the constant, as it would appear
-after a symbol descriptor (@pxref{String Field}).  @var{value} is the
-numeric value of the constant.  GDB 4.9 does not actually get the right
-value if @var{value} does not fit in a host @code{int}, but it does not
-do anything violent, and future debuggers could be extended to accept
-integers of any size (whether unsigned or not).  This constant type is
-usually documented as being only for enumeration constants, but GDB has
-never imposed that restriction; I don't know about other debuggers.
-
-@item i @var{value}
-Integer constant.  @var{value} is the numeric value.  The type is some
-sort of generic integer type (for GDB, a host @code{int}); to specify
-the type explicitly, use @samp{e} instead.
-
-@item r @var{value}
-Real constant.  @var{value} is the real value, which can be @samp{INF}
-(optionally preceded by a sign) for infinity, @samp{QNAN} for a quiet
-NaN (not-a-number), or @samp{SNAN} for a signalling NaN.  If it is a
-normal number the format is that accepted by the C library function
-@code{atof}.
-
-@item s @var{string}
-String constant.  @var{string} is a string enclosed in either @samp{'}
-(in which case @samp{'} characters within the string are represented as
-@samp{\'} or @samp{"} (in which case @samp{"} characters within the
-string are represented as @samp{\"}).
-
-@item S @var{type-information} , @var{elements} , @var{bits} , @var{pattern}
-Set constant.  @var{type-information} is the type of the constant, as it
-would appear after a symbol descriptor (@pxref{String Field}).
-@var{elements} is the number of elements in the set (does this means
-how many bits of @var{pattern} are actually used, which would be
-redundant with the type, or perhaps the number of bits set in
-@var{pattern}?  I don't get it), @var{bits} is the number of bits in the
-constant (meaning it specifies the length of @var{pattern}, I think),
-and @var{pattern} is a hexadecimal representation of the set.  AIX
-documentation refers to a limit of 32 bytes, but I see no reason why
-this limit should exist.  This form could probably be used for arbitrary
-constants, not just sets; the only catch is that @var{pattern} should be
-understood to be target, not host, byte order and format.
-@end table
-
-The boolean, character, string, and set constants are not supported by
-GDB 4.9, but it ignores them.  GDB 4.8 and earlier gave an error
-message and refused to read symbols from the file containing the
-constants.
-
-The above information is followed by @samp{;}.
-
-@node Variables
-@chapter Variables
-
-Different types of stabs describe the various ways that variables can be
-allocated: on the stack, globally, in registers, in common blocks,
-statically, or as arguments to a function.
-
-@menu
-* Stack Variables::		Variables allocated on the stack.
-* Global Variables::		Variables used by more than one source file.
-* Register Variables::		Variables in registers.
-* Common Blocks::		Variables statically allocated together.
-* Statics::			Variables local to one source file.
-* Based Variables::		Fortran pointer based variables.
-* Parameters::			Variables for arguments to functions.
-@end menu
-
-@node Stack Variables
-@section Automatic Variables Allocated on the Stack
-
-If a variable's scope is local to a function and its lifetime is only as
-long as that function executes (C calls such variables
-@dfn{automatic}), it can be allocated in a register (@pxref{Register
-Variables}) or on the stack.
-
-@findex N_LSYM, for stack variables
-@findex C_LSYM
-Each variable allocated on the stack has a stab with the symbol
-descriptor omitted.  Since type information should begin with a digit,
-@samp{-}, or @samp{(}, only those characters precluded from being used
-for symbol descriptors.  However, the Acorn RISC machine (ARM) is said
-to get this wrong: it puts out a mere type definition here, without the
-preceding @samp{@var{type-number}=}.  This is a bad idea; there is no
-guarantee that type descriptors are distinct from symbol descriptors.
-Stabs for stack variables use the @code{N_LSYM} stab type, or
-@code{C_LSYM} for XCOFF.
-
-The value of the stab is the offset of the variable within the
-local variables.  On most machines this is an offset from the frame
-pointer and is negative.  The location of the stab specifies which block
-it is defined in; see @ref{Block Structure}.
-
-For example, the following C code:
-
-@example
-int
-main ()
-@{
-  int x;
-@}
-@end example
-
-produces the following stabs:
-
-@example
-.stabs "main:F1",36,0,0,_main   # @r{36 is N_FUN}
-.stabs "x:1",128,0,0,-12        # @r{128 is N_LSYM}
-.stabn 192,0,0,LBB2             # @r{192 is N_LBRAC}
-.stabn 224,0,0,LBE2             # @r{224 is N_RBRAC}
-@end example
-
-See @ref{Procedures} for more information on the @code{N_FUN} stab, and
-@ref{Block Structure} for more information on the @code{N_LBRAC} and
-@code{N_RBRAC} stabs.
-
-@node Global Variables
-@section Global Variables
-
-@findex N_GSYM
-@findex C_GSYM
-@c FIXME: verify for sure that it really is C_GSYM on XCOFF
-A variable whose scope is not specific to just one source file is
-represented by the @samp{G} symbol descriptor.  These stabs use the
-@code{N_GSYM} stab type (C_GSYM for XCOFF).  The type information for
-the stab (@pxref{String Field}) gives the type of the variable.
-
-For example, the following source code:
-
-@example
-char g_foo = 'c';
-@end example
-
-@noindent
-yields the following assembly code:
-
-@example
-.stabs "g_foo:G2",32,0,0,0     # @r{32 is N_GSYM}
-     .global _g_foo
-     .data
-_g_foo:
-     .byte 99
-@end example
-
-The address of the variable represented by the @code{N_GSYM} is not
-contained in the @code{N_GSYM} stab.  The debugger gets this information
-from the external symbol for the global variable.  In the example above,
-the @code{.global _g_foo} and @code{_g_foo:} lines tell the assembler to
-produce an external symbol.
-
-Some compilers, like GCC, output @code{N_GSYM} stabs only once, where
-the variable is defined.  Other compilers, like SunOS4 /bin/cc, output a
-@code{N_GSYM} stab for each compilation unit which references the
-variable.
-
-@node Register Variables
-@section Register Variables
-
-@findex N_RSYM
-@findex C_RSYM
-@c According to an old version of this manual, AIX uses C_RPSYM instead
-@c of C_RSYM.  I am skeptical; this should be verified.
-Register variables have their own stab type, @code{N_RSYM}
-(@code{C_RSYM} for XCOFF), and their own symbol descriptor, @samp{r}.
-The stab's value is the number of the register where the variable data
-will be stored.
-@c .stabs "name:type",N_RSYM,0,RegSize,RegNumber (Sun doc)
-
-AIX defines a separate symbol descriptor @samp{d} for floating point
-registers.  This seems unnecessary; why not just just give floating
-point registers different register numbers?  I have not verified whether
-the compiler actually uses @samp{d}.
-
-If the register is explicitly allocated to a global variable, but not
-initialized, as in:
-
-@example
-register int g_bar asm ("%g5");
-@end example
-
-@noindent
-then the stab may be emitted at the end of the object file, with
-the other bss symbols.
-
-@node Common Blocks
-@section Common Blocks
-
-A common block is a statically allocated section of memory which can be
-referred to by several source files.  It may contain several variables.
-I believe Fortran is the only language with this feature.
-
-@findex N_BCOMM
-@findex N_ECOMM
-@findex C_BCOMM
-@findex C_ECOMM
-A @code{N_BCOMM} stab begins a common block and an @code{N_ECOMM} stab
-ends it.  The only field that is significant in these two stabs is the
-string, which names a normal (non-debugging) symbol that gives the
-address of the common block.  According to IBM documentation, only the
-@code{N_BCOMM} has the name of the common block (even though their
-compiler actually puts it both places).
-
-@findex N_ECOML
-@findex C_ECOML
-The stabs for the members of the common block are between the
-@code{N_BCOMM} and the @code{N_ECOMM}; the value of each stab is the
-offset within the common block of that variable.  IBM uses the
-@code{C_ECOML} stab type, and there is a corresponding @code{N_ECOML}
-stab type, but Sun's Fortran compiler uses @code{N_GSYM} instead.  The
-variables within a common block use the @samp{V} symbol descriptor (I
-believe this is true of all Fortran variables).  Other stabs (at least
-type declarations using @code{C_DECL}) can also be between the
-@code{N_BCOMM} and the @code{N_ECOMM}.
-
-@node Statics
-@section Static Variables
-
-Initialized static variables are represented by the @samp{S} and
-@samp{V} symbol descriptors.  @samp{S} means file scope static, and
-@samp{V} means procedure scope static.  One exception: in XCOFF, IBM's
-xlc compiler always uses @samp{V}, and whether it is file scope or not
-is distinguished by whether the stab is located within a function.
-
-@c This is probably not worth mentioning; it is only true on the sparc
-@c for `double' variables which although declared const are actually in
-@c the data segment (the text segment can't guarantee 8 byte alignment).
-@c (although GCC
-@c 2.4.5 has a bug in that it uses @code{N_FUN}, so neither dbx nor GDB can
-@c find the variables)
-@findex N_STSYM
-@findex N_LCSYM
-@findex N_FUN, for variables
-@findex N_ROSYM
-In a.out files, @code{N_STSYM} means the data section, @code{N_FUN}
-means the text section, and @code{N_LCSYM} means the bss section.  For
-those systems with a read-only data section separate from the text
-section (Solaris), @code{N_ROSYM} means the read-only data section.
-
-For example, the source lines:
-
-@example
-static const int var_const = 5;
-static int var_init = 2;
-static int var_noinit;
-@end example
-
-@noindent
-yield the following stabs:
-
-@example
-.stabs "var_const:S1",36,0,0,_var_const      # @r{36 is N_FUN}
-@dots{}
-.stabs "var_init:S1",38,0,0,_var_init        # @r{38 is N_STSYM}
-@dots{}
-.stabs "var_noinit:S1",40,0,0,_var_noinit    # @r{40 is N_LCSYM}
-@end example
-
-@findex C_STSYM
-@findex C_BSTAT
-@findex C_ESTAT
-In XCOFF files, the stab type need not indicate the section;
-@code{C_STSYM} can be used for all statics.  Also, each static variable
-is enclosed in a static block.  A @code{C_BSTAT} (emitted with a
-@samp{.bs} assembler directive) symbol begins the static block; its
-value is the symbol number of the csect symbol whose value is the
-address of the static block, its section is the section of the variables
-in that static block, and its name is @samp{.bs}.  A @code{C_ESTAT}
-(emitted with a @samp{.es} assembler directive) symbol ends the static
-block; its name is @samp{.es} and its value and section are ignored.
-
-In ECOFF files, the storage class is used to specify the section, so the
-stab type need not indicate the section.
-
-In ELF files, for the SunPRO compiler version 2.0.1, symbol descriptor
-@samp{S} means that the address is absolute (the linker relocates it)
-and symbol descriptor @samp{V} means that the address is relative to the
-start of the relevant section for that compilation unit.  SunPRO has
-plans to have the linker stop relocating stabs; I suspect that their the
-debugger gets the address from the corresponding ELF (not stab) symbol.
-I'm not sure how to find which symbol of that name is the right one.
-The clean way to do all this would be to have the value of a symbol
-descriptor @samp{S} symbol be an offset relative to the start of the
-file, just like everything else, but that introduces obvious
-compatibility problems.  For more information on linker stab relocation,
-@xref{ELF Linker Relocation}.
-
-@node Based Variables
-@section Fortran Based Variables
-
-Fortran (at least, the Sun and SGI dialects of FORTRAN-77) has a feature
-which allows allocating arrays with @code{malloc}, but which avoids
-blurring the line between arrays and pointers the way that C does.  In
-stabs such a variable uses the @samp{b} symbol descriptor.
-
-For example, the Fortran declarations
-
-@example
-real foo, foo10(10), foo10_5(10,5)
-pointer (foop, foo)
-pointer (foo10p, foo10)
-pointer (foo105p, foo10_5)
-@end example
-
-produce the stabs
-
-@example
-foo:b6
-foo10:bar3;1;10;6
-foo10_5:bar3;1;5;ar3;1;10;6
-@end example
-
-In this example, @code{real} is type 6 and type 3 is an integral type
-which is the type of the subscripts of the array (probably
-@code{integer}).
-
-The @samp{b} symbol descriptor is like @samp{V} in that it denotes a
-statically allocated symbol whose scope is local to a function; see
-@xref{Statics}.  The value of the symbol, instead of being the address
-of the variable itself, is the address of a pointer to that variable.
-So in the above example, the value of the @code{foo} stab is the address
-of a pointer to a real, the value of the @code{foo10} stab is the
-address of a pointer to a 10-element array of reals, and the value of
-the @code{foo10_5} stab is the address of a pointer to a 5-element array
-of 10-element arrays of reals.
-
-@node Parameters
-@section Parameters
-
-Formal parameters to a function are represented by a stab (or sometimes
-two; see below) for each parameter.  The stabs are in the order in which
-the debugger should print the parameters (i.e., the order in which the
-parameters are declared in the source file).  The exact form of the stab
-depends on how the parameter is being passed.
-
-@findex N_PSYM
-@findex C_PSYM
-Parameters passed on the stack use the symbol descriptor @samp{p} and
-the @code{N_PSYM} symbol type (or @code{C_PSYM} for XCOFF).  The value
-of the symbol is an offset used to locate the parameter on the stack;
-its exact meaning is machine-dependent, but on most machines it is an
-offset from the frame pointer.
-
-As a simple example, the code:
-
-@example
-main (argc, argv)
-     int argc;
-     char **argv;
-@end example
-
-produces the stabs:
-
-@example
-.stabs "main:F1",36,0,0,_main                 # @r{36 is N_FUN}
-.stabs "argc:p1",160,0,0,68                   # @r{160 is N_PSYM}
-.stabs "argv:p20=*21=*2",160,0,0,72
-@end example
-
-The type definition of @code{argv} is interesting because it contains
-several type definitions.  Type 21 is pointer to type 2 (char) and
-@code{argv} (type 20) is pointer to type 21.
-
-@c FIXME: figure out what these mean and describe them coherently.
-The following symbol descriptors are also said to go with @code{N_PSYM}.
-The value of the symbol is said to be an offset from the argument
-pointer (I'm not sure whether this is true or not).
-
-@example
-pP (<<??>>)
-pF Fortran function parameter
-X  (function result variable)
-@end example
-
-@menu
-* Register Parameters::
-* Local Variable Parameters::
-* Reference Parameters::
-* Conformant Arrays::
-@end menu
-
-@node Register Parameters
-@subsection Passing Parameters in Registers
-
-If the parameter is passed in a register, then traditionally there are
-two symbols for each argument:
-
-@example
-.stabs "arg:p1" . . .       ; N_PSYM
-.stabs "arg:r1" . . .       ; N_RSYM
-@end example
-
-Debuggers use the second one to find the value, and the first one to
-know that it is an argument.
-
-@findex C_RPSYM
-@findex N_RSYM, for parameters
-Because that approach is kind of ugly, some compilers use symbol
-descriptor @samp{P} or @samp{R} to indicate an argument which is in a
-register.  Symbol type @code{C_RPSYM} is used in XCOFF and @code{N_RSYM}
-is used otherwise.  The symbol's value is the register number.  @samp{P}
-and @samp{R} mean the same thing; the difference is that @samp{P} is a
-GNU invention and @samp{R} is an IBM (XCOFF) invention.  As of version
-4.9, GDB should handle either one.
-
-There is at least one case where GCC uses a @samp{p} and @samp{r} pair
-rather than @samp{P}; this is where the argument is passed in the
-argument list and then loaded into a register.
-
-According to the AIX documentation, symbol descriptor @samp{D} is for a
-parameter passed in a floating point register.  This seems
-unnecessary---why not just use @samp{R} with a register number which
-indicates that it's a floating point register?  I haven't verified
-whether the system actually does what the documentation indicates.
-
-@c FIXME: On the hppa this is for any type > 8 bytes, I think, and not
-@c for small structures (investigate).
-On the sparc and hppa, for a @samp{P} symbol whose type is a structure
-or union, the register contains the address of the structure.  On the
-sparc, this is also true of a @samp{p} and @samp{r} pair (using Sun
-@code{cc}) or a @samp{p} symbol.  However, if a (small) structure is
-really in a register, @samp{r} is used.  And, to top it all off, on the
-hppa it might be a structure which was passed on the stack and loaded
-into a register and for which there is a @samp{p} and @samp{r} pair!  I
-believe that symbol descriptor @samp{i} is supposed to deal with this
-case (it is said to mean "value parameter by reference, indirect
-access"; I don't know the source for this information), but I don't know
-details or what compilers or debuggers use it, if any (not GDB or GCC).
-It is not clear to me whether this case needs to be dealt with
-differently than parameters passed by reference (@pxref{Reference Parameters}).
-
-@node Local Variable Parameters
-@subsection Storing Parameters as Local Variables
-
-There is a case similar to an argument in a register, which is an
-argument that is actually stored as a local variable.  Sometimes this
-happens when the argument was passed in a register and then the compiler
-stores it as a local variable.  If possible, the compiler should claim
-that it's in a register, but this isn't always done.
-
-If a parameter is passed as one type and converted to a smaller type by
-the prologue (for example, the parameter is declared as a @code{float},
-but the calling conventions specify that it is passed as a
-@code{double}), then GCC2 (sometimes) uses a pair of symbols.  The first
-symbol uses symbol descriptor @samp{p} and the type which is passed.
-The second symbol has the type and location which the parameter actually
-has after the prologue.  For example, suppose the following C code
-appears with no prototypes involved:
-
-@example
-void
-subr (f)
-     float f;
-@{
-@end example
-
-if @code{f} is passed as a double at stack offset 8, and the prologue
-converts it to a float in register number 0, then the stabs look like:
-
-@example
-.stabs "f:p13",160,0,3,8   # @r{160 is @code{N_PSYM}, here 13 is @code{double}}
-.stabs "f:r12",64,0,3,0    # @r{64 is @code{N_RSYM}, here 12 is @code{float}}
-@end example
-
-In both stabs 3 is the line number where @code{f} is declared
-(@pxref{Line Numbers}).
-
-@findex N_LSYM, for parameter
-GCC, at least on the 960, has another solution to the same problem.  It
-uses a single @samp{p} symbol descriptor for an argument which is stored
-as a local variable but uses @code{N_LSYM} instead of @code{N_PSYM}.  In
-this case, the value of the symbol is an offset relative to the local
-variables for that function, not relative to the arguments; on some
-machines those are the same thing, but not on all.
-
-@c This is mostly just background info; the part that logically belongs
-@c here is the last sentence.  
-On the VAX or on other machines in which the calling convention includes
-the number of words of arguments actually passed, the debugger (GDB at
-least) uses the parameter symbols to keep track of whether it needs to
-print nameless arguments in addition to the formal parameters which it
-has printed because each one has a stab.  For example, in 
-
-@example
-extern int fprintf (FILE *stream, char *format, @dots{});
-@dots{}
-fprintf (stdout, "%d\n", x);
-@end example
-
-there are stabs for @code{stream} and @code{format}.  On most machines,
-the debugger can only print those two arguments (because it has no way
-of knowing that additional arguments were passed), but on the VAX or
-other machines with a calling convention which indicates the number of
-words of arguments, the debugger can print all three arguments.  To do
-so, the parameter symbol (symbol descriptor @samp{p}) (not necessarily
-@samp{r} or symbol descriptor omitted symbols) needs to contain the
-actual type as passed (for example, @code{double} not @code{float} if it
-is passed as a double and converted to a float).
-
-@node Reference Parameters
-@subsection Passing Parameters by Reference
-
-If the parameter is passed by reference (e.g., Pascal @code{VAR}
-parameters), then the symbol descriptor is @samp{v} if it is in the
-argument list, or @samp{a} if it in a register.  Other than the fact
-that these contain the address of the parameter rather than the
-parameter itself, they are identical to @samp{p} and @samp{R},
-respectively.  I believe @samp{a} is an AIX invention; @samp{v} is
-supported by all stabs-using systems as far as I know.
-
-@node Conformant Arrays
-@subsection Passing Conformant Array Parameters
-
-@c Is this paragraph correct?  It is based on piecing together patchy
-@c information and some guesswork
-Conformant arrays are a feature of Modula-2, and perhaps other
-languages, in which the size of an array parameter is not known to the
-called function until run-time.  Such parameters have two stabs: a
-@samp{x} for the array itself, and a @samp{C}, which represents the size
-of the array.  The value of the @samp{x} stab is the offset in the
-argument list where the address of the array is stored (it this right?
-it is a guess); the value of the @samp{C} stab is the offset in the
-argument list where the size of the array (in elements? in bytes?) is
-stored.
-
-@node Types
-@chapter Defining Types
-
-The examples so far have described types as references to previously
-defined types, or defined in terms of subranges of or pointers to
-previously defined types.  This chapter describes the other type
-descriptors that may follow the @samp{=} in a type definition.
-
-@menu
-* Builtin Types::		Integers, floating point, void, etc.
-* Miscellaneous Types::		Pointers, sets, files, etc.
-* Cross-References::		Referring to a type not yet defined.
-* Subranges::			A type with a specific range.
-* Arrays::			An aggregate type of same-typed elements.
-* Strings::			Like an array but also has a length.
-* Enumerations::		Like an integer but the values have names.
-* Structures::			An aggregate type of different-typed elements.
-* Typedefs::			Giving a type a name.
-* Unions::			Different types sharing storage.
-* Function Types::
-@end menu
-
-@node Builtin Types
-@section Builtin Types
-
-Certain types are built in (@code{int}, @code{short}, @code{void},
-@code{float}, etc.); the debugger recognizes these types and knows how
-to handle them.  Thus, don't be surprised if some of the following ways
-of specifying builtin types do not specify everything that a debugger
-would need to know about the type---in some cases they merely specify
-enough information to distinguish the type from other types.
-
-The traditional way to define builtin types is convoluted, so new ways
-have been invented to describe them.  Sun's @code{acc} uses special
-builtin type descriptors (@samp{b} and @samp{R}), and IBM uses negative
-type numbers.  GDB accepts all three ways, as of version 4.8; dbx just
-accepts the traditional builtin types and perhaps one of the other two
-formats.  The following sections describe each of these formats.
-
-@menu
-* Traditional Builtin Types::	Put on your seat belts and prepare for kludgery
-* Builtin Type Descriptors::	Builtin types with special type descriptors
-* Negative Type Numbers::	Builtin types using negative type numbers
-@end menu
-
-@node Traditional Builtin Types
-@subsection Traditional Builtin Types
-
-This is the traditional, convoluted method for defining builtin types.
-There are several classes of such type definitions: integer, floating
-point, and @code{void}.
-
-@menu
-* Traditional Integer Types::
-* Traditional Other Types::
-@end menu
-
-@node Traditional Integer Types
-@subsubsection Traditional Integer Types
-
-Often types are defined as subranges of themselves.  If the bounding values
-fit within an @code{int}, then they are given normally.  For example:
-
-@example
-.stabs "int:t1=r1;-2147483648;2147483647;",128,0,0,0    # @r{128 is N_LSYM}
-.stabs "char:t2=r2;0;127;",128,0,0,0
-@end example
-
-Builtin types can also be described as subranges of @code{int}:
-
-@example
-.stabs "unsigned short:t6=r1;0;65535;",128,0,0,0
-@end example
-
-If the lower bound of a subrange is 0 and the upper bound is -1,
-the type is an unsigned integral type whose bounds are too
-big to describe in an @code{int}.  Traditionally this is only used for
-@code{unsigned int} and @code{unsigned long}:
-
-@example
-.stabs "unsigned int:t4=r1;0;-1;",128,0,0,0
-@end example
-
-For larger types, GCC 2.4.5 puts out bounds in octal, with one or more
-leading zeroes.  In this case a negative bound consists of a number
-which is a 1 bit (for the sign bit) followed by a 0 bit for each bit in
-the number (except the sign bit), and a positive bound is one which is a
-1 bit for each bit in the number (except possibly the sign bit).  All
-known versions of dbx and GDB version 4 accept this (at least in the
-sense of not refusing to process the file), but GDB 3.5 refuses to read
-the whole file containing such symbols.  So GCC 2.3.3 did not output the
-proper size for these types.  As an example of octal bounds, the string
-fields of the stabs for 64 bit integer types look like:
-
-@c .stabs directives, etc., omitted to make it fit on the page.
-@example
-long int:t3=r1;001000000000000000000000;000777777777777777777777;
-long unsigned int:t5=r1;000000000000000000000000;001777777777777777777777;
-@end example
-
-If the lower bound of a subrange is 0 and the upper bound is negative,
-the type is an unsigned integral type whose size in bytes is the
-absolute value of the upper bound.  I believe this is a Convex
-convention for @code{unsigned long long}.
-
-If the lower bound of a subrange is negative and the upper bound is 0,
-the type is a signed integral type whose size in bytes is
-the absolute value of the lower bound.  I believe this is a Convex
-convention for @code{long long}.  To distinguish this from a legitimate
-subrange, the type should be a subrange of itself.  I'm not sure whether
-this is the case for Convex.
-
-@node Traditional Other Types
-@subsubsection Traditional Other Types
-
-If the upper bound of a subrange is 0 and the lower bound is positive,
-the type is a floating point type, and the lower bound of the subrange
-indicates the number of bytes in the type:
-
-@example
-.stabs "float:t12=r1;4;0;",128,0,0,0
-.stabs "double:t13=r1;8;0;",128,0,0,0
-@end example
-
-However, GCC writes @code{long double} the same way it writes
-@code{double}, so there is no way to distinguish.
-
-@example
-.stabs "long double:t14=r1;8;0;",128,0,0,0
-@end example
-
-Complex types are defined the same way as floating-point types; there is
-no way to distinguish a single-precision complex from a double-precision
-floating-point type.
-
-The C @code{void} type is defined as itself:
-
-@example
-.stabs "void:t15=15",128,0,0,0
-@end example
-
-I'm not sure how a boolean type is represented.
-
-@node Builtin Type Descriptors
-@subsection Defining Builtin Types Using Builtin Type Descriptors
-
-This is the method used by Sun's @code{acc} for defining builtin types.
-These are the type descriptors to define builtin types:
-
-@table @code
-@c FIXME: clean up description of width and offset, once we figure out
-@c what they mean
-@item b @var{signed} @var{char-flag} @var{width} ; @var{offset} ; @var{nbits} ;
-Define an integral type.  @var{signed} is @samp{u} for unsigned or
-@samp{s} for signed.  @var{char-flag} is @samp{c} which indicates this
-is a character type, or is omitted.  I assume this is to distinguish an
-integral type from a character type of the same size, for example it
-might make sense to set it for the C type @code{wchar_t} so the debugger
-can print such variables differently (Solaris does not do this).  Sun
-sets it on the C types @code{signed char} and @code{unsigned char} which
-arguably is wrong.  @var{width} and @var{offset} appear to be for small
-objects stored in larger ones, for example a @code{short} in an
-@code{int} register.  @var{width} is normally the number of bytes in the
-type.  @var{offset} seems to always be zero.  @var{nbits} is the number
-of bits in the type.
-
-Note that type descriptor @samp{b} used for builtin types conflicts with
-its use for Pascal space types (@pxref{Miscellaneous Types}); they can
-be distinguished because the character following the type descriptor
-will be a digit, @samp{(}, or @samp{-} for a Pascal space type, or
-@samp{u} or @samp{s} for a builtin type.
-
-@item w
-Documented by AIX to define a wide character type, but their compiler
-actually uses negative type numbers (@pxref{Negative Type Numbers}).
-
-@item R @var{fp-type} ; @var{bytes} ;
-Define a floating point type.  @var{fp-type} has one of the following values:
-
-@table @code
-@item 1 (NF_SINGLE)
-IEEE 32-bit (single precision) floating point format.
-
-@item 2 (NF_DOUBLE)
-IEEE 64-bit (double precision) floating point format.
-
-@item 3 (NF_COMPLEX)
-@item 4 (NF_COMPLEX16)
-@item 5 (NF_COMPLEX32)
-@c "GDB source" really means @file{include/aout/stab_gnu.h}, but trying
-@c to put that here got an overfull hbox.
-These are for complex numbers.  A comment in the GDB source describes
-them as Fortran @code{complex}, @code{double complex}, and
-@code{complex*16}, respectively, but what does that mean?  (i.e., Single
-precision?  Double precision?).
-
-@item 6 (NF_LDOUBLE)
-Long double.  This should probably only be used for Sun format
-@code{long double}, and new codes should be used for other floating
-point formats (@code{NF_DOUBLE} can be used if a @code{long double} is
-really just an IEEE double, of course).
-@end table
-
-@var{bytes} is the number of bytes occupied by the type.  This allows a
-debugger to perform some operations with the type even if it doesn't
-understand @var{fp-type}.
-
-@item g @var{type-information} ; @var{nbits}
-Documented by AIX to define a floating type, but their compiler actually
-uses negative type numbers (@pxref{Negative Type Numbers}).
-
-@item c @var{type-information} ; @var{nbits}
-Documented by AIX to define a complex type, but their compiler actually
-uses negative type numbers (@pxref{Negative Type Numbers}).
-@end table
-
-The C @code{void} type is defined as a signed integral type 0 bits long:
-@example
-.stabs "void:t19=bs0;0;0",128,0,0,0
-@end example
-The Solaris compiler seems to omit the trailing semicolon in this case.
-Getting sloppy in this way is not a swift move because if a type is
-embedded in a more complex expression it is necessary to be able to tell
-where it ends.
-
-I'm not sure how a boolean type is represented.
-
-@node Negative Type Numbers
-@subsection Negative Type Numbers
-
-This is the method used in XCOFF for defining builtin types.
-Since the debugger knows about the builtin types anyway, the idea of
-negative type numbers is simply to give a special type number which
-indicates the builtin type.  There is no stab defining these types.
-
-There are several subtle issues with negative type numbers.
-
-One is the size of the type.  A builtin type (for example the C types
-@code{int} or @code{long}) might have different sizes depending on
-compiler options, the target architecture, the ABI, etc.  This issue
-doesn't come up for IBM tools since (so far) they just target the
-RS/6000; the sizes indicated below for each size are what the IBM
-RS/6000 tools use.  To deal with differing sizes, either define separate
-negative type numbers for each size (which works but requires changing
-the debugger, and, unless you get both AIX dbx and GDB to accept the
-change, introduces an incompatibility), or use a type attribute
-(@pxref{String Field}) to define a new type with the appropriate size
-(which merely requires a debugger which understands type attributes,
-like AIX dbx or GDB).  For example,
-
-@example
-.stabs "boolean:t10=@@s8;-16",128,0,0,0
-@end example
-
-defines an 8-bit boolean type, and
-
-@example
-.stabs "boolean:t10=@@s64;-16",128,0,0,0
-@end example
-
-defines a 64-bit boolean type.
-
-A similar issue is the format of the type.  This comes up most often for
-floating-point types, which could have various formats (particularly
-extended doubles, which vary quite a bit even among IEEE systems).
-Again, it is best to define a new negative type number for each
-different format; changing the format based on the target system has
-various problems.  One such problem is that the Alpha has both VAX and
-IEEE floating types.  One can easily imagine one library using the VAX
-types and another library in the same executable using the IEEE types.
-Another example is that the interpretation of whether a boolean is true
-or false can be based on the least significant bit, most significant
-bit, whether it is zero, etc., and different compilers (or different
-options to the same compiler) might provide different kinds of boolean.
-
-The last major issue is the names of the types.  The name of a given
-type depends @emph{only} on the negative type number given; these do not
-vary depending on the language, the target system, or anything else.
-One can always define separate type numbers---in the following list you
-will see for example separate @code{int} and @code{integer*4} types
-which are identical except for the name.  But compatibility can be
-maintained by not inventing new negative type numbers and instead just
-defining a new type with a new name.  For example:
-
-@example
-.stabs "CARDINAL:t10=-8",128,0,0,0
-@end example
-
-Here is the list of negative type numbers.  The phrase @dfn{integral
-type} is used to mean twos-complement (I strongly suspect that all
-machines which use stabs use twos-complement; most machines use
-twos-complement these days).
-
-@table @code
-@item -1
-@code{int}, 32 bit signed integral type.
-
-@item -2
-@code{char}, 8 bit type holding a character.   Both GDB and dbx on AIX
-treat this as signed.  GCC uses this type whether @code{char} is signed
-or not, which seems like a bad idea.  The AIX compiler (@code{xlc}) seems to
-avoid this type; it uses -5 instead for @code{char}.
-
-@item -3
-@code{short}, 16 bit signed integral type.
-
-@item -4
-@code{long}, 32 bit signed integral type.
-
-@item -5
-@code{unsigned char}, 8 bit unsigned integral type.
-
-@item -6
-@code{signed char}, 8 bit signed integral type.
-
-@item -7
-@code{unsigned short}, 16 bit unsigned integral type.
-
-@item -8
-@code{unsigned int}, 32 bit unsigned integral type.
-
-@item -9
-@code{unsigned}, 32 bit unsigned integral type.
-
-@item -10
-@code{unsigned long}, 32 bit unsigned integral type.
-
-@item -11
-@code{void}, type indicating the lack of a value.
-
-@item -12
-@code{float}, IEEE single precision.
-
-@item -13
-@code{double}, IEEE double precision.
-
-@item -14
-@code{long double}, IEEE double precision.  The compiler claims the size
-will increase in a future release, and for binary compatibility you have
-to avoid using @code{long double}.  I hope when they increase it they
-use a new negative type number.
-
-@item -15
-@code{integer}.  32 bit signed integral type.
-
-@item -16
-@code{boolean}.  32 bit type.  GDB and GCC assume that zero is false,
-one is true, and other values have unspecified meaning.  I hope this
-agrees with how the IBM tools use the type.
-
-@item -17
-@code{short real}.  IEEE single precision.
-
-@item -18
-@code{real}.  IEEE double precision.
-
-@item -19
-@code{stringptr}.  @xref{Strings}.
-
-@item -20
-@code{character}, 8 bit unsigned character type.
-
-@item -21
-@code{logical*1}, 8 bit type.  This Fortran type has a split
-personality in that it is used for boolean variables, but can also be
-used for unsigned integers.  0 is false, 1 is true, and other values are
-non-boolean.
-
-@item -22
-@code{logical*2}, 16 bit type.  This Fortran type has a split
-personality in that it is used for boolean variables, but can also be
-used for unsigned integers.  0 is false, 1 is true, and other values are
-non-boolean.
-
-@item -23
-@code{logical*4}, 32 bit type.  This Fortran type has a split
-personality in that it is used for boolean variables, but can also be
-used for unsigned integers.  0 is false, 1 is true, and other values are
-non-boolean.
-
-@item -24
-@code{logical}, 32 bit type.  This Fortran type has a split
-personality in that it is used for boolean variables, but can also be
-used for unsigned integers.  0 is false, 1 is true, and other values are
-non-boolean.
-
-@item -25
-@code{complex}.  A complex type consisting of two IEEE single-precision
-floating point values.
-
-@item -26
-@code{complex}.  A complex type consisting of two IEEE double-precision
-floating point values.
-
-@item -27
-@code{integer*1}, 8 bit signed integral type.
-
-@item -28
-@code{integer*2}, 16 bit signed integral type.
-
-@item -29
-@code{integer*4}, 32 bit signed integral type.
-
-@item -30
-@code{wchar}.  Wide character, 16 bits wide, unsigned (what format?
-Unicode?).
-
-@item -31
-@code{long long}, 64 bit signed integral type.
-
-@item -32
-@code{unsigned long long}, 64 bit unsigned integral type.
-
-@item -33
-@code{logical*8}, 64 bit unsigned integral type.
-
-@item -34
-@code{integer*8}, 64 bit signed integral type.
-@end table
-
-@node Miscellaneous Types
-@section Miscellaneous Types
-
-@table @code
-@item b @var{type-information} ; @var{bytes}
-Pascal space type.  This is documented by IBM; what does it mean?
-
-This use of the @samp{b} type descriptor can be distinguished
-from its use for builtin integral types (@pxref{Builtin Type
-Descriptors}) because the character following the type descriptor is
-always a digit, @samp{(}, or @samp{-}.
-
-@item B @var{type-information}
-A volatile-qualified version of @var{type-information}.  This is
-a Sun extension.  References and stores to a variable with a
-volatile-qualified type must not be optimized or cached; they
-must occur as the user specifies them.
-
-@item d @var{type-information}
-File of type @var{type-information}.  As far as I know this is only used
-by Pascal.
-
-@item k @var{type-information}
-A const-qualified version of @var{type-information}.  This is a Sun
-extension.  A variable with a const-qualified type cannot be modified.
-
-@item M @var{type-information} ; @var{length}
-Multiple instance type.  The type seems to composed of @var{length}
-repetitions of @var{type-information}, for example @code{character*3} is
-represented by @samp{M-2;3}, where @samp{-2} is a reference to a
-character type (@pxref{Negative Type Numbers}).  I'm not sure how this
-differs from an array.  This appears to be a Fortran feature.
-@var{length} is a bound, like those in range types; see @ref{Subranges}.
-
-@item S @var{type-information}
-Pascal set type.  @var{type-information} must be a small type such as an
-enumeration or a subrange, and the type is a bitmask whose length is
-specified by the number of elements in @var{type-information}.
-
-In CHILL, if it is a bitstring instead of a set, also use the @samp{S}
-type attribute (@pxref{String Field}).
-
-@item * @var{type-information}
-Pointer to @var{type-information}.
-@end table
-
-@node Cross-References
-@section Cross-References to Other Types
-
-A type can be used before it is defined; one common way to deal with
-that situation is just to use a type reference to a type which has not
-yet been defined.
-
-Another way is with the @samp{x} type descriptor, which is followed by
-@samp{s} for a structure tag, @samp{u} for a union tag, or @samp{e} for
-a enumerator tag, followed by the name of the tag, followed by @samp{:}.
-If the name contains @samp{::} between a @samp{<} and @samp{>} pair (for
-C@t{++} templates), such a @samp{::} does not end the name---only a single
-@samp{:} ends the name; see @ref{Nested Symbols}.
-
-For example, the following C declarations:
-
-@example
-struct foo;
-struct foo *bar;
-@end example
-
-@noindent
-produce:
-
-@example
-.stabs "bar:G16=*17=xsfoo:",32,0,0,0
-@end example
-
-Not all debuggers support the @samp{x} type descriptor, so on some
-machines GCC does not use it.  I believe that for the above example it
-would just emit a reference to type 17 and never define it, but I
-haven't verified that.
-
-Modula-2 imported types, at least on AIX, use the @samp{i} type
-descriptor, which is followed by the name of the module from which the
-type is imported, followed by @samp{:}, followed by the name of the
-type.  There is then optionally a comma followed by type information for
-the type.  This differs from merely naming the type (@pxref{Typedefs}) in
-that it identifies the module; I don't understand whether the name of
-the type given here is always just the same as the name we are giving
-it, or whether this type descriptor is used with a nameless stab
-(@pxref{String Field}), or what.  The symbol ends with @samp{;}.
-
-@node Subranges
-@section Subrange Types
-
-The @samp{r} type descriptor defines a type as a subrange of another
-type.  It is followed by type information for the type of which it is a
-subrange, a semicolon, an integral lower bound, a semicolon, an
-integral upper bound, and a semicolon.  The AIX documentation does not
-specify the trailing semicolon, in an effort to specify array indexes
-more cleanly, but a subrange which is not an array index has always
-included a trailing semicolon (@pxref{Arrays}).
-
-Instead of an integer, either bound can be one of the following:
-
-@table @code
-@item A @var{offset}
-The bound is passed by reference on the stack at offset @var{offset}
-from the argument list.  @xref{Parameters}, for more information on such
-offsets.
-
-@item T @var{offset}
-The bound is passed by value on the stack at offset @var{offset} from
-the argument list.
-
-@item a @var{register-number}
-The bound is passed by reference in register number
-@var{register-number}.
-
-@item t @var{register-number}
-The bound is passed by value in register number @var{register-number}.
-
-@item J
-There is no bound.
-@end table
-
-Subranges are also used for builtin types; see @ref{Traditional Builtin Types}.
-
-@node Arrays
-@section Array Types
-
-Arrays use the @samp{a} type descriptor.  Following the type descriptor
-is the type of the index and the type of the array elements.  If the
-index type is a range type, it ends in a semicolon; otherwise
-(for example, if it is a type reference), there does not
-appear to be any way to tell where the types are separated.  In an
-effort to clean up this mess, IBM documents the two types as being
-separated by a semicolon, and a range type as not ending in a semicolon
-(but this is not right for range types which are not array indexes,
-@pxref{Subranges}).  I think probably the best solution is to specify
-that a semicolon ends a range type, and that the index type and element
-type of an array are separated by a semicolon, but that if the index
-type is a range type, the extra semicolon can be omitted.  GDB (at least
-through version 4.9) doesn't support any kind of index type other than a
-range anyway; I'm not sure about dbx.
-
-It is well established, and widely used, that the type of the index,
-unlike most types found in the stabs, is merely a type definition, not
-type information (@pxref{String Field}) (that is, it need not start with
-@samp{@var{type-number}=} if it is defining a new type).  According to a
-comment in GDB, this is also true of the type of the array elements; it
-gives @samp{ar1;1;10;ar1;1;10;4} as a legitimate way to express a two
-dimensional array.  According to AIX documentation, the element type
-must be type information.  GDB accepts either.
-
-The type of the index is often a range type, expressed as the type
-descriptor @samp{r} and some parameters.  It defines the size of the
-array.  In the example below, the range @samp{r1;0;2;} defines an index
-type which is a subrange of type 1 (integer), with a lower bound of 0
-and an upper bound of 2.  This defines the valid range of subscripts of
-a three-element C array.
-
-For example, the definition:
-
-@example
-char char_vec[3] = @{'a','b','c'@};
-@end example
-
-@noindent
-produces the output:
-
-@example
-.stabs "char_vec:G19=ar1;0;2;2",32,0,0,0
-     .global _char_vec
-     .align 4
-_char_vec:
-     .byte 97
-     .byte 98
-     .byte 99
-@end example
-
-If an array is @dfn{packed}, the elements are spaced more
-closely than normal, saving memory at the expense of speed.  For
-example, an array of 3-byte objects might, if unpacked, have each
-element aligned on a 4-byte boundary, but if packed, have no padding.
-One way to specify that something is packed is with type attributes
-(@pxref{String Field}).  In the case of arrays, another is to use the
-@samp{P} type descriptor instead of @samp{a}.  Other than specifying a
-packed array, @samp{P} is identical to @samp{a}.
-
-@c FIXME-what is it?  A pointer?
-An open array is represented by the @samp{A} type descriptor followed by
-type information specifying the type of the array elements.
-
-@c FIXME: what is the format of this type?  A pointer to a vector of pointers?
-An N-dimensional dynamic array is represented by
-
-@example
-D @var{dimensions} ; @var{type-information}
-@end example
-
-@c Does dimensions really have this meaning?  The AIX documentation
-@c doesn't say.
-@var{dimensions} is the number of dimensions; @var{type-information}
-specifies the type of the array elements.
-
-@c FIXME: what is the format of this type?  A pointer to some offsets in
-@c another array?
-A subarray of an N-dimensional array is represented by
-
-@example
-E @var{dimensions} ; @var{type-information}
-@end example
-
-@c Does dimensions really have this meaning?  The AIX documentation
-@c doesn't say.
-@var{dimensions} is the number of dimensions; @var{type-information}
-specifies the type of the array elements.
-
-@node Strings
-@section Strings
-
-Some languages, like C or the original Pascal, do not have string types,
-they just have related things like arrays of characters.  But most
-Pascals and various other languages have string types, which are
-indicated as follows:
-
-@table @code
-@item n @var{type-information} ; @var{bytes}
-@var{bytes} is the maximum length.  I'm not sure what
-@var{type-information} is; I suspect that it means that this is a string
-of @var{type-information} (thus allowing a string of integers, a string
-of wide characters, etc., as well as a string of characters).  Not sure
-what the format of this type is.  This is an AIX feature.
-
-@item z @var{type-information} ; @var{bytes}
-Just like @samp{n} except that this is a gstring, not an ordinary
-string.  I don't know the difference.
-
-@item N
-Pascal Stringptr.  What is this?  This is an AIX feature.
-@end table
-
-Languages, such as CHILL which have a string type which is basically
-just an array of characters use the @samp{S} type attribute
-(@pxref{String Field}).
-
-@node Enumerations
-@section Enumerations
-
-Enumerations are defined with the @samp{e} type descriptor.
-
-@c FIXME: Where does this information properly go?  Perhaps it is
-@c redundant with something we already explain.
-The source line below declares an enumeration type at file scope.
-The type definition is located after the @code{N_RBRAC} that marks the end of
-the previous procedure's block scope, and before the @code{N_FUN} that marks
-the beginning of the next procedure's block scope.  Therefore it does not
-describe a block local symbol, but a file local one.
-
-The source line:
-
-@example
-enum e_places @{first,second=3,last@};
-@end example
-
-@noindent
-generates the following stab:
-
-@example
-.stabs "e_places:T22=efirst:0,second:3,last:4,;",128,0,0,0
-@end example
-
-The symbol descriptor (@samp{T}) says that the stab describes a
-structure, enumeration, or union tag.  The type descriptor @samp{e},
-following the @samp{22=} of the type definition narrows it down to an
-enumeration type.  Following the @samp{e} is a list of the elements of
-the enumeration.  The format is @samp{@var{name}:@var{value},}.  The
-list of elements ends with @samp{;}.  The fact that @var{value} is
-specified as an integer can cause problems if the value is large.  GCC
-2.5.2 tries to output it in octal in that case with a leading zero,
-which is probably a good thing, although GDB 4.11 supports octal only in
-cases where decimal is perfectly good.  Negative decimal values are
-supported by both GDB and dbx.
-
-There is no standard way to specify the size of an enumeration type; it
-is determined by the architecture (normally all enumerations types are
-32 bits).  Type attributes can be used to specify an enumeration type of
-another size for debuggers which support them; see @ref{String Field}.
-
-Enumeration types are unusual in that they define symbols for the
-enumeration values (@code{first}, @code{second}, and @code{third} in the
-above example), and even though these symbols are visible in the file as
-a whole (rather than being in a more local namespace like structure
-member names), they are defined in the type definition for the
-enumeration type rather than each having their own symbol.  In order to
-be fast, GDB will only get symbols from such types (in its initial scan
-of the stabs) if the type is the first thing defined after a @samp{T} or
-@samp{t} symbol descriptor (the above example fulfills this
-requirement).  If the type does not have a name, the compiler should
-emit it in a nameless stab (@pxref{String Field}); GCC does this.
-
-@node Structures
-@section Structures
-
-The encoding of structures in stabs can be shown with an example.
-
-The following source code declares a structure tag and defines an
-instance of the structure in global scope. Then a @code{typedef} equates the
-structure tag with a new type.  Separate stabs are generated for the
-structure tag, the structure @code{typedef}, and the structure instance.  The
-stabs for the tag and the @code{typedef} are emitted when the definitions are
-encountered.  Since the structure elements are not initialized, the
-stab and code for the structure variable itself is located at the end
-of the program in the bss section.
-
-@example
-struct s_tag @{
-  int   s_int;
-  float s_float;
-  char  s_char_vec[8];
-  struct s_tag* s_next;
-@} g_an_s;
-
-typedef struct s_tag s_typedef;
-@end example
-
-The structure tag has an @code{N_LSYM} stab type because, like the
-enumeration, the symbol has file scope.  Like the enumeration, the
-symbol descriptor is @samp{T}, for enumeration, structure, or tag type.
-The type descriptor @samp{s} following the @samp{16=} of the type
-definition narrows the symbol type to structure.
-
-Following the @samp{s} type descriptor is the number of bytes the
-structure occupies, followed by a description of each structure element.
-The structure element descriptions are of the form
-@samp{@var{name}:@var{type}, @var{bit offset from the start of the
-struct}, @var{number of bits in the element}}.
-
-@c FIXME: phony line break.  Can probably be fixed by using an example
-@c with fewer fields.
-@example
-# @r{128 is N_LSYM}
-.stabs "s_tag:T16=s20s_int:1,0,32;s_float:12,32,32;
-        s_char_vec:17=ar1;0;7;2,64,64;s_next:18=*16,128,32;;",128,0,0,0
-@end example
-
-In this example, the first two structure elements are previously defined
-types.  For these, the type following the @samp{@var{name}:} part of the
-element description is a simple type reference.  The other two structure
-elements are new types.  In this case there is a type definition
-embedded after the @samp{@var{name}:}.  The type definition for the
-array element looks just like a type definition for a stand-alone array.
-The @code{s_next} field is a pointer to the same kind of structure that
-the field is an element of.  So the definition of structure type 16
-contains a type definition for an element which is a pointer to type 16.
-
-If a field is a static member (this is a C@t{++} feature in which a single
-variable appears to be a field of every structure of a given type) it
-still starts out with the field name, a colon, and the type, but then
-instead of a comma, bit position, comma, and bit size, there is a colon
-followed by the name of the variable which each such field refers to.
-
-If the structure has methods (a C@t{++} feature), they follow the non-method
-fields; see @ref{Cplusplus}.
-
-@node Typedefs
-@section Giving a Type a Name
-
-@findex N_LSYM, for types
-@findex C_DECL, for types
-To give a type a name, use the @samp{t} symbol descriptor.  The type
-is specified by the type information (@pxref{String Field}) for the stab.
-For example,
-
-@example
-.stabs "s_typedef:t16",128,0,0,0     # @r{128 is N_LSYM}
-@end example
-
-specifies that @code{s_typedef} refers to type number 16.  Such stabs
-have symbol type @code{N_LSYM} (or @code{C_DECL} for XCOFF).  (The Sun
-documentation mentions using @code{N_GSYM} in some cases).
-
-If you are specifying the tag name for a structure, union, or
-enumeration, use the @samp{T} symbol descriptor instead.  I believe C is
-the only language with this feature.
-
-If the type is an opaque type (I believe this is a Modula-2 feature),
-AIX provides a type descriptor to specify it.  The type descriptor is
-@samp{o} and is followed by a name.  I don't know what the name
-means---is it always the same as the name of the type, or is this type
-descriptor used with a nameless stab (@pxref{String Field})?  There
-optionally follows a comma followed by type information which defines
-the type of this type.  If omitted, a semicolon is used in place of the
-comma and the type information, and the type is much like a generic
-pointer type---it has a known size but little else about it is
-specified.
-
-@node Unions
-@section Unions
-
-@example
-union u_tag @{
-  int  u_int;
-  float u_float;
-  char* u_char;
-@} an_u;
-@end example
-
-This code generates a stab for a union tag and a stab for a union
-variable.  Both use the @code{N_LSYM} stab type.  If a union variable is
-scoped locally to the procedure in which it is defined, its stab is
-located immediately preceding the @code{N_LBRAC} for the procedure's block
-start.
-
-The stab for the union tag, however, is located preceding the code for
-the procedure in which it is defined.  The stab type is @code{N_LSYM}.  This
-would seem to imply that the union type is file scope, like the struct
-type @code{s_tag}.  This is not true.  The contents and position of the stab
-for @code{u_type} do not convey any information about its procedure local
-scope.
-
-@c FIXME: phony line break.  Can probably be fixed by using an example
-@c with fewer fields.
-@smallexample
-# @r{128 is N_LSYM}
-.stabs "u_tag:T23=u4u_int:1,0,32;u_float:12,0,32;u_char:21,0,32;;",
-       128,0,0,0
-@end smallexample
-
-The symbol descriptor @samp{T}, following the @samp{name:} means that
-the stab describes an enumeration, structure, or union tag.  The type
-descriptor @samp{u}, following the @samp{23=} of the type definition,
-narrows it down to a union type definition.  Following the @samp{u} is
-the number of bytes in the union.  After that is a list of union element
-descriptions.  Their format is @samp{@var{name}:@var{type}, @var{bit
-offset into the union}, @var{number of bytes for the element};}.
-
-The stab for the union variable is:
-
-@example
-.stabs "an_u:23",128,0,0,-20     # @r{128 is N_LSYM}
-@end example
-
-@samp{-20} specifies where the variable is stored (@pxref{Stack
-Variables}).
-
-@node Function Types
-@section Function Types
-
-Various types can be defined for function variables.  These types are
-not used in defining functions (@pxref{Procedures}); they are used for
-things like pointers to functions.
-
-The simple, traditional, type is type descriptor @samp{f} is followed by
-type information for the return type of the function, followed by a
-semicolon.
-
-This does not deal with functions for which the number and types of the
-parameters are part of the type, as in Modula-2 or ANSI C.  AIX provides
-extensions to specify these, using the @samp{f}, @samp{F}, @samp{p}, and
-@samp{R} type descriptors.
-
-First comes the type descriptor.  If it is @samp{f} or @samp{F}, this
-type involves a function rather than a procedure, and the type
-information for the return type of the function follows, followed by a
-comma.  Then comes the number of parameters to the function and a
-semicolon.  Then, for each parameter, there is the name of the parameter
-followed by a colon (this is only present for type descriptors @samp{R}
-and @samp{F} which represent Pascal function or procedure parameters),
-type information for the parameter, a comma, 0 if passed by reference or
-1 if passed by value, and a semicolon.  The type definition ends with a
-semicolon.
-
-For example, this variable definition:
-
-@example
-int (*g_pf)();
-@end example
-
-@noindent
-generates the following code:
-
-@example
-.stabs "g_pf:G24=*25=f1",32,0,0,0
-    .common _g_pf,4,"bss"
-@end example
-
-The variable defines a new type, 24, which is a pointer to another new
-type, 25, which is a function returning @code{int}.
-
-@node Macro define and undefine
-@chapter Representation of #define and #undef
-
-This section describes the stabs support for macro define and undefine
-information, supported on some systems.  (e.g., with @option{-g3}
-@option{-gstabs} when using GCC).
-
-A @code{#define @var{macro-name} @var{macro-body}} is represented with
-an @code{N_MAC_DEFINE} stab with a string field of
-@code{@var{macro-name} @var{macro-body}}.
-@findex N_MAC_DEFINE
-
-An @code{#undef @var{macro-name}} is represented with an
-@code{N_MAC_UNDEF} stabs with a string field of simply
-@code{@var{macro-name}}.
-@findex N_MAC_UNDEF
-
-For both @code{N_MAC_DEFINE} and @code{N_MAC_UNDEF}, the desc field is
-the line number within the file where the corresponding @code{#define}
-or @code{#undef} occurred.
-
-For example, the following C code:
-
-@example
-    #define NONE	42
-    #define TWO(a, b)	(a + (a) + 2 * b)
-    #define ONE(c)	(c + 19)
-
-    main(int argc, char *argv[])
-    @{
-      func(NONE, TWO(10, 11));
-      func(NONE, ONE(23));
-
-    #undef ONE
-    #define ONE(c)	(c + 23)
-
-      func(NONE, ONE(-23));
-
-      return (0);
-    @}
-
-    int global;
-
-    func(int arg1, int arg2)
-    @{
-      global = arg1 + arg2;
-    @}
-@end example
-
-@noindent
-produces the following stabs (as well as many others):
-
-@example
-    .stabs	"NONE 42",54,0,1,0
-    .stabs	"TWO(a,b) (a + (a) + 2 * b)",54,0,2,0
-    .stabs	"ONE(c) (c + 19)",54,0,3,0
-    .stabs	"ONE",58,0,10,0
-    .stabs	"ONE(c) (c + 23)",54,0,11,0
-@end example
-
-@noindent
-NOTE: In the above example, @code{54} is @code{N_MAC_DEFINE} and
-@code{58} is @code{N_MAC_UNDEF}.
-
-@node Symbol Tables
-@chapter Symbol Information in Symbol Tables
-
-This chapter describes the format of symbol table entries
-and how stab assembler directives map to them.  It also describes the
-transformations that the assembler and linker make on data from stabs.
-
-@menu
-* Symbol Table Format::
-* Transformations On Symbol Tables::
-@end menu
-
-@node Symbol Table Format
-@section Symbol Table Format
-
-Each time the assembler encounters a stab directive, it puts
-each field of the stab into a corresponding field in a symbol table
-entry of its output file.  If the stab contains a string field, the
-symbol table entry for that stab points to a string table entry
-containing the string data from the stab.  Assembler labels become
-relocatable addresses.  Symbol table entries in a.out have the format:
-
-@c FIXME: should refer to external, not internal.
-@example
-struct internal_nlist @{
-  unsigned long n_strx;         /* index into string table of name */
-  unsigned char n_type;         /* type of symbol */
-  unsigned char n_other;        /* misc info (usually empty) */
-  unsigned short n_desc;        /* description field */
-  bfd_vma n_value;              /* value of symbol */
-@};
-@end example
-
-If the stab has a string, the @code{n_strx} field holds the offset in
-bytes of the string within the string table.  The string is terminated
-by a NUL character.  If the stab lacks a string (for example, it was
-produced by a @code{.stabn} or @code{.stabd} directive), the
-@code{n_strx} field is zero.
-
-Symbol table entries with @code{n_type} field values greater than 0x1f
-originated as stabs generated by the compiler (with one random
-exception).  The other entries were placed in the symbol table of the
-executable by the assembler or the linker.
-
-@node Transformations On Symbol Tables
-@section Transformations on Symbol Tables
-
-The linker concatenates object files and does fixups of externally
-defined symbols.
-
-You can see the transformations made on stab data by the assembler and
-linker by examining the symbol table after each pass of the build.  To
-do this, use @samp{nm -ap}, which dumps the symbol table, including
-debugging information, unsorted.  For stab entries the columns are:
-@var{value}, @var{other}, @var{desc}, @var{type}, @var{string}.  For
-assembler and linker symbols, the columns are: @var{value}, @var{type},
-@var{string}.
-
-The low 5 bits of the stab type tell the linker how to relocate the
-value of the stab.  Thus for stab types like @code{N_RSYM} and
-@code{N_LSYM}, where the value is an offset or a register number, the
-low 5 bits are @code{N_ABS}, which tells the linker not to relocate the
-value.
-
-Where the value of a stab contains an assembly language label,
-it is transformed by each build step.  The assembler turns it into a
-relocatable address and the linker turns it into an absolute address.
-
-@menu
-* Transformations On Static Variables::
-* Transformations On Global Variables::
-* Stab Section Transformations::	   For some object file formats,
-                                           things are a bit different.
-@end menu
-
-@node Transformations On Static Variables
-@subsection Transformations on Static Variables
-
-This source line defines a static variable at file scope:
-
-@example
-static int s_g_repeat
-@end example
-
-@noindent
-The following stab describes the symbol:
-
-@example
-.stabs "s_g_repeat:S1",38,0,0,_s_g_repeat
-@end example
-
-@noindent
-The assembler transforms the stab into this symbol table entry in the
-@file{.o} file.  The location is expressed as a data segment offset.
-
-@example
-00000084 - 00 0000 STSYM s_g_repeat:S1
-@end example
-
-@noindent
-In the symbol table entry from the executable, the linker has made the
-relocatable address absolute.
-
-@example
-0000e00c - 00 0000 STSYM s_g_repeat:S1
-@end example
-
-@node Transformations On Global Variables
-@subsection Transformations on Global Variables
-
-Stabs for global variables do not contain location information. In
-this case, the debugger finds location information in the assembler or
-linker symbol table entry describing the variable.  The source line:
-
-@example
-char g_foo = 'c';
-@end example
-
-@noindent
-generates the stab:
-
-@example
-.stabs "g_foo:G2",32,0,0,0
-@end example
-
-The variable is represented by two symbol table entries in the object
-file (see below).  The first one originated as a stab.  The second one
-is an external symbol.  The upper case @samp{D} signifies that the
-@code{n_type} field of the symbol table contains 7, @code{N_DATA} with
-local linkage.  The stab's value is zero since the value is not used for
-@code{N_GSYM} stabs.  The value of the linker symbol is the relocatable
-address corresponding to the variable.
-
-@example
-00000000 - 00 0000  GSYM g_foo:G2
-00000080 D _g_foo
-@end example
-
-@noindent
-These entries as transformed by the linker.  The linker symbol table
-entry now holds an absolute address:
-
-@example
-00000000 - 00 0000  GSYM g_foo:G2
-@dots{}
-0000e008 D _g_foo
-@end example
-
-@node Stab Section Transformations
-@subsection Transformations of Stabs in separate sections
-
-For object file formats using stabs in separate sections (@pxref{Stab
-Sections}), use @code{objdump --stabs} instead of @code{nm} to show the
-stabs in an object or executable file.  @code{objdump} is a GNU utility;
-Sun does not provide any equivalent.
-
-The following example is for a stab whose value is an address is
-relative to the compilation unit (@pxref{ELF Linker Relocation}).  For
-example, if the source line
-
-@example
-static int ld = 5;
-@end example
-
-appears within a function, then the assembly language output from the
-compiler contains:
-
-@example
-.Ddata.data:
-@dots{}
-        .stabs "ld:V(0,3)",0x26,0,4,.L18-Ddata.data    # @r{0x26 is N_STSYM}
-@dots{}
-.L18:
-        .align 4
-        .word 0x5
-@end example
-
-Because the value is formed by subtracting one symbol from another, the
-value is absolute, not relocatable, and so the object file contains
-
-@example
-Symnum n_type n_othr n_desc n_value  n_strx String
-31     STSYM  0      4      00000004 680    ld:V(0,3)
-@end example
-
-without any relocations, and the executable file also contains
-
-@example
-Symnum n_type n_othr n_desc n_value  n_strx String
-31     STSYM  0      4      00000004 680    ld:V(0,3)
-@end example
-
-@node Cplusplus
-@chapter GNU C@t{++} Stabs
-
-@menu
-* Class Names::			C++ class names are both tags and typedefs.
-* Nested Symbols::		C++ symbol names can be within other types.
-* Basic Cplusplus Types::
-* Simple Classes::
-* Class Instance::
-* Methods::			Method definition
-* Method Type Descriptor::      The @samp{#} type descriptor
-* Member Type Descriptor::      The @samp{@@} type descriptor
-* Protections::
-* Method Modifiers::
-* Virtual Methods::
-* Inheritance::
-* Virtual Base Classes::
-* Static Members::
-@end menu
-
-@node Class Names
-@section C@t{++} Class Names
-
-In C@t{++}, a class name which is declared with @code{class}, @code{struct},
-or @code{union}, is not only a tag, as in C, but also a type name.  Thus
-there should be stabs with both @samp{t} and @samp{T} symbol descriptors
-(@pxref{Typedefs}).
-
-To save space, there is a special abbreviation for this case.  If the
-@samp{T} symbol descriptor is followed by @samp{t}, then the stab
-defines both a type name and a tag.
-
-For example, the C@t{++} code
-
-@example
-struct foo @{int x;@};
-@end example
-
-can be represented as either
-
-@example
-.stabs "foo:T19=s4x:1,0,32;;",128,0,0,0       # @r{128 is N_LSYM}
-.stabs "foo:t19",128,0,0,0
-@end example
-
-or
-
-@example
-.stabs "foo:Tt19=s4x:1,0,32;;",128,0,0,0
-@end example
-
-@node Nested Symbols
-@section Defining a Symbol Within Another Type
-
-In C@t{++}, a symbol (such as a type name) can be defined within another type.
-@c FIXME: Needs example.
-
-In stabs, this is sometimes represented by making the name of a symbol
-which contains @samp{::}.  Such a pair of colons does not end the name
-of the symbol, the way a single colon would (@pxref{String Field}).  I'm
-not sure how consistently used or well thought out this mechanism is.
-So that a pair of colons in this position always has this meaning,
-@samp{:} cannot be used as a symbol descriptor.
-
-For example, if the string for a stab is @samp{foo::bar::baz:t5=*6},
-then @code{foo::bar::baz} is the name of the symbol, @samp{t} is the
-symbol descriptor, and @samp{5=*6} is the type information.
-
-@node Basic Cplusplus Types
-@section Basic Types For C@t{++}
-
-<< the examples that follow are based on a01.C >>
-
-
-C@t{++} adds two more builtin types to the set defined for C.  These are
-the unknown type and the vtable record type.  The unknown type, type
-16, is defined in terms of itself like the void type.
-
-The vtable record type, type 17, is defined as a structure type and
-then as a structure tag.  The structure has four fields: delta, index,
-pfn, and delta2.  pfn is the function pointer.
-
-<< In boilerplate $vtbl_ptr_type, what are the fields delta,
-index, and delta2 used for? >>
-
-This basic type is present in all C@t{++} programs even if there are no
-virtual methods defined.
-
-@display
-.stabs "struct_name:sym_desc(type)type_def(17)=type_desc(struct)struct_bytes(8)
-        elem_name(delta):type_ref(short int),bit_offset(0),field_bits(16);
-        elem_name(index):type_ref(short int),bit_offset(16),field_bits(16);
-        elem_name(pfn):type_def(18)=type_desc(ptr to)type_ref(void),
-                                    bit_offset(32),field_bits(32);
-        elem_name(delta2):type_def(short int);bit_offset(32),field_bits(16);;"
-        N_LSYM, NIL, NIL
-@end display
-
-@smallexample
-.stabs "$vtbl_ptr_type:t17=s8
-        delta:6,0,16;index:6,16,16;pfn:18=*15,32,32;delta2:6,32,16;;"
-        ,128,0,0,0
-@end smallexample
-
-@display
-.stabs "name:sym_dec(struct tag)type_ref($vtbl_ptr_type)",N_LSYM,NIL,NIL,NIL
-@end display
-
-@example
-.stabs "$vtbl_ptr_type:T17",128,0,0,0
-@end example
-
-@node Simple Classes
-@section Simple Class Definition
-
-The stabs describing C@t{++} language features are an extension of the
-stabs describing C.  Stabs representing C@t{++} class types elaborate
-extensively on the stab format used to describe structure types in C.
-Stabs representing class type variables look just like stabs
-representing C language variables.
-
-Consider the following very simple class definition.
-
-@example
-class baseA @{
-public:
-        int Adat;
-        int Ameth(int in, char other);
-@};
-@end example
-
-The class @code{baseA} is represented by two stabs.  The first stab describes
-the class as a structure type.  The second stab describes a structure
-tag of the class type.  Both stabs are of stab type @code{N_LSYM}.  Since the
-stab is not located between an @code{N_FUN} and an @code{N_LBRAC} stab this indicates
-that the class is defined at file scope.  If it were, then the @code{N_LSYM}
-would signify a local variable.
-
-A stab describing a C@t{++} class type is similar in format to a stab
-describing a C struct, with each class member shown as a field in the
-structure.  The part of the struct format describing fields is
-expanded to include extra information relevant to C@t{++} class members.
-In addition, if the class has multiple base classes or virtual
-functions the struct format outside of the field parts is also
-augmented.
-
-In this simple example the field part of the C@t{++} class stab
-representing member data looks just like the field part of a C struct
-stab.  The section on protections describes how its format is
-sometimes extended for member data.
-
-The field part of a C@t{++} class stab representing a member function
-differs substantially from the field part of a C struct stab.  It
-still begins with @samp{name:} but then goes on to define a new type number
-for the member function, describe its return type, its argument types,
-its protection level, any qualifiers applied to the method definition,
-and whether the method is virtual or not.  If the method is virtual
-then the method description goes on to give the vtable index of the
-method, and the type number of the first base class defining the
-method.
-
-When the field name is a method name it is followed by two colons rather
-than one.  This is followed by a new type definition for the method.
-This is a number followed by an equal sign and the type of the method.
-Normally this will be a type declared using the @samp{#} type
-descriptor; see @ref{Method Type Descriptor}; static member functions
-are declared using the @samp{f} type descriptor instead; see
-@ref{Function Types}.
-
-The format of an overloaded operator method name differs from that of
-other methods.  It is @samp{op$::@var{operator-name}.} where
-@var{operator-name} is the operator name such as @samp{+} or @samp{+=}.
-The name ends with a period, and any characters except the period can
-occur in the @var{operator-name} string.
-
-The next part of the method description represents the arguments to the
-method, preceded by a colon and ending with a semi-colon.  The types of
-the arguments are expressed in the same way argument types are expressed
-in C@t{++} name mangling.  In this example an @code{int} and a @code{char}
-map to @samp{ic}.
-
-This is followed by a number, a letter, and an asterisk or period,
-followed by another semicolon.  The number indicates the protections
-that apply to the member function.  Here the 2 means public.  The
-letter encodes any qualifier applied to the method definition.  In
-this case, @samp{A} means that it is a normal function definition.  The dot
-shows that the method is not virtual.  The sections that follow
-elaborate further on these fields and describe the additional
-information present for virtual methods.
-
-
-@display
-.stabs "class_name:sym_desc(type)type_def(20)=type_desc(struct)struct_bytes(4)
-        field_name(Adat):type(int),bit_offset(0),field_bits(32);
-
-        method_name(Ameth)::type_def(21)=type_desc(method)return_type(int);
-        :arg_types(int char);
-        protection(public)qualifier(normal)virtual(no);;"
-        N_LSYM,NIL,NIL,NIL
-@end display
-
-@smallexample
-.stabs "baseA:t20=s4Adat:1,0,32;Ameth::21=##1;:ic;2A.;;",128,0,0,0
-
-.stabs "class_name:sym_desc(struct tag)",N_LSYM,NIL,NIL,NIL
-
-.stabs "baseA:T20",128,0,0,0
-@end smallexample
-
-@node Class Instance
-@section Class Instance
-
-As shown above, describing even a simple C@t{++} class definition is
-accomplished by massively extending the stab format used in C to
-describe structure types.  However, once the class is defined, C stabs
-with no modifications can be used to describe class instances.  The
-following source:
-
-@example
-main () @{
-        baseA AbaseA;
-@}
-@end example
-
-@noindent
-yields the following stab describing the class instance.  It looks no
-different from a standard C stab describing a local variable.
-
-@display
-.stabs "name:type_ref(baseA)", N_LSYM, NIL, NIL, frame_ptr_offset
-@end display
-
-@example
-.stabs "AbaseA:20",128,0,0,-20
-@end example
-
-@node Methods
-@section Method Definition
-
-The class definition shown above declares Ameth.  The C@t{++} source below
-defines Ameth:
-
-@example
-int
-baseA::Ameth(int in, char other)
-@{
-        return in;
-@};
-@end example
-
-
-This method definition yields three stabs following the code of the
-method.  One stab describes the method itself and following two describe
-its parameters.  Although there is only one formal argument all methods
-have an implicit argument which is the @code{this} pointer.  The @code{this}
-pointer is a pointer to the object on which the method was called.  Note
-that the method name is mangled to encode the class name and argument
-types.  Name mangling is described in the @sc{arm} (@cite{The Annotated
-C++ Reference Manual}, by Ellis and Stroustrup, @sc{isbn}
-0-201-51459-1); @file{gpcompare.texi} in Cygnus GCC distributions
-describes the differences between GNU mangling and @sc{arm}
-mangling.
-@c FIXME: Use @xref, especially if this is generally installed in the
-@c info tree.
-@c FIXME: This information should be in a net release, either of GCC or
-@c GDB.  But gpcompare.texi doesn't seem to be in the FSF GCC.
-
-@example
-.stabs "name:symbol_descriptor(global function)return_type(int)",
-        N_FUN, NIL, NIL, code_addr_of_method_start
-
-.stabs "Ameth__5baseAic:F1",36,0,0,_Ameth__5baseAic
-@end example
-
-Here is the stab for the @code{this} pointer implicit argument.  The
-name of the @code{this} pointer is always @code{this}.  Type 19, the
-@code{this} pointer is defined as a pointer to type 20, @code{baseA},
-but a stab defining @code{baseA} has not yet been emitted.  Since the
-compiler knows it will be emitted shortly, here it just outputs a cross
-reference to the undefined symbol, by prefixing the symbol name with
-@samp{xs}.
-
-@example
-.stabs "name:sym_desc(register param)type_def(19)=
-        type_desc(ptr to)type_ref(baseA)=
-        type_desc(cross-reference to)baseA:",N_RSYM,NIL,NIL,register_number
-
-.stabs "this:P19=*20=xsbaseA:",64,0,0,8
-@end example
-
-The stab for the explicit integer argument looks just like a parameter
-to a C function.  The last field of the stab is the offset from the
-argument pointer, which in most systems is the same as the frame
-pointer.
-
-@example
-.stabs "name:sym_desc(value parameter)type_ref(int)",
-        N_PSYM,NIL,NIL,offset_from_arg_ptr
-
-.stabs "in:p1",160,0,0,72
-@end example
-
-<< The examples that follow are based on A1.C >>
-
-@node Method Type Descriptor
-@section The @samp{#} Type Descriptor
-
-This is used to describe a class method.  This is a function which takes
-an extra argument as its first argument, for the @code{this} pointer.
-
-If the @samp{#} is immediately followed by another @samp{#}, the second
-one will be followed by the return type and a semicolon.  The class and
-argument types are not specified, and must be determined by demangling
-the name of the method if it is available.
-
-Otherwise, the single @samp{#} is followed by the class type, a comma,
-the return type, a comma, and zero or more parameter types separated by
-commas.  The list of arguments is terminated by a semicolon.  In the
-debugging output generated by gcc, a final argument type of @code{void}
-indicates a method which does not take a variable number of arguments.
-If the final argument type of @code{void} does not appear, the method
-was declared with an ellipsis.
-
-Note that although such a type will normally be used to describe fields
-in structures, unions, or classes, for at least some versions of the
-compiler it can also be used in other contexts.
-
-@node Member Type Descriptor
-@section The @samp{@@} Type Descriptor
-
-The @samp{@@} type descriptor is used for a
-pointer-to-non-static-member-data type.  It is followed
-by type information for the class (or union), a comma, and type
-information for the member data.
-
-The following C@t{++} source:
-
-@smallexample
-typedef int A::*int_in_a;
-@end smallexample
-
-generates the following stab:
-
-@smallexample
-.stabs "int_in_a:t20=21=@@19,1",128,0,0,0
-@end smallexample
-
-Note that there is a conflict between this and type attributes
-(@pxref{String Field}); both use type descriptor @samp{@@}.
-Fortunately, the @samp{@@} type descriptor used in this C@t{++} sense always
-will be followed by a digit, @samp{(}, or @samp{-}, and type attributes
-never start with those things.
-
-@node Protections
-@section Protections
-
-In the simple class definition shown above all member data and
-functions were publicly accessible.  The example that follows
-contrasts public, protected and privately accessible fields and shows
-how these protections are encoded in C@t{++} stabs.
-
-If the character following the @samp{@var{field-name}:} part of the
-string is @samp{/}, then the next character is the visibility.  @samp{0}
-means private, @samp{1} means protected, and @samp{2} means public.
-Debuggers should ignore visibility characters they do not recognize, and
-assume a reasonable default (such as public) (GDB 4.11 does not, but
-this should be fixed in the next GDB release).  If no visibility is
-specified the field is public.  The visibility @samp{9} means that the
-field has been optimized out and is public (there is no way to specify
-an optimized out field with a private or protected visibility).
-Visibility @samp{9} is not supported by GDB 4.11; this should be fixed
-in the next GDB release.
-
-The following C@t{++} source:
-
-@example
-class vis @{
-private:
-        int   priv;
-protected:
-        char  prot;
-public:
-        float pub;
-@};
-@end example
-
-@noindent
-generates the following stab:
-
-@example
-# @r{128 is N_LSYM}
-.stabs "vis:T19=s12priv:/01,0,32;prot:/12,32,8;pub:12,64,32;;",128,0,0,0
-@end example
-
-@samp{vis:T19=s12} indicates that type number 19 is a 12 byte structure
-named @code{vis} The @code{priv} field has public visibility
-(@samp{/0}), type int (@samp{1}), and offset and size @samp{,0,32;}.
-The @code{prot} field has protected visibility (@samp{/1}), type char
-(@samp{2}) and offset and size @samp{,32,8;}.  The @code{pub} field has
-type float (@samp{12}), and offset and size @samp{,64,32;}.
-
-Protections for member functions are signified by one digit embedded in
-the field part of the stab describing the method.  The digit is 0 if
-private, 1 if protected and 2 if public.  Consider the C@t{++} class
-definition below:
-
-@example
-class all_methods @{
-private:
-        int   priv_meth(int in)@{return in;@};
-protected:
-        char  protMeth(char in)@{return in;@};
-public:
-        float pubMeth(float in)@{return in;@};
-@};
-@end example
-
-It generates the following stab.  The digit in question is to the left
-of an @samp{A} in each case.  Notice also that in this case two symbol
-descriptors apply to the class name struct tag and struct type.
-
-@display
-.stabs "class_name:sym_desc(struct tag&type)type_def(21)=
-        sym_desc(struct)struct_bytes(1)
-        meth_name::type_def(22)=sym_desc(method)returning(int);
-        :args(int);protection(private)modifier(normal)virtual(no);
-        meth_name::type_def(23)=sym_desc(method)returning(char);
-        :args(char);protection(protected)modifier(normal)virtual(no);
-        meth_name::type_def(24)=sym_desc(method)returning(float);
-        :args(float);protection(public)modifier(normal)virtual(no);;",
-        N_LSYM,NIL,NIL,NIL
-@end display
-
-@smallexample
-.stabs "all_methods:Tt21=s1priv_meth::22=##1;:i;0A.;protMeth::23=##2;:c;1A.;
-        pubMeth::24=##12;:f;2A.;;",128,0,0,0
-@end smallexample
-
-@node Method Modifiers
-@section Method Modifiers (@code{const}, @code{volatile}, @code{const volatile})
-
-<< based on a6.C >>
-
-In the class example described above all the methods have the normal
-modifier.  This method modifier information is located just after the
-protection information for the method.  This field has four possible
-character values.  Normal methods use @samp{A}, const methods use
-@samp{B}, volatile methods use @samp{C}, and const volatile methods use
-@samp{D}.  Consider the class definition below:
-
-@example
-class A @{
-public:
-        int ConstMeth (int arg) const @{ return arg; @};
-        char VolatileMeth (char arg) volatile @{ return arg; @};
-        float ConstVolMeth (float arg) const volatile @{return arg; @};
-@};
-@end example
-
-This class is described by the following stab:
-
-@display
-.stabs "class(A):sym_desc(struct)type_def(20)=type_desc(struct)struct_bytes(1)
-        meth_name(ConstMeth)::type_def(21)sym_desc(method)
-        returning(int);:arg(int);protection(public)modifier(const)virtual(no);
-        meth_name(VolatileMeth)::type_def(22)=sym_desc(method)
-        returning(char);:arg(char);protection(public)modifier(volatile)virt(no)
-        meth_name(ConstVolMeth)::type_def(23)=sym_desc(method)
-        returning(float);:arg(float);protection(public)modifier(const volatile)
-        virtual(no);;", @dots{}
-@end display
-
-@example
-.stabs "A:T20=s1ConstMeth::21=##1;:i;2B.;VolatileMeth::22=##2;:c;2C.;
-             ConstVolMeth::23=##12;:f;2D.;;",128,0,0,0
-@end example
-
-@node Virtual Methods
-@section Virtual Methods
-
-<< The following examples are based on a4.C >>
-
-The presence of virtual methods in a class definition adds additional
-data to the class description.  The extra data is appended to the
-description of the virtual method and to the end of the class
-description.  Consider the class definition below:
-
-@example
-class A @{
-public:
-        int Adat;
-        virtual int A_virt (int arg) @{ return arg; @};
-@};
-@end example
-
-This results in the stab below describing class A.  It defines a new
-type (20) which is an 8 byte structure.  The first field of the class
-struct is @samp{Adat}, an integer, starting at structure offset 0 and
-occupying 32 bits.
-
-The second field in the class struct is not explicitly defined by the
-C@t{++} class definition but is implied by the fact that the class
-contains a virtual method.  This field is the vtable pointer.  The
-name of the vtable pointer field starts with @samp{$vf} and continues with a
-type reference to the class it is part of.  In this example the type
-reference for class A is 20 so the name of its vtable pointer field is
-@samp{$vf20}, followed by the usual colon.
-
-Next there is a type definition for the vtable pointer type (21).
-This is in turn defined as a pointer to another new type (22).
-
-Type 22 is the vtable itself, which is defined as an array, indexed by
-a range of integers between 0 and 1, and whose elements are of type
-17.  Type 17 was the vtable record type defined by the boilerplate C@t{++}
-type definitions, as shown earlier.
-
-The bit offset of the vtable pointer field is 32.  The number of bits
-in the field are not specified when the field is a vtable pointer.
-
-Next is the method definition for the virtual member function @code{A_virt}.
-Its description starts out using the same format as the non-virtual
-member functions described above, except instead of a dot after the
-@samp{A} there is an asterisk, indicating that the function is virtual.
-Since is is virtual some addition information is appended to the end
-of the method description.
-
-The first number represents the vtable index of the method.  This is a
-32 bit unsigned number with the high bit set, followed by a
-semi-colon.
-
-The second number is a type reference to the first base class in the
-inheritance hierarchy defining the virtual member function.  In this
-case the class stab describes a base class so the virtual function is
-not overriding any other definition of the method.  Therefore the
-reference is to the type number of the class that the stab is
-describing (20).
-
-This is followed by three semi-colons.  One marks the end of the
-current sub-section, one marks the end of the method field, and the
-third marks the end of the struct definition.
-
-For classes containing virtual functions the very last section of the
-string part of the stab holds a type reference to the first base
-class.  This is preceded by @samp{~%} and followed by a final semi-colon.
-
-@display
-.stabs "class_name(A):type_def(20)=sym_desc(struct)struct_bytes(8)
-        field_name(Adat):type_ref(int),bit_offset(0),field_bits(32);
-        field_name(A virt func ptr):type_def(21)=type_desc(ptr to)type_def(22)=
-        sym_desc(array)index_type_ref(range of int from 0 to 1);
-        elem_type_ref(vtbl elem type),
-        bit_offset(32);
-        meth_name(A_virt)::typedef(23)=sym_desc(method)returning(int);
-        :arg_type(int),protection(public)normal(yes)virtual(yes)
-        vtable_index(1);class_first_defining(A);;;~%first_base(A);",
-        N_LSYM,NIL,NIL,NIL
-@end display
-
-@c FIXME: bogus line break.
-@example
-.stabs "A:t20=s8Adat:1,0,32;$vf20:21=*22=ar1;0;1;17,32;
-        A_virt::23=##1;:i;2A*-2147483647;20;;;~%20;",128,0,0,0
-@end example
-
-@node Inheritance
-@section Inheritance
-
-Stabs describing C@t{++} derived classes include additional sections that
-describe the inheritance hierarchy of the class.  A derived class stab
-also encodes the number of base classes.  For each base class it tells
-if the base class is virtual or not, and if the inheritance is private
-or public.  It also gives the offset into the object of the portion of
-the object corresponding to each base class.
-
-This additional information is embedded in the class stab following the
-number of bytes in the struct.  First the number of base classes
-appears bracketed by an exclamation point and a comma.
-
-Then for each base type there repeats a series: a virtual character, a
-visibility character, a number, a comma, another number, and a
-semi-colon.
-
-The virtual character is @samp{1} if the base class is virtual and
-@samp{0} if not.  The visibility character is @samp{2} if the derivation
-is public, @samp{1} if it is protected, and @samp{0} if it is private.
-Debuggers should ignore virtual or visibility characters they do not
-recognize, and assume a reasonable default (such as public and
-non-virtual) (GDB 4.11 does not, but this should be fixed in the next
-GDB release).
-
-The number following the virtual and visibility characters is the offset
-from the start of the object to the part of the object pertaining to the
-base class.
-
-After the comma, the second number is a type_descriptor for the base
-type.  Finally a semi-colon ends the series, which repeats for each
-base class.
-
-The source below defines three base classes @code{A}, @code{B}, and
-@code{C} and the derived class @code{D}.
-
-
-@example
-class A @{
-public:
-        int Adat;
-        virtual int A_virt (int arg) @{ return arg; @};
-@};
-
-class B @{
-public:
-        int B_dat;
-        virtual int B_virt (int arg) @{return arg; @};
-@};
-
-class C @{
-public:
-        int Cdat;
-        virtual int C_virt (int arg) @{return arg; @};
-@};
-
-class D : A, virtual B, public C @{
-public:
-        int Ddat;
-        virtual int A_virt (int arg ) @{ return arg+1; @};
-        virtual int B_virt (int arg)  @{ return arg+2; @};
-        virtual int C_virt (int arg)  @{ return arg+3; @};
-        virtual int D_virt (int arg)  @{ return arg; @};
-@};
-@end example
-
-Class stabs similar to the ones described earlier are generated for
-each base class.
-
-@c FIXME!!! the linebreaks in the following example probably make the
-@c examples literally unusable, but I don't know any other way to get
-@c them on the page.
-@c One solution would be to put some of the type definitions into
-@c separate stabs, even if that's not exactly what the compiler actually
-@c emits.
-@smallexample
-.stabs "A:T20=s8Adat:1,0,32;$vf20:21=*22=ar1;0;1;17,32;
-        A_virt::23=##1;:i;2A*-2147483647;20;;;~%20;",128,0,0,0
-
-.stabs "B:Tt25=s8Bdat:1,0,32;$vf25:21,32;B_virt::26=##1;
-        :i;2A*-2147483647;25;;;~%25;",128,0,0,0
-
-.stabs "C:Tt28=s8Cdat:1,0,32;$vf28:21,32;C_virt::29=##1;
-        :i;2A*-2147483647;28;;;~%28;",128,0,0,0
-@end smallexample
-
-In the stab describing derived class @code{D} below, the information about
-the derivation of this class is encoded as follows.
-
-@display
-.stabs "derived_class_name:symbol_descriptors(struct tag&type)=
-        type_descriptor(struct)struct_bytes(32)!num_bases(3),
-        base_virtual(no)inheritance_public(no)base_offset(0),
-        base_class_type_ref(A);
-        base_virtual(yes)inheritance_public(no)base_offset(NIL),
-        base_class_type_ref(B);
-        base_virtual(no)inheritance_public(yes)base_offset(64),
-        base_class_type_ref(C); @dots{}
-@end display
-
-@c FIXME! fake linebreaks.
-@smallexample
-.stabs "D:Tt31=s32!3,000,20;100,25;0264,28;$vb25:24,128;Ddat:
-        1,160,32;A_virt::32=##1;:i;2A*-2147483647;20;;B_virt:
-        :32:i;2A*-2147483647;25;;C_virt::32:i;2A*-2147483647;
-        28;;D_virt::32:i;2A*-2147483646;31;;;~%20;",128,0,0,0
-@end smallexample
-
-@node Virtual Base Classes
-@section Virtual Base Classes
-
-A derived class object consists of a concatenation in memory of the data
-areas defined by each base class, starting with the leftmost and ending
-with the rightmost in the list of base classes.  The exception to this
-rule is for virtual inheritance.  In the example above, class @code{D}
-inherits virtually from base class @code{B}.  This means that an
-instance of a @code{D} object will not contain its own @code{B} part but
-merely a pointer to a @code{B} part, known as a virtual base pointer.
-
-In a derived class stab, the base offset part of the derivation
-information, described above, shows how the base class parts are
-ordered.  The base offset for a virtual base class is always given as 0.
-Notice that the base offset for @code{B} is given as 0 even though
-@code{B} is not the first base class.  The first base class @code{A}
-starts at offset 0.
-
-The field information part of the stab for class @code{D} describes the field
-which is the pointer to the virtual base class @code{B}. The vbase pointer
-name is @samp{$vb} followed by a type reference to the virtual base class.
-Since the type id for @code{B} in this example is 25, the vbase pointer name
-is @samp{$vb25}.
-
-@c FIXME!! fake linebreaks below
-@smallexample
-.stabs "D:Tt31=s32!3,000,20;100,25;0264,28;$vb25:24,128;Ddat:1,
-       160,32;A_virt::32=##1;:i;2A*-2147483647;20;;B_virt::32:i;
-       2A*-2147483647;25;;C_virt::32:i;2A*-2147483647;28;;D_virt:
-       :32:i;2A*-2147483646;31;;;~%20;",128,0,0,0
-@end smallexample
-
-Following the name and a semicolon is a type reference describing the
-type of the virtual base class pointer, in this case 24.  Type 24 was
-defined earlier as the type of the @code{B} class @code{this} pointer.  The
-@code{this} pointer for a class is a pointer to the class type.
-
-@example
-.stabs "this:P24=*25=xsB:",64,0,0,8
-@end example
-
-Finally the field offset part of the vbase pointer field description
-shows that the vbase pointer is the first field in the @code{D} object,
-before any data fields defined by the class.  The layout of a @code{D}
-class object is a follows, @code{Adat} at 0, the vtable pointer for
-@code{A} at 32, @code{Cdat} at 64, the vtable pointer for C at 96, the
-virtual base pointer for @code{B} at 128, and @code{Ddat} at 160.
-
-
-@node Static Members
-@section Static Members
-
-The data area for a class is a concatenation of the space used by the
-data members of the class.  If the class has virtual methods, a vtable
-pointer follows the class data.  The field offset part of each field
-description in the class stab shows this ordering.
-
-<< How is this reflected in stabs?  See Cygnus bug #677 for some info.  >>
-
-@node Stab Types
-@appendix Table of Stab Types
-
-The following are all the possible values for the stab type field, for
-a.out files, in numeric order.  This does not apply to XCOFF, but
-it does apply to stabs in sections (@pxref{Stab Sections}).  Stabs in
-ECOFF use these values but add 0x8f300 to distinguish them from non-stab
-symbols.
-
-The symbolic names are defined in the file @file{include/aout/stabs.def}.
-
-@menu
-* Non-Stab Symbol Types::	Types from 0 to 0x1f
-* Stab Symbol Types::		Types from 0x20 to 0xff
-@end menu
-
-@node Non-Stab Symbol Types
-@appendixsec Non-Stab Symbol Types
-
-The following types are used by the linker and assembler, not by stab
-directives.  Since this document does not attempt to describe aspects of
-object file format other than the debugging format, no details are
-given.
-
-@c Try to get most of these to fit on a single line.
-@iftex
-@tableindent=1.5in
-@end iftex
-
-@table @code
-@item 0x0     N_UNDF
-Undefined symbol
-
-@item 0x2     N_ABS
-File scope absolute symbol
-
-@item 0x3     N_ABS | N_EXT
-External absolute symbol
-
-@item 0x4     N_TEXT
-File scope text symbol
-
-@item 0x5     N_TEXT | N_EXT
-External text symbol
-
-@item 0x6     N_DATA
-File scope data symbol
-
-@item 0x7     N_DATA | N_EXT
-External data symbol
-
-@item 0x8     N_BSS
-File scope BSS symbol
-
-@item 0x9     N_BSS | N_EXT
-External BSS symbol
-
-@item 0x0c    N_FN_SEQ
-Same as @code{N_FN}, for Sequent compilers
-
-@item 0x0a    N_INDR
-Symbol is indirected to another symbol
-
-@item 0x12    N_COMM
-Common---visible after shared library dynamic link
-
-@item 0x14 N_SETA
-@itemx 0x15 N_SETA | N_EXT
-Absolute set element
-
-@item 0x16 N_SETT
-@itemx 0x17 N_SETT | N_EXT
-Text segment set element
-
-@item 0x18 N_SETD
-@itemx 0x19 N_SETD | N_EXT
-Data segment set element
-
-@item 0x1a N_SETB
-@itemx 0x1b N_SETB | N_EXT
-BSS segment set element
-
-@item 0x1c N_SETV
-@itemx 0x1d N_SETV | N_EXT
-Pointer to set vector
-
-@item 0x1e N_WARNING
-Print a warning message during linking
-
-@item 0x1f    N_FN
-File name of a @file{.o} file
-@end table
-
-@node Stab Symbol Types
-@appendixsec Stab Symbol Types
-
-The following symbol types indicate that this is a stab.  This is the
-full list of stab numbers, including stab types that are used in
-languages other than C.
-
-@table @code
-@item 0x20     N_GSYM
-Global symbol; see @ref{Global Variables}.
-
-@item 0x22     N_FNAME
-Function name (for BSD Fortran); see @ref{Procedures}.
-
-@item 0x24     N_FUN
-Function name (@pxref{Procedures}) or text segment variable
-(@pxref{Statics}).
-
-@item 0x26 N_STSYM
-Data segment file-scope variable; see @ref{Statics}.
-
-@item 0x28 N_LCSYM
-BSS segment file-scope variable; see @ref{Statics}.
-
-@item 0x2a N_MAIN
-Name of main routine; see @ref{Main Program}.
-
-@item 0x2c N_ROSYM
-Variable in @code{.rodata} section; see @ref{Statics}.
-
-@item 0x30     N_PC
-Global symbol (for Pascal); see @ref{N_PC}.
-
-@item 0x32     N_NSYMS
-Number of symbols (according to Ultrix V4.0); see @ref{N_NSYMS}.
-
-@item 0x34     N_NOMAP
-No DST map; see @ref{N_NOMAP}.
-
-@item 0x36     N_MAC_DEFINE
-Name and body of a @code{#define}d macro; see @ref{Macro define and undefine}.
-
-@c FIXME: describe this solaris feature in the body of the text (see
-@c comments in include/aout/stab.def).
-@item 0x38 N_OBJ
-Object file (Solaris2).
-
-@item 0x3a     N_MAC_UNDEF
-Name of an @code{#undef}ed macro; see @ref{Macro define and undefine}.
-
-@c See include/aout/stab.def for (a little) more info.
-@item 0x3c N_OPT
-Debugger options (Solaris2).
-
-@item 0x40     N_RSYM
-Register variable; see @ref{Register Variables}.
-
-@item 0x42     N_M2C
-Modula-2 compilation unit; see @ref{N_M2C}.
-
-@item 0x44     N_SLINE
-Line number in text segment; see @ref{Line Numbers}.
-
-@item 0x46     N_DSLINE
-Line number in data segment; see @ref{Line Numbers}.
-
-@item 0x48     N_BSLINE
-Line number in bss segment; see @ref{Line Numbers}.
-
-@item 0x48     N_BROWS
-Sun source code browser, path to @file{.cb} file; see @ref{N_BROWS}.
-
-@item 0x4a     N_DEFD
-GNU Modula2 definition module dependency; see @ref{N_DEFD}.
-
-@item 0x4c N_FLINE
-Function start/body/end line numbers (Solaris2).
-
-@item 0x50     N_EHDECL
-GNU C@t{++} exception variable; see @ref{N_EHDECL}.
-
-@item 0x50     N_MOD2
-Modula2 info "for imc" (according to Ultrix V4.0); see @ref{N_MOD2}.
-
-@item 0x54     N_CATCH
-GNU C@t{++} @code{catch} clause; see @ref{N_CATCH}.
-
-@item 0x60     N_SSYM
-Structure of union element; see @ref{N_SSYM}.
-
-@item 0x62 N_ENDM
-Last stab for module (Solaris2).
-
-@item 0x64     N_SO
-Path and name of source file; see @ref{Source Files}.
-
-@item 0x80 N_LSYM
-Stack variable (@pxref{Stack Variables}) or type (@pxref{Typedefs}).
-
-@item 0x82     N_BINCL
-Beginning of an include file (Sun only); see @ref{Include Files}.
-
-@item 0x84     N_SOL
-Name of include file; see @ref{Include Files}.
-
-@item 0xa0     N_PSYM
-Parameter variable; see @ref{Parameters}.
-
-@item 0xa2     N_EINCL
-End of an include file; see @ref{Include Files}.
-
-@item 0xa4     N_ENTRY
-Alternate entry point; see @ref{Alternate Entry Points}.
-
-@item 0xc0     N_LBRAC
-Beginning of a lexical block; see @ref{Block Structure}.
-
-@item 0xc2     N_EXCL
-Place holder for a deleted include file; see @ref{Include Files}.
-
-@item 0xc4     N_SCOPE
-Modula2 scope information (Sun linker); see @ref{N_SCOPE}.
-
-@item 0xe0     N_RBRAC
-End of a lexical block; see @ref{Block Structure}.
-
-@item 0xe2     N_BCOMM
-Begin named common block; see @ref{Common Blocks}.
-
-@item 0xe4     N_ECOMM
-End named common block; see @ref{Common Blocks}.
-
-@item 0xe8     N_ECOML
-Member of a common block; see @ref{Common Blocks}.
-
-@c FIXME: How does this really work?  Move it to main body of document.
-@item 0xea N_WITH
-Pascal @code{with} statement: type,,0,0,offset (Solaris2).
-
-@item 0xf0     N_NBTEXT
-Gould non-base registers; see @ref{Gould}.
-
-@item 0xf2     N_NBDATA
-Gould non-base registers; see @ref{Gould}.
-
-@item 0xf4     N_NBBSS
-Gould non-base registers; see @ref{Gould}.
-
-@item 0xf6     N_NBSTS
-Gould non-base registers; see @ref{Gould}.
-
-@item 0xf8     N_NBLCS
-Gould non-base registers; see @ref{Gould}.
-@end table
-
-@c Restore the default table indent
-@iftex
-@tableindent=.8in
-@end iftex
-
-@node Symbol Descriptors
-@appendix Table of Symbol Descriptors
-
-The symbol descriptor is the character which follows the colon in many
-stabs, and which tells what kind of stab it is.  @xref{String Field},
-for more information about their use.
-
-@c Please keep this alphabetical
-@table @code
-@c In TeX, this looks great, digit is in italics.  But makeinfo insists
-@c on putting it in `', not realizing that @var should override @code.
-@c I don't know of any way to make makeinfo do the right thing.  Seems
-@c like a makeinfo bug to me.
-@item @var{digit}
-@itemx (
-@itemx -
-Variable on the stack; see @ref{Stack Variables}.
-
-@item :
-C@t{++} nested symbol; see @xref{Nested Symbols}.
-
-@item a
-Parameter passed by reference in register; see @ref{Reference Parameters}.
-
-@item b
-Based variable; see @ref{Based Variables}.
-
-@item c
-Constant; see @ref{Constants}.
-
-@item C
-Conformant array bound (Pascal, maybe other languages); @ref{Conformant
-Arrays}.  Name of a caught exception (GNU C@t{++}).  These can be
-distinguished because the latter uses @code{N_CATCH} and the former uses
-another symbol type.
-
-@item d
-Floating point register variable; see @ref{Register Variables}.
-
-@item D
-Parameter in floating point register; see @ref{Register Parameters}.
-
-@item f
-File scope function; see @ref{Procedures}.
-
-@item F
-Global function; see @ref{Procedures}.
-
-@item G
-Global variable; see @ref{Global Variables}.
-
-@item i
-@xref{Register Parameters}.
-
-@item I
-Internal (nested) procedure; see @ref{Nested Procedures}.
-
-@item J
-Internal (nested) function; see @ref{Nested Procedures}.
-
-@item L
-Label name (documented by AIX, no further information known).
-
-@item m
-Module; see @ref{Procedures}.
-
-@item p
-Argument list parameter; see @ref{Parameters}.
-
-@item pP
-@xref{Parameters}.
-
-@item pF
-Fortran Function parameter; see @ref{Parameters}.
-
-@item P
-Unfortunately, three separate meanings have been independently invented
-for this symbol descriptor.  At least the GNU and Sun uses can be
-distinguished by the symbol type.  Global Procedure (AIX) (symbol type
-used unknown); see @ref{Procedures}.  Register parameter (GNU) (symbol
-type @code{N_PSYM}); see @ref{Parameters}.  Prototype of function
-referenced by this file (Sun @code{acc}) (symbol type @code{N_FUN}).
-
-@item Q
-Static Procedure; see @ref{Procedures}.
-
-@item R
-Register parameter; see @ref{Register Parameters}.
-
-@item r
-Register variable; see @ref{Register Variables}.
-
-@item S
-File scope variable; see @ref{Statics}.
-
-@item s
-Local variable (OS9000).
-
-@item t
-Type name; see @ref{Typedefs}.
-
-@item T
-Enumeration, structure, or union tag; see @ref{Typedefs}.
-
-@item v
-Parameter passed by reference; see @ref{Reference Parameters}.
-
-@item V
-Procedure scope static variable; see @ref{Statics}.
-
-@item x
-Conformant array; see @ref{Conformant Arrays}.
-
-@item X
-Function return variable; see @ref{Parameters}.
-@end table
-
-@node Type Descriptors
-@appendix Table of Type Descriptors
-
-The type descriptor is the character which follows the type number and
-an equals sign.  It specifies what kind of type is being defined.
-@xref{String Field}, for more information about their use.
-
-@table @code
-@item @var{digit}
-@itemx (
-Type reference; see @ref{String Field}.
-
-@item -
-Reference to builtin type; see @ref{Negative Type Numbers}.
-
-@item #
-Method (C@t{++}); see @ref{Method Type Descriptor}.
-
-@item *
-Pointer; see @ref{Miscellaneous Types}.
-
-@item &
-Reference (C@t{++}).
-
-@item @@
-Type Attributes (AIX); see @ref{String Field}.  Member (class and variable)
-type (GNU C@t{++}); see @ref{Member Type Descriptor}.
-
-@item a
-Array; see @ref{Arrays}.
-
-@item A
-Open array; see @ref{Arrays}.
-
-@item b
-Pascal space type (AIX); see @ref{Miscellaneous Types}.  Builtin integer
-type (Sun); see @ref{Builtin Type Descriptors}.  Const and volatile
-qualified type (OS9000).
-
-@item B
-Volatile-qualified type; see @ref{Miscellaneous Types}.
-
-@item c
-Complex builtin type (AIX); see @ref{Builtin Type Descriptors}.
-Const-qualified type (OS9000).
-
-@item C
-COBOL Picture type.  See AIX documentation for details.
-
-@item d
-File type; see @ref{Miscellaneous Types}.
-
-@item D
-N-dimensional dynamic array; see @ref{Arrays}.
-
-@item e
-Enumeration type; see @ref{Enumerations}.
-
-@item E
-N-dimensional subarray; see @ref{Arrays}.
-
-@item f
-Function type; see @ref{Function Types}.
-
-@item F
-Pascal function parameter; see @ref{Function Types}
-
-@item g
-Builtin floating point type; see @ref{Builtin Type Descriptors}.
-
-@item G
-COBOL Group.  See AIX documentation for details.
-
-@item i
-Imported type (AIX); see @ref{Cross-References}.  Volatile-qualified
-type (OS9000).
-
-@item k
-Const-qualified type; see @ref{Miscellaneous Types}.
-
-@item K
-COBOL File Descriptor.  See AIX documentation for details.
-
-@item M
-Multiple instance type; see @ref{Miscellaneous Types}.
-
-@item n
-String type; see @ref{Strings}.
-
-@item N
-Stringptr; see @ref{Strings}.
-
-@item o
-Opaque type; see @ref{Typedefs}.
-
-@item p
-Procedure; see @ref{Function Types}.
-
-@item P
-Packed array; see @ref{Arrays}.
-
-@item r
-Range type; see @ref{Subranges}.
-
-@item R
-Builtin floating type; see @ref{Builtin Type Descriptors} (Sun).  Pascal
-subroutine parameter; see @ref{Function Types} (AIX).  Detecting this
-conflict is possible with careful parsing (hint: a Pascal subroutine
-parameter type will always contain a comma, and a builtin type
-descriptor never will).
-
-@item s
-Structure type; see @ref{Structures}.
-
-@item S
-Set type; see @ref{Miscellaneous Types}.
-
-@item u
-Union; see @ref{Unions}.
-
-@item v
-Variant record.  This is a Pascal and Modula-2 feature which is like a
-union within a struct in C.  See AIX documentation for details.
-
-@item w
-Wide character; see @ref{Builtin Type Descriptors}.
-
-@item x
-Cross-reference; see @ref{Cross-References}.
-
-@item Y
-Used by IBM's xlC C@t{++} compiler (for structures, I think).
-
-@item z
-gstring; see @ref{Strings}.
-@end table
-
-@node Expanded Reference
-@appendix Expanded Reference by Stab Type
-
-@c FIXME: This appendix should go away; see N_PSYM or N_SO for an example.
-
-For a full list of stab types, and cross-references to where they are
-described, see @ref{Stab Types}.  This appendix just covers certain
-stabs which are not yet described in the main body of this document;
-eventually the information will all be in one place.
-
-Format of an entry:
-
-The first line is the symbol type (see @file{include/aout/stab.def}).
-
-The second line describes the language constructs the symbol type
-represents.
-
-The third line is the stab format with the significant stab fields
-named and the rest NIL.
-
-Subsequent lines expand upon the meaning and possible values for each
-significant stab field.
-
-Finally, any further information.
-
-@menu
-* N_PC::			Pascal global symbol
-* N_NSYMS::			Number of symbols
-* N_NOMAP::			No DST map
-* N_M2C::			Modula-2 compilation unit
-* N_BROWS::			Path to .cb file for Sun source code browser
-* N_DEFD::			GNU Modula2 definition module dependency
-* N_EHDECL::			GNU C++ exception variable
-* N_MOD2::			Modula2 information "for imc"
-* N_CATCH::			GNU C++ "catch" clause
-* N_SSYM::			Structure or union element
-* N_SCOPE::			Modula2 scope information (Sun only)
-* Gould::			non-base register symbols used on Gould systems
-* N_LENG::			Length of preceding entry
-@end menu
-
-@node N_PC
-@section N_PC
-
-@deffn @code{.stabs} N_PC
-@findex N_PC
-Global symbol (for Pascal).
-
-@example
-"name" -> "symbol_name"  <<?>>
-value  -> supposedly the line number (stab.def is skeptical)
-@end example
-
-@display
-@file{stabdump.c} says:
-
-global pascal symbol: name,,0,subtype,line
-<< subtype? >>
-@end display
-@end deffn
-
-@node N_NSYMS
-@section N_NSYMS
-
-@deffn @code{.stabn} N_NSYMS
-@findex N_NSYMS
-Number of symbols (according to Ultrix V4.0).
-
-@display
-        0, files,,funcs,lines (stab.def)
-@end display
-@end deffn
-
-@node N_NOMAP
-@section N_NOMAP
-
-@deffn @code{.stabs} N_NOMAP
-@findex N_NOMAP
-No DST map for symbol (according to Ultrix V4.0).  I think this means a
-variable has been optimized out.
-
-@display
-        name, ,0,type,ignored (stab.def)
-@end display
-@end deffn
-
-@node N_M2C
-@section N_M2C
-
-@deffn @code{.stabs} N_M2C
-@findex N_M2C
-Modula-2 compilation unit.
-
-@example
-"string" -> "unit_name,unit_time_stamp[,code_time_stamp]"
-desc   -> unit_number
-value  -> 0 (main unit)
-          1 (any other unit)
-@end example
-
-See @cite{Dbx and Dbxtool Interfaces}, 2nd edition, by Sun, 1988, for
-more information.
-
-@end deffn
-
-@node N_BROWS
-@section N_BROWS
-
-@deffn @code{.stabs} N_BROWS
-@findex N_BROWS
-Sun source code browser, path to @file{.cb} file
-
-<<?>>
-"path to associated @file{.cb} file"
-
-Note: N_BROWS has the same value as N_BSLINE.
-@end deffn
-
-@node N_DEFD
-@section N_DEFD
-
-@deffn @code{.stabn} N_DEFD
-@findex N_DEFD
-GNU Modula2 definition module dependency.
-
-GNU Modula-2 definition module dependency.  The value is the
-modification time of the definition file.  The other field is non-zero
-if it is imported with the GNU M2 keyword @code{%INITIALIZE}.  Perhaps
-@code{N_M2C} can be used if there are enough empty fields?
-@end deffn
-
-@node N_EHDECL
-@section N_EHDECL
-
-@deffn @code{.stabs} N_EHDECL
-@findex N_EHDECL
-GNU C@t{++} exception variable <<?>>.
-
-"@var{string} is variable name"
-
-Note: conflicts with @code{N_MOD2}.
-@end deffn
-
-@node N_MOD2
-@section N_MOD2
-
-@deffn @code{.stab?} N_MOD2
-@findex N_MOD2
-Modula2 info "for imc" (according to Ultrix V4.0)
-
-Note: conflicts with @code{N_EHDECL}  <<?>>
-@end deffn
-
-@node N_CATCH
-@section N_CATCH
-
-@deffn @code{.stabn} N_CATCH
-@findex N_CATCH
-GNU C@t{++} @code{catch} clause
-
-GNU C@t{++} @code{catch} clause.  The value is its address.  The desc field
-is nonzero if this entry is immediately followed by a @code{CAUGHT} stab
-saying what exception was caught.  Multiple @code{CAUGHT} stabs means
-that multiple exceptions can be caught here.  If desc is 0, it means all
-exceptions are caught here.
-@end deffn
-
-@node N_SSYM
-@section N_SSYM
-
-@deffn @code{.stabn} N_SSYM
-@findex N_SSYM
-Structure or union element.
-
-The value is the offset in the structure.
-
-<<?looking at structs and unions in C I didn't see these>>
-@end deffn
-
-@node N_SCOPE
-@section N_SCOPE
-
-@deffn @code{.stab?} N_SCOPE
-@findex N_SCOPE
-Modula2 scope information (Sun linker)
-<<?>>
-@end deffn
-
-@node Gould
-@section Non-base registers on Gould systems
-
-@deffn @code{.stab?} N_NBTEXT
-@deffnx @code{.stab?} N_NBDATA
-@deffnx @code{.stab?} N_NBBSS
-@deffnx @code{.stab?} N_NBSTS
-@deffnx @code{.stab?} N_NBLCS
-@findex N_NBTEXT
-@findex N_NBDATA
-@findex N_NBBSS
-@findex N_NBSTS
-@findex N_NBLCS
-These are used on Gould systems for non-base registers syms.
-
-However, the following values are not the values used by Gould; they are
-the values which GNU has been documenting for these values for a long
-time, without actually checking what Gould uses.  I include these values
-only because perhaps some someone actually did something with the GNU
-information (I hope not, why GNU knowingly assigned wrong values to
-these in the header file is a complete mystery to me).
-
-@example
-240    0xf0     N_NBTEXT  ??
-242    0xf2     N_NBDATA  ??
-244    0xf4     N_NBBSS   ??
-246    0xf6     N_NBSTS   ??
-248    0xf8     N_NBLCS   ??
-@end example
-@end deffn
-
-@node N_LENG
-@section N_LENG
-
-@deffn @code{.stabn} N_LENG
-@findex N_LENG
-Second symbol entry containing a length-value for the preceding entry.
-The value is the length.
-@end deffn
-
-@node Questions
-@appendix Questions and Anomalies
-
-@itemize @bullet
-@item
-@c I think this is changed in GCC 2.4.5 to put the line number there.
-For GNU C stabs defining local and global variables (@code{N_LSYM} and
-@code{N_GSYM}), the desc field is supposed to contain the source
-line number on which the variable is defined.  In reality the desc
-field is always 0.  (This behavior is defined in @file{dbxout.c} and
-putting a line number in desc is controlled by @samp{#ifdef
-WINNING_GDB}, which defaults to false). GDB supposedly uses this
-information if you say @samp{list @var{var}}.  In reality, @var{var} can
-be a variable defined in the program and GDB says @samp{function
-@var{var} not defined}.
-
-@item
-In GNU C stabs, there seems to be no way to differentiate tag types:
-structures, unions, and enums (symbol descriptor @samp{T}) and typedefs
-(symbol descriptor @samp{t}) defined at file scope from types defined locally
-to a procedure or other more local scope.  They all use the @code{N_LSYM}
-stab type.  Types defined at procedure scope are emitted after the
-@code{N_RBRAC} of the preceding function and before the code of the
-procedure in which they are defined.  This is exactly the same as
-types defined in the source file between the two procedure bodies.
-GDB over-compensates by placing all types in block #1, the block for
-symbols of file scope.  This is true for default, @samp{-ansi} and
-@samp{-traditional} compiler options. (Bugs gcc/1063, gdb/1066.)
-
-@item
-What ends the procedure scope?  Is it the proc block's @code{N_RBRAC} or the
-next @code{N_FUN}?  (I believe it's the first.)
-@end itemize
-
-@node Stab Sections
-@appendix Using Stabs in Their Own Sections
-
-Many object file formats allow tools to create object files with custom
-sections containing any arbitrary data.  For any such object file
-format, stabs can be embedded in special sections.  This is how stabs
-are used with ELF and SOM, and aside from ECOFF and XCOFF, is how stabs
-are used with COFF.
-
-@menu
-* Stab Section Basics::    How to embed stabs in sections
-* ELF Linker Relocation::  Sun ELF hacks
-@end menu
-
-@node Stab Section Basics
-@appendixsec How to Embed Stabs in Sections
-
-The assembler creates two custom sections, a section named @code{.stab}
-which contains an array of fixed length structures, one struct per stab,
-and a section named @code{.stabstr} containing all the variable length
-strings that are referenced by stabs in the @code{.stab} section.  The
-byte order of the stabs binary data depends on the object file format.
-For ELF, it matches the byte order of the ELF file itself, as determined
-from the @code{EI_DATA} field in the @code{e_ident} member of the ELF
-header.  For SOM, it is always big-endian (is this true??? FIXME).  For
-COFF, it matches the byte order of the COFF headers.  The meaning of the
-fields is the same as for a.out (@pxref{Symbol Table Format}), except
-that the @code{n_strx} field is relative to the strings for the current
-compilation unit (which can be found using the synthetic N_UNDF stab
-described below), rather than the entire string table.
-
-The first stab in the @code{.stab} section for each compilation unit is
-synthetic, generated entirely by the assembler, with no corresponding
-@code{.stab} directive as input to the assembler.  This stab contains
-the following fields:
-
-@table @code
-@item n_strx
-Offset in the @code{.stabstr} section to the source filename.
-
-@item n_type
-@code{N_UNDF}.
-
-@item n_other
-Unused field, always zero.
-This may eventually be used to hold overflows from the count in
-the @code{n_desc} field.
-
-@item n_desc
-Count of upcoming symbols, i.e., the number of remaining stabs for this
-source file.
-
-@item n_value
-Size of the string table fragment associated with this source file, in
-bytes.
-@end table
-
-The @code{.stabstr} section always starts with a null byte (so that string
-offsets of zero reference a null string), followed by random length strings,
-each of which is null byte terminated.
-
-The ELF section header for the @code{.stab} section has its
-@code{sh_link} member set to the section number of the @code{.stabstr}
-section, and the @code{.stabstr} section has its ELF section
-header @code{sh_type} member set to @code{SHT_STRTAB} to mark it as a
-string table.  SOM and COFF have no way of linking the sections together
-or marking them as string tables.
-
-For COFF, the @code{.stab} and @code{.stabstr} sections may be simply
-concatenated by the linker.  GDB then uses the @code{n_desc} fields to
-figure out the extent of the original sections.  Similarly, the
-@code{n_value} fields of the header symbols are added together in order
-to get the actual position of the strings in a desired @code{.stabstr}
-section.  Although this design obviates any need for the linker to
-relocate or otherwise manipulate @code{.stab} and @code{.stabstr}
-sections, it also requires some care to ensure that the offsets are
-calculated correctly.  For instance, if the linker were to pad in
-between the @code{.stabstr} sections before concatenating, then the
-offsets to strings in the middle of the executable's @code{.stabstr}
-section would be wrong.
-
-The GNU linker is able to optimize stabs information by merging
-duplicate strings and removing duplicate header file information
-(@pxref{Include Files}).  When some versions of the GNU linker optimize
-stabs in sections, they remove the leading @code{N_UNDF} symbol and
-arranges for all the @code{n_strx} fields to be relative to the start of
-the @code{.stabstr} section.
-
-@node ELF Linker Relocation
-@appendixsec Having the Linker Relocate Stabs in ELF 
-
-This section describes some Sun hacks for Stabs in ELF; it does not
-apply to COFF or SOM.  While @value{GDBN} no longer supports this hack
-for Sun Stabs in ELF, this section is kept to document the issue.
-
-To keep linking fast, you don't want the linker to have to relocate very
-many stabs.  Making sure this is done for @code{N_SLINE},
-@code{N_RBRAC}, and @code{N_LBRAC} stabs is the most important thing
-(see the descriptions of those stabs for more information).  But Sun's
-stabs in ELF has taken this further, to make all addresses in the
-@code{n_value} field (functions and static variables) relative to the
-source file.  For the @code{N_SO} symbol itself, Sun simply omits the
-address.  To find the address of each section corresponding to a given
-source file, the compiler puts out symbols giving the address of each
-section for a given source file.  Since these are ELF (not stab)
-symbols, the linker relocates them correctly without having to touch the
-stabs section.  They are named @code{Bbss.bss} for the bss section,
-@code{Ddata.data} for the data section, and @code{Drodata.rodata} for
-the rodata section.  For the text section, there is no such symbol (but
-there should be, see below).  For an example of how these symbols work,
-@xref{Stab Section Transformations}.  GCC does not provide these symbols;
-it instead relies on the stabs getting relocated.  Thus addresses which
-would normally be relative to @code{Bbss.bss}, etc., are already
-relocated.  The Sun linker provided with Solaris 2.2 and earlier
-relocates stabs using normal ELF relocation information, as it would do
-for any section.  Sun has been threatening to kludge their linker to not
-do this (to speed up linking), even though the correct way to avoid
-having the linker do these relocations is to have the compiler no longer
-output relocatable values.  Last I heard they had been talked out of the
-linker kludge.  See Sun point patch 101052-01 and Sun bug 1142109.  With
-the Sun compiler this affects @samp{S} symbol descriptor stabs
-(@pxref{Statics}) and functions (@pxref{Procedures}).  In the latter
-case, to adopt the clean solution (making the value of the stab relative
-to the start of the compilation unit), it would be necessary to invent a
-@code{Ttext.text} symbol, analogous to the @code{Bbss.bss}, etc.,
-symbols.  I recommend this rather than using a zero value and getting
-the address from the ELF symbols.
-
-Finding the correct @code{Bbss.bss}, etc., symbol is difficult, because
-the linker simply concatenates the @code{.stab} sections from each
-@file{.o} file without including any information about which part of a
-@code{.stab} section comes from which @file{.o} file.  The way GDB use to
-do this is to look for an ELF @code{STT_FILE} symbol which has the same
-name as the last component of the file name from the @code{N_SO} symbol
-in the stabs (for example, if the file name is @file{../../gdb/main.c},
-it looks for an ELF @code{STT_FILE} symbol named @code{main.c}).  This
-loses if different files have the same name (they could be in different
-directories, a library could have been copied from one system to
-another, etc.).  It would be much cleaner to have the @code{Bbss.bss}
-symbols in the stabs themselves.  Having the linker relocate them there
-is no more work than having the linker relocate ELF symbols, and it
-solves the problem of having to associate the ELF and stab symbols.
-However, no one has yet designed or implemented such a scheme.
-
-@node GNU Free Documentation License
-@appendix GNU Free Documentation License
-@include fdl.texi
-
-@node Symbol Types Index
-@unnumbered Symbol Types Index
-
-@printindex fn
-
-@bye
diff --git a/gdb/gdbarch-gen.c b/gdb/gdbarch-gen.c
index 7887b1386c6..9623a75f4df 100644
--- a/gdb/gdbarch-gen.c
+++ b/gdb/gdbarch-gen.c
@@ -140,7 +140,6 @@ struct gdbarch
   gdbarch_unwind_sp_ftype *unwind_sp = default_unwind_sp;
   gdbarch_frame_num_args_ftype *frame_num_args = nullptr;
   gdbarch_frame_align_ftype *frame_align = nullptr;
-  gdbarch_stabs_argument_has_addr_ftype *stabs_argument_has_addr = default_stabs_argument_has_addr;
   int frame_red_zone_size = 0;
   gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity;
   gdbarch_addr_bits_remove_ftype *addr_bits_remove = core_addr_identity;
@@ -409,7 +408,6 @@ verify_gdbarch (struct gdbarch *gdbarch)
   /* Skip verify of unwind_sp, invalid_p == 0.  */
   /* Skip verify of frame_num_args, has predicate.  */
   /* Skip verify of frame_align, has predicate.  */
-  /* Skip verify of stabs_argument_has_addr, invalid_p == 0.  */
   /* Skip verify of frame_red_zone_size, invalid_p == 0.  */
   /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0.  */
   /* Skip verify of addr_bits_remove, invalid_p == 0.  */
@@ -910,9 +908,6 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file)
   gdb_printf (file,
 	      "gdbarch_dump: frame_align = <%s>\n",
 	      host_address_to_string (gdbarch->frame_align));
-  gdb_printf (file,
-	      "gdbarch_dump: stabs_argument_has_addr = <%s>\n",
-	      host_address_to_string (gdbarch->stabs_argument_has_addr));
   gdb_printf (file,
 	      "gdbarch_dump: frame_red_zone_size = %s\n",
 	      plongest (gdbarch->frame_red_zone_size));
@@ -3174,23 +3169,6 @@ set_gdbarch_frame_align (struct gdbarch *gdbarch,
   gdbarch->frame_align = frame_align;
 }
 
-int
-gdbarch_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
-{
-  gdb_assert (gdbarch != NULL);
-  gdb_assert (gdbarch->stabs_argument_has_addr != NULL);
-  if (gdbarch_debug >= 2)
-    gdb_printf (gdb_stdlog, "gdbarch_stabs_argument_has_addr called\n");
-  return gdbarch->stabs_argument_has_addr (gdbarch, type);
-}
-
-void
-set_gdbarch_stabs_argument_has_addr (struct gdbarch *gdbarch,
-				     gdbarch_stabs_argument_has_addr_ftype stabs_argument_has_addr)
-{
-  gdbarch->stabs_argument_has_addr = stabs_argument_has_addr;
-}
-
 int
 gdbarch_frame_red_zone_size (struct gdbarch *gdbarch)
 {
diff --git a/gdb/gdbarch-gen.h b/gdb/gdbarch-gen.h
index 24fa8bab2db..180e7ced7ed 100644
--- a/gdb/gdbarch-gen.h
+++ b/gdb/gdbarch-gen.h
@@ -666,10 +666,6 @@ typedef CORE_ADDR (gdbarch_frame_align_ftype) (struct gdbarch *gdbarch, CORE_ADD
 extern CORE_ADDR gdbarch_frame_align (struct gdbarch *gdbarch, CORE_ADDR address);
 extern void set_gdbarch_frame_align (struct gdbarch *gdbarch, gdbarch_frame_align_ftype *frame_align);
 
-typedef int (gdbarch_stabs_argument_has_addr_ftype) (struct gdbarch *gdbarch, struct type *type);
-extern int gdbarch_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type);
-extern void set_gdbarch_stabs_argument_has_addr (struct gdbarch *gdbarch, gdbarch_stabs_argument_has_addr_ftype *stabs_argument_has_addr);
-
 extern int gdbarch_frame_red_zone_size (struct gdbarch *gdbarch);
 extern void set_gdbarch_frame_red_zone_size (struct gdbarch *gdbarch, int frame_red_zone_size);
 
diff --git a/gdb/gdbarch_components.py b/gdb/gdbarch_components.py
index 3820ae3c94c..eac068028ed 100644
--- a/gdb/gdbarch_components.py
+++ b/gdb/gdbarch_components.py
@@ -1201,14 +1201,6 @@ Method(
     predicate=True,
 )
 
-Method(
-    type="int",
-    name="stabs_argument_has_addr",
-    params=[("struct type *", "type")],
-    predefault="default_stabs_argument_has_addr",
-    invalid=False,
-)
-
 Value(
     type="int",
     name="frame_red_zone_size",
diff --git a/gdb/microblaze-tdep.c b/gdb/microblaze-tdep.c
index 404e4cde2ad..bf04f64decd 100644
--- a/gdb/microblaze-tdep.c
+++ b/gdb/microblaze-tdep.c
@@ -584,12 +584,6 @@ microblaze_return_value (struct gdbarch *gdbarch, struct value *function,
   return RETURN_VALUE_REGISTER_CONVENTION;
 }
 
-static int
-microblaze_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
-{
-  return (type->length () == 16);
-}
-
 /* Return next pc values : next in sequence and/or branch/return target.  */
 
 static std::vector<CORE_ADDR>
@@ -794,8 +788,6 @@ microblaze_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_call_dummy_location (gdbarch, ON_STACK);
 
   set_gdbarch_return_value (gdbarch, microblaze_return_value);
-  set_gdbarch_stabs_argument_has_addr
-    (gdbarch, microblaze_stabs_argument_has_addr);
 
   set_gdbarch_skip_prologue (gdbarch, microblaze_skip_prologue);
 
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index 3c4e568b98c..35ef6035bc7 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -152,9 +152,6 @@ struct objstats
   /* Number of full symbols read.  */
   int n_syms = 0;
 
-  /* Number of ".stabs" read (if applicable).  */
-  int n_stabs = 0;
-
   /* Number of types.  */
   int n_types = 0;
 
diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c
index 914a568c98b..a161fe546ca 100644
--- a/gdb/sparc-tdep.c
+++ b/gdb/sparc-tdep.c
@@ -1540,14 +1540,6 @@ sparc32_return_value (struct gdbarch *gdbarch, struct value *function,
   return RETURN_VALUE_REGISTER_CONVENTION;
 }
 
-static int
-sparc32_stabs_argument_has_addr (struct gdbarch *gdbarch, struct type *type)
-{
-  return (sparc_structure_or_union_p (type)
-	  || (sparc_floating_p (type) && type->length () == 16)
-	  || sparc_complex_floating_p (type));
-}
-
 static int
 sparc32_dwarf2_struct_return_p (const frame_info_ptr &this_frame)
 {
@@ -1859,8 +1851,6 @@ sparc32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   set_gdbarch_push_dummy_call (gdbarch, sparc32_push_dummy_call);
 
   set_gdbarch_return_value_as_value (gdbarch, sparc32_return_value);
-  set_gdbarch_stabs_argument_has_addr
-    (gdbarch, sparc32_stabs_argument_has_addr);
 
   set_gdbarch_skip_prologue (gdbarch, sparc32_skip_prologue);
 
diff --git a/gdb/sparc64-tdep.c b/gdb/sparc64-tdep.c
index 68464212802..5797f85d6c9 100644
--- a/gdb/sparc64-tdep.c
+++ b/gdb/sparc64-tdep.c
@@ -1838,8 +1838,6 @@ sparc64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
 
   set_gdbarch_return_value (gdbarch, sparc64_return_value);
   set_gdbarch_return_value_as_value (gdbarch, default_gdbarch_return_value);
-  set_gdbarch_stabs_argument_has_addr
-    (gdbarch, default_stabs_argument_has_addr);
 
   set_gdbarch_skip_prologue (gdbarch, sparc64_skip_prologue);
   set_gdbarch_stack_frame_destroyed_p (gdbarch, sparc_stack_frame_destroyed_p);
diff --git a/gdb/stabsread.c b/gdb/stabsread.c
deleted file mode 100644
index 60cd5702396..00000000000
--- a/gdb/stabsread.c
+++ /dev/null
@@ -1,7209 +0,0 @@
-/* Support routines for decoding "stabs" debugging information format.
-
-   Copyright (C) 1986-2025 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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-/* Support routines for reading and decoding debugging information in
-   the "stabs" format.  This format is used by some systems that use
-   COFF or ELF where the stabs data is placed in a special section (as
-   well as with many old systems that used the a.out object file
-   format).  Avoid placing any object file format specific code in
-   this file.  */
-
-#include "bfd.h"
-#include "event-top.h"
-#include "gdbsupport/gdb_obstack.h"
-#include "symtab.h"
-#include "gdbtypes.h"
-#include "expression.h"
-#include "symfile.h"
-#include "objfiles.h"
-#include "aout/stab_gnu.h"
-#include "psymtab.h"
-#include "libaout.h"
-#include "aout/aout64.h"
-#include "gdb-stabs.h"
-#include "buildsym-legacy.h"
-#include "complaints.h"
-#include "demangle.h"
-#include "gdb-demangle.h"
-#include "language.h"
-#include "target-float.h"
-#include "c-lang.h"
-#include "cp-abi.h"
-#include "cp-support.h"
-#include "block.h"
-#include "filenames.h"
-
-#include "stabsread.h"
-
-/* See stabsread.h for these globals.  */
-unsigned int symnum;
-const char *(*next_symbol_text_func) (struct objfile *);
-unsigned char processing_gcc_compilation;
-int within_function;
-struct symbol *global_sym_chain[HASHSIZE];
-struct pending_stabs *global_stabs;
-int previous_stab_code;
-int *this_object_header_files;
-int n_this_object_header_files;
-int n_allocated_this_object_header_files;
-
-/* See stabsread.h.  */
-
-const registry<objfile>::key<dbx_symfile_info> dbx_objfile_data_key;
-
-dbx_symfile_info::~dbx_symfile_info ()
-{
-  if (header_files != NULL)
-    {
-      int i = n_header_files;
-      struct header_file *hfiles = header_files;
-
-      while (--i >= 0)
-	{
-	  xfree (hfiles[i].name);
-	  xfree (hfiles[i].vector);
-	}
-      xfree (hfiles);
-    }
-}
-
-struct stabs_nextfield
-{
-  struct stabs_nextfield *next;
-
-  struct field field;
-};
-
-struct next_fnfieldlist
-{
-  struct next_fnfieldlist *next;
-  struct fn_fieldlist fn_fieldlist;
-};
-
-/* The routines that read and process a complete stabs for a C struct or 
-   C++ class pass lists of data member fields and lists of member function
-   fields in an instance of a field_info structure, as defined below.
-   This is part of some reorganization of low level C++ support and is
-   expected to eventually go away...  (FIXME) */
-
-struct stab_field_info
-  {
-    struct stabs_nextfield *list = nullptr;
-    struct next_fnfieldlist *fnlist = nullptr;
-
-    auto_obstack obstack;
-  };
-
-static void
-read_one_struct_field (struct stab_field_info *, const char **, const char *,
-		       struct type *, struct objfile *);
-
-static struct type *dbx_alloc_type (int[2], struct objfile *);
-
-static long read_huge_number (const char **, int, int *, int);
-
-static struct type *error_type (const char **, struct objfile *);
-
-static void
-patch_block_stabs (struct pending *, struct pending_stabs *,
-		   struct objfile *);
-
-static int read_type_number (const char **, int *);
-
-static struct type *read_type (const char **, struct objfile *);
-
-static struct type *read_range_type (const char **, int[2],
-				     int, struct objfile *);
-
-static struct type *read_sun_builtin_type (const char **,
-					   int[2], struct objfile *);
-
-static struct type *read_sun_floating_type (const char **, int[2],
-					    struct objfile *);
-
-static struct type *read_enum_type (const char **, struct type *, struct objfile *);
-
-static struct type *rs6000_builtin_type (int, struct objfile *);
-
-static int
-read_member_functions (struct stab_field_info *, const char **, struct type *,
-		       struct objfile *);
-
-static int
-read_struct_fields (struct stab_field_info *, const char **, struct type *,
-		    struct objfile *);
-
-static int
-read_baseclasses (struct stab_field_info *, const char **, struct type *,
-		  struct objfile *);
-
-static int
-read_tilde_fields (struct stab_field_info *, const char **, struct type *,
-		   struct objfile *);
-
-static int attach_fn_fields_to_type (struct stab_field_info *, struct type *);
-
-static int attach_fields_to_type (struct stab_field_info *, struct type *,
-				  struct objfile *);
-
-static struct type *read_struct_type (const char **, struct type *,
-				      enum type_code,
-				      struct objfile *);
-
-static struct type *read_array_type (const char **, struct type *,
-				     struct objfile *);
-
-static struct field *read_args (const char **, int, struct objfile *,
-				int *, int *);
-
-static void add_undefined_type (struct type *, int[2]);
-
-static int
-read_cpp_abbrev (struct stab_field_info *, const char **, struct type *,
-		 struct objfile *);
-
-static const char *find_name_end (const char *name);
-
-static int process_reference (const char **string);
-
-void stabsread_clear_cache (void);
-
-static const char vptr_name[] = "_vptr$";
-static const char vb_name[] = "_vb$";
-
-void
-unknown_symtype_complaint (const char *arg1)
-{
-  complaint (_("unknown symbol type %s"), arg1);
-}
-
-void
-lbrac_mismatch_complaint (int arg1)
-{
-  complaint (_("N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d"), arg1);
-}
-
-void
-repeated_header_complaint (const char *arg1, int arg2)
-{
-  complaint (_("\"repeated\" header file %s not "
-	       "previously seen, at symtab pos %d"),
-	     arg1, arg2);
-}
-
-static void
-invalid_cpp_abbrev_complaint (const char *arg1)
-{
-  complaint (_("invalid C++ abbreviation `%s'"), arg1);
-}
-
-static void
-reg_value_complaint (int regnum, int num_regs, const char *sym)
-{
-  complaint (_("bad register number %d (max %d) in symbol %s"),
-	     regnum, num_regs - 1, sym);
-}
-
-static void
-stabs_general_complaint (const char *arg1)
-{
-  complaint ("%s", arg1);
-}
-
-static void
-function_outside_compilation_unit_complaint (const char *arg1)
-{
-  complaint (_("function `%s' appears to be defined "
-	       "outside of all compilation units"),
-	     arg1);
-}
-
-/* Make a list of forward references which haven't been defined.  */
-
-static struct type **undef_types;
-static int undef_types_allocated;
-static int undef_types_length;
-static struct symbol *current_symbol = NULL;
-
-/* Make a list of nameless types that are undefined.
-   This happens when another type is referenced by its number
-   before this type is actually defined.  For instance "t(0,1)=k(0,2)"
-   and type (0,2) is defined only later.  */
-
-struct nat
-{
-  int typenums[2];
-  struct type *type;
-};
-static struct nat *noname_undefs;
-static int noname_undefs_allocated;
-static int noname_undefs_length;
-
-/* Check for and handle cretinous stabs symbol name continuation!  */
-#define STABS_CONTINUE(pp,objfile)				\
-  do {							\
-    if (**(pp) == '\\' || (**(pp) == '?' && (*(pp))[1] == '\0')) \
-      *(pp) = next_symbol_text (objfile);	\
-  } while (0)
-
-/* Vector of types defined so far, indexed by their type numbers.
-   (In newer sun systems, dbx uses a pair of numbers in parens,
-   as in "(SUBFILENUM,NUMWITHINSUBFILE)".
-   Then these numbers must be translated through the type_translations
-   hash table to get the index into the type vector.)  */
-
-static struct type **type_vector;
-
-/* Number of elements allocated for type_vector currently.  */
-
-static int type_vector_length;
-
-/* Initial size of type vector.  Is realloc'd larger if needed, and
-   realloc'd down to the size actually used, when completed.  */
-
-#define INITIAL_TYPE_VECTOR_LENGTH 160
-\f
-
-/* Look up a dbx type-number pair.  Return the address of the slot
-   where the type for that number-pair is stored.
-   The number-pair is in TYPENUMS.
-
-   This can be used for finding the type associated with that pair
-   or for associating a new type with the pair.  */
-
-static struct type **
-dbx_lookup_type (int typenums[2], struct objfile *objfile)
-{
-  int filenum = typenums[0];
-  int index = typenums[1];
-  unsigned old_len;
-  int real_filenum;
-  struct header_file *f;
-  int f_orig_length;
-
-  if (filenum == -1)		/* -1,-1 is for temporary types.  */
-    return 0;
-
-  if (filenum < 0 || filenum >= n_this_object_header_files)
-    {
-      complaint (_("Invalid symbol data: type number "
-		   "(%d,%d) out of range at symtab pos %d."),
-		 filenum, index, symnum);
-      goto error_return;
-    }
-
-  if (filenum == 0)
-    {
-      if (index < 0)
-	{
-	  /* Caller wants address of address of type.  We think
-	     that negative (rs6k builtin) types will never appear as
-	     "lvalues", (nor should they), so we stuff the real type
-	     pointer into a temp, and return its address.  If referenced,
-	     this will do the right thing.  */
-	  static struct type *temp_type;
-
-	  temp_type = rs6000_builtin_type (index, objfile);
-	  return &temp_type;
-	}
-
-      /* Type is defined outside of header files.
-	 Find it in this object file's type vector.  */
-      if (index >= type_vector_length)
-	{
-	  old_len = type_vector_length;
-	  if (old_len == 0)
-	    {
-	      type_vector_length = INITIAL_TYPE_VECTOR_LENGTH;
-	      type_vector = XNEWVEC (struct type *, type_vector_length);
-	    }
-	  while (index >= type_vector_length)
-	    {
-	      type_vector_length *= 2;
-	    }
-	  type_vector = (struct type **)
-	    xrealloc ((char *) type_vector,
-		      (type_vector_length * sizeof (struct type *)));
-	  memset (&type_vector[old_len], 0,
-		  (type_vector_length - old_len) * sizeof (struct type *));
-	}
-      return (&type_vector[index]);
-    }
-  else
-    {
-      real_filenum = this_object_header_files[filenum];
-
-      if (real_filenum >= N_HEADER_FILES (objfile))
-	{
-	  static struct type *temp_type;
-
-	  warning (_("GDB internal error: bad real_filenum"));
-
-	error_return:
-	  temp_type = builtin_type (objfile)->builtin_error;
-	  return &temp_type;
-	}
-
-      f = HEADER_FILES (objfile) + real_filenum;
-
-      f_orig_length = f->length;
-      if (index >= f_orig_length)
-	{
-	  while (index >= f->length)
-	    {
-	      f->length *= 2;
-	    }
-	  f->vector = (struct type **)
-	    xrealloc ((char *) f->vector, f->length * sizeof (struct type *));
-	  memset (&f->vector[f_orig_length], 0,
-		  (f->length - f_orig_length) * sizeof (struct type *));
-	}
-      return (&f->vector[index]);
-    }
-}
-
-/* Make sure there is a type allocated for type numbers TYPENUMS
-   and return the type object.
-   This can create an empty (zeroed) type object.
-   TYPENUMS may be (-1, -1) to return a new type object that is not
-   put into the type vector, and so may not be referred to by number.  */
-
-static struct type *
-dbx_alloc_type (int typenums[2], struct objfile *objfile)
-{
-  struct type **type_addr;
-
-  if (typenums[0] == -1)
-    {
-      return type_allocator (objfile,
-			     get_current_subfile ()->language).new_type ();
-    }
-
-  type_addr = dbx_lookup_type (typenums, objfile);
-
-  /* If we are referring to a type not known at all yet,
-     allocate an empty type for it.
-     We will fill it in later if we find out how.  */
-  if (*type_addr == 0)
-    {
-      *type_addr = type_allocator (objfile,
-				   get_current_subfile ()->language).new_type ();
-    }
-
-  return (*type_addr);
-}
-
-/* Allocate a floating-point type of size BITS.  */
-
-static struct type *
-dbx_init_float_type (struct objfile *objfile, int bits)
-{
-  struct gdbarch *gdbarch = objfile->arch ();
-  const struct floatformat **format;
-  struct type *type;
-
-  format = gdbarch_floatformat_for_type (gdbarch, NULL, bits);
-  type_allocator alloc (objfile, get_current_subfile ()->language);
-  if (format)
-    type = init_float_type (alloc, bits, NULL, format);
-  else
-    type = alloc.new_type (TYPE_CODE_ERROR, bits, NULL);
-
-  return type;
-}
-
-/* for all the stabs in a given stab vector, build appropriate types 
-   and fix their symbols in given symbol vector.  */
-
-static void
-patch_block_stabs (struct pending *symbols, struct pending_stabs *stabs,
-		   struct objfile *objfile)
-{
-  int ii;
-  char *name;
-  const char *pp;
-  struct symbol *sym;
-
-  if (stabs)
-    {
-      /* for all the stab entries, find their corresponding symbols and 
-	 patch their types!  */
-
-      for (ii = 0; ii < stabs->count; ++ii)
-	{
-	  name = stabs->stab[ii];
-	  pp = (char *) strchr (name, ':');
-	  gdb_assert (pp);	/* Must find a ':' or game's over.  */
-	  while (pp[1] == ':')
-	    {
-	      pp += 2;
-	      pp = (char *) strchr (pp, ':');
-	    }
-	  sym = find_symbol_in_list (symbols, name, pp - name);
-	  if (!sym)
-	    {
-	      /* FIXME-maybe: it would be nice if we noticed whether
-		 the variable was defined *anywhere*, not just whether
-		 it is defined in this compilation unit.  But neither
-		 xlc or GCC seem to need such a definition, and until
-		 we do psymtabs (so that the minimal symbols from all
-		 compilation units are available now), I'm not sure
-		 how to get the information.  */
-
-	      /* On xcoff, if a global is defined and never referenced,
-		 ld will remove it from the executable.  There is then
-		 a N_GSYM stab for it, but no regular (C_EXT) symbol.  */
-	      sym = new (&objfile->objfile_obstack) symbol;
-	      sym->set_domain (VAR_DOMAIN);
-	      sym->set_loc_class_index (LOC_OPTIMIZED_OUT);
-	      sym->set_linkage_name
-		(obstack_strndup (&objfile->objfile_obstack, name, pp - name));
-	      pp += 2;
-	      if (*(pp - 1) == 'F' || *(pp - 1) == 'f')
-		{
-		  /* I don't think the linker does this with functions,
-		     so as far as I know this is never executed.
-		     But it doesn't hurt to check.  */
-		  sym->set_type
-		    (lookup_function_type (read_type (&pp, objfile)));
-		}
-	      else
-		{
-		  sym->set_type (read_type (&pp, objfile));
-		}
-	      add_symbol_to_list (sym, get_global_symbols ());
-	    }
-	  else
-	    {
-	      pp += 2;
-	      if (*(pp - 1) == 'F' || *(pp - 1) == 'f')
-		{
-		  sym->set_type
-		    (lookup_function_type (read_type (&pp, objfile)));
-		}
-	      else
-		{
-		  sym->set_type (read_type (&pp, objfile));
-		}
-	    }
-	}
-    }
-}
-\f
-
-/* Read a number by which a type is referred to in dbx data,
-   or perhaps read a pair (FILENUM, TYPENUM) in parentheses.
-   Just a single number N is equivalent to (0,N).
-   Return the two numbers by storing them in the vector TYPENUMS.
-   TYPENUMS will then be used as an argument to dbx_lookup_type.
-
-   Returns 0 for success, -1 for error.  */
-
-static int
-read_type_number (const char **pp, int *typenums)
-{
-  int nbits;
-
-  if (**pp == '(')
-    {
-      (*pp)++;
-      typenums[0] = read_huge_number (pp, ',', &nbits, 0);
-      if (nbits != 0)
-	return -1;
-      typenums[1] = read_huge_number (pp, ')', &nbits, 0);
-      if (nbits != 0)
-	return -1;
-    }
-  else
-    {
-      typenums[0] = 0;
-      typenums[1] = read_huge_number (pp, 0, &nbits, 0);
-      if (nbits != 0)
-	return -1;
-    }
-  return 0;
-}
-\f
-
-/* Free up old header file tables.  */
-
-void
-free_header_files (void)
-{
-  if (this_object_header_files)
-    {
-      xfree (this_object_header_files);
-      this_object_header_files = NULL;
-    }
-  n_allocated_this_object_header_files = 0;
-}
-
-/* Allocate new header file tables.  */
-
-void
-init_header_files (void)
-{
-  n_allocated_this_object_header_files = 10;
-  this_object_header_files = XNEWVEC (int, 10);
-}
-
-/* Close off the current usage of PST.
-   Returns PST or NULL if the partial symtab was empty and thrown away.
-
-   FIXME:  List variables and peculiarities of same.  */
-
-legacy_psymtab *
-stabs_end_psymtab (struct objfile *objfile, psymtab_storage *partial_symtabs,
-		   legacy_psymtab *pst,
-		   const char **include_list, int num_includes,
-		   int capping_symbol_offset, unrelocated_addr capping_text,
-		   legacy_psymtab **dependency_list,
-		   int number_dependencies,
-		   int textlow_not_set)
-{
-  int i;
-  struct gdbarch *gdbarch = objfile->arch ();
-  dbx_symfile_info *key = dbx_objfile_data_key. get (objfile);
-
-  if (capping_symbol_offset != -1)
-    LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
-  pst->set_text_high (capping_text);
-
-  /* Under Solaris, the N_SO symbols always have a value of 0,
-     instead of the usual address of the .o file.  Therefore,
-     we have to do some tricks to fill in texthigh and textlow.
-     The first trick is: if we see a static
-     or global function, and the textlow for the current pst
-     is not set (ie: textlow_not_set), then we use that function's
-     address for the textlow of the pst.  */
-
-  /* Now, to fill in texthigh, we remember the last function seen
-     in the .o file.  Also, there's a hack in
-     bfd/elf.c and gdb/elfread.c to pass the ELF st_size field
-     to here via the misc_info field.  Therefore, we can fill in
-     a reliable texthigh by taking the address plus size of the
-     last function in the file.  */
-
-  if (!pst->text_high_valid && key->ctx.last_function_name
-      && gdbarch_sofun_address_maybe_missing (gdbarch))
-    {
-      int n;
-
-      const char *colon = strchr (key->ctx.last_function_name, ':');
-      if (colon == NULL)
-	n = 0;
-      else
-	n = colon - key->ctx.last_function_name;
-      char *p = (char *) alloca (n + 2);
-      strncpy (p, key->ctx.last_function_name, n);
-      p[n] = 0;
-
-      bound_minimal_symbol minsym
-	= lookup_minimal_symbol (current_program_space, p, objfile,
-				 pst->filename);
-      if (minsym.minsym == NULL)
-	{
-	  /* Sun Fortran appends an underscore to the minimal symbol name,
-	     try again with an appended underscore if the minimal symbol
-	     was not found.  */
-	  p[n] = '_';
-	  p[n + 1] = 0;
-	  minsym = lookup_minimal_symbol (current_program_space, p, objfile,
-					  pst->filename);
-	}
-
-      if (minsym.minsym)
-	pst->set_text_high
-	  (unrelocated_addr (CORE_ADDR (minsym.minsym->unrelocated_address ())
-			     + minsym.minsym->size ()));
-
-      key->ctx.last_function_name = NULL;
-    }
-
-  if (!gdbarch_sofun_address_maybe_missing (gdbarch))
-    ;
-  /* This test will be true if the last .o file is only data.  */
-  else if (textlow_not_set)
-    pst->set_text_low (pst->unrelocated_text_high ());
-  else
-    {
-      /* If we know our own starting text address, then walk through all other
-	 psymtabs for this objfile, and if any didn't know their ending text
-	 address, set it to our starting address.  Take care to not set our
-	 own ending address to our starting address.  */
-
-      for (partial_symtab *p1 : partial_symtabs->range ())
-	if (!p1->text_high_valid && p1->text_low_valid && p1 != pst)
-	  p1->set_text_high (pst->unrelocated_text_low ());
-    }
-
-  /* End of kludge for patching Solaris textlow and texthigh.  */
-
-  pst->end ();
-
-  pst->number_of_dependencies = number_dependencies;
-  if (number_dependencies)
-    {
-      pst->dependencies
-	= partial_symtabs->allocate_dependencies (number_dependencies);
-      memcpy (pst->dependencies, dependency_list,
-	      number_dependencies * sizeof (legacy_psymtab *));
-    }
-  else
-    pst->dependencies = 0;
-
-  for (i = 0; i < num_includes; i++)
-    {
-      legacy_psymtab *subpst =
-	new legacy_psymtab (include_list[i], partial_symtabs, objfile->per_bfd);
-
-      subpst->read_symtab_private =
-	XOBNEW (&objfile->objfile_obstack, struct symloc);
-      LDSYMOFF (subpst) =
-	LDSYMLEN (subpst) = 0;
-
-      /* We could save slight bits of space by only making one of these,
-	 shared by the entire set of include files.  FIXME-someday.  */
-      subpst->dependencies =
-	partial_symtabs->allocate_dependencies (1);
-      subpst->dependencies[0] = pst;
-      subpst->number_of_dependencies = 1;
-
-      subpst->legacy_read_symtab = pst->legacy_read_symtab;
-      subpst->legacy_expand_psymtab = pst->legacy_expand_psymtab;
-    }
-
-  if (num_includes == 0
-      && number_dependencies == 0
-      && pst->empty ()
-      && key->ctx.has_line_numbers == 0)
-    {
-      /* Throw away this psymtab, it's empty.  */
-      /* Empty psymtabs happen as a result of header files which don't have
-	 any symbols in them.  There can be a lot of them.  But this check
-	 is wrong, in that a psymtab with N_SLINE entries but nothing else
-	 is not empty, but we don't realize that.  Fixing that without slowing
-	 things down might be tricky.  */
-
-      partial_symtabs->discard_psymtab (pst);
-
-      /* Indicate that psymtab was thrown away.  */
-      pst = NULL;
-    }
-  return pst;
-}
-
-/* Set namestring based on nlist.  If the string table index is invalid, 
-   give a fake name, and print a single error message per symbol file read,
-   rather than abort the symbol reading or flood the user with messages.  */
-
-static const char *
-set_namestring (struct objfile *objfile, const struct internal_nlist *nlist)
-{
-  const char *namestring;
-  struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
-  if (nlist->n_strx + key->ctx.file_string_table_offset
-      >= DBX_STRINGTAB_SIZE (objfile)
-      || nlist->n_strx + key->ctx.file_string_table_offset < nlist->n_strx)
-    {
-      complaint (_("bad string table offset in symbol %d"),
-		 symnum);
-      namestring = "<bad string table offset>";
-    } 
-  else
-    namestring = (nlist->n_strx + key->ctx.file_string_table_offset
-		  + DBX_STRINGTAB (objfile));
-  return namestring;
-}
-
-static void
-stabs_seek (int sym_offset, struct objfile *objfile)
-{
-  dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-  if (key->ctx.stabs_data)
-    {
-      key->ctx.symbuf_read += sym_offset;
-      key->ctx.symbuf_left -= sym_offset;
-    }
-  else
-    if (bfd_seek (objfile->obfd.get (), sym_offset, SEEK_CUR) != 0)
-      perror_with_name (bfd_get_filename (objfile->obfd.get ()));
-}
-
-/* Buffer for reading the symbol table entries.  */
-static struct external_nlist symbuf[4096];
-static int symbuf_idx;
-static int symbuf_end;
-
-/* Refill the symbol table input buffer
-   and set the variables that control fetching entries from it.
-   Reports an error if no data available.
-   This function can read past the end of the symbol table
-   (into the string table) but this does no harm.  */
-
-static void
-fill_symbuf (bfd *sym_bfd, struct objfile *objfile)
-{
-  unsigned int count;
-  int nbytes;
-  struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
-  if (key->ctx.stabs_data)
-    {
-      nbytes = sizeof (symbuf);
-      if (nbytes > key->ctx.symbuf_left)
-	nbytes = key->ctx.symbuf_left;
-      memcpy (symbuf, key->ctx.stabs_data + key->ctx.symbuf_read, nbytes);
-    }
-  else if (key->ctx.symbuf_sections == NULL)
-    {
-      count = sizeof (symbuf);
-      nbytes = bfd_read (symbuf, count, sym_bfd);
-    }
-  else
-    {
-      if (key->ctx.symbuf_left <= 0)
-	{
-	  file_ptr filepos = (*key->ctx.symbuf_sections)[key->ctx.sect_idx]->filepos;
-
-	  if (bfd_seek (sym_bfd, filepos, SEEK_SET) != 0)
-	    perror_with_name (bfd_get_filename (sym_bfd));
-	  key->ctx.symbuf_left = bfd_section_size ((*key->ctx.symbuf_sections)[key->ctx.sect_idx]);
-	  key->ctx.symbol_table_offset = filepos - key->ctx.symbuf_read;
-	  ++key->ctx.sect_idx;
-	}
-
-      count = key->ctx.symbuf_left;
-      if (count > sizeof (symbuf))
-	count = sizeof (symbuf);
-      nbytes = bfd_read (symbuf, count, sym_bfd);
-    }
-
-  if (nbytes < 0)
-    perror_with_name (bfd_get_filename (sym_bfd));
-  else if (nbytes == 0)
-    error (_("Premature end of file reading symbol table"));
-  symbuf_end = nbytes / key->ctx.symbol_size;
-  symbuf_idx = 0;
-  key->ctx.symbuf_left -= nbytes;
-  key->ctx.symbuf_read += nbytes;
-}
-
-/* Read in a defined section of a specific object file's symbols.  */
-
-static void
-read_ofile_symtab (struct objfile *objfile, legacy_psymtab *pst)
-{
-  const char *namestring;
-  struct external_nlist *bufp;
-  struct internal_nlist nlist;
-  unsigned char type;
-  unsigned max_symnum;
-  bfd *abfd;
-  int sym_offset;		/* Offset to start of symbols to read */
-  int sym_size;			/* Size of symbols to read */
-  CORE_ADDR text_offset;	/* Start of text segment for symbols */
-  int text_size;		/* Size of text segment for symbols */
-  struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
-  sym_offset = LDSYMOFF (pst);
-  sym_size = LDSYMLEN (pst);
-  text_offset = pst->text_low (objfile);
-  text_size = pst->text_high (objfile) - pst->text_low (objfile);
-  const section_offsets &section_offsets = objfile->section_offsets;
-
-  key->ctx.stringtab_global = DBX_STRINGTAB (objfile);
-  set_last_source_file (NULL);
-
-  abfd = objfile->obfd.get ();
-  symbuf_end = symbuf_idx = 0;
-  key->ctx.symbuf_read = 0;
-  key->ctx.symbuf_left = sym_offset + sym_size;
-
-  /* It is necessary to actually read one symbol *before* the start
-     of this symtab's symbols, because the GCC_COMPILED_FLAG_SYMBOL
-     occurs before the N_SO symbol.
-
-     Detecting this in read_stabs_symtab
-     would slow down initial readin, so we look for it here instead.  */
-  if (!key->ctx.processing_acc_compilation && sym_offset >= (int) key->ctx.symbol_size)
-    {
-      stabs_seek (sym_offset - key->ctx.symbol_size, objfile);
-      fill_symbuf (abfd, objfile);
-      bufp = &symbuf[symbuf_idx++];
-      INTERNALIZE_SYMBOL (nlist, bufp, abfd);
-      OBJSTAT (objfile, n_stabs++);
-
-      namestring = set_namestring (objfile, &nlist);
-
-      processing_gcc_compilation = 0;
-      if (nlist.n_type == N_TEXT)
-	{
-	  const char *tempstring = namestring;
-
-	  if (strcmp (namestring, GCC_COMPILED_FLAG_SYMBOL) == 0)
-	    processing_gcc_compilation = 1;
-	  else if (strcmp (namestring, GCC2_COMPILED_FLAG_SYMBOL) == 0)
-	    processing_gcc_compilation = 2;
-	  if (*tempstring != '\0'
-	      && *tempstring == bfd_get_symbol_leading_char (objfile->obfd.get ()))
-	    ++tempstring;
-	  if (startswith (tempstring, "__gnu_compiled"))
-	    processing_gcc_compilation = 2;
-	}
-    }
-  else
-    {
-      /* The N_SO starting this symtab is the first symbol, so we
-	 better not check the symbol before it.  I'm not this can
-	 happen, but it doesn't hurt to check for it.  */
-      stabs_seek (sym_offset, objfile);
-      processing_gcc_compilation = 0;
-    }
-
-  if (symbuf_idx == symbuf_end)
-    fill_symbuf (abfd, objfile);
-  bufp = &symbuf[symbuf_idx];
-  if (bfd_h_get_8 (abfd, bufp->e_type) != N_SO)
-    error (_("First symbol in segment of executable not a source symbol"));
-
-  max_symnum = sym_size / key->ctx.symbol_size;
-
-  for (symnum = 0;
-       symnum < max_symnum;
-       symnum++)
-    {
-      QUIT;			/* Allow this to be interruptible.  */
-      if (symbuf_idx == symbuf_end)
-	fill_symbuf (abfd, objfile);
-      bufp = &symbuf[symbuf_idx++];
-      INTERNALIZE_SYMBOL (nlist, bufp, abfd);
-      OBJSTAT (objfile, n_stabs++);
-
-      type = bfd_h_get_8 (abfd, bufp->e_type);
-
-      namestring = set_namestring (objfile, &nlist);
-
-      if (type & N_STAB)
-	{
-	  if (sizeof (nlist.n_value) > 4
-	      /* We are a 64-bit debugger debugging a 32-bit program.  */
-	      && (type == N_LSYM || type == N_PSYM))
-	      /* We have to be careful with the n_value in the case of N_LSYM
-		 and N_PSYM entries, because they are signed offsets from frame
-		 pointer, but we actually read them as unsigned 32-bit values.
-		 This is not a problem for 32-bit debuggers, for which negative
-		 values end up being interpreted correctly (as negative
-		 offsets) due to integer overflow.
-		 But we need to sign-extend the value for 64-bit debuggers,
-		 or we'll end up interpreting negative values as very large
-		 positive offsets.  */
-	    nlist.n_value = (nlist.n_value ^ 0x80000000) - 0x80000000;
-	  process_one_symbol (type, nlist.n_desc, nlist.n_value,
-			      namestring, section_offsets, objfile,
-			      PST_LANGUAGE (pst));
-	}
-      /* We skip checking for a new .o or -l file; that should never
-	 happen in this routine.  */
-      else if (type == N_TEXT)
-	{
-	  /* I don't think this code will ever be executed, because
-	     the GCC_COMPILED_FLAG_SYMBOL usually is right before
-	     the N_SO symbol which starts this source file.
-	     However, there is no reason not to accept
-	     the GCC_COMPILED_FLAG_SYMBOL anywhere.  */
-
-	  if (strcmp (namestring, GCC_COMPILED_FLAG_SYMBOL) == 0)
-	    processing_gcc_compilation = 1;
-	  else if (strcmp (namestring, GCC2_COMPILED_FLAG_SYMBOL) == 0)
-	    processing_gcc_compilation = 2;
-	}
-      else if (type & N_EXT || type == (unsigned char) N_TEXT
-	       || type == (unsigned char) N_NBTEXT)
-	{
-	  /* Global symbol: see if we came across a dbx definition for
-	     a corresponding symbol.  If so, store the value.  Remove
-	     syms from the chain when their values are stored, but
-	     search the whole chain, as there may be several syms from
-	     different files with the same name.  */
-	  /* This is probably not true.  Since the files will be read
-	     in one at a time, each reference to a global symbol will
-	     be satisfied in each file as it appears.  So we skip this
-	     section.  */
-	  ;
-	}
-    }
-
-  /* In a Solaris elf file, this variable, which comes from the value
-     of the N_SO symbol, will still be 0.  Luckily, text_offset, which
-     comes from low text address of PST, is correct.  */
-  if (get_last_source_start_addr () == 0)
-    set_last_source_start_addr (text_offset);
-
-  /* In reordered executables last_source_start_addr may not be the
-     lower bound for this symtab, instead use text_offset which comes
-     from the low text address of PST, which is correct.  */
-  if (get_last_source_start_addr () > text_offset)
-    set_last_source_start_addr (text_offset);
-
-  pst->compunit_symtab = end_compunit_symtab (text_offset + text_size);
-
-  end_stabs ();
-
-}
-
-static void
-dbx_expand_psymtab (legacy_psymtab *pst, struct objfile *objfile)
-{
-  gdb_assert (!pst->readin);
-  struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
-  /* Read in all partial symtabs on which this one is dependent.  */
-  pst->expand_dependencies (objfile);
-
-  if (LDSYMLEN (pst))		/* Otherwise it's a dummy.  */
-    {
-      /* Init stuff necessary for reading in symbols */
-      stabsread_init ();
-      scoped_free_pendings free_pending;
-      key->ctx.file_string_table_offset = FILE_STRING_OFFSET (pst);
-      key->ctx.symbol_size = SYMBOL_SIZE (pst);
-
-      /* Read in this file's symbols.  */
-      if (bfd_seek (objfile->obfd.get (), SYMBOL_OFFSET (pst), SEEK_SET) == 0)
-	read_ofile_symtab (objfile, pst);
-    }
-
-  pst->readin = true;
-}
-
-/* Invariant: The symbol pointed to by symbuf_idx is the first one
-   that hasn't been swapped.  Swap the symbol at the same time
-   that symbuf_idx is incremented.  */
-
-/* dbx allows the text of a symbol name to be continued into the
-   next symbol name!  When such a continuation is encountered
-   (a \ at the end of the text of a name)
-   call this function to get the continuation.  */
-
-static const char *
-dbx_next_symbol_text (struct objfile *objfile)
-{
-  struct internal_nlist nlist;
-  dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
-  if (symbuf_idx == symbuf_end)
-    fill_symbuf (objfile->obfd.get (), objfile);
-
-  symnum++;
-  INTERNALIZE_SYMBOL (nlist, &symbuf[symbuf_idx], objfile->obfd.get ());
-  OBJSTAT (objfile, n_stabs++);
-
-  symbuf_idx++;
-
-  return nlist.n_strx + key->ctx.stringtab_global
-    + key->ctx.file_string_table_offset;
-}
-
-/* Read in all of the symbols for a given psymtab for real.
-   Be verbose about it if the user wants that.  SELF is not NULL.  */
-
-static void
-stabs_read_symtab (legacy_psymtab *self, struct objfile *objfile)
-{
-  gdb_assert (!self->readin);
-
-  if (LDSYMLEN (self) || self->number_of_dependencies)
-    {
-      next_symbol_text_func = dbx_next_symbol_text;
-      dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
-      {
-	scoped_restore restore_stabs_data = make_scoped_restore (&key->ctx.stabs_data);
-	gdb::unique_xmalloc_ptr<gdb_byte> data_holder;
-	if (DBX_STAB_SECTION (objfile))
-	  {
-	    key->ctx.stabs_data
-	      = symfile_relocate_debug_section (objfile,
-						DBX_STAB_SECTION (objfile),
-						NULL);
-	    data_holder.reset (key->ctx.stabs_data);
-	  }
-
-	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);
-    }
-}
-
-static void
-record_minimal_symbol (minimal_symbol_reader &reader,
-		       const char *name, unrelocated_addr address, int type,
-		       struct objfile *objfile)
-{
-  enum minimal_symbol_type ms_type;
-  int section;
-  struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
-  switch (type)
-    {
-    case N_TEXT | N_EXT:
-      ms_type = mst_text;
-      section = SECT_OFF_TEXT (objfile);
-      break;
-    case N_DATA | N_EXT:
-      ms_type = mst_data;
-      section = SECT_OFF_DATA (objfile);
-      break;
-    case N_BSS | N_EXT:
-      ms_type = mst_bss;
-      section = SECT_OFF_BSS (objfile);
-      break;
-    case N_ABS | N_EXT:
-      ms_type = mst_abs;
-      section = -1;
-      break;
-#ifdef N_SETV
-    case N_SETV | N_EXT:
-      ms_type = mst_data;
-      section = SECT_OFF_DATA (objfile);
-      break;
-    case N_SETV:
-      /* I don't think this type actually exists; since a N_SETV is the result
-	 of going over many .o files, it doesn't make sense to have one
-	 file local.  */
-      ms_type = mst_file_data;
-      section = SECT_OFF_DATA (objfile);
-      break;
-#endif
-    case N_TEXT:
-    case N_NBTEXT:
-    case N_FN:
-    case N_FN_SEQ:
-      ms_type = mst_file_text;
-      section = SECT_OFF_TEXT (objfile);
-      break;
-    case N_DATA:
-      ms_type = mst_file_data;
-
-      /* Check for __DYNAMIC, which is used by Sun shared libraries. 
-	 Record it as global even if it's local, not global, so
-	 lookup_minimal_symbol can find it.  We don't check symbol_leading_char
-	 because for SunOS4 it always is '_'.  */
-      if (strcmp ("__DYNAMIC", name) == 0)
-	ms_type = mst_data;
-
-      /* Same with virtual function tables, both global and static.  */
-      {
-	const char *tempstring = name;
-
-	if (*tempstring != '\0'
-	    && *tempstring == bfd_get_symbol_leading_char (objfile->obfd.get ()))
-	  ++tempstring;
-	if (is_vtable_name (tempstring))
-	  ms_type = mst_data;
-      }
-      section = SECT_OFF_DATA (objfile);
-      break;
-    case N_BSS:
-      ms_type = mst_file_bss;
-      section = SECT_OFF_BSS (objfile);
-      break;
-    default:
-      ms_type = mst_unknown;
-      section = -1;
-      break;
-    }
-
-  if ((ms_type == mst_file_text || ms_type == mst_text)
-      && address < key->ctx.lowest_text_address)
-    key->ctx.lowest_text_address = address;
-
-  reader.record_with_info (name, address, ms_type, section);
-}
-
-/* Given a name, value pair, find the corresponding
-   bincl in the list.  Return the partial symtab associated
-   with that header_file_location.  */
-
-static legacy_psymtab *
-find_corresponding_bincl_psymtab (const char *name, int instance,
-				  struct objfile* objfile)
-{
-  stabsread_context ctx = dbx_objfile_data_key.get (objfile) -> ctx;
-  for (const header_file_location &bincl : ctx.bincl_list)
-    if (bincl.instance == instance
-	&& strcmp (name, bincl.name) == 0)
-      return bincl.pst;
-
-  repeated_header_complaint (name, symnum);
-  return (legacy_psymtab *) 0;
-}
-
-/* Allocate and partially fill a partial symtab.  It will be
-   completely filled at the end of the symbol list.
-
-   SYMFILE_NAME is the name of the symbol-file we are reading from, and ADDR
-   is the address relative to which its symbols are (incremental) or 0
-   (normal).  */
-
-static legacy_psymtab *
-start_psymtab (psymtab_storage *partial_symtabs, struct objfile *objfile,
-	       const char *filename, unrelocated_addr textlow, int ldsymoff)
-{
-  legacy_psymtab *result = new legacy_psymtab (filename, partial_symtabs,
-					       objfile->per_bfd, textlow);
-
-  struct dbx_symfile_info *key = dbx_objfile_data_key.get(objfile);
-
-  result->read_symtab_private =
-    XOBNEW (&objfile->objfile_obstack, struct symloc);
-  LDSYMOFF (result) = ldsymoff;
-  result->legacy_read_symtab = stabs_read_symtab;
-  result->legacy_expand_psymtab = dbx_expand_psymtab;
-  SYMBOL_SIZE (result) = key->ctx.symbol_size;
-  SYMBOL_OFFSET (result) = key->ctx.symbol_table_offset;
-  STRING_OFFSET (result) = 0; /* This used to be an uninitialized global.  */
-  FILE_STRING_OFFSET (result) = key->ctx.file_string_table_offset;
-
-  /* Deduce the source language from the filename for this psymtab.  */
-  key->ctx.psymtab_language = deduce_language_from_filename (filename);
-  PST_LANGUAGE (result) = key->ctx.psymtab_language;
-
-  return result;
-}
-
-/* See stabsread.h. */
-
-static void
-read_stabs_symtab_1 (minimal_symbol_reader &reader,
-		     psymtab_storage *partial_symtabs,
-		     struct objfile *objfile)
-{
-  struct gdbarch *gdbarch = objfile->arch ();
-  struct external_nlist *bufp = 0;	/* =0 avoids gcc -Wall glitch.  */
-  struct internal_nlist nlist;
-  CORE_ADDR text_addr;
-  int text_size;
-  const char *sym_name;
-  int sym_len;
-  unsigned int next_file_string_table_offset = 0;
-  struct dbx_symfile_info *dbx = dbx_objfile_data_key.get(objfile);
-
-  const char *namestring;
-  int nsl;
-  int past_first_source_file = 0;
-  CORE_ADDR last_function_start = 0;
-  bfd *abfd;
-  int textlow_not_set;
-  int data_sect_index;
-
-  /* Current partial symtab.  */
-  legacy_psymtab *pst;
-
-  /* List of current psymtab's include files.  */
-  const char **psymtab_include_list;
-  int includes_allocated;
-  int includes_used;
-
-  /* Index within current psymtab dependency list.  */
-  legacy_psymtab **dependency_list;
-  int dependencies_used, dependencies_allocated;
-
-  text_addr = DBX_TEXT_ADDR (objfile);
-  text_size = DBX_TEXT_SIZE (objfile);
-
-  /* FIXME.  We probably want to change stringtab_global rather than add this
-     while processing every symbol entry.  FIXME.  */
-  dbx->ctx.file_string_table_offset = 0;
-
-  dbx->ctx.stringtab_global = DBX_STRINGTAB (objfile);
-
-  pst = (legacy_psymtab *) 0;
-
-  includes_allocated = 30;
-  includes_used = 0;
-  psymtab_include_list = (const char **) alloca (includes_allocated *
-						 sizeof (const char *));
-
-  dependencies_allocated = 30;
-  dependencies_used = 0;
-  dependency_list =
-    (legacy_psymtab **) alloca (dependencies_allocated *
-				sizeof (legacy_psymtab *));
-
-  /* Init bincl list */
-  std::vector<struct header_file_location> bincl_storage;
-  scoped_restore restore_bincl_global
-    = make_scoped_restore (&(dbx->ctx.bincl_list), bincl_storage);
-
-  set_last_source_file (NULL);
-
-  dbx->ctx.lowest_text_address = (unrelocated_addr) -1;
-
-  abfd = objfile->obfd.get ();
-  symbuf_end = symbuf_idx = 0;
-  next_symbol_text_func = dbx_next_symbol_text;
-  textlow_not_set = 1;
-  dbx->ctx.has_line_numbers = 0;
-
-  /* FIXME: jimb/2003-09-12: We don't apply the right section's offset
-     to global and static variables.  The stab for a global or static
-     variable doesn't give us any indication of which section it's in,
-     so we can't tell immediately which offset in
-     objfile->section_offsets we should apply to the variable's
-     address.
-
-     We could certainly find out which section contains the variable
-     by looking up the variable's unrelocated address with
-     find_pc_section, but that would be expensive; this is the
-     function that constructs the partial symbol tables by examining
-     every symbol in the entire executable, and it's
-     performance-critical.  So that expense would not be welcome.  I'm
-     not sure what to do about this at the moment.
-
-     What we have done for years is to simply assume that the .data
-     section's offset is appropriate for all global and static
-     variables.  Recently, this was expanded to fall back to the .bss
-     section's offset if there is no .data section, and then to the
-     .rodata section's offset.  */
-  data_sect_index = objfile->sect_index_data;
-  if (data_sect_index == -1)
-    data_sect_index = SECT_OFF_BSS (objfile);
-  if (data_sect_index == -1)
-    data_sect_index = SECT_OFF_RODATA (objfile);
-
-  /* If data_sect_index is still -1, that's okay.  It's perfectly fine
-     for the file to have no .data, no .bss, and no .text at all, if
-     it also has no global or static variables.  */
-
-  for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++)
-    {
-      /* Get the symbol for this run and pull out some info.  */
-      QUIT;			/* Allow this to be interruptible.  */
-      if (symbuf_idx == symbuf_end)
-	fill_symbuf (abfd, objfile);
-      bufp = &symbuf[symbuf_idx++];
-
-      /*
-       * Special case to speed up readin.
-       */
-      if (bfd_h_get_8 (abfd, bufp->e_type) == N_SLINE)
-	{
-	  dbx->ctx.has_line_numbers = 1;
-	  continue;
-	}
-
-      INTERNALIZE_SYMBOL (nlist, bufp, abfd);
-      OBJSTAT (objfile, n_stabs++);
-
-      /* Ok.  There is a lot of code duplicated in the rest of this
-	 switch statement (for efficiency reasons).  Since I don't
-	 like duplicating code, I will do my penance here, and
-	 describe the code which is duplicated:
-
-	 *) The assignment to namestring.
-	 *) The call to strchr.
-	 *) The addition of a partial symbol the two partial
-	 symbol lists.  This last is a large section of code, so
-	 I've embedded it in the following macro.  */
-
-      switch (nlist.n_type)
-	{
-	  /*
-	   * 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:
-	  namestring = set_namestring (objfile, &nlist);
-
-	  record_minimal_symbol (reader, namestring,
-				 unrelocated_addr (nlist.n_value),
-				 nlist.n_type, objfile);	/* 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:
-	  namestring = set_namestring (objfile, &nlist);
-
-	  if ((namestring[0] == '-' && namestring[1] == 'l')
-	      || (namestring[(nsl = strlen (namestring)) - 1] == 'o'
-		  && namestring[nsl - 2] == '.'))
-	    {
-	      unrelocated_addr unrel_val = unrelocated_addr (nlist.n_value);
-
-	      if (past_first_source_file && pst
-		  /* The gould NP1 uses low values for .o and -l symbols
-		     which are not the address.  */
-		  && unrel_val >= pst->unrelocated_text_low ())
-		{
-		  stabs_end_psymtab (objfile, partial_symtabs,
-				     pst, psymtab_include_list,
-				     includes_used, symnum * dbx->ctx.symbol_size,
-				     unrel_val > pst->unrelocated_text_high ()
-				     ? unrel_val : pst->unrelocated_text_high (),
-				     dependency_list, dependencies_used,
-				     textlow_not_set);
-		  pst = (legacy_psymtab *) 0;
-		  includes_used = 0;
-		  dependencies_used = 0;
-		  dbx->ctx.has_line_numbers = 0;
-		}
-	      else
-		past_first_source_file = 1;
-	    }
-	  else
-	    goto record_it;
-	  continue;
-
-	case N_DATA:
-	  goto record_it;
-
-	case N_UNDF | N_EXT:
-	  /* The case (nlist.n_value != 0) is a "Fortran COMMON" symbol.
-	     We used to rely on the target to tell us whether it knows
-	     where the symbol has been relocated to, but none of the
-	     target implementations actually provided that operation.
-	     So we just ignore the symbol, the same way we would do if
-	     we had a target-side symbol lookup which returned no match.
-
-	     All other symbols (with nlist.n_value == 0), are really
-	     undefined, and so we ignore them too.  */
-	  continue;
-
-	case N_UNDF:
-	  if (dbx->ctx.processing_acc_compilation && nlist.n_strx == 1)
-	    {
-	      /* Deal with relative offsets in the string table
-		 used in ELF+STAB under Solaris.  If we want to use the
-		 n_strx field, which contains the name of the file,
-		 we must adjust file_string_table_offset *before* calling
-		 set_namestring().  */
-	      past_first_source_file = 1;
-	      dbx->ctx.file_string_table_offset = next_file_string_table_offset;
-	     next_file_string_table_offset =
-		dbx->ctx.file_string_table_offset + nlist.n_value;
-	      if (next_file_string_table_offset < dbx->ctx.file_string_table_offset)
-		error (_("string table offset backs up at %d"), symnum);
-	      /* FIXME -- replace error() with complaint.  */
-	      continue;
-	    }
-	  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:
-	  {
-	    CORE_ADDR valu;
-	    static int prev_so_symnum = -10;
-	    static int first_so_symnum;
-	    const char *p;
-	    static const char *dirname_nso;
-	    int prev_textlow_not_set;
-
-	    valu = nlist.n_value;
-
-	    prev_textlow_not_set = textlow_not_set;
-
-	    /* 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 (nlist.n_value == 0
-		&& gdbarch_sofun_address_maybe_missing (gdbarch))
-	      {
-		textlow_not_set = 1;
-		valu = 0;
-	      }
-	    else
-	      textlow_not_set = 0;
-
-	    past_first_source_file = 1;
-
-	    if (prev_so_symnum != symnum - 1)
-	      {			/* Here if prev stab wasn't N_SO.  */
-		first_so_symnum = symnum;
-
-		if (pst)
-		  {
-		    unrelocated_addr unrel_value = unrelocated_addr (valu);
-		    stabs_end_psymtab (objfile, partial_symtabs,
-				       pst, psymtab_include_list,
-				       includes_used, symnum * dbx->ctx.symbol_size,
-				       unrel_value > pst->unrelocated_text_high ()
-				       ? unrel_value
-				       : pst->unrelocated_text_high (),
-				       dependency_list, dependencies_used,
-				       prev_textlow_not_set);
-		    pst = (legacy_psymtab *) 0;
-		    includes_used = 0;
-		    dependencies_used = 0;
-		    dbx->ctx.has_line_numbers = 0;
-		  }
-	      }
-
-	    prev_so_symnum = symnum;
-
-	    /* End the current partial symtab and start a new one.  */
-
-	    namestring = set_namestring (objfile, &nlist);
-
-	    /* 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.  */
-
-	    p = lbasename (namestring);
-	    if (p != namestring && *p == '\000')
-	      {
-		/* Save the directory name SOs locally, then save it into
-		   the psymtab when it's created below.  */
-		dirname_nso = namestring;
-		continue;		
-	      }
-
-	    /* Some other compilers (C++ ones in particular) emit useless
-	       SOs for non-existent .c files.  We ignore all subsequent SOs
-	       that immediately follow the first.  */
-
-	    if (!pst)
-	      {
-		pst = start_psymtab (partial_symtabs, objfile,
-				     namestring,
-				     unrelocated_addr (valu),
-				     first_so_symnum * dbx->ctx.symbol_size);
-		pst->dirname = dirname_nso;
-		dirname_nso = NULL;
-	      }
-	    continue;
-	  }
-
-	case N_BINCL:
-	  {
-	    enum language tmp_language;
-
-	    /* Add this bincl to the bincl_list for future EXCLs.  No
-	       need to save the string; it'll be around until
-	       read_stabs_symtab function returns.  */
-
-	    namestring = set_namestring (objfile, &nlist);
-	    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
-		    || dbx->ctx.psymtab_language != language_cplus))
-	      dbx->ctx.psymtab_language = tmp_language;
-
-	    if (pst == NULL)
-	      {
-		/* FIXME: we should not get here without a PST to work on.
-		   Attempt to recover.  */
-		complaint (_("N_BINCL %s not in entries for "
-			     "any file, at symtab pos %d"),
-			   namestring, symnum);
-		continue;
-	      }
-	    dbx->ctx.bincl_list.emplace_back (namestring, nlist.n_value, pst);
-
-	    /* Mark down an include file in the current psymtab.  */
-
-	    goto record_include_file;
-	  }
-
-	case N_SOL:
-	  {
-	    enum language tmp_language;
-
-	    /* Mark down an include file in the current psymtab.  */
-	    namestring = set_namestring (objfile, &nlist);
-	    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
-		    || dbx->ctx.psymtab_language != language_cplus))
-	      dbx->ctx.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;
-	    {
-	      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;
-	    }
-
-	  record_include_file:
-
-	    psymtab_include_list[includes_used++] = namestring;
-	    if (includes_used >= includes_allocated)
-	      {
-		const char **orig = psymtab_include_list;
-
-		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.   */
-	{
-	  const char *p;
-
-	  namestring = set_namestring (objfile, &nlist);
-
-	  /* See if this is an end of function stab.  */
-	  if (pst && nlist.n_type == N_FUN && *namestring == '\000')
-	    {
-	      unrelocated_addr valu;
-
-	      /* It's value is the size (in bytes) of the function for
-		 function relative stabs, or the address of the function's
-		 end for old style stabs.  */
-	      valu = unrelocated_addr (nlist.n_value + last_function_start);
-	      if (pst->unrelocated_text_high () == unrelocated_addr (0)
-		  || valu > pst->unrelocated_text_high ())
-		pst->set_text_high (valu);
-	      break;
-	    }
-
-	  p = (char *) strchr (namestring, ':');
-	  if (!p)
-	    continue;		/* Not a debugging symbol.   */
-
-	  sym_len = 0;
-	  sym_name = NULL;	/* pacify "gcc -Werror" */
-	  if (dbx->ctx.psymtab_language == language_cplus)
-	    {
-	      std::string name (namestring, p - namestring);
-	      gdb::unique_xmalloc_ptr<char> new_name
-		= cp_canonicalize_string (name.c_str ());
-	      if (new_name != nullptr)
-		{
-		  sym_len = strlen (new_name.get ());
-		  sym_name = obstack_strdup (&objfile->objfile_obstack,
-					     new_name.get ());
-		}
-	    }
-	  else if (dbx->ctx.psymtab_language == language_c)
-	    {
-	      std::string name (namestring, p - namestring);
-	      gdb::unique_xmalloc_ptr<char> new_name
-		= c_canonicalize_name (name.c_str ());
-	      if (new_name != nullptr)
-		{
-		  sym_len = strlen (new_name.get ());
-		  sym_name = obstack_strdup (&objfile->objfile_obstack,
-					     new_name.get ());
-		}
-	    }
-
-	  if (sym_len == 0)
-	    {
-	      sym_name = namestring;
-	      sym_len = p - namestring;
-	    }
-
-	  /* 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':
-	      if (pst != nullptr)
-		pst->add_psymbol (std::string_view (sym_name, sym_len), true,
-				  VAR_DOMAIN, LOC_STATIC,
-				  data_sect_index,
-				  psymbol_placement::STATIC,
-				  unrelocated_addr (nlist.n_value),
-				  dbx->ctx.psymtab_language,
-				  partial_symtabs, objfile);
-	      else
-		complaint (_("static `%*s' appears to be defined "
-			     "outside of all compilation units"),
-			   sym_len, sym_name);
-	      continue;
-
-	    case 'G':
-	      /* The addresses in these entries are reported to be
-		 wrong.  See the code that reads 'G's for symtabs.  */
-	      if (pst != nullptr)
-		pst->add_psymbol (std::string_view (sym_name, sym_len), true,
-				  VAR_DOMAIN, LOC_STATIC,
-				  data_sect_index,
-				  psymbol_placement::GLOBAL,
-				  unrelocated_addr (nlist.n_value),
-				  dbx->ctx.psymtab_language,
-				  partial_symtabs, objfile);
-	      else
-		complaint (_("global `%*s' appears to be defined "
-			     "outside of all compilation units"),
-			   sym_len, sym_name);
-	      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] != ' '))
-		{
-		  if (pst != nullptr)
-		    pst->add_psymbol (std::string_view (sym_name, sym_len),
-				      true, STRUCT_DOMAIN, LOC_TYPEDEF, -1,
-				      psymbol_placement::STATIC,
-				      unrelocated_addr (0),
-				      dbx->ctx.psymtab_language,
-				      partial_symtabs, objfile);
-		  else
-		    complaint (_("enum, struct, or union `%*s' appears "
-				 "to be defined outside of all "
-				 "compilation units"),
-			       sym_len, sym_name);
-		  if (p[2] == 't')
-		    {
-		      /* Also a typedef with the same name.  */
-		      if (pst != nullptr)
-			pst->add_psymbol (std::string_view (sym_name, sym_len),
-					  true, VAR_DOMAIN, LOC_TYPEDEF, -1,
-					  psymbol_placement::STATIC,
-					  unrelocated_addr (0),
-					  dbx->ctx.psymtab_language,
-					  partial_symtabs, objfile);
-		      else
-			complaint (_("typedef `%*s' appears to be defined "
-				     "outside of all compilation units"),
-				   sym_len, sym_name);
-		      p += 1;
-		    }
-		}
-	      goto check_enum;
-
-	    case 't':
-	      if (p != namestring)	/* a name is there, not just :T...  */
-		{
-		  if (pst != nullptr)
-		    pst->add_psymbol (std::string_view (sym_name, sym_len),
-				      true, VAR_DOMAIN, LOC_TYPEDEF, -1,
-				      psymbol_placement::STATIC,
-				      unrelocated_addr (0),
-				      dbx->ctx.psymtab_language,
-				      partial_symtabs, objfile);
-		  else
-		    complaint (_("typename `%*s' appears to be defined "
-				 "outside of all compilation units"),
-			       sym_len, sym_name);
-		}
-	    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.  */
-		      if (pst != nullptr)
-			pst->add_psymbol (std::string_view (p, q - p), true,
-					  VAR_DOMAIN, LOC_CONST, -1,
-					  psymbol_placement::STATIC,
-					  unrelocated_addr (0),
-					  dbx->ctx.psymtab_language,
-					  partial_symtabs, objfile);
-		      else
-			complaint (_("enum constant `%*s' appears to be defined "
-				     "outside of all compilation units"),
-				   ((int) (q - p)), p);
-		      /* 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.  */
-	      if (pst != nullptr)
-		pst->add_psymbol (std::string_view (sym_name, sym_len), true,
-				  VAR_DOMAIN, LOC_CONST, -1,
-				  psymbol_placement::STATIC,
-				  unrelocated_addr (0),
-				  dbx->ctx.psymtab_language,
-				  partial_symtabs, objfile);
-	      else
-		complaint (_("constant `%*s' appears to be defined "
-			     "outside of all compilation units"),
-			   sym_len, sym_name);
-
-	      continue;
-
-	    case 'f':
-	      if (! pst)
-		{
-		  std::string name (namestring, (p - namestring));
-		  function_outside_compilation_unit_complaint (name.c_str ());
-		}
-	      /* Kludges for ELF/STABS with Sun ACC.  */
-	      dbx->ctx.last_function_name = namestring;
-	      /* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
-		 value for the bottom of the text seg in those cases.  */
-	      if (nlist.n_value == 0
-		  && gdbarch_sofun_address_maybe_missing (gdbarch))
-		{
-		  bound_minimal_symbol minsym
-		    = find_stab_function (namestring,
-					  pst ? pst->filename : NULL, objfile);
-		  if (minsym.minsym != NULL)
-		    nlist.n_value
-		      = CORE_ADDR (minsym.minsym->unrelocated_address ());
-		}
-	      if (pst && textlow_not_set
-		  && gdbarch_sofun_address_maybe_missing (gdbarch))
-		{
-		  pst->set_text_low (unrelocated_addr (nlist.n_value));
-		  textlow_not_set = 0;
-		}
-	      /* End kludge.  */
-
-	      /* Keep track of the start of the last function so we
-		 can handle end of function symbols.  */
-	      last_function_start = nlist.n_value;
-
-	      /* In reordered executables this function may lie outside
-		 the bounds created by N_SO symbols.  If that's the case
-		 use the address of this function as the low bound for
-		 the partial symbol table.  */
-	      if (pst
-		  && (textlow_not_set
-		      || (unrelocated_addr (nlist.n_value)
-			  < pst->unrelocated_text_low ()
-			  && (nlist.n_value != 0))))
-		{
-		  pst->set_text_low (unrelocated_addr (nlist.n_value));
-		  textlow_not_set = 0;
-		}
-	      if (pst != nullptr)
-		pst->add_psymbol (std::string_view (sym_name, sym_len), true,
-				  VAR_DOMAIN, LOC_BLOCK,
-				  SECT_OFF_TEXT (objfile),
-				  psymbol_placement::STATIC,
-				  unrelocated_addr (nlist.n_value),
-				  dbx->ctx.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 name (namestring, (p - namestring));
-		  function_outside_compilation_unit_complaint (name.c_str ());
-		}
-	      /* Kludges for ELF/STABS with Sun ACC.  */
-	      dbx->ctx.last_function_name = namestring;
-	      /* Do not fix textlow==0 for .o or NLM files, as 0 is a legit
-		 value for the bottom of the text seg in those cases.  */
-	      if (nlist.n_value == 0
-		  && gdbarch_sofun_address_maybe_missing (gdbarch))
-		{
-		  bound_minimal_symbol minsym
-		    = find_stab_function (namestring,
-					  pst ? pst->filename : NULL, objfile);
-		  if (minsym.minsym != NULL)
-		    nlist.n_value
-		      = CORE_ADDR (minsym.minsym->unrelocated_address ());
-		}
-	      if (pst && textlow_not_set
-		  && gdbarch_sofun_address_maybe_missing (gdbarch))
-		{
-		  pst->set_text_low (unrelocated_addr (nlist.n_value));
-		  textlow_not_set = 0;
-		}
-	      /* End kludge.  */
-
-	      /* Keep track of the start of the last function so we
-		 can handle end of function symbols.  */
-	      last_function_start = nlist.n_value;
-
-	      /* In reordered executables this function may lie outside
-		 the bounds created by N_SO symbols.  If that's the case
-		 use the address of this function as the low bound for
-		 the partial symbol table.  */
-	      if (pst
-		  && (textlow_not_set
-		      || (unrelocated_addr (nlist.n_value)
-			  < pst->unrelocated_text_low ()
-			  && (nlist.n_value != 0))))
-		{
-		  pst->set_text_low (unrelocated_addr (nlist.n_value));
-		  textlow_not_set = 0;
-		}
-	      if (pst != nullptr)
-		pst->add_psymbol (std::string_view (sym_name, sym_len), true,
-				  VAR_DOMAIN, LOC_BLOCK,
-				  SECT_OFF_TEXT (objfile),
-				  psymbol_placement::GLOBAL,
-				  unrelocated_addr (nlist.n_value),
-				  dbx->ctx.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 N_EXCL:
-
-	  namestring = set_namestring (objfile, &nlist);
-
-	  /* Find the corresponding bincl and mark that psymtab on the
-	     psymtab dependency list.  */
-	  {
-	    legacy_psymtab *needed_pst =
-	      find_corresponding_bincl_psymtab (namestring, nlist.n_value, objfile);
-
-	    /* 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)
-		  {
-		    legacy_psymtab **orig = dependency_list;
-
-		    dependency_list =
-		      (legacy_psymtab **)
-		      alloca ((dependencies_allocated *= 2)
-			      * sizeof (legacy_psymtab *));
-		    memcpy (dependency_list, orig,
-			    (dependencies_used
-			     * sizeof (legacy_psymtab *)));
-#ifdef DEBUG_INFO
-		    gdb_printf (gdb_stderr,
-				"Had to reallocate "
-				"dependency list.\n");
-		    gdb_printf (gdb_stderr,
-				"New dependencies allocated: %d\n",
-				dependencies_allocated);
-#endif
-		  }
-	      }
-	  }
-	  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))
-	    {
-	      stabs_end_psymtab (objfile, partial_symtabs, pst,
-				 psymtab_include_list, includes_used,
-				 symnum * dbx->ctx.symbol_size,
-				 (unrelocated_addr) 0, dependency_list,
-				 dependencies_used, textlow_not_set);
-	      pst = (legacy_psymtab *) 0;
-	      includes_used = 0;
-	      dependencies_used = 0;
-	      dbx->ctx.has_line_numbers = 0;
-	    }
-	  continue;
-
-	case N_RBRAC:
-#ifdef HANDLE_RBRAC
-	  HANDLE_RBRAC (nlist.n_value);
-	  continue;
-#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_BNSYM:
-	case N_ENSYM:
-	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:
-	case N_PATCH:
-	  /* 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.  */
-	  unknown_symtype_complaint (hex_string (nlist.n_type));
-	  continue;
-	}
-    }
-
-  /* If there's stuff to be cleaned up, clean it up.  */
-  if (pst)
-    {
-      /* Don't set high text address of PST lower than it already
-	 is.  */
-      unrelocated_addr text_end
-	= (unrelocated_addr
-	   ((dbx->ctx.lowest_text_address == (unrelocated_addr) -1
-	     ? text_addr
-	     : CORE_ADDR (dbx->ctx.lowest_text_address))
-	    + text_size));
-
-      stabs_end_psymtab (objfile, partial_symtabs,
-			 pst, psymtab_include_list, includes_used,
-			 symnum * dbx->ctx.symbol_size,
-			 (text_end > pst->unrelocated_text_high ()
-			  ? text_end : pst->unrelocated_text_high ()),
-			 dependency_list, dependencies_used, textlow_not_set);
-    }
-}
-
-/* Scan and build partial symbols for a symbol file.
-   We have been initialized by a call to dbx_symfile_init, which 
-   put all the relevant info into a "struct dbx_symfile_info",
-   hung off the objfile structure.  */
-
-void
-read_stabs_symtab (struct objfile *objfile, symfile_add_flags symfile_flags)
-{
-  bfd *sym_bfd;
-  int val;
-  struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
-  sym_bfd = objfile->obfd.get ();
-
-  stabs_deprecated_warning ();
-
-  /* .o and .nlm files are relocatables with text, data and bss segs based at
-     0.  This flag disables special (Solaris stabs-in-elf only) fixups for
-     symbols with a value of 0.  */
-
-  key->ctx.symfile_relocatable = bfd_get_file_flags (sym_bfd) & HAS_RELOC;
-
-  val = bfd_seek (sym_bfd, DBX_SYMTAB_OFFSET (objfile), SEEK_SET);
-  if (val < 0)
-    perror_with_name (objfile_name (objfile));
-
-  key->ctx.symbol_size = DBX_SYMBOL_SIZE (objfile);
-  key->ctx.symbol_table_offset = DBX_SYMTAB_OFFSET (objfile);
-
-  scoped_free_pendings free_pending;
-
-  minimal_symbol_reader reader (objfile);
-
-  /* Read stabs data from executable file and define symbols.  */
-
-  psymbol_functions *psf = new psymbol_functions ();
-  psymtab_storage *partial_symtabs = psf->get_partial_symtabs ().get ();
-  objfile->qf.emplace_front (psf);
-  read_stabs_symtab_1 (reader, partial_symtabs, objfile);
-
-  /* Install any minimal symbols that have been collected as the current
-     minimal symbols for this objfile.  */
-
-  reader.install ();
-}
-
-/* Record the namespace that the function defined by SYMBOL was
-   defined in, if necessary.  BLOCK is the associated block; use
-   OBSTACK for allocation.  */
-
-static void
-cp_set_block_scope (const struct symbol *symbol,
-		    struct block *block,
-		    struct obstack *obstack)
-{
-  if (symbol->demangled_name () != NULL)
-    {
-      /* Try to figure out the appropriate namespace from the
-	 demangled name.  */
-
-      /* FIXME: carlton/2003-04-15: If the function in question is
-	 a method of a class, the name will actually include the
-	 name of the class as well.  This should be harmless, but
-	 is a little unfortunate.  */
-
-      const char *name = symbol->demangled_name ();
-      unsigned int prefix_len = cp_entire_prefix_len (name);
-
-      block->set_scope (obstack_strndup (obstack, name, prefix_len),
-			obstack);
-    }
-}
-
-bound_minimal_symbol
-find_stab_function (const char *namestring, const char *filename,
-		    struct objfile *objfile)
-{
-  int n;
-
-  const char *colon = strchr (namestring, ':');
-  if (colon == NULL)
-    n = 0;
-  else
-    n = colon - namestring;
-
-  char *p = (char *) alloca (n + 2);
-  strncpy (p, namestring, n);
-  p[n] = 0;
-
-  bound_minimal_symbol msym
-    = lookup_minimal_symbol (current_program_space, p, objfile, filename);
-  if (msym.minsym == NULL)
-    {
-      /* Sun Fortran appends an underscore to the minimal symbol name,
-	 try again with an appended underscore if the minimal symbol
-	 was not found.  */
-      p[n] = '_';
-      p[n + 1] = 0;
-      msym
-	= lookup_minimal_symbol (current_program_space, p, objfile, filename);
-    }
-
-  if (msym.minsym == NULL && filename != NULL)
-    {
-      /* Try again without the filename.  */
-      p[n] = 0;
-      msym = lookup_minimal_symbol (current_program_space, p, objfile);
-    }
-  if (msym.minsym == NULL && filename != NULL)
-    {
-      /* And try again for Sun Fortran, but without the filename.  */
-      p[n] = '_';
-      p[n + 1] = 0;
-      msym = lookup_minimal_symbol (current_program_space, p, objfile);
-    }
-
-  return msym;
-}
-
-/* Add header file number I for this object file
-   at the next successive FILENUM.  */
-
-static void
-add_this_object_header_file (int i)
-{
-  if (n_this_object_header_files == n_allocated_this_object_header_files)
-    {
-      n_allocated_this_object_header_files *= 2;
-      this_object_header_files
-	= (int *) xrealloc ((char *) this_object_header_files,
-		       n_allocated_this_object_header_files * sizeof (int));
-    }
-
-  this_object_header_files[n_this_object_header_files++] = i;
-}
-
-/* Add to this file an "old" header file, one already seen in
-   a previous object file.  NAME is the header file's name.
-   INSTANCE is its instance code, to select among multiple
-   symbol tables for the same header file.  */
-
-static void
-add_old_header_file (const char *name, int instance, struct objfile *objfile)
-{
-  struct header_file *p = HEADER_FILES (objfile);
-  int i;
-
-  for (i = 0; i < N_HEADER_FILES (objfile); i++)
-    if (filename_cmp (p[i].name, name) == 0 && instance == p[i].instance)
-      {
-	add_this_object_header_file (i);
-	return;
-      }
-  repeated_header_complaint (name, symnum);
-}
-
-/* Add to this file a "new" header file: definitions for its types follow.
-   NAME is the header file's name.
-   Most often this happens only once for each distinct header file,
-   but not necessarily.  If it happens more than once, INSTANCE has
-   a different value each time, and references to the header file
-   use INSTANCE values to select among them.
-
-   dbx output contains "begin" and "end" markers for each new header file,
-   but at this level we just need to know which files there have been;
-   so we record the file when its "begin" is seen and ignore the "end".  */
-
-static void
-add_new_header_file (const char *name, int instance, struct objfile *objfile)
-{
-  int i;
-  struct header_file *hfile;
-
-  /* Make sure there is room for one more header file.  */
-
-  i = N_ALLOCATED_HEADER_FILES (objfile);
-
-  if (N_HEADER_FILES (objfile) == i)
-    {
-      if (i == 0)
-	{
-	  N_ALLOCATED_HEADER_FILES (objfile) = 10;
-	  HEADER_FILES (objfile) = (struct header_file *)
-	    xmalloc (10 * sizeof (struct header_file));
-	}
-      else
-	{
-	  i *= 2;
-	  N_ALLOCATED_HEADER_FILES (objfile) = i;
-	  HEADER_FILES (objfile) = (struct header_file *)
-	    xrealloc ((char *) HEADER_FILES (objfile),
-		      (i * sizeof (struct header_file)));
-	}
-    }
-
-  /* Create an entry for this header file.  */
-
-  i = N_HEADER_FILES (objfile)++;
-  hfile = HEADER_FILES (objfile) + i;
-  hfile->name = xstrdup (name);
-  hfile->instance = instance;
-  hfile->length = 10;
-  hfile->vector = XCNEWVEC (struct type *, 10);
-
-  add_this_object_header_file (i);
-}
-
-/* See stabsread.h.  */
-
-void
-process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
-		    const section_offsets &section_offsets,
-		    struct objfile *objfile, enum language language)
-{
-  struct gdbarch *gdbarch = objfile->arch ();
-  struct context_stack *newobj;
-  struct context_stack cstk;
-  /* This remembers the address of the start of a function.  It is
-     used because in Solaris 2, N_LBRAC, N_RBRAC, and N_SLINE entries
-     are relative to the current function's start address.  On systems
-     other than Solaris 2, this just holds the SECT_OFF_TEXT value,
-     and is used to relocate these symbol types rather than
-     SECTION_OFFSETS.  */
-  static CORE_ADDR function_start_offset;
-
-  /* This holds the address of the start of a function, without the
-     system peculiarities of function_start_offset.  */
-  static CORE_ADDR last_function_start;
-
-  /* If this is nonzero, we've seen an N_SLINE since the start of the
-     current function.  We use this to tell us to move the first sline
-     to the beginning of the function regardless of what its given
-     value is.  */
-  static int sline_found_in_function = 1;
-
-  /* If this is nonzero, we've seen a non-gcc N_OPT symbol for this
-     source file.  Used to detect the SunPRO solaris compiler.  */
-  static int n_opt_found;
-
-  /* The section index for this symbol.  */
-  int section_index = -1;
-
-  struct dbx_symfile_info *key = dbx_objfile_data_key.get (objfile);
-
-  /* Something is wrong if we see real data before seeing a source
-     file name.  */
-
-  if (get_last_source_file () == NULL && type != (unsigned char) N_SO)
-    {
-      /* Ignore any symbols which appear before an N_SO symbol.
-	 Currently no one puts symbols there, but we should deal
-	 gracefully with the case.  A complain()t might be in order,
-	 but this should not be an error ().  */
-      return;
-    }
-
-  switch (type)
-    {
-    case N_FUN:
-    case N_FNAME:
-
-      if (*name == '\000')
-	{
-	  /* This N_FUN marks the end of a function.  This closes off
-	     the current block.  */
-	  struct block *block;
-
-	  if (outermost_context_p ())
-	    {
-	      lbrac_mismatch_complaint (symnum);
-	      break;
-	    }
-
-	  /* The following check is added before recording line 0 at
-	     end of function so as to handle hand-generated stabs
-	     which may have an N_FUN stabs at the end of the function,
-	     but no N_SLINE stabs.  */
-	  if (sline_found_in_function)
-	    {
-	      CORE_ADDR addr = last_function_start + valu;
-
-	      record_line
-		(get_current_subfile (), 0,
-		 unrelocated_addr (gdbarch_addr_bits_remove (gdbarch, addr)
-				   - objfile->text_section_offset ()));
-	    }
-
-	  within_function = 0;
-	  cstk = pop_context ();
-
-	  /* Make a block for the local symbols within.  */
-	  block = finish_block (cstk.name,
-				cstk.old_blocks, NULL,
-				cstk.start_addr, cstk.start_addr + valu);
-
-	  /* For C++, set the block's scope.  */
-	  if (cstk.name->language () == language_cplus)
-	    cp_set_block_scope (cstk.name, block, &objfile->objfile_obstack);
-
-	  /* May be switching to an assembler file which may not be using
-	     block relative stabs, so reset the offset.  */
-	  function_start_offset = 0;
-
-	  break;
-	}
-
-      sline_found_in_function = 0;
-
-      /* Relocate for dynamic loading.  */
-      section_index = SECT_OFF_TEXT (objfile);
-      valu += section_offsets[SECT_OFF_TEXT (objfile)];
-      valu = gdbarch_addr_bits_remove (gdbarch, valu);
-      last_function_start = valu;
-
-      goto define_a_symbol;
-
-    case N_LBRAC:
-      /* This "symbol" just indicates the start of an inner lexical
-	 context within a function.  */
-
-      /* Ignore extra outermost context from SunPRO cc and acc.  */
-      if (n_opt_found && desc == 1)
-	break;
-
-      valu += function_start_offset;
-
-      push_context (desc, valu);
-      break;
-
-    case N_RBRAC:
-      /* This "symbol" just indicates the end of an inner lexical
-	 context that was started with N_LBRAC.  */
-
-      /* Ignore extra outermost context from SunPRO cc and acc.  */
-      if (n_opt_found && desc == 1)
-	break;
-
-      valu += function_start_offset;
-
-      if (outermost_context_p ())
-	{
-	  lbrac_mismatch_complaint (symnum);
-	  break;
-	}
-
-      cstk = pop_context ();
-      if (desc != cstk.depth)
-	lbrac_mismatch_complaint (symnum);
-
-      if (*get_local_symbols () != NULL)
-	{
-	  /* GCC development snapshots from March to December of
-	     2000 would output N_LSYM entries after N_LBRAC
-	     entries.  As a consequence, these symbols are simply
-	     discarded.  Complain if this is the case.  */
-	  complaint (_("misplaced N_LBRAC entry; discarding local "
-		       "symbols which have no enclosing block"));
-	}
-      *get_local_symbols () = cstk.locals;
-
-      if (get_context_stack_depth () > 1)
-	{
-	  /* This is not the outermost LBRAC...RBRAC pair in the
-	     function, its local symbols preceded it, and are the ones
-	     just recovered from the context stack.  Define the block
-	     for them (but don't bother if the block contains no
-	     symbols.  Should we complain on blocks without symbols?
-	     I can't think of any useful purpose for them).  */
-	  if (*get_local_symbols () != NULL)
-	    {
-	      /* Muzzle a compiler bug that makes end < start.
-
-		 ??? Which compilers?  Is this ever harmful?.  */
-	      if (cstk.start_addr > valu)
-		{
-		  complaint (_("block start larger than block end"));
-		  cstk.start_addr = valu;
-		}
-	      /* Make a block for the local symbols within.  */
-	      finish_block (0, cstk.old_blocks, NULL,
-			    cstk.start_addr, valu);
-	    }
-	}
-      else
-	{
-	  /* This is the outermost LBRAC...RBRAC pair.  There is no
-	     need to do anything; leave the symbols that preceded it
-	     to be attached to the function's own block.  We need to
-	     indicate that we just moved outside of the function.  */
-	  within_function = 0;
-	}
-
-      break;
-
-    case N_FN:
-    case N_FN_SEQ:
-      /* This kind of symbol indicates the start of an object file.
-	 Relocate for dynamic loading.  */
-      section_index = SECT_OFF_TEXT (objfile);
-      valu += section_offsets[SECT_OFF_TEXT (objfile)];
-      break;
-
-    case N_SO:
-      /* This type of symbol indicates the start of data for one
-	 source file.  Finish the symbol table of the previous source
-	 file (if any) and start accumulating a new symbol table.
-	 Relocate for dynamic loading.  */
-      section_index = SECT_OFF_TEXT (objfile);
-      valu += section_offsets[SECT_OFF_TEXT (objfile)];
-
-      n_opt_found = 0;
-
-      if (get_last_source_file ())
-	{
-	  /* 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 == (unsigned char) N_SO)
-	    {
-	      patch_subfile_names (get_current_subfile (), name);
-	      break;		/* Ignore repeated SOs.  */
-	    }
-	  end_compunit_symtab (valu);
-	  end_stabs ();
-	}
-
-      /* Null name means this just marks the end of text for this .o
-	 file.  Don't start a new symtab in this case.  */
-      if (*name == '\000')
-	break;
-
-      function_start_offset = 0;
-
-      start_stabs ();
-      start_compunit_symtab (objfile, name, NULL, valu, language);
-      record_debugformat ("stabs");
-      break;
-
-    case N_SOL:
-      /* This type of symbol indicates the start of data for a
-	 sub-source-file, one whose contents were copied or included
-	 in the compilation of the main source file (whose name was
-	 given in the N_SO symbol).  Relocate for dynamic loading.  */
-      section_index = SECT_OFF_TEXT (objfile);
-      valu += section_offsets[SECT_OFF_TEXT (objfile)];
-      start_subfile (name);
-      break;
-
-    case N_BINCL:
-      push_subfile ();
-      add_new_header_file (name, valu, objfile);
-      start_subfile (name);
-      break;
-
-    case N_EINCL:
-      start_subfile (pop_subfile ());
-      break;
-
-    case N_EXCL:
-      add_old_header_file (name, valu, objfile);
-      break;
-
-    case N_SLINE:
-      /* This type of "symbol" really just records one line-number --
-	 core-address correspondence.  Enter it in the line list for
-	 this symbol table.  */
-
-      /* Relocate for dynamic loading and for ELF acc
-	 function-relative symbols.  */
-      valu += function_start_offset;
-
-      /* GCC 2.95.3 emits the first N_SLINE stab somewhere in the
-	 middle of the prologue instead of right at the start of the
-	 function.  To deal with this we record the address for the
-	 first N_SLINE stab to be the start of the function instead of
-	 the listed location.  We really shouldn't to this.  When
-	 compiling with optimization, this first N_SLINE stab might be
-	 optimized away.  Other (non-GCC) compilers don't emit this
-	 stab at all.  There is no real harm in having an extra
-	 numbered line, although it can be a bit annoying for the
-	 user.  However, it totally screws up our testsuite.
-
-	 So for now, keep adjusting the address of the first N_SLINE
-	 stab, but only for code compiled with GCC.  */
-
-      if (within_function && sline_found_in_function == 0)
-	{
-	  CORE_ADDR addr = processing_gcc_compilation == 2 ?
-			   last_function_start : valu;
-
-	  record_line
-	    (get_current_subfile (), desc,
-	     unrelocated_addr (gdbarch_addr_bits_remove (gdbarch, addr)
-			       - objfile->text_section_offset ()));
-	  sline_found_in_function = 1;
-	}
-      else
-	record_line
-	  (get_current_subfile (), desc,
-	   unrelocated_addr (gdbarch_addr_bits_remove (gdbarch, valu)
-			     - objfile->text_section_offset ()));
-      break;
-
-    case N_BCOMM:
-      common_block_start (name, objfile);
-      break;
-
-    case N_ECOMM:
-      common_block_end (objfile);
-      break;
-
-      /* The following symbol types need to have the appropriate
-	 offset added to their value; then we process symbol
-	 definitions in the name.  */
-
-    case N_STSYM:		/* Static symbol in data segment.  */
-    case N_LCSYM:		/* Static symbol in BSS segment.  */
-    case N_ROSYM:		/* Static symbol in read-only data segment.  */
-      /* HORRID HACK DEPT.  However, it's Sun's furgin' fault.
-	 Solaris 2's stabs-in-elf makes *most* symbols relative but
-	 leaves a few absolute (at least for Solaris 2.1 and version
-	 2.0.1 of the SunPRO compiler).  N_STSYM and friends sit on
-	 the fence.  .stab "foo:S...",N_STSYM is absolute (ld
-	 relocates it) .stab "foo:V...",N_STSYM is relative (section
-	 base subtracted).  This leaves us no choice but to search for
-	 the 'S' or 'V'...  (or pass the whole section_offsets stuff
-	 down ONE MORE function call level, which we really don't want
-	 to do).  */
-      {
-	const char *p;
-
-	/* Normal object file and NLMs have non-zero text seg offsets,
-	   but don't need their static syms offset in this fashion.
-	   XXX - This is really a crock that should be fixed in the
-	   solib handling code so that I don't have to work around it
-	   here.  */
-
-	if (!key->ctx.symfile_relocatable)
-	  {
-	    p = strchr (name, ':');
-	    if (p != 0 && p[1] == 'S')
-	      {
-		/* The linker relocated it.  We don't want to add a
-		   Sun-stabs Tfoo.foo-like offset, but we *do*
-		   want to add whatever solib.c passed to
-		   symbol_file_add as addr (this is known to affect
-		   SunOS 4, and I suspect ELF too).  Since there is no
-		   Ttext.text symbol, we can get addr from the text offset.  */
-		section_index = SECT_OFF_TEXT (objfile);
-		valu += section_offsets[SECT_OFF_TEXT (objfile)];
-		goto define_a_symbol;
-	      }
-	  }
-	/* Since it's not the kludge case, re-dispatch to the right
-	   handler.  */
-	switch (type)
-	  {
-	  case N_STSYM:
-	    goto case_N_STSYM;
-	  case N_LCSYM:
-	    goto case_N_LCSYM;
-	  case N_ROSYM:
-	    goto case_N_ROSYM;
-	  default:
-	    internal_error (_("failed internal consistency check"));
-	  }
-      }
-
-    case_N_STSYM:		/* Static symbol in data segment.  */
-    case N_DSLINE:		/* Source line number, data segment.  */
-      section_index = SECT_OFF_DATA (objfile);
-      valu += section_offsets[SECT_OFF_DATA (objfile)];
-      goto define_a_symbol;
-
-    case_N_LCSYM:		/* Static symbol in BSS segment.  */
-    case N_BSLINE:		/* Source line number, BSS segment.  */
-      /* N_BROWS: overlaps with N_BSLINE.  */
-      section_index = SECT_OFF_BSS (objfile);
-      valu += section_offsets[SECT_OFF_BSS (objfile)];
-      goto define_a_symbol;
-
-    case_N_ROSYM:		/* Static symbol in read-only data segment.  */
-      section_index = SECT_OFF_RODATA (objfile);
-      valu += section_offsets[SECT_OFF_RODATA (objfile)];
-      goto define_a_symbol;
-
-    case N_ENTRY:		/* Alternate entry point.  */
-      /* Relocate for dynamic loading.  */
-      section_index = SECT_OFF_TEXT (objfile);
-      valu += section_offsets[SECT_OFF_TEXT (objfile)];
-      goto define_a_symbol;
-
-      /* The following symbol types we don't know how to process.
-	 Handle them in a "default" way, but complain to people who
-	 care.  */
-    default:
-    case N_CATCH:		/* Exception handler catcher.  */
-    case N_EHDECL:		/* Exception handler name.  */
-    case N_PC:			/* Global symbol in Pascal.  */
-    case N_M2C:			/* Modula-2 compilation unit.  */
-      /* N_MOD2: overlaps with N_EHDECL.  */
-    case N_SCOPE:		/* Modula-2 scope information.  */
-    case N_ECOML:		/* End common (local name).  */
-    case N_NBTEXT:		/* Gould Non-Base-Register symbols???  */
-    case N_NBDATA:
-    case N_NBBSS:
-    case N_NBSTS:
-    case N_NBLCS:
-      unknown_symtype_complaint (hex_string (type));
-
-    define_a_symbol:
-      [[fallthrough]];
-      /* These symbol types don't need the address field relocated,
-	 since it is either unused, or is absolute.  */
-    case N_GSYM:		/* Global variable.  */
-    case N_NSYMS:		/* Number of symbols (Ultrix).  */
-    case N_NOMAP:		/* No map?  (Ultrix).  */
-    case N_RSYM:		/* Register variable.  */
-    case N_DEFD:		/* Modula-2 GNU module dependency.  */
-    case N_SSYM:		/* Struct or union element.  */
-    case N_LSYM:		/* Local symbol in stack.  */
-    case N_PSYM:		/* Parameter variable.  */
-    case N_LENG:		/* Length of preceding symbol type.  */
-      if (name)
-	{
-	  int deftype;
-	  const char *colon_pos = strchr (name, ':');
-
-	  if (colon_pos == NULL)
-	    deftype = '\0';
-	  else
-	    deftype = colon_pos[1];
-
-	  switch (deftype)
-	    {
-	    case 'f':
-	    case 'F':
-	      /* Deal with the SunPRO 3.0 compiler which omits the
-		 address from N_FUN symbols.  */
-	      if (type == N_FUN
-		  && valu == section_offsets[SECT_OFF_TEXT (objfile)]
-		  && gdbarch_sofun_address_maybe_missing (gdbarch))
-		{
-		  bound_minimal_symbol minsym
-		    = find_stab_function (name, get_last_source_file (),
-					  objfile);
-		  if (minsym.minsym != NULL)
-		    valu = minsym.value_address ();
-		}
-
-	      /* These addresses are absolute.  */
-	      function_start_offset = valu;
-
-	      within_function = 1;
-
-	      if (get_context_stack_depth () > 1)
-		{
-		  complaint (_("unmatched N_LBRAC before symtab pos %d"),
-			     symnum);
-		  break;
-		}
-
-	      if (!outermost_context_p ())
-		{
-		  struct block *block;
-
-		  cstk = pop_context ();
-		  /* Make a block for the local symbols within.  */
-		  block = finish_block (cstk.name,
-					cstk.old_blocks, NULL,
-					cstk.start_addr, valu);
-
-		  /* For C++, set the block's scope.  */
-		  if (cstk.name->language () == language_cplus)
-		    cp_set_block_scope (cstk.name, block,
-					&objfile->objfile_obstack);
-		}
-
-	      newobj = push_context (0, valu);
-	      newobj->name = define_symbol (valu, name, desc, type, objfile);
-	      if (newobj->name != nullptr)
-		newobj->name->set_section_index (section_index);
-	      break;
-
-	    default:
-	      {
-		struct symbol *sym = define_symbol (valu, name, desc, type,
-						    objfile);
-		if (sym != nullptr)
-		  sym->set_section_index (section_index);
-	      }
-	      break;
-	    }
-	}
-      break;
-
-      /* We use N_OPT to carry the gcc2_compiled flag.  Sun uses it
-	 for a bunch of other flags, too.  Someday we may parse their
-	 flags; for now we ignore theirs and hope they'll ignore ours.  */
-    case N_OPT:			/* Solaris 2: Compiler options.  */
-      if (name)
-	{
-	  if (strcmp (name, GCC2_COMPILED_FLAG_SYMBOL) == 0)
-	    {
-	      processing_gcc_compilation = 2;
-	    }
-	  else
-	    n_opt_found = 1;
-	}
-      break;
-
-    case N_MAIN:		/* Name of main routine.  */
-      /* FIXME: If one has a symbol file with N_MAIN and then replaces
-	 it with a symbol file with "main" and without N_MAIN.  I'm
-	 not sure exactly what rule to follow but probably something
-	 like: N_MAIN takes precedence over "main" no matter what
-	 objfile it is in; If there is more than one N_MAIN, choose
-	 the one in the symfile_objfile; If there is more than one
-	 N_MAIN within a given objfile, complain() and choose
-	 arbitrarily.  (kingdon) */
-      if (name != NULL)
-	set_objfile_main_name (objfile, name, language_unknown);
-      break;
-
-      /* The following symbol types can be ignored.  */
-    case N_OBJ:			/* Solaris 2: Object file dir and name.  */
-    case N_PATCH:		/* Solaris 2: Patch Run Time Checker.  */
-      /* N_UNDF:                   Solaris 2: File separator mark.  */
-      /* N_UNDF: -- we will never encounter it, since we only process
-	 one file's symbols at once.  */
-    case N_ENDM:		/* Solaris 2: End of module.  */
-    case N_ALIAS:		/* SunPro F77: alias name, ignore for now.  */
-      break;
-    }
-
-  /* '#' is a GNU C extension to allow one symbol to refer to another
-     related symbol.
-
-     Generally this is used so that an alias can refer to its main
-     symbol.  */
-  gdb_assert (name);
-  if (name[0] == '#')
-    {
-      /* Initialize symbol reference names and determine if this is a
-	 definition.  If a symbol reference is being defined, go ahead
-	 and add it.  Otherwise, just return.  */
-
-      const char *s = name;
-      int refnum;
-
-      /* If this stab defines a new reference ID that is not on the
-	 reference list, then put it on the reference list.
-
-	 We go ahead and advance NAME past the reference, even though
-	 it is not strictly necessary at this time.  */
-      refnum = symbol_reference_defined (&s);
-      if (refnum >= 0)
-	if (!ref_search (refnum))
-	  ref_add (refnum, 0, name, valu);
-      name = s;
-    }
-
-  previous_stab_code = type;
-}
-
-#define VISIBILITY_PRIVATE	'0'	/* Stabs character for private field */
-#define VISIBILITY_PROTECTED	'1'	/* Stabs character for protected fld */
-#define VISIBILITY_PUBLIC	'2'	/* Stabs character for public field */
-#define VISIBILITY_IGNORE	'9'	/* Optimized out or zero length */
-
-/* Structure for storing pointers to reference definitions for fast lookup 
-   during "process_later".  */
-
-struct ref_map
-{
-  const char *stabs;
-  CORE_ADDR value;
-  struct symbol *sym;
-};
-
-#define MAX_CHUNK_REFS 100
-#define REF_CHUNK_SIZE (MAX_CHUNK_REFS * sizeof (struct ref_map))
-#define REF_MAP_SIZE(ref_chunk) ((ref_chunk) * REF_CHUNK_SIZE)
-
-static struct ref_map *ref_map;
-
-/* Ptr to free cell in chunk's linked list.  */
-static int ref_count = 0;
-
-/* Number of chunks malloced.  */
-static int ref_chunk = 0;
-
-/* This file maintains a cache of stabs aliases found in the symbol
-   table.  If the symbol table changes, this cache must be cleared
-   or we are left holding onto data in invalid obstacks.  */
-void
-stabsread_clear_cache (void)
-{
-  ref_count = 0;
-  ref_chunk = 0;
-}
-
-/* Create array of pointers mapping refids to symbols and stab strings.
-   Add pointers to reference definition symbols and/or their values as we 
-   find them, using their reference numbers as our index.
-   These will be used later when we resolve references.  */
-void
-ref_add (int refnum, struct symbol *sym, const char *stabs, CORE_ADDR value)
-{
-  if (ref_count == 0)
-    ref_chunk = 0;
-  if (refnum >= ref_count)
-    ref_count = refnum + 1;
-  if (ref_count > ref_chunk * MAX_CHUNK_REFS)
-    {
-      int new_slots = ref_count - ref_chunk * MAX_CHUNK_REFS;
-      int new_chunks = new_slots / MAX_CHUNK_REFS + 1;
-
-      ref_map = (struct ref_map *)
-	xrealloc (ref_map, REF_MAP_SIZE (ref_chunk + new_chunks));
-      memset (ref_map + ref_chunk * MAX_CHUNK_REFS, 0, 
-	      new_chunks * REF_CHUNK_SIZE);
-      ref_chunk += new_chunks;
-    }
-  ref_map[refnum].stabs = stabs;
-  ref_map[refnum].sym = sym;
-  ref_map[refnum].value = value;
-}
-
-/* Return defined sym for the reference REFNUM.  */
-struct symbol *
-ref_search (int refnum)
-{
-  if (refnum < 0 || refnum > ref_count)
-    return 0;
-  return ref_map[refnum].sym;
-}
-
-/* Parse a reference id in STRING and return the resulting
-   reference number.  Move STRING beyond the reference id.  */
-
-static int
-process_reference (const char **string)
-{
-  const char *p;
-  int refnum = 0;
-
-  if (**string != '#')
-    return 0;
-
-  /* Advance beyond the initial '#'.  */
-  p = *string + 1;
-
-  /* Read number as reference id.  */
-  while (*p && c_isdigit (*p))
-    {
-      refnum = refnum * 10 + *p - '0';
-      p++;
-    }
-  *string = p;
-  return refnum;
-}
-
-/* If STRING defines a reference, store away a pointer to the reference 
-   definition for later use.  Return the reference number.  */
-
-int
-symbol_reference_defined (const char **string)
-{
-  const char *p = *string;
-  int refnum = 0;
-
-  refnum = process_reference (&p);
-
-  /* Defining symbols end in '='.  */
-  if (*p == '=')
-    {
-      /* Symbol is being defined here.  */
-      *string = p + 1;
-      return refnum;
-    }
-  else
-    {
-      /* Must be a reference.  Either the symbol has already been defined,
-	 or this is a forward reference to it.  */
-      *string = p;
-      return -1;
-    }
-}
-
-static int
-stab_reg_to_regnum (struct symbol *sym, struct gdbarch *gdbarch)
-{
-  int regno = gdbarch_stab_reg_to_regnum (gdbarch, sym->value_longest ());
-
-  if (regno < 0 || regno >= gdbarch_num_cooked_regs (gdbarch))
-    {
-      reg_value_complaint (regno, gdbarch_num_cooked_regs (gdbarch),
-			   sym->print_name ());
-
-      regno = gdbarch_sp_regnum (gdbarch); /* Known safe, though useless.  */
-    }
-
-  return regno;
-}
-
-static const struct symbol_register_ops stab_register_funcs = {
-  stab_reg_to_regnum
-};
-
-/* The "loc_class" indices for computed symbols.  */
-
-static int stab_register_index;
-static int stab_regparm_index;
-
-struct symbol *
-define_symbol (CORE_ADDR valu, const char *string, int desc, int type,
-	       struct objfile *objfile)
-{
-  struct gdbarch *gdbarch = objfile->arch ();
-  struct symbol *sym;
-  const char *p = find_name_end (string);
-  int deftype;
-  int synonym = 0;
-  int i;
-
-  /* We would like to eliminate nameless symbols, but keep their types.
-     E.g. stab entry ":t10=*2" should produce a type 10, which is a pointer
-     to type 2, but, should not create a symbol to address that type.  Since
-     the symbol will be nameless, there is no way any user can refer to it.  */
-
-  int nameless;
-
-  /* Ignore syms with empty names.  */
-  if (string[0] == 0)
-    return 0;
-
-  /* Ignore old-style symbols from cc -go.  */
-  if (p == 0)
-    return 0;
-
-  while (p[1] == ':')
-    {
-      p += 2;
-      p = strchr (p, ':');
-      if (p == NULL)
-	{
-	  complaint (
-		     _("Bad stabs string '%s'"), string);
-	  return NULL;
-	}
-    }
-
-  /* If a nameless stab entry, all we need is the type, not the symbol.
-     e.g. ":t10=*2" or a nameless enum like " :T16=ered:0,green:1,blue:2,;" */
-  nameless = (p == string || ((string[0] == ' ') && (string[1] == ':')));
-
-  current_symbol = sym = new (&objfile->objfile_obstack) symbol;
-
-  if (processing_gcc_compilation)
-    {
-      /* GCC 2.x puts the line number in desc.  SunOS apparently puts in the
-	 number of bytes occupied by a type or object, which we ignore.  */
-      sym->set_line (desc);
-    }
-  else
-    {
-      sym->set_line (0);	/* unknown */
-    }
-
-  sym->set_language (get_current_subfile ()->language,
-		     &objfile->objfile_obstack);
-
-  if (is_cplus_marker (string[0]))
-    {
-      /* Special GNU C++ names.  */
-      switch (string[1])
-	{
-	case 't':
-	  sym->set_linkage_name ("this");
-	  break;
-
-	case 'v':		/* $vtbl_ptr_type */
-	  goto normal;
-
-	case 'e':
-	  sym->set_linkage_name ("eh_throw");
-	  break;
-
-	case '_':
-	  /* This was an anonymous type that was never fixed up.  */
-	  goto normal;
-
-	default:
-	  complaint (_("Unknown C++ symbol name `%s'"),
-		     string);
-	  goto normal;		/* Do *something* with it.  */
-	}
-    }
-  else
-    {
-    normal:
-      gdb::unique_xmalloc_ptr<char> new_name;
-
-      if (sym->language () == language_cplus)
-	{
-	  std::string name (string, p - string);
-	  new_name = cp_canonicalize_string (name.c_str ());
-	}
-      else if (sym->language () == language_c)
-	{
-	  std::string name (string, p - string);
-	  new_name = c_canonicalize_name (name.c_str ());
-	}
-      if (new_name != nullptr)
-	sym->compute_and_set_names (new_name.get (), true, objfile->per_bfd);
-      else
-	sym->compute_and_set_names (std::string_view (string, p - string), true,
-				    objfile->per_bfd);
-
-      if (sym->language () == language_cplus)
-	cp_scan_for_anonymous_namespaces (get_buildsym_compunit (), sym,
-					  objfile);
-
-    }
-  p++;
-
-  /* Determine the type of name being defined.  */
-#if 0
-  /* Getting GDB to correctly skip the symbol on an undefined symbol
-     descriptor and not ever dump core is a very dodgy proposition if
-     we do things this way.  I say the acorn RISC machine can just
-     fix their compiler.  */
-  /* The Acorn RISC machine's compiler can put out locals that don't
-     start with "234=" or "(3,4)=", so assume anything other than the
-     deftypes we know how to handle is a local.  */
-  if (!strchr ("cfFGpPrStTvVXCR", *p))
-#else
-  if (c_isdigit (*p) || *p == '(' || *p == '-')
-#endif
-    deftype = 'l';
-  else
-    deftype = *p++;
-
-  switch (deftype)
-    {
-    case 'c':
-      /* c is a special case, not followed by a type-number.
-	 SYMBOL:c=iVALUE for an integer constant symbol.
-	 SYMBOL:c=rVALUE for a floating constant symbol.
-	 SYMBOL:c=eTYPE,INTVALUE for an enum constant symbol.
-	 e.g. "b:c=e6,0" for "const b = blob1"
-	 (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;").  */
-      if (*p != '=')
-	{
-	  sym->set_loc_class_index (LOC_CONST);
-	  sym->set_type (error_type (&p, objfile));
-	  sym->set_domain (VAR_DOMAIN);
-	  add_symbol_to_list (sym, get_file_symbols ());
-	  return sym;
-	}
-      ++p;
-      switch (*p++)
-	{
-	case 'r':
-	  {
-	    gdb_byte *dbl_valu;
-	    struct type *dbl_type;
-
-	    dbl_type = builtin_type (objfile)->builtin_double;
-	    dbl_valu
-	      = (gdb_byte *) obstack_alloc (&objfile->objfile_obstack,
-					    dbl_type->length ());
-
-	    target_float_from_string (dbl_valu, dbl_type, std::string (p));
-
-	    sym->set_type (dbl_type);
-	    sym->set_value_bytes (dbl_valu);
-	    sym->set_loc_class_index (LOC_CONST_BYTES);
-	  }
-	  break;
-	case 'i':
-	  {
-	    /* Defining integer constants this way is kind of silly,
-	       since 'e' constants allows the compiler to give not
-	       only the value, but the type as well.  C has at least
-	       int, long, unsigned int, and long long as constant
-	       types; other languages probably should have at least
-	       unsigned as well as signed constants.  */
-
-	    sym->set_type (builtin_type (objfile)->builtin_long);
-	    sym->set_value_longest (atoi (p));
-	    sym->set_loc_class_index (LOC_CONST);
-	  }
-	  break;
-
-	case 'c':
-	  {
-	    sym->set_type (builtin_type (objfile)->builtin_char);
-	    sym->set_value_longest (atoi (p));
-	    sym->set_loc_class_index (LOC_CONST);
-	  }
-	  break;
-
-	case 's':
-	  {
-	    struct type *range_type;
-	    int ind = 0;
-	    char quote = *p++;
-	    gdb_byte *string_local = (gdb_byte *) alloca (strlen (p));
-	    gdb_byte *string_value;
-
-	    if (quote != '\'' && quote != '"')
-	      {
-		sym->set_loc_class_index (LOC_CONST);
-		sym->set_type (error_type (&p, objfile));
-		sym->set_domain (VAR_DOMAIN);
-		add_symbol_to_list (sym, get_file_symbols ());
-		return sym;
-	      }
-
-	    /* Find matching quote, rejecting escaped quotes.  */
-	    while (*p && *p != quote)
-	      {
-		if (*p == '\\' && p[1] == quote)
-		  {
-		    string_local[ind] = (gdb_byte) quote;
-		    ind++;
-		    p += 2;
-		  }
-		else if (*p) 
-		  {
-		    string_local[ind] = (gdb_byte) (*p);
-		    ind++;
-		    p++;
-		  }
-	      }
-	    if (*p != quote)
-	      {
-		sym->set_loc_class_index (LOC_CONST);
-		sym->set_type (error_type (&p, objfile));
-		sym->set_domain (VAR_DOMAIN);
-		add_symbol_to_list (sym, get_file_symbols ());
-		return sym;
-	      }
-
-	    /* NULL terminate the string.  */
-	    string_local[ind] = 0;
-	    type_allocator alloc (objfile, get_current_subfile ()->language);
-	    range_type
-	      = create_static_range_type (alloc,
-					  builtin_type (objfile)->builtin_int,
-					  0, ind);
-	    sym->set_type
-	      (create_array_type (alloc, builtin_type (objfile)->builtin_char,
-				  range_type));
-	    string_value
-	      = (gdb_byte *) obstack_alloc (&objfile->objfile_obstack, ind + 1);
-	    memcpy (string_value, string_local, ind + 1);
-	    p++;
-
-	    sym->set_value_bytes (string_value);
-	    sym->set_loc_class_index (LOC_CONST_BYTES);
-	  }
-	  break;
-
-	case 'e':
-	  /* SYMBOL:c=eTYPE,INTVALUE for a constant symbol whose value
-	     can be represented as integral.
-	     e.g. "b:c=e6,0" for "const b = blob1"
-	     (where type 6 is defined by "blobs:t6=eblob1:0,blob2:1,;").  */
-	  {
-	    sym->set_loc_class_index (LOC_CONST);
-	    sym->set_type (read_type (&p, objfile));
-
-	    if (*p != ',')
-	      {
-		sym->set_type (error_type (&p, objfile));
-		break;
-	      }
-	    ++p;
-
-	    /* If the value is too big to fit in an int (perhaps because
-	       it is unsigned), or something like that, we silently get
-	       a bogus value.  The type and everything else about it is
-	       correct.  Ideally, we should be using whatever we have
-	       available for parsing unsigned and long long values,
-	       however.  */
-	    sym->set_value_longest (atoi (p));
-	  }
-	  break;
-	default:
-	  {
-	    sym->set_loc_class_index (LOC_CONST);
-	    sym->set_type (error_type (&p, objfile));
-	  }
-	}
-      sym->set_domain (VAR_DOMAIN);
-      add_symbol_to_list (sym, get_file_symbols ());
-      return sym;
-
-    case 'C':
-      /* The name of a caught exception.  */
-      sym->set_type (read_type (&p, objfile));
-      sym->set_loc_class_index (LOC_LABEL);
-      sym->set_domain (VAR_DOMAIN);
-      sym->set_value_address (valu);
-      add_symbol_to_list (sym, get_local_symbols ());
-      break;
-
-    case 'f':
-      /* A static function definition.  */
-      sym->set_type (read_type (&p, objfile));
-      sym->set_loc_class_index (LOC_BLOCK);
-      sym->set_domain (FUNCTION_DOMAIN);
-      add_symbol_to_list (sym, get_file_symbols ());
-      /* fall into process_function_types.  */
-
-    process_function_types:
-      /* Function result types are described as the result type in stabs.
-	 We need to convert this to the function-returning-type-X type
-	 in GDB.  E.g. "int" is converted to "function returning int".  */
-      if (sym->type ()->code () != TYPE_CODE_FUNC)
-	sym->set_type (lookup_function_type (sym->type ()));
-
-      /* All functions in C++ have prototypes.  Stabs does not offer an
-	 explicit way to identify prototyped or unprototyped functions,
-	 but both GCC and Sun CC emit stabs for the "call-as" type rather
-	 than the "declared-as" type for unprototyped functions, so
-	 we treat all functions as if they were prototyped.  This is used
-	 primarily for promotion when calling the function from GDB.  */
-      sym->type ()->set_is_prototyped (true);
-
-      /* fall into process_prototype_types.  */
-
-    process_prototype_types:
-      /* Sun acc puts declared types of arguments here.  */
-      if (*p == ';')
-	{
-	  struct type *ftype = sym->type ();
-	  int nsemi = 0;
-	  int nparams = 0;
-	  const char *p1 = p;
-
-	  /* Obtain a worst case guess for the number of arguments
-	     by counting the semicolons.  */
-	  while (*p1)
-	    {
-	      if (*p1++ == ';')
-		nsemi++;
-	    }
-
-	  /* Allocate parameter information fields and fill them in.  */
-	  ftype->alloc_fields (nsemi);
-	  while (*p++ == ';')
-	    {
-	      struct type *ptype;
-
-	      /* A type number of zero indicates the start of varargs.
-		 FIXME: GDB currently ignores vararg functions.  */
-	      if (p[0] == '0' && p[1] == '\0')
-		break;
-	      ptype = read_type (&p, objfile);
-
-	      /* The Sun compilers mark integer arguments, which should
-		 be promoted to the width of the calling conventions, with
-		 a type which references itself.  This type is turned into
-		 a TYPE_CODE_VOID type by read_type, and we have to turn
-		 it back into builtin_int here.
-		 FIXME: Do we need a new builtin_promoted_int_arg ?  */
-	      if (ptype->code () == TYPE_CODE_VOID)
-		ptype = builtin_type (objfile)->builtin_int;
-	      ftype->field (nparams).set_type (ptype);
-	      ftype->field (nparams).set_is_artificial (false);
-	      nparams++;
-	    }
-	  ftype->set_num_fields (nparams);
-	  ftype->set_is_prototyped (true);
-	}
-      break;
-
-    case 'F':
-      /* A global function definition.  */
-      sym->set_type (read_type (&p, objfile));
-      sym->set_loc_class_index (LOC_BLOCK);
-      sym->set_domain (FUNCTION_DOMAIN);
-      add_symbol_to_list (sym, get_global_symbols ());
-      goto process_function_types;
-
-    case 'G':
-      /* For a class G (global) symbol, it appears that the
-	 value is not correct.  It is necessary to search for the
-	 corresponding linker definition to find the value.
-	 These definitions appear at the end of the namelist.  */
-      sym->set_type (read_type (&p, objfile));
-      sym->set_loc_class_index (LOC_STATIC);
-      sym->set_domain (VAR_DOMAIN);
-      /* Don't add symbol references to global_sym_chain.
-	 Symbol references don't have valid names and won't match up with
-	 minimal symbols when the global_sym_chain is relocated.
-	 We'll fixup symbol references when we fixup the defining symbol.  */
-      if (sym->linkage_name () && sym->linkage_name ()[0] != '#')
-	{
-	  i = hashname (sym->linkage_name ());
-	  sym->set_value_chain (global_sym_chain[i]);
-	  global_sym_chain[i] = sym;
-	}
-      add_symbol_to_list (sym, get_global_symbols ());
-      break;
-
-      /* This case is faked by a conditional above,
-	 when there is no code letter in the dbx data.
-	 Dbx data never actually contains 'l'.  */
-    case 's':
-    case 'l':
-      sym->set_type (read_type (&p, objfile));
-      sym->set_loc_class_index (LOC_LOCAL);
-      sym->set_value_longest (valu);
-      sym->set_domain (VAR_DOMAIN);
-      add_symbol_to_list (sym, get_local_symbols ());
-      break;
-
-    case 'p':
-      if (*p == 'F')
-	/* pF is a two-letter code that means a function parameter in Fortran.
-	   The type-number specifies the type of the return value.
-	   Translate it into a pointer-to-function type.  */
-	{
-	  p++;
-	  sym->set_type
-	    (lookup_pointer_type
-	       (lookup_function_type (read_type (&p, objfile))));
-	}
-      else
-	sym->set_type (read_type (&p, objfile));
-
-      sym->set_loc_class_index (LOC_ARG);
-      sym->set_value_longest (valu);
-      sym->set_domain (VAR_DOMAIN);
-      sym->set_is_argument (1);
-      add_symbol_to_list (sym, get_local_symbols ());
-
-      if (gdbarch_byte_order (gdbarch) != BFD_ENDIAN_BIG)
-	{
-	  /* On little-endian machines, this crud is never necessary,
-	     and, if the extra bytes contain garbage, is harmful.  */
-	  break;
-	}
-
-      /* If it's gcc-compiled, if it says `short', believe it.  */
-      if (processing_gcc_compilation
-	  || gdbarch_believe_pcc_promotion (gdbarch))
-	break;
-
-      if (!gdbarch_believe_pcc_promotion (gdbarch))
-	{
-	  /* If PCC says a parameter is a short or a char, it is
-	     really an int.  */
-	  if (sym->type ()->length ()
-	      < gdbarch_int_bit (gdbarch) / TARGET_CHAR_BIT
-	      && sym->type ()->code () == TYPE_CODE_INT)
-	    {
-	      sym->set_type
-		(sym->type ()->is_unsigned ()
-		 ? builtin_type (objfile)->builtin_unsigned_int
-		 : builtin_type (objfile)->builtin_int);
-	    }
-	  break;
-	}
-      [[fallthrough]];
-
-    case 'P':
-      /* acc seems to use P to declare the prototypes of functions that
-	 are referenced by this file.  gdb is not prepared to deal
-	 with this extra information.  FIXME, it ought to.  */
-      if (type == N_FUN)
-	{
-	  sym->set_type (read_type (&p, objfile));
-	  goto process_prototype_types;
-	}
-      [[fallthrough]];
-
-    case 'R':
-      /* Parameter which is in a register.  */
-      sym->set_type (read_type (&p, objfile));
-      sym->set_loc_class_index (stab_register_index);
-      sym->set_is_argument (1);
-      sym->set_value_longest (valu);
-      sym->set_domain (VAR_DOMAIN);
-      add_symbol_to_list (sym, get_local_symbols ());
-      break;
-
-    case 'r':
-      /* Register variable (either global or local).  */
-      sym->set_type (read_type (&p, objfile));
-      sym->set_loc_class_index (stab_register_index);
-      sym->set_value_longest (valu);
-      sym->set_domain (VAR_DOMAIN);
-      if (within_function)
-	{
-	  /* Sun cc uses a pair of symbols, one 'p' and one 'r', with
-	     the same name to represent an argument passed in a
-	     register.  GCC uses 'P' for the same case.  So if we find
-	     such a symbol pair we combine it into one 'P' symbol.
-	     For Sun cc we need to do this regardless of stabs_argument_has_addr, because the compiler puts out
-	     the 'p' symbol even if it never saves the argument onto
-	     the stack.
-
-	     On most machines, we want to preserve both symbols, so
-	     that we can still get information about what is going on
-	     with the stack (VAX for computing args_printed, using
-	     stack slots instead of saved registers in backtraces,
-	     etc.).
-
-	     Note that this code illegally combines
-	     main(argc) struct foo argc; { register struct foo argc; }
-	     but this case is considered pathological and causes a warning
-	     from a decent compiler.  */
-
-	  struct pending *local_symbols = *get_local_symbols ();
-	  if (local_symbols
-	      && local_symbols->nsyms > 0
-	      && gdbarch_stabs_argument_has_addr (gdbarch, sym->type ()))
-	    {
-	      struct symbol *prev_sym;
-
-	      prev_sym = local_symbols->symbol[local_symbols->nsyms - 1];
-	      if ((prev_sym->loc_class () == LOC_REF_ARG
-		   || prev_sym->loc_class () == LOC_ARG)
-		  && strcmp (prev_sym->linkage_name (),
-			     sym->linkage_name ()) == 0)
-		{
-		  prev_sym->set_loc_class_index (stab_register_index);
-		  /* Use the type from the LOC_REGISTER; that is the type
-		     that is actually in that register.  */
-		  prev_sym->set_type (sym->type ());
-		  prev_sym->set_value_longest (sym->value_longest ());
-		  sym = prev_sym;
-		  break;
-		}
-	    }
-	  add_symbol_to_list (sym, get_local_symbols ());
-	}
-      else
-	add_symbol_to_list (sym, get_file_symbols ());
-      break;
-
-    case 'S':
-      /* Static symbol at top level of file.  */
-      sym->set_type (read_type (&p, objfile));
-      sym->set_loc_class_index (LOC_STATIC);
-      sym->set_value_address (valu);
-      sym->set_domain (VAR_DOMAIN);
-      add_symbol_to_list (sym, get_file_symbols ());
-      break;
-
-    case 't':
-      /* In Ada, there is no distinction between typedef and non-typedef;
-	 any type declaration implicitly has the equivalent of a typedef,
-	 and thus 't' is in fact equivalent to 'Tt'.
-
-	 Therefore, for Ada units, we check the character immediately
-	 before the 't', and if we do not find a 'T', then make sure to
-	 create the associated symbol in the STRUCT_DOMAIN ('t' definitions
-	 will be stored in the VAR_DOMAIN).  If the symbol was indeed
-	 defined as 'Tt' then the STRUCT_DOMAIN symbol will be created
-	 elsewhere, so we don't need to take care of that.
-	 
-	 This is important to do, because of forward references:
-	 The cleanup of undefined types stored in undef_types only uses
-	 STRUCT_DOMAIN symbols to perform the replacement.  */
-      synonym = (sym->language () == language_ada && p[-2] != 'T');
-
-      /* Typedef */
-      sym->set_type (read_type (&p, objfile));
-
-      /* For a nameless type, we don't want a create a symbol, thus we
-	 did not use `sym'.  Return without further processing.  */
-      if (nameless)
-	return NULL;
-
-      sym->set_loc_class_index (LOC_TYPEDEF);
-      sym->set_value_longest (valu);
-      sym->set_domain (TYPE_DOMAIN);
-      /* C++ vagaries: we may have a type which is derived from
-	 a base type which did not have its name defined when the
-	 derived class was output.  We fill in the derived class's
-	 base part member's name here in that case.  */
-      if (sym->type ()->name () != NULL)
-	if ((sym->type ()->code () == TYPE_CODE_STRUCT
-	     || sym->type ()->code () == TYPE_CODE_UNION)
-	    && TYPE_N_BASECLASSES (sym->type ()))
-	  {
-	    int j;
-
-	    for (j = TYPE_N_BASECLASSES (sym->type ()) - 1; j >= 0; j--)
-	      if (TYPE_BASECLASS_NAME (sym->type (), j) == 0)
-		sym->type ()->field (j).set_name
-		  (TYPE_BASECLASS (sym->type (), j)->name ());
-	  }
-
-      if (sym->type ()->name () == NULL)
-	{
-	  if ((sym->type ()->code () == TYPE_CODE_PTR
-	       && strcmp (sym->linkage_name (), vtbl_ptr_name))
-	      || sym->type ()->code () == TYPE_CODE_FUNC)
-	    {
-	      /* If we are giving a name to a type such as "pointer to
-		 foo" or "function returning foo", we better not set
-		 the TYPE_NAME.  If the program contains "typedef char
-		 *caddr_t;", we don't want all variables of type char
-		 * to print as caddr_t.  This is not just a
-		 consequence of GDB's type management; PCC and GCC (at
-		 least through version 2.4) both output variables of
-		 either type char * or caddr_t with the type number
-		 defined in the 't' symbol for caddr_t.  If a future
-		 compiler cleans this up it GDB is not ready for it
-		 yet, but if it becomes ready we somehow need to
-		 disable this check (without breaking the PCC/GCC2.4
-		 case).
-
-		 Sigh.
-
-		 Fortunately, this check seems not to be necessary
-		 for anything except pointers or functions.  */
-	      /* ezannoni: 2000-10-26.  This seems to apply for
-		 versions of gcc older than 2.8.  This was the original
-		 problem: with the following code gdb would tell that
-		 the type for name1 is caddr_t, and func is char().
-
-		 typedef char *caddr_t;
-		 char *name2;
-		 struct x
-		 {
-		   char *name1;
-		 } xx;
-		 char *func()
-		 {
-		 }
-		 main () {}
-		 */
-
-	      /* Pascal accepts names for pointer types.  */
-	      if (get_current_subfile ()->language == language_pascal)
-		sym->type ()->set_name (sym->linkage_name ());
-	    }
-	  else
-	    sym->type ()->set_name (sym->linkage_name ());
-	}
-
-      add_symbol_to_list (sym, get_file_symbols ());
-
-      if (synonym)
-	{
-	  /* Create the STRUCT_DOMAIN clone.  */
-	  struct symbol *struct_sym = new (&objfile->objfile_obstack) symbol;
-
-	  *struct_sym = *sym;
-	  struct_sym->set_loc_class_index (LOC_TYPEDEF);
-	  struct_sym->set_value_longest (valu);
-	  struct_sym->set_domain (STRUCT_DOMAIN);
-	  if (sym->type ()->name () == 0)
-	    sym->type ()->set_name
-	      (obconcat (&objfile->objfile_obstack, sym->linkage_name (),
-			 (char *) NULL));
-	  add_symbol_to_list (struct_sym, get_file_symbols ());
-	}
-
-      break;
-
-    case 'T':
-      /* Struct, union, or enum tag.  For GNU C++, this can be be followed
-	 by 't' which means we are typedef'ing it as well.  */
-      synonym = *p == 't';
-
-      if (synonym)
-	p++;
-
-      sym->set_type (read_type (&p, objfile));
- 
-      /* For a nameless type, we don't want a create a symbol, thus we
-	 did not use `sym'.  Return without further processing.  */
-      if (nameless)
-	return NULL;
-
-      sym->set_loc_class_index (LOC_TYPEDEF);
-      sym->set_value_longest (valu);
-      sym->set_domain (STRUCT_DOMAIN);
-      if (sym->type ()->name () == 0)
-	sym->type ()->set_name
-	  (obconcat (&objfile->objfile_obstack, sym->linkage_name (),
-		     (char *) NULL));
-      add_symbol_to_list (sym, get_file_symbols ());
-
-      if (synonym)
-	{
-	  /* Clone the sym and then modify it.  */
-	  struct symbol *typedef_sym = new (&objfile->objfile_obstack) symbol;
-
-	  *typedef_sym = *sym;
-	  typedef_sym->set_loc_class_index (LOC_TYPEDEF);
-	  typedef_sym->set_value_longest (valu);
-	  typedef_sym->set_domain (TYPE_DOMAIN);
-	  if (sym->type ()->name () == 0)
-	    sym->type ()->set_name
-	      (obconcat (&objfile->objfile_obstack, sym->linkage_name (),
-			 (char *) NULL));
-	  add_symbol_to_list (typedef_sym, get_file_symbols ());
-	}
-      break;
-
-    case 'V':
-      /* Static symbol of local scope.  */
-      sym->set_type (read_type (&p, objfile));
-      sym->set_loc_class_index (LOC_STATIC);
-      sym->set_value_address (valu);
-      sym->set_domain (VAR_DOMAIN);
-      add_symbol_to_list (sym, get_local_symbols ());
-      break;
-
-    case 'v':
-      /* Reference parameter */
-      sym->set_type (read_type (&p, objfile));
-      sym->set_loc_class_index (LOC_REF_ARG);
-      sym->set_is_argument (1);
-      sym->set_value_longest (valu);
-      sym->set_domain (VAR_DOMAIN);
-      add_symbol_to_list (sym, get_local_symbols ());
-      break;
-
-    case 'a':
-      /* Reference parameter which is in a register.  */
-      sym->set_type (read_type (&p, objfile));
-      sym->set_loc_class_index (stab_regparm_index);
-      sym->set_is_argument (1);
-      sym->set_value_longest (valu);
-      sym->set_domain (VAR_DOMAIN);
-      add_symbol_to_list (sym, get_local_symbols ());
-      break;
-
-    case 'X':
-      /* This is used by Sun FORTRAN for "function result value".
-	 Sun claims ("dbx and dbxtool interfaces", 2nd ed)
-	 that Pascal uses it too, but when I tried it Pascal used
-	 "x:3" (local symbol) instead.  */
-      sym->set_type (read_type (&p, objfile));
-      sym->set_loc_class_index (LOC_LOCAL);
-      sym->set_value_longest (valu);
-      sym->set_domain (VAR_DOMAIN);
-      add_symbol_to_list (sym, get_local_symbols ());
-      break;
-
-    default:
-      sym->set_type (error_type (&p, objfile));
-      sym->set_loc_class_index (LOC_CONST);
-      sym->set_value_longest (0);
-      sym->set_domain (VAR_DOMAIN);
-      add_symbol_to_list (sym, get_file_symbols ());
-      break;
-    }
-
-  /* Some systems pass variables of certain types by reference instead
-     of by value, i.e. they will pass the address of a structure (in a
-     register or on the stack) instead of the structure itself.  */
-
-  if (gdbarch_stabs_argument_has_addr (gdbarch, sym->type ())
-      && sym->is_argument ())
-    {
-      /* We have to convert LOC_REGISTER to LOC_REGPARM_ADDR (for
-	 variables passed in a register).  */
-      if (sym->loc_class () == LOC_REGISTER)
-	sym->set_loc_class_index (LOC_REGPARM_ADDR);
-      /* Likewise for converting LOC_ARG to LOC_REF_ARG (for the 7th
-	 and subsequent arguments on SPARC, for example).  */
-      else if (sym->loc_class () == LOC_ARG)
-	sym->set_loc_class_index (LOC_REF_ARG);
-    }
-
-  return sym;
-}
-
-/* Skip rest of this symbol and return an error type.
-
-   General notes on error recovery:  error_type always skips to the
-   end of the symbol (modulo cretinous dbx symbol name continuation).
-   Thus code like this:
-
-   if (*(*pp)++ != ';')
-   return error_type (pp, objfile);
-
-   is wrong because if *pp starts out pointing at '\0' (typically as the
-   result of an earlier error), it will be incremented to point to the
-   start of the next symbol, which might produce strange results, at least
-   if you run off the end of the string table.  Instead use
-
-   if (**pp != ';')
-   return error_type (pp, objfile);
-   ++*pp;
-
-   or
-
-   if (**pp != ';')
-   foo = error_type (pp, objfile);
-   else
-   ++*pp;
-
-   And in case it isn't obvious, the point of all this hair is so the compiler
-   can define new types and new syntaxes, and old versions of the
-   debugger will be able to read the new symbol tables.  */
-
-static struct type *
-error_type (const char **pp, struct objfile *objfile)
-{
-  complaint (_("couldn't parse type; debugger out of date?"));
-  while (1)
-    {
-      /* Skip to end of symbol.  */
-      while (**pp != '\0')
-	{
-	  (*pp)++;
-	}
-
-      /* Check for and handle cretinous dbx symbol name continuation!  */
-      if ((*pp)[-1] == '\\' || (*pp)[-1] == '?')
-	{
-	  *pp = next_symbol_text (objfile);
-	}
-      else
-	{
-	  break;
-	}
-    }
-  return builtin_type (objfile)->builtin_error;
-}
-\f
-
-/* Allocate a stub method whose return type is TYPE.  This apparently
-   happens for speed of symbol reading, since parsing out the
-   arguments to the method is cpu-intensive, the way we are doing it.
-   So, we will fill in arguments later.  This always returns a fresh
-   type.  */
-
-static struct type *
-allocate_stub_method (struct type *type)
-{
-  struct type *mtype;
-
-  mtype = type_allocator (type).new_type ();
-  mtype->set_code (TYPE_CODE_METHOD);
-  mtype->set_length (1);
-  mtype->set_is_stub (true);
-  mtype->set_target_type (type);
-  /* TYPE_SELF_TYPE (mtype) = unknown yet */
-  return mtype;
-}
-
-/* Read type information or a type definition; return the type.  Even
-   though this routine accepts either type information or a type
-   definition, the distinction is relevant--some parts of stabsread.c
-   assume that type information starts with a digit, '-', or '(' in
-   deciding whether to call read_type.  */
-
-static struct type *
-read_type (const char **pp, struct objfile *objfile)
-{
-  struct type *type = 0;
-  struct type *type1;
-  int typenums[2];
-  char type_descriptor;
-
-  /* Size in bits of type if specified by a type attribute, or -1 if
-     there is no size attribute.  */
-  int type_size = -1;
-
-  /* Used to distinguish string and bitstring from char-array and set.  */
-  int is_string = 0;
-
-  /* Used to distinguish vector from array.  */
-  int is_vector = 0;
-
-  /* Read type number if present.  The type number may be omitted.
-     for instance in a two-dimensional array declared with type
-     "ar1;1;10;ar1;1;10;4".  */
-  if ((**pp >= '0' && **pp <= '9')
-      || **pp == '('
-      || **pp == '-')
-    {
-      if (read_type_number (pp, typenums) != 0)
-	return error_type (pp, objfile);
-
-      if (**pp != '=')
-	{
-	  /* Type is not being defined here.  Either it already
-	     exists, or this is a forward reference to it.
-	     dbx_alloc_type handles both cases.  */
-	  type = dbx_alloc_type (typenums, objfile);
-
-	  /* If this is a forward reference, arrange to complain if it
-	     doesn't get patched up by the time we're done
-	     reading.  */
-	  if (type->code () == TYPE_CODE_UNDEF)
-	    add_undefined_type (type, typenums);
-
-	  return type;
-	}
-
-      /* Type is being defined here.  */
-      /* Skip the '='.
-	 Also skip the type descriptor - we get it below with (*pp)[-1].  */
-      (*pp) += 2;
-    }
-  else
-    {
-      /* 'typenums=' not present, type is anonymous.  Read and return
-	 the definition, but don't put it in the type vector.  */
-      typenums[0] = typenums[1] = -1;
-      (*pp)++;
-    }
-
-again:
-  type_descriptor = (*pp)[-1];
-  switch (type_descriptor)
-    {
-    case 'x':
-      {
-	enum type_code code;
-
-	/* Used to index through file_symbols.  */
-	struct pending *ppt;
-	int i;
-
-	/* Name including "struct", etc.  */
-	char *type_name;
-
-	{
-	  const char *from, *p, *q1, *q2;
-
-	  /* Set the type code according to the following letter.  */
-	  switch ((*pp)[0])
-	    {
-	    case 's':
-	      code = TYPE_CODE_STRUCT;
-	      break;
-	    case 'u':
-	      code = TYPE_CODE_UNION;
-	      break;
-	    case 'e':
-	      code = TYPE_CODE_ENUM;
-	      break;
-	    default:
-	      {
-		/* Complain and keep going, so compilers can invent new
-		   cross-reference types.  */
-		complaint (_("Unrecognized cross-reference type `%c'"),
-			   (*pp)[0]);
-		code = TYPE_CODE_STRUCT;
-		break;
-	      }
-	    }
-
-	  q1 = strchr (*pp, '<');
-	  p = strchr (*pp, ':');
-	  if (p == NULL)
-	    return error_type (pp, objfile);
-	  if (q1 && p > q1 && p[1] == ':')
-	    {
-	      int nesting_level = 0;
-
-	      for (q2 = q1; *q2; q2++)
-		{
-		  if (*q2 == '<')
-		    nesting_level++;
-		  else if (*q2 == '>')
-		    nesting_level--;
-		  else if (*q2 == ':' && nesting_level == 0)
-		    break;
-		}
-	      p = q2;
-	      if (*p != ':')
-		return error_type (pp, objfile);
-	    }
-	  type_name = NULL;
-	  if (get_current_subfile ()->language == language_cplus)
-	    {
-	      std::string name (*pp, p - *pp);
-	      gdb::unique_xmalloc_ptr<char> new_name
-		= cp_canonicalize_string (name.c_str ());
-	      if (new_name != nullptr)
-		type_name = obstack_strdup (&objfile->objfile_obstack,
-					    new_name.get ());
-	    }
-	  else if (get_current_subfile ()->language == language_c)
-	    {
-	      std::string name (*pp, p - *pp);
-	      gdb::unique_xmalloc_ptr<char> new_name
-		= c_canonicalize_name (name.c_str ());
-	      if (new_name != nullptr)
-		type_name = obstack_strdup (&objfile->objfile_obstack,
-					    new_name.get ());
-	    }
-	  if (type_name == NULL)
-	    {
-	      char *to = type_name = (char *)
-		obstack_alloc (&objfile->objfile_obstack, p - *pp + 1);
-
-	      /* Copy the name.  */
-	      from = *pp + 1;
-	      while (from < p)
-		*to++ = *from++;
-	      *to = '\0';
-	    }
-
-	  /* Set the pointer ahead of the name which we just read, and
-	     the colon.  */
-	  *pp = p + 1;
-	}
-
-	/* If this type has already been declared, then reuse the same
-	   type, rather than allocating a new one.  This saves some
-	   memory.  */
-
-	for (ppt = *get_file_symbols (); ppt; ppt = ppt->next)
-	  for (i = 0; i < ppt->nsyms; i++)
-	    {
-	      struct symbol *sym = ppt->symbol[i];
-
-	      if (sym->loc_class () == LOC_TYPEDEF
-		  && sym->domain () == STRUCT_DOMAIN
-		  && (sym->type ()->code () == code)
-		  && strcmp (sym->linkage_name (), type_name) == 0)
-		{
-		  obstack_free (&objfile->objfile_obstack, type_name);
-		  type = sym->type ();
-		  if (typenums[0] != -1)
-		    *dbx_lookup_type (typenums, objfile) = type;
-		  return type;
-		}
-	    }
-
-	/* Didn't find the type to which this refers, so we must
-	   be dealing with a forward reference.  Allocate a type
-	   structure for it, and keep track of it so we can
-	   fill in the rest of the fields when we get the full
-	   type.  */
-	type = dbx_alloc_type (typenums, objfile);
-	type->set_code (code);
-	type->set_name (type_name);
-	INIT_CPLUS_SPECIFIC (type);
-	type->set_is_stub (true);
-
-	add_undefined_type (type, typenums);
-	return type;
-      }
-
-    case '-':			/* RS/6000 built-in type */
-    case '0':
-    case '1':
-    case '2':
-    case '3':
-    case '4':
-    case '5':
-    case '6':
-    case '7':
-    case '8':
-    case '9':
-    case '(':
-      (*pp)--;
-
-      /* We deal with something like t(1,2)=(3,4)=... which
-	 the Lucid compiler and recent gcc versions (post 2.7.3) use.  */
-
-      /* Allocate and enter the typedef type first.
-	 This handles recursive types.  */
-      type = dbx_alloc_type (typenums, objfile);
-      type->set_code (TYPE_CODE_TYPEDEF);
-      {
-	struct type *xtype = read_type (pp, objfile);
-
-	if (type == xtype)
-	  {
-	    /* It's being defined as itself.  That means it is "void".  */
-	    type->set_code (TYPE_CODE_VOID);
-	    type->set_length (1);
-	  }
-	else if (type_size >= 0 || is_string)
-	  {
-	    /* This is the absolute wrong way to construct types.  Every
-	       other debug format has found a way around this problem and
-	       the related problems with unnecessarily stubbed types;
-	       someone motivated should attempt to clean up the issue
-	       here as well.  Once a type pointed to has been created it
-	       should not be modified.
-
-	       Well, it's not *absolutely* wrong.  Constructing recursive
-	       types (trees, linked lists) necessarily entails modifying
-	       types after creating them.  Constructing any loop structure
-	       entails side effects.  The Dwarf 2 reader does handle this
-	       more gracefully (it never constructs more than once
-	       instance of a type object, so it doesn't have to copy type
-	       objects wholesale), but it still mutates type objects after
-	       other folks have references to them.
-
-	       Keep in mind that this circularity/mutation issue shows up
-	       at the source language level, too: C's "incomplete types",
-	       for example.  So the proper cleanup, I think, would be to
-	       limit GDB's type smashing to match exactly those required
-	       by the source language.  So GDB could have a
-	       "complete_this_type" function, but never create unnecessary
-	       copies of a type otherwise.  */
-	    replace_type (type, xtype);
-	    type->set_name (NULL);
-	  }
-	else
-	  {
-	    type->set_target_is_stub (true);
-	    type->set_target_type (xtype);
-	  }
-      }
-      break;
-
-      /* In the following types, we must be sure to overwrite any existing
-	 type that the typenums refer to, rather than allocating a new one
-	 and making the typenums point to the new one.  This is because there
-	 may already be pointers to the existing type (if it had been
-	 forward-referenced), and we must change it to a pointer, function,
-	 reference, or whatever, *in-place*.  */
-
-    case '*':			/* Pointer to another type */
-      type1 = read_type (pp, objfile);
-      type = make_pointer_type (type1, dbx_lookup_type (typenums, objfile));
-      break;
-
-    case '&':			/* Reference to another type */
-      type1 = read_type (pp, objfile);
-      type = make_reference_type (type1, dbx_lookup_type (typenums, objfile),
-				  TYPE_CODE_REF);
-      break;
-
-    case 'f':			/* Function returning another type */
-      type1 = read_type (pp, objfile);
-      type = make_function_type (type1, dbx_lookup_type (typenums, objfile));
-      break;
-
-    case 'g':                   /* Prototyped function.  (Sun)  */
-      {
-	/* Unresolved questions:
-
-	   - According to Sun's ``STABS Interface Manual'', for 'f'
-	   and 'F' symbol descriptors, a `0' in the argument type list
-	   indicates a varargs function.  But it doesn't say how 'g'
-	   type descriptors represent that info.  Someone with access
-	   to Sun's toolchain should try it out.
-
-	   - According to the comment in define_symbol (search for
-	   `process_prototype_types:'), Sun emits integer arguments as
-	   types which ref themselves --- like `void' types.  Do we
-	   have to deal with that here, too?  Again, someone with
-	   access to Sun's toolchain should try it out and let us
-	   know.  */
-
-	const char *type_start = (*pp) - 1;
-	struct type *return_type = read_type (pp, objfile);
-	struct type *func_type
-	  = make_function_type (return_type,
-				dbx_lookup_type (typenums, objfile));
-	struct type_list {
-	  struct type *type;
-	  struct type_list *next;
-	} *arg_types = 0;
-	int num_args = 0;
-
-	while (**pp && **pp != '#')
-	  {
-	    struct type *arg_type = read_type (pp, objfile);
-	    struct type_list *newobj = XALLOCA (struct type_list);
-	    newobj->type = arg_type;
-	    newobj->next = arg_types;
-	    arg_types = newobj;
-	    num_args++;
-	  }
-	if (**pp == '#')
-	  ++*pp;
-	else
-	  {
-	    complaint (_("Prototyped function type didn't "
-			 "end arguments with `#':\n%s"),
-		       type_start);
-	  }
-
-	/* If there is just one argument whose type is `void', then
-	   that's just an empty argument list.  */
-	if (arg_types
-	    && ! arg_types->next
-	    && arg_types->type->code () == TYPE_CODE_VOID)
-	  num_args = 0;
-
-	func_type->alloc_fields (num_args);
-	{
-	  int i;
-	  struct type_list *t;
-
-	  /* We stuck each argument type onto the front of the list
-	     when we read it, so the list is reversed.  Build the
-	     fields array right-to-left.  */
-	  for (t = arg_types, i = num_args - 1; t; t = t->next, i--)
-	    func_type->field (i).set_type (t->type);
-	}
-	func_type->set_num_fields (num_args);
-	func_type->set_is_prototyped (true);
-
-	type = func_type;
-	break;
-      }
-
-    case 'k':			/* Const qualifier on some type (Sun) */
-      type = read_type (pp, objfile);
-      type = make_cv_type (1, TYPE_VOLATILE (type), type,
-			   dbx_lookup_type (typenums, objfile));
-      break;
-
-    case 'B':			/* Volatile qual on some type (Sun) */
-      type = read_type (pp, objfile);
-      type = make_cv_type (TYPE_CONST (type), 1, type,
-			   dbx_lookup_type (typenums, objfile));
-      break;
-
-    case '@':
-      if (c_isdigit (**pp) || **pp == '(' || **pp == '-')
-	{			/* Member (class & variable) type */
-	  /* FIXME -- we should be doing smash_to_XXX types here.  */
-
-	  struct type *domain = read_type (pp, objfile);
-	  struct type *memtype;
-
-	  if (**pp != ',')
-	    /* Invalid member type data format.  */
-	    return error_type (pp, objfile);
-	  ++*pp;
-
-	  memtype = read_type (pp, objfile);
-	  type = dbx_alloc_type (typenums, objfile);
-	  smash_to_memberptr_type (type, domain, memtype);
-	}
-      else
-	/* type attribute */
-	{
-	  const char *attr = *pp;
-
-	  /* Skip to the semicolon.  */
-	  while (**pp != ';' && **pp != '\0')
-	    ++(*pp);
-	  if (**pp == '\0')
-	    return error_type (pp, objfile);
-	  else
-	    ++ * pp;		/* Skip the semicolon.  */
-
-	  switch (*attr)
-	    {
-	    case 's':		/* Size attribute */
-	      type_size = atoi (attr + 1);
-	      if (type_size <= 0)
-		type_size = -1;
-	      break;
-
-	    case 'S':		/* String attribute */
-	      /* FIXME: check to see if following type is array?  */
-	      is_string = 1;
-	      break;
-
-	    case 'V':		/* Vector attribute */
-	      /* FIXME: check to see if following type is array?  */
-	      is_vector = 1;
-	      break;
-
-	    default:
-	      /* Ignore unrecognized type attributes, so future compilers
-		 can invent new ones.  */
-	      break;
-	    }
-	  ++*pp;
-	  goto again;
-	}
-      break;
-
-    case '#':			/* Method (class & fn) type */
-      if ((*pp)[0] == '#')
-	{
-	  /* We'll get the parameter types from the name.  */
-	  struct type *return_type;
-
-	  (*pp)++;
-	  return_type = read_type (pp, objfile);
-	  if (*(*pp)++ != ';')
-	    complaint (_("invalid (minimal) member type "
-			 "data format at symtab pos %d."),
-		       symnum);
-	  type = allocate_stub_method (return_type);
-	  if (typenums[0] != -1)
-	    *dbx_lookup_type (typenums, objfile) = type;
-	}
-      else
-	{
-	  struct type *domain = read_type (pp, objfile);
-	  struct type *return_type;
-	  struct field *args;
-	  int nargs, varargs;
-
-	  if (**pp != ',')
-	    /* Invalid member type data format.  */
-	    return error_type (pp, objfile);
-	  else
-	    ++(*pp);
-
-	  return_type = read_type (pp, objfile);
-	  args = read_args (pp, ';', objfile, &nargs, &varargs);
-	  if (args == NULL)
-	    return error_type (pp, objfile);
-	  type = dbx_alloc_type (typenums, objfile);
-	  smash_to_method_type (type, domain, return_type,
-				gdb::make_array_view (args, nargs),
-				varargs);
-	}
-      break;
-
-    case 'r':			/* Range type */
-      type = read_range_type (pp, typenums, type_size, objfile);
-      if (typenums[0] != -1)
-	*dbx_lookup_type (typenums, objfile) = type;
-      break;
-
-    case 'b':
-	{
-	  /* Sun ACC builtin int type */
-	  type = read_sun_builtin_type (pp, typenums, objfile);
-	  if (typenums[0] != -1)
-	    *dbx_lookup_type (typenums, objfile) = type;
-	}
-      break;
-
-    case 'R':			/* Sun ACC builtin float type */
-      type = read_sun_floating_type (pp, typenums, objfile);
-      if (typenums[0] != -1)
-	*dbx_lookup_type (typenums, objfile) = type;
-      break;
-
-    case 'e':			/* Enumeration type */
-      type = dbx_alloc_type (typenums, objfile);
-      type = read_enum_type (pp, type, objfile);
-      if (typenums[0] != -1)
-	*dbx_lookup_type (typenums, objfile) = type;
-      break;
-
-    case 's':			/* Struct type */
-    case 'u':			/* Union type */
-      {
-	enum type_code type_code = TYPE_CODE_UNDEF;
-	type = dbx_alloc_type (typenums, objfile);
-	switch (type_descriptor)
-	  {
-	  case 's':
-	    type_code = TYPE_CODE_STRUCT;
-	    break;
-	  case 'u':
-	    type_code = TYPE_CODE_UNION;
-	    break;
-	  }
-	type = read_struct_type (pp, type, type_code, objfile);
-	break;
-      }
-
-    case 'a':			/* Array type */
-      if (**pp != 'r')
-	return error_type (pp, objfile);
-      ++*pp;
-
-      type = dbx_alloc_type (typenums, objfile);
-      type = read_array_type (pp, type, objfile);
-      if (is_string)
-	type->set_code (TYPE_CODE_STRING);
-      if (is_vector)
-	make_vector_type (type);
-      break;
-
-    case 'S':			/* Set type */
-      {
-	type1 = read_type (pp, objfile);
-	type_allocator alloc (objfile, get_current_subfile ()->language);
-	type = create_set_type (alloc, type1);
-	if (typenums[0] != -1)
-	  *dbx_lookup_type (typenums, objfile) = type;
-      }
-      break;
-
-    default:
-      --*pp;			/* Go back to the symbol in error.  */
-      /* Particularly important if it was \0!  */
-      return error_type (pp, objfile);
-    }
-
-  if (type == 0)
-    {
-      warning (_("GDB internal error, type is NULL in stabsread.c."));
-      return error_type (pp, objfile);
-    }
-
-  /* Size specified in a type attribute overrides any other size.  */
-  if (type_size != -1)
-    type->set_length ((type_size + TARGET_CHAR_BIT - 1) / TARGET_CHAR_BIT);
-
-  return type;
-}
-\f
-/* RS/6000 xlc/dbx combination uses a set of builtin types, starting from -1.
-   Return the proper type node for a given builtin type number.  */
-
-static const registry<objfile>::key<struct type *,
-				    gdb::noop_deleter<struct type *>>
-  rs6000_builtin_type_data;
-
-static struct type *
-rs6000_builtin_type (int typenum, struct objfile *objfile)
-{
-  struct type **negative_types = rs6000_builtin_type_data.get (objfile);
-
-  /* We recognize types numbered from -NUMBER_RECOGNIZED to -1.  */
-#define NUMBER_RECOGNIZED 34
-  struct type *rettype = NULL;
-
-  if (typenum >= 0 || typenum < -NUMBER_RECOGNIZED)
-    {
-      complaint (_("Unknown builtin type %d"), typenum);
-      return builtin_type (objfile)->builtin_error;
-    }
-
-  if (!negative_types)
-    {
-      /* This includes an empty slot for type number -0.  */
-      negative_types = OBSTACK_CALLOC (&objfile->objfile_obstack,
-				       NUMBER_RECOGNIZED + 1, struct type *);
-      rs6000_builtin_type_data.set (objfile, negative_types);
-    }
-
-  if (negative_types[-typenum] != NULL)
-    return negative_types[-typenum];
-
-#if TARGET_CHAR_BIT != 8
-#error This code wrong for TARGET_CHAR_BIT not 8
-  /* These definitions all assume that TARGET_CHAR_BIT is 8.  I think
-     that if that ever becomes not true, the correct fix will be to
-     make the size in the struct type to be in bits, not in units of
-     TARGET_CHAR_BIT.  */
-#endif
-
-  type_allocator alloc (objfile, get_current_subfile ()->language);
-  switch (-typenum)
-    {
-    case 1:
-      /* The size of this and all the other types are fixed, defined
-	 by the debugging format.  If there is a type called "int" which
-	 is other than 32 bits, then it should use a new negative type
-	 number (or avoid negative type numbers for that case).
-	 See stabs.texinfo.  */
-      rettype = init_integer_type (alloc, 32, 0, "int");
-      break;
-    case 2:
-      rettype = init_integer_type (alloc, 8, 0, "char");
-      rettype->set_has_no_signedness (true);
-      break;
-    case 3:
-      rettype = init_integer_type (alloc, 16, 0, "short");
-      break;
-    case 4:
-      rettype = init_integer_type (alloc, 32, 0, "long");
-      break;
-    case 5:
-      rettype = init_integer_type (alloc, 8, 1, "unsigned char");
-      break;
-    case 6:
-      rettype = init_integer_type (alloc, 8, 0, "signed char");
-      break;
-    case 7:
-      rettype = init_integer_type (alloc, 16, 1, "unsigned short");
-      break;
-    case 8:
-      rettype = init_integer_type (alloc, 32, 1, "unsigned int");
-      break;
-    case 9:
-      rettype = init_integer_type (alloc, 32, 1, "unsigned");
-      break;
-    case 10:
-      rettype = init_integer_type (alloc, 32, 1, "unsigned long");
-      break;
-    case 11:
-      rettype = alloc.new_type (TYPE_CODE_VOID, TARGET_CHAR_BIT, "void");
-      break;
-    case 12:
-      /* IEEE single precision (32 bit).  */
-      rettype = init_float_type (alloc, 32, "float",
-				 floatformats_ieee_single);
-      break;
-    case 13:
-      /* IEEE double precision (64 bit).  */
-      rettype = init_float_type (alloc, 64, "double",
-				 floatformats_ieee_double);
-      break;
-    case 14:
-      /* This is an IEEE double on the RS/6000, and different machines with
-	 different sizes for "long double" should use different negative
-	 type numbers.  See stabs.texinfo.  */
-      rettype = init_float_type (alloc, 64, "long double",
-				 floatformats_ieee_double);
-      break;
-    case 15:
-      rettype = init_integer_type (alloc, 32, 0, "integer");
-      break;
-    case 16:
-      rettype = init_boolean_type (alloc, 32, 1, "boolean");
-      break;
-    case 17:
-      rettype = init_float_type (alloc, 32, "short real",
-				 floatformats_ieee_single);
-      break;
-    case 18:
-      rettype = init_float_type (alloc, 64, "real",
-				 floatformats_ieee_double);
-      break;
-    case 19:
-      rettype = alloc.new_type (TYPE_CODE_ERROR, 0, "stringptr");
-      break;
-    case 20:
-      rettype = init_character_type (alloc, 8, 1, "character");
-      break;
-    case 21:
-      rettype = init_boolean_type (alloc, 8, 1, "logical*1");
-      break;
-    case 22:
-      rettype = init_boolean_type (alloc, 16, 1, "logical*2");
-      break;
-    case 23:
-      rettype = init_boolean_type (alloc, 32, 1, "logical*4");
-      break;
-    case 24:
-      rettype = init_boolean_type (alloc, 32, 1, "logical");
-      break;
-    case 25:
-      /* Complex type consisting of two IEEE single precision values.  */
-      rettype = init_complex_type ("complex",
-				   rs6000_builtin_type (12, objfile));
-      break;
-    case 26:
-      /* Complex type consisting of two IEEE double precision values.  */
-      rettype = init_complex_type ("double complex",
-				   rs6000_builtin_type (13, objfile));
-      break;
-    case 27:
-      rettype = init_integer_type (alloc, 8, 0, "integer*1");
-      break;
-    case 28:
-      rettype = init_integer_type (alloc, 16, 0, "integer*2");
-      break;
-    case 29:
-      rettype = init_integer_type (alloc, 32, 0, "integer*4");
-      break;
-    case 30:
-      rettype = init_character_type (alloc, 16, 0, "wchar");
-      break;
-    case 31:
-      rettype = init_integer_type (alloc, 64, 0, "long long");
-      break;
-    case 32:
-      rettype = init_integer_type (alloc, 64, 1, "unsigned long long");
-      break;
-    case 33:
-      rettype = init_integer_type (alloc, 64, 1, "logical*8");
-      break;
-    case 34:
-      rettype = init_integer_type (alloc, 64, 0, "integer*8");
-      break;
-    }
-  negative_types[-typenum] = rettype;
-  return rettype;
-}
-\f
-/* This page contains subroutines of read_type.  */
-
-/* Wrapper around method_name_from_physname to flag a complaint
-   if there is an error.  */
-
-static char *
-stabs_method_name_from_physname (const char *physname)
-{
-  char *method_name;
-
-  method_name = method_name_from_physname (physname);
-
-  if (method_name == NULL)
-    {
-      complaint (_("Method has bad physname %s\n"), physname);
-      return NULL;
-    }
-
-  return method_name;
-}
-
-/* Read member function stabs info for C++ classes.  The form of each member
-   function data is:
-
-   NAME :: TYPENUM[=type definition] ARGS : PHYSNAME ;
-
-   An example with two member functions is:
-
-   afunc1::20=##15;:i;2A.;afunc2::20:i;2A.;
-
-   For the case of overloaded operators, the format is op$::*.funcs, where
-   $ is the CPLUS_MARKER (usually '$'), `*' holds the place for an operator
-   name (such as `+=') and `.' marks the end of the operator name.
-
-   Returns 1 for success, 0 for failure.  */
-
-static int
-read_member_functions (struct stab_field_info *fip, const char **pp,
-		       struct type *type, struct objfile *objfile)
-{
-  int nfn_fields = 0;
-  int length = 0;
-  int i;
-  struct next_fnfield
-    {
-      struct next_fnfield *next;
-      struct fn_field fn_field;
-    }
-   *sublist;
-  struct type *look_ahead_type;
-  struct next_fnfieldlist *new_fnlist;
-  struct next_fnfield *new_sublist;
-  char *main_fn_name;
-  const char *p;
-
-  /* Process each list until we find something that is not a member function
-     or find the end of the functions.  */
-
-  while (**pp != ';')
-    {
-      /* We should be positioned at the start of the function name.
-	 Scan forward to find the first ':' and if it is not the
-	 first of a "::" delimiter, then this is not a member function.  */
-      p = *pp;
-      while (*p != ':')
-	{
-	  p++;
-	}
-      if (p[1] != ':')
-	{
-	  break;
-	}
-
-      sublist = NULL;
-      look_ahead_type = NULL;
-      length = 0;
-
-      new_fnlist = OBSTACK_ZALLOC (&fip->obstack, struct next_fnfieldlist);
-
-      if ((*pp)[0] == 'o' && (*pp)[1] == 'p' && is_cplus_marker ((*pp)[2]))
-	{
-	  /* This is a completely weird case.  In order to stuff in the
-	     names that might contain colons (the usual name delimiter),
-	     Mike Tiemann defined a different name format which is
-	     signalled if the identifier is "op$".  In that case, the
-	     format is "op$::XXXX." where XXXX is the name.  This is
-	     used for names like "+" or "=".  YUUUUUUUK!  FIXME!  */
-	  /* This lets the user type "break operator+".
-	     We could just put in "+" as the name, but that wouldn't
-	     work for "*".  */
-	  static char opname[32] = "op$";
-	  char *o = opname + 3;
-
-	  /* Skip past '::'.  */
-	  *pp = p + 2;
-
-	  STABS_CONTINUE (pp, objfile);
-	  p = *pp;
-	  while (*p != '.')
-	    {
-	      *o++ = *p++;
-	    }
-	  main_fn_name = savestring (opname, o - opname);
-	  /* Skip past '.'  */
-	  *pp = p + 1;
-	}
-      else
-	{
-	  main_fn_name = savestring (*pp, p - *pp);
-	  /* Skip past '::'.  */
-	  *pp = p + 2;
-	}
-      new_fnlist->fn_fieldlist.name = main_fn_name;
-
-      do
-	{
-	  new_sublist = OBSTACK_ZALLOC (&fip->obstack, struct next_fnfield);
-
-	  /* Check for and handle cretinous dbx symbol name continuation!  */
-	  if (look_ahead_type == NULL)
-	    {
-	      /* Normal case.  */
-	      STABS_CONTINUE (pp, objfile);
-
-	      new_sublist->fn_field.type = read_type (pp, objfile);
-	      if (**pp != ':')
-		{
-		  /* Invalid symtab info for member function.  */
-		  return 0;
-		}
-	    }
-	  else
-	    {
-	      /* g++ version 1 kludge */
-	      new_sublist->fn_field.type = look_ahead_type;
-	      look_ahead_type = NULL;
-	    }
-
-	  (*pp)++;
-	  p = *pp;
-	  while (*p != ';')
-	    {
-	      p++;
-	    }
-
-	  /* These are methods, not functions.  */
-	  if (new_sublist->fn_field.type->code () == TYPE_CODE_FUNC)
-	    new_sublist->fn_field.type->set_code (TYPE_CODE_METHOD);
-
-	  /* If this is just a stub, then we don't have the real name here.  */
-	  if (new_sublist->fn_field.type->is_stub ())
-	    {
-	      if (!TYPE_SELF_TYPE (new_sublist->fn_field.type))
-		set_type_self_type (new_sublist->fn_field.type, type);
-	      new_sublist->fn_field.is_stub = 1;
-	    }
-
-	  new_sublist->fn_field.physname = savestring (*pp, p - *pp);
-	  *pp = p + 1;
-
-	  /* Set this member function's visibility fields.  */
-	  switch (*(*pp)++)
-	    {
-	    case VISIBILITY_PRIVATE:
-	      new_sublist->fn_field.accessibility = accessibility::PRIVATE;
-	      break;
-	    case VISIBILITY_PROTECTED:
-	      new_sublist->fn_field.accessibility = accessibility::PROTECTED;
-	      break;
-	    }
-
-	  STABS_CONTINUE (pp, objfile);
-	  switch (**pp)
-	    {
-	    case 'A':		/* Normal functions.  */
-	      new_sublist->fn_field.is_const = 0;
-	      new_sublist->fn_field.is_volatile = 0;
-	      (*pp)++;
-	      break;
-	    case 'B':		/* `const' member functions.  */
-	      new_sublist->fn_field.is_const = 1;
-	      new_sublist->fn_field.is_volatile = 0;
-	      (*pp)++;
-	      break;
-	    case 'C':		/* `volatile' member function.  */
-	      new_sublist->fn_field.is_const = 0;
-	      new_sublist->fn_field.is_volatile = 1;
-	      (*pp)++;
-	      break;
-	    case 'D':		/* `const volatile' member function.  */
-	      new_sublist->fn_field.is_const = 1;
-	      new_sublist->fn_field.is_volatile = 1;
-	      (*pp)++;
-	      break;
-	    case '*':		/* File compiled with g++ version 1 --
-				   no info.  */
-	    case '?':
-	    case '.':
-	      break;
-	    default:
-	      complaint (_("const/volatile indicator missing, got '%c'"),
-			 **pp);
-	      break;
-	    }
-
-	  switch (*(*pp)++)
-	    {
-	    case '*':
-	      {
-		int nbits;
-		/* virtual member function, followed by index.
-		   The sign bit is set to distinguish pointers-to-methods
-		   from virtual function indices.  Since the array is
-		   in words, the quantity must be shifted left by 1
-		   on 16 bit machine, and by 2 on 32 bit machine, forcing
-		   the sign bit out, and usable as a valid index into
-		   the array.  Remove the sign bit here.  */
-		new_sublist->fn_field.voffset =
-		  (0x7fffffff & read_huge_number (pp, ';', &nbits, 0)) + 2;
-		if (nbits != 0)
-		  return 0;
-
-		STABS_CONTINUE (pp, objfile);
-		if (**pp == ';' || **pp == '\0')
-		  {
-		    /* Must be g++ version 1.  */
-		    new_sublist->fn_field.fcontext = 0;
-		  }
-		else
-		  {
-		    /* Figure out from whence this virtual function came.
-		       It may belong to virtual function table of
-		       one of its baseclasses.  */
-		    look_ahead_type = read_type (pp, objfile);
-		    if (**pp == ':')
-		      {
-			/* g++ version 1 overloaded methods.  */
-		      }
-		    else
-		      {
-			new_sublist->fn_field.fcontext = look_ahead_type;
-			if (**pp != ';')
-			  {
-			    return 0;
-			  }
-			else
-			  {
-			    ++*pp;
-			  }
-			look_ahead_type = NULL;
-		      }
-		  }
-		break;
-	      }
-	    case '?':
-	      /* static member function.  */
-	      {
-		int slen = strlen (main_fn_name);
-
-		new_sublist->fn_field.voffset = VOFFSET_STATIC;
-
-		/* For static member functions, we can't tell if they
-		   are stubbed, as they are put out as functions, and not as
-		   methods.
-		   GCC v2 emits the fully mangled name if
-		   dbxout.c:flag_minimal_debug is not set, so we have to
-		   detect a fully mangled physname here and set is_stub
-		   accordingly.  Fully mangled physnames in v2 start with
-		   the member function name, followed by two underscores.
-		   GCC v3 currently always emits stubbed member functions,
-		   but with fully mangled physnames, which start with _Z.  */
-		if (!(strncmp (new_sublist->fn_field.physname,
-			       main_fn_name, slen) == 0
-		      && new_sublist->fn_field.physname[slen] == '_'
-		      && new_sublist->fn_field.physname[slen + 1] == '_'))
-		  {
-		    new_sublist->fn_field.is_stub = 1;
-		  }
-		break;
-	      }
-
-	    default:
-	      /* error */
-	      complaint (_("member function type missing, got '%c'"),
-			 (*pp)[-1]);
-	      /* Normal member function.  */
-	      [[fallthrough]];
-
-	    case '.':
-	      /* normal member function.  */
-	      new_sublist->fn_field.voffset = 0;
-	      new_sublist->fn_field.fcontext = 0;
-	      break;
-	    }
-
-	  new_sublist->next = sublist;
-	  sublist = new_sublist;
-	  length++;
-	  STABS_CONTINUE (pp, objfile);
-	}
-      while (**pp != ';' && **pp != '\0');
-
-      (*pp)++;
-      STABS_CONTINUE (pp, objfile);
-
-      /* Skip GCC 3.X member functions which are duplicates of the callable
-	 constructor/destructor.  */
-      if (strcmp_iw (main_fn_name, "__base_ctor ") == 0
-	  || strcmp_iw (main_fn_name, "__base_dtor ") == 0
-	  || strcmp (main_fn_name, "__deleting_dtor") == 0)
-	{
-	  xfree (main_fn_name);
-	}
-      else
-	{
-	  int has_destructor = 0, has_other = 0;
-	  int is_v3 = 0;
-	  struct next_fnfield *tmp_sublist;
-
-	  /* Various versions of GCC emit various mostly-useless
-	     strings in the name field for special member functions.
-
-	     For stub methods, we need to defer correcting the name
-	     until we are ready to unstub the method, because the current
-	     name string is used by gdb_mangle_name.  The only stub methods
-	     of concern here are GNU v2 operators; other methods have their
-	     names correct (see caveat below).
-
-	     For non-stub methods, in GNU v3, we have a complete physname.
-	     Therefore we can safely correct the name now.  This primarily
-	     affects constructors and destructors, whose name will be
-	     __comp_ctor or __comp_dtor instead of Foo or ~Foo.  Cast
-	     operators will also have incorrect names; for instance,
-	     "operator int" will be named "operator i" (i.e. the type is
-	     mangled).
-
-	     For non-stub methods in GNU v2, we have no easy way to
-	     know if we have a complete physname or not.  For most
-	     methods the result depends on the platform (if CPLUS_MARKER
-	     can be `$' or `.', it will use minimal debug information, or
-	     otherwise the full physname will be included).
-
-	     Rather than dealing with this, we take a different approach.
-	     For v3 mangled names, we can use the full physname; for v2,
-	     we use cplus_demangle_opname (which is actually v2 specific),
-	     because the only interesting names are all operators - once again
-	     barring the caveat below.  Skip this process if any method in the
-	     group is a stub, to prevent our fouling up the workings of
-	     gdb_mangle_name.
-
-	     The caveat: GCC 2.95.x (and earlier?) put constructors and
-	     destructors in the same method group.  We need to split this
-	     into two groups, because they should have different names.
-	     So for each method group we check whether it contains both
-	     routines whose physname appears to be a destructor (the physnames
-	     for and destructors are always provided, due to quirks in v2
-	     mangling) and routines whose physname does not appear to be a
-	     destructor.  If so then we break up the list into two halves.
-	     Even if the constructors and destructors aren't in the same group
-	     the destructor will still lack the leading tilde, so that also
-	     needs to be fixed.
-
-	     So, to summarize what we expect and handle here:
-
-		Given         Given          Real         Real       Action
-	     method name     physname      physname   method name
-
-	     __opi            [none]     __opi__3Foo  operator int    opname
-								 [now or later]
-	     Foo              _._3Foo       _._3Foo      ~Foo      separate and
-								       rename
-	     operator i     _ZN3FoocviEv _ZN3FoocviEv operator int    demangle
-	     __comp_ctor  _ZN3FooC1ERKS_ _ZN3FooC1ERKS_   Foo         demangle
-	  */
-
-	  tmp_sublist = sublist;
-	  while (tmp_sublist != NULL)
-	    {
-	      if (tmp_sublist->fn_field.physname[0] == '_'
-		  && tmp_sublist->fn_field.physname[1] == 'Z')
-		is_v3 = 1;
-
-	      if (is_destructor_name (tmp_sublist->fn_field.physname))
-		has_destructor++;
-	      else
-		has_other++;
-
-	      tmp_sublist = tmp_sublist->next;
-	    }
-
-	  if (has_destructor && has_other)
-	    {
-	      struct next_fnfieldlist *destr_fnlist;
-	      struct next_fnfield *last_sublist;
-
-	      /* Create a new fn_fieldlist for the destructors.  */
-
-	      destr_fnlist = OBSTACK_ZALLOC (&fip->obstack,
-					     struct next_fnfieldlist);
-
-	      destr_fnlist->fn_fieldlist.name
-		= obconcat (&objfile->objfile_obstack, "~",
-			    new_fnlist->fn_fieldlist.name, (char *) NULL);
-
-	      destr_fnlist->fn_fieldlist.fn_fields =
-		XOBNEWVEC (&objfile->objfile_obstack,
-			   struct fn_field, has_destructor);
-	      memset (destr_fnlist->fn_fieldlist.fn_fields, 0,
-		  sizeof (struct fn_field) * has_destructor);
-	      tmp_sublist = sublist;
-	      last_sublist = NULL;
-	      i = 0;
-	      while (tmp_sublist != NULL)
-		{
-		  if (!is_destructor_name (tmp_sublist->fn_field.physname))
-		    {
-		      tmp_sublist = tmp_sublist->next;
-		      continue;
-		    }
-		  
-		  destr_fnlist->fn_fieldlist.fn_fields[i++]
-		    = tmp_sublist->fn_field;
-		  if (last_sublist)
-		    last_sublist->next = tmp_sublist->next;
-		  else
-		    sublist = tmp_sublist->next;
-		  last_sublist = tmp_sublist;
-		  tmp_sublist = tmp_sublist->next;
-		}
-
-	      destr_fnlist->fn_fieldlist.length = has_destructor;
-	      destr_fnlist->next = fip->fnlist;
-	      fip->fnlist = destr_fnlist;
-	      nfn_fields++;
-	      length -= has_destructor;
-	    }
-	  else if (is_v3)
-	    {
-	      /* v3 mangling prevents the use of abbreviated physnames,
-		 so we can do this here.  There are stubbed methods in v3
-		 only:
-		 - in -gstabs instead of -gstabs+
-		 - or for static methods, which are output as a function type
-		   instead of a method type.  */
-	      char *new_method_name =
-		stabs_method_name_from_physname (sublist->fn_field.physname);
-
-	      if (new_method_name != NULL
-		  && strcmp (new_method_name,
-			     new_fnlist->fn_fieldlist.name) != 0)
-		{
-		  new_fnlist->fn_fieldlist.name = new_method_name;
-		  xfree (main_fn_name);
-		}
-	      else
-		xfree (new_method_name);
-	    }
-	  else if (has_destructor && new_fnlist->fn_fieldlist.name[0] != '~')
-	    {
-	      new_fnlist->fn_fieldlist.name =
-		obconcat (&objfile->objfile_obstack,
-			  "~", main_fn_name, (char *)NULL);
-	      xfree (main_fn_name);
-	    }
-
-	  new_fnlist->fn_fieldlist.fn_fields
-	    = OBSTACK_CALLOC (&objfile->objfile_obstack, length, fn_field);
-	  for (i = length; (i--, sublist); sublist = sublist->next)
-	    {
-	      new_fnlist->fn_fieldlist.fn_fields[i] = sublist->fn_field;
-	    }
-
-	  new_fnlist->fn_fieldlist.length = length;
-	  new_fnlist->next = fip->fnlist;
-	  fip->fnlist = new_fnlist;
-	  nfn_fields++;
-	}
-    }
-
-  if (nfn_fields)
-    {
-      ALLOCATE_CPLUS_STRUCT_TYPE (type);
-      TYPE_FN_FIELDLISTS (type) = (struct fn_fieldlist *)
-	TYPE_ZALLOC (type, sizeof (struct fn_fieldlist) * nfn_fields);
-      TYPE_NFN_FIELDS (type) = nfn_fields;
-    }
-
-  return 1;
-}
-
-/* Special GNU C++ name.
-
-   Returns 1 for success, 0 for failure.  "failure" means that we can't
-   keep parsing and it's time for error_type().  */
-
-static int
-read_cpp_abbrev (struct stab_field_info *fip, const char **pp,
-		 struct type *type, struct objfile *objfile)
-{
-  const char *p;
-  const char *name;
-  char cpp_abbrev;
-  struct type *context;
-
-  p = *pp;
-  if (*++p == 'v')
-    {
-      name = NULL;
-      cpp_abbrev = *++p;
-
-      *pp = p + 1;
-
-      /* At this point, *pp points to something like "22:23=*22...",
-	 where the type number before the ':' is the "context" and
-	 everything after is a regular type definition.  Lookup the
-	 type, find it's name, and construct the field name.  */
-
-      context = read_type (pp, objfile);
-
-      switch (cpp_abbrev)
-	{
-	case 'f':		/* $vf -- a virtual function table pointer */
-	  name = context->name ();
-	  if (name == NULL)
-	    {
-	      name = "";
-	    }
-	  fip->list->field.set_name (obconcat (&objfile->objfile_obstack,
-					       vptr_name, name, (char *) NULL));
-	  break;
-
-	case 'b':		/* $vb -- a virtual bsomethingorother */
-	  name = context->name ();
-	  if (name == NULL)
-	    {
-	      complaint (_("C++ abbreviated type name "
-			   "unknown at symtab pos %d"),
-			 symnum);
-	      name = "FOO";
-	    }
-	  fip->list->field.set_name (obconcat (&objfile->objfile_obstack,
-					       vb_name, name, (char *) NULL));
-	  break;
-
-	default:
-	  invalid_cpp_abbrev_complaint (*pp);
-	  fip->list->field.set_name (obconcat (&objfile->objfile_obstack,
-					       "INVALID_CPLUSPLUS_ABBREV",
-					       (char *) NULL));
-	  break;
-	}
-
-      /* At this point, *pp points to the ':'.  Skip it and read the
-	 field type.  */
-
-      p = ++(*pp);
-      if (p[-1] != ':')
-	{
-	  invalid_cpp_abbrev_complaint (*pp);
-	  return 0;
-	}
-      fip->list->field.set_type (read_type (pp, objfile));
-      if (**pp == ',')
-	(*pp)++;		/* Skip the comma.  */
-      else
-	return 0;
-
-      {
-	int nbits;
-
-	fip->list->field.set_loc_bitpos (read_huge_number (pp, ';', &nbits, 0));
-	if (nbits != 0)
-	  return 0;
-      }
-      /* This field is unpacked.  */
-      fip->list->field.set_bitsize (0);
-      fip->list->field.set_accessibility (accessibility::PRIVATE);
-    }
-  else
-    {
-      invalid_cpp_abbrev_complaint (*pp);
-      /* We have no idea what syntax an unrecognized abbrev would have, so
-	 better return 0.  If we returned 1, we would need to at least advance
-	 *pp to avoid an infinite loop.  */
-      return 0;
-    }
-  return 1;
-}
-
-static void
-read_one_struct_field (struct stab_field_info *fip, const char **pp,
-		       const char *p, struct type *type,
-		       struct objfile *objfile)
-{
-  struct gdbarch *gdbarch = objfile->arch ();
-
-  fip->list->field.set_name
-    (obstack_strndup (&objfile->objfile_obstack, *pp, p - *pp));
-  *pp = p + 1;
-
-  /* This means we have a visibility for a field coming.  */
-  int visibility;
-  if (**pp == '/')
-    {
-      (*pp)++;
-      visibility = *(*pp)++;
-    }
-  else
-    {
-      /* normal dbx-style format, no explicit visibility */
-      visibility = VISIBILITY_PUBLIC;
-    }
-
-  switch (visibility)
-    {
-    case VISIBILITY_PRIVATE:
-      fip->list->field.set_accessibility (accessibility::PRIVATE);
-      break;
-
-    case VISIBILITY_PROTECTED:
-      fip->list->field.set_accessibility (accessibility::PROTECTED);
-      break;
-
-    case VISIBILITY_IGNORE:
-      fip->list->field.set_ignored ();
-      break;
-
-    case VISIBILITY_PUBLIC:
-      break;
-
-    default:
-      /* Unknown visibility.  Complain and treat it as public.  */
-      {
-	complaint (_("Unknown visibility `%c' for field"),
-		   visibility);
-      }
-      break;
-    }
-
-  fip->list->field.set_type (read_type (pp, objfile));
-  if (**pp == ':')
-    {
-      p = ++(*pp);
-#if 0
-      /* Possible future hook for nested types.  */
-      if (**pp == '!')
-	{
-	  fip->list->field.bitpos = (long) -2;	/* nested type */
-	  p = ++(*pp);
-	}
-      else
-	...;
-#endif
-      while (*p != ';')
-	{
-	  p++;
-	}
-      /* Static class member.  */
-      fip->list->field.set_loc_physname (savestring (*pp, p - *pp));
-      *pp = p + 1;
-      return;
-    }
-  else if (**pp != ',')
-    {
-      /* Bad structure-type format.  */
-      stabs_general_complaint ("bad structure-type format");
-      return;
-    }
-
-  (*pp)++;			/* Skip the comma.  */
-
-  {
-    int nbits;
-
-    fip->list->field.set_loc_bitpos (read_huge_number (pp, ',', &nbits, 0));
-    if (nbits != 0)
-      {
-	stabs_general_complaint ("bad structure-type format");
-	return;
-      }
-    fip->list->field.set_bitsize (read_huge_number (pp, ';', &nbits, 0));
-    if (nbits != 0)
-      {
-	stabs_general_complaint ("bad structure-type format");
-	return;
-      }
-  }
-
-  if (fip->list->field.loc_bitpos () == 0
-      && fip->list->field.bitsize () == 0)
-    {
-      /* This can happen in two cases: (1) at least for gcc 2.4.5 or so,
-	 it is a field which has been optimized out.  The correct stab for
-	 this case is to use VISIBILITY_IGNORE, but that is a recent
-	 invention.  (2) It is a 0-size array.  For example
-	 union { int num; char str[0]; } foo.  Printing _("<no value>" for
-	 str in "p foo" is OK, since foo.str (and thus foo.str[3])
-	 will continue to work, and a 0-size array as a whole doesn't
-	 have any contents to print.
-
-	 I suspect this probably could also happen with gcc -gstabs (not
-	 -gstabs+) for static fields, and perhaps other C++ extensions.
-	 Hopefully few people use -gstabs with gdb, since it is intended
-	 for dbx compatibility.  */
-
-      /* Ignore this field.  */
-      fip->list->field.set_ignored ();
-    }
-  else
-    {
-      /* Detect an unpacked field and mark it as such.
-	 dbx gives a bit size for all fields.
-	 Note that forward refs cannot be packed,
-	 and treat enums as if they had the width of ints.  */
-
-      struct type *field_type = check_typedef (fip->list->field.type ());
-
-      if (field_type->code () != TYPE_CODE_INT
-	  && field_type->code () != TYPE_CODE_RANGE
-	  && field_type->code () != TYPE_CODE_BOOL
-	  && field_type->code () != TYPE_CODE_ENUM)
-	{
-	  fip->list->field.set_bitsize (0);
-	}
-      if ((fip->list->field.bitsize ()
-	   == TARGET_CHAR_BIT * field_type->length ()
-	   || (field_type->code () == TYPE_CODE_ENUM
-	       && (fip->list->field.bitsize ()
-		   == gdbarch_int_bit (gdbarch)))
-	  )
-	  &&
-	  fip->list->field.loc_bitpos () % 8 == 0)
-	{
-	  fip->list->field.set_bitsize (0);
-	}
-    }
-}
-
-
-/* Read struct or class data fields.  They have the form:
-
-   NAME : [VISIBILITY] TYPENUM , BITPOS , BITSIZE ;
-
-   At the end, we see a semicolon instead of a field.
-
-   In C++, this may wind up being NAME:?TYPENUM:PHYSNAME; for
-   a static field.
-
-   The optional VISIBILITY is one of:
-
-   '/0' (VISIBILITY_PRIVATE)
-   '/1' (VISIBILITY_PROTECTED)
-   '/2' (VISIBILITY_PUBLIC)
-   '/9' (VISIBILITY_IGNORE)
-
-   or nothing, for C style fields with public visibility.
-
-   Returns 1 for success, 0 for failure.  */
-
-static int
-read_struct_fields (struct stab_field_info *fip, const char **pp,
-		    struct type *type, struct objfile *objfile)
-{
-  const char *p;
-  struct stabs_nextfield *newobj;
-
-  /* We better set p right now, in case there are no fields at all...    */
-
-  p = *pp;
-
-  /* Read each data member type until we find the terminating ';' at the end of
-     the data member list, or break for some other reason such as finding the
-     start of the member function list.  */
-  /* Stab string for structure/union does not end with two ';' in
-     SUN C compiler 5.3 i.e. F6U2, hence check for end of string.  */
-
-  while (**pp != ';' && **pp != '\0')
-    {
-      STABS_CONTINUE (pp, objfile);
-      /* Get space to record the next field's data.  */
-      newobj = OBSTACK_ZALLOC (&fip->obstack, struct stabs_nextfield);
-
-      newobj->next = fip->list;
-      fip->list = newobj;
-
-      /* Get the field name.  */
-      p = *pp;
-
-      /* If is starts with CPLUS_MARKER it is a special abbreviation,
-	 unless the CPLUS_MARKER is followed by an underscore, in
-	 which case it is just the name of an anonymous type, which we
-	 should handle like any other type name.  */
-
-      if (is_cplus_marker (p[0]) && p[1] != '_')
-	{
-	  if (!read_cpp_abbrev (fip, pp, type, objfile))
-	    return 0;
-	  continue;
-	}
-
-      /* Look for the ':' that separates the field name from the field
-	 values.  Data members are delimited by a single ':', while member
-	 functions are delimited by a pair of ':'s.  When we hit the member
-	 functions (if any), terminate scan loop and return.  */
-
-      while (*p != ':' && *p != '\0')
-	{
-	  p++;
-	}
-      if (*p == '\0')
-	return 0;
-
-      /* Check to see if we have hit the member functions yet.  */
-      if (p[1] == ':')
-	{
-	  break;
-	}
-      read_one_struct_field (fip, pp, p, type, objfile);
-    }
-  if (p[0] == ':' && p[1] == ':')
-    {
-      /* (the deleted) chill the list of fields: the last entry (at
-	 the head) is a partially constructed entry which we now
-	 scrub.  */
-      fip->list = fip->list->next;
-    }
-  return 1;
-}
-/* The stabs for C++ derived classes contain baseclass information which
-   is marked by a '!' character after the total size.  This function is
-   called when we encounter the baseclass marker, and slurps up all the
-   baseclass information.
-
-   Immediately following the '!' marker is the number of base classes that
-   the class is derived from, followed by information for each base class.
-   For each base class, there are two visibility specifiers, a bit offset
-   to the base class information within the derived class, a reference to
-   the type for the base class, and a terminating semicolon.
-
-   A typical example, with two base classes, would be "!2,020,19;0264,21;".
-						       ^^ ^ ^ ^  ^ ^  ^
-	Baseclass information marker __________________|| | | |  | |  |
-	Number of baseclasses __________________________| | | |  | |  |
-	Visibility specifiers (2) ________________________| | |  | |  |
-	Offset in bits from start of class _________________| |  | |  |
-	Type number for base class ___________________________|  | |  |
-	Visibility specifiers (2) _______________________________| |  |
-	Offset in bits from start of class ________________________|  |
-	Type number of base class ____________________________________|
-
-  Return 1 for success, 0 for (error-type-inducing) failure.  */
-
-
-
-static int
-read_baseclasses (struct stab_field_info *fip, const char **pp,
-		  struct type *type, struct objfile *objfile)
-{
-  int i;
-  struct stabs_nextfield *newobj;
-
-  if (**pp != '!')
-    {
-      return 1;
-    }
-  else
-    {
-      /* Skip the '!' baseclass information marker.  */
-      (*pp)++;
-    }
-
-  ALLOCATE_CPLUS_STRUCT_TYPE (type);
-  {
-    int nbits;
-
-    TYPE_N_BASECLASSES (type) = read_huge_number (pp, ',', &nbits, 0);
-    if (nbits != 0)
-      return 0;
-  }
-
-  for (i = 0; i < TYPE_N_BASECLASSES (type); i++)
-    {
-      newobj = OBSTACK_ZALLOC (&fip->obstack, struct stabs_nextfield);
-
-      newobj->next = fip->list;
-      fip->list = newobj;
-      newobj->field.set_bitsize (0);	/* This should be an unpacked
-					   field!  */
-
-      STABS_CONTINUE (pp, objfile);
-      switch (**pp)
-	{
-	case '0':
-	  /* Nothing to do.  */
-	  break;
-	case '1':
-	  newobj->field.set_virtual ();
-	  break;
-	default:
-	  /* Unknown character.  Complain and treat it as non-virtual.  */
-	  {
-	    complaint (_("Unknown virtual character `%c' for baseclass"),
-		       **pp);
-	  }
-	}
-      ++(*pp);
-
-      int visibility = *(*pp)++;
-      switch (visibility)
-	{
-	case VISIBILITY_PRIVATE:
-	  newobj->field.set_accessibility (accessibility::PRIVATE);
-	  break;
-	case VISIBILITY_PROTECTED:
-	  newobj->field.set_accessibility (accessibility::PROTECTED);
-	  break;
-	case VISIBILITY_PUBLIC:
-	  break;
-	default:
-	  /* Bad visibility format.  Complain and treat it as
-	     public.  */
-	  {
-	    complaint (_("Unknown visibility `%c' for baseclass"),
-		       visibility);
-	  }
-	}
-
-      {
-	int nbits;
-
-	/* The remaining value is the bit offset of the portion of the object
-	   corresponding to this baseclass.  Always zero in the absence of
-	   multiple inheritance.  */
-
-	newobj->field.set_loc_bitpos (read_huge_number (pp, ',', &nbits, 0));
-	if (nbits != 0)
-	  return 0;
-      }
-
-      /* The last piece of baseclass information is the type of the
-	 base class.  Read it, and remember it's type name as this
-	 field's name.  */
-
-      newobj->field.set_type (read_type (pp, objfile));
-      newobj->field.set_name (newobj->field.type ()->name ());
-
-      /* Skip trailing ';' and bump count of number of fields seen.  */
-      if (**pp == ';')
-	(*pp)++;
-      else
-	return 0;
-    }
-  return 1;
-}
-
-/* The tail end of stabs for C++ classes that contain a virtual function
-   pointer contains a tilde, a %, and a type number.
-   The type number refers to the base class (possibly this class itself) which
-   contains the vtable pointer for the current class.
-
-   This function is called when we have parsed all the method declarations,
-   so we can look for the vptr base class info.  */
-
-static int
-read_tilde_fields (struct stab_field_info *fip, const char **pp,
-		   struct type *type, struct objfile *objfile)
-{
-  const char *p;
-
-  STABS_CONTINUE (pp, objfile);
-
-  /* If we are positioned at a ';', then skip it.  */
-  if (**pp == ';')
-    {
-      (*pp)++;
-    }
-
-  if (**pp == '~')
-    {
-      (*pp)++;
-
-      if (**pp == '=' || **pp == '+' || **pp == '-')
-	{
-	  /* Obsolete flags that used to indicate the presence
-	     of constructors and/or destructors.  */
-	  (*pp)++;
-	}
-
-      /* Read either a '%' or the final ';'.  */
-      if (*(*pp)++ == '%')
-	{
-	  /* The next number is the type number of the base class
-	     (possibly our own class) which supplies the vtable for
-	     this class.  Parse it out, and search that class to find
-	     its vtable pointer, and install those into TYPE_VPTR_BASETYPE
-	     and TYPE_VPTR_FIELDNO.  */
-
-	  struct type *t;
-	  int i;
-
-	  t = read_type (pp, objfile);
-	  p = (*pp)++;
-	  while (*p != '\0' && *p != ';')
-	    {
-	      p++;
-	    }
-	  if (*p == '\0')
-	    {
-	      /* Premature end of symbol.  */
-	      return 0;
-	    }
-
-	  set_type_vptr_basetype (type, t);
-	  if (type == t)	/* Our own class provides vtbl ptr.  */
-	    {
-	      for (i = t->num_fields () - 1;
-		   i >= TYPE_N_BASECLASSES (t);
-		   --i)
-		{
-		  const char *name = t->field (i).name ();
-
-		  if (!strncmp (name, vptr_name, sizeof (vptr_name) - 2)
-		      && is_cplus_marker (name[sizeof (vptr_name) - 2]))
-		    {
-		      set_type_vptr_fieldno (type, i);
-		      goto gotit;
-		    }
-		}
-	      /* Virtual function table field not found.  */
-	      complaint (_("virtual function table pointer "
-			   "not found when defining class `%s'"),
-			 type->name ());
-	      return 0;
-	    }
-	  else
-	    {
-	      set_type_vptr_fieldno (type, TYPE_VPTR_FIELDNO (t));
-	    }
-
-	gotit:
-	  *pp = p + 1;
-	}
-    }
-  return 1;
-}
-
-static int
-attach_fn_fields_to_type (struct stab_field_info *fip, struct type *type)
-{
-  int n;
-
-  for (n = TYPE_NFN_FIELDS (type);
-       fip->fnlist != NULL;
-       fip->fnlist = fip->fnlist->next)
-    {
-      --n;			/* Circumvent Sun3 compiler bug.  */
-      TYPE_FN_FIELDLISTS (type)[n] = fip->fnlist->fn_fieldlist;
-    }
-  return 1;
-}
-
-/* Create the vector of fields, and record how big it is.
-   We need this info to record proper virtual function table information
-   for this class's virtual functions.  */
-
-static int
-attach_fields_to_type (struct stab_field_info *fip, struct type *type,
-		       struct objfile *objfile)
-{
-  int nfields = 0;
-  struct stabs_nextfield *scan;
-
-  /* Count up the number of fields that we have.  */
-
-  for (scan = fip->list; scan != NULL; scan = scan->next)
-    nfields++;
-
-  /* Now we know how many fields there are, and whether or not there are any
-     non-public fields.  Record the field count, allocate space for the
-     array of fields.  */
-
-  type->alloc_fields (nfields);
-
-  /* Copy the saved-up fields into the field vector.  Start from the
-     head of the list, adding to the tail of the field array, so that
-     they end up in the same order in the array in which they were
-     added to the list.  */
-
-  while (nfields-- > 0)
-    {
-      type->field (nfields) = fip->list->field;
-      fip->list = fip->list->next;
-    }
-  return 1;
-}
-
-
-/* Complain that the compiler has emitted more than one definition for the
-   structure type TYPE.  */
-static void 
-complain_about_struct_wipeout (struct type *type)
-{
-  const char *name = "";
-  const char *kind = "";
-
-  if (type->name ())
-    {
-      name = type->name ();
-      switch (type->code ())
-	{
-	case TYPE_CODE_STRUCT: kind = "struct "; break;
-	case TYPE_CODE_UNION:  kind = "union ";  break;
-	case TYPE_CODE_ENUM:   kind = "enum ";   break;
-	default: kind = "";
-	}
-    }
-  else
-    {
-      name = "<unknown>";
-      kind = "";
-    }
-
-  complaint (_("struct/union type gets multiply defined: %s%s"), kind, name);
-}
-
-/* Set the length for all variants of a same main_type, which are
-   connected in the closed chain.
-   
-   This is something that needs to be done when a type is defined *after*
-   some cross references to this type have already been read.  Consider
-   for instance the following scenario where we have the following two
-   stabs entries:
-
-	.stabs  "t:p(0,21)=*(0,22)=k(0,23)=xsdummy:",160,0,28,-24
-	.stabs  "dummy:T(0,23)=s16x:(0,1),0,3[...]"
-
-   A stubbed version of type dummy is created while processing the first
-   stabs entry.  The length of that type is initially set to zero, since
-   it is unknown at this point.  Also, a "constant" variation of type
-   "dummy" is created as well (this is the "(0,22)=k(0,23)" section of
-   the stabs line).
-
-   The second stabs entry allows us to replace the stubbed definition
-   with the real definition.  However, we still need to adjust the length
-   of the "constant" variation of that type, as its length was left
-   untouched during the main type replacement...  */
-
-static void
-set_length_in_type_chain (struct type *type)
-{
-  struct type *ntype = TYPE_CHAIN (type);
-
-  while (ntype != type)
-    {
-      if (ntype->length () == 0)
-	ntype->set_length (type->length ());
-      else
-	complain_about_struct_wipeout (ntype);
-      ntype = TYPE_CHAIN (ntype);
-    }
-}
-
-/* Read the description of a structure (or union type) and return an object
-   describing the type.
-
-   PP points to a character pointer that points to the next unconsumed token
-   in the stabs string.  For example, given stabs "A:T4=s4a:1,0,32;;",
-   *PP will point to "4a:1,0,32;;".
-
-   TYPE points to an incomplete type that needs to be filled in.
-
-   OBJFILE points to the current objfile from which the stabs information is
-   being read.  (Note that it is redundant in that TYPE also contains a pointer
-   to this same objfile, so it might be a good idea to eliminate it.  FIXME). 
- */
-
-static struct type *
-read_struct_type (const char **pp, struct type *type, enum type_code type_code,
-		  struct objfile *objfile)
-{
-  struct stab_field_info fi;
-
-  /* When describing struct/union/class types in stabs, G++ always drops
-     all qualifications from the name.  So if you've got:
-       struct A { ... struct B { ... }; ... };
-     then G++ will emit stabs for `struct A::B' that call it simply
-     `struct B'.  Obviously, if you've got a real top-level definition for
-     `struct B', or other nested definitions, this is going to cause
-     problems.
-
-     Obviously, GDB can't fix this by itself, but it can at least avoid
-     scribbling on existing structure type objects when new definitions
-     appear.  */
-  if (! (type->code () == TYPE_CODE_UNDEF
-	 || type->is_stub ()))
-    {
-      complain_about_struct_wipeout (type);
-
-      /* It's probably best to return the type unchanged.  */
-      return type;
-    }
-
-  INIT_CPLUS_SPECIFIC (type);
-  type->set_code (type_code);
-  type->set_is_stub (false);
-
-  /* First comes the total size in bytes.  */
-
-  {
-    int nbits;
-
-    type->set_length (read_huge_number (pp, 0, &nbits, 0));
-    if (nbits != 0)
-      return error_type (pp, objfile);
-    set_length_in_type_chain (type);
-  }
-
-  /* Now read the baseclasses, if any, read the regular C struct or C++
-     class member fields, attach the fields to the type, read the C++
-     member functions, attach them to the type, and then read any tilde
-     field (baseclass specifier for the class holding the main vtable).  */
-
-  if (!read_baseclasses (&fi, pp, type, objfile)
-      || !read_struct_fields (&fi, pp, type, objfile)
-      || !attach_fields_to_type (&fi, type, objfile)
-      || !read_member_functions (&fi, pp, type, objfile)
-      || !attach_fn_fields_to_type (&fi, type)
-      || !read_tilde_fields (&fi, pp, type, objfile))
-    {
-      type = error_type (pp, objfile);
-    }
-
-  return (type);
-}
-
-/* Read a definition of an array type,
-   and create and return a suitable type object.
-   Also creates a range type which represents the bounds of that
-   array.  */
-
-static struct type *
-read_array_type (const char **pp, struct type *type,
-		 struct objfile *objfile)
-{
-  struct type *index_type, *element_type, *range_type;
-  int lower, upper;
-  int adjustable = 0;
-  int nbits;
-
-  /* Format of an array type:
-     "ar<index type>;lower;upper;<array_contents_type>".
-     OS9000: "arlower,upper;<array_contents_type>".
-
-     Fortran adjustable arrays use Adigits or Tdigits for lower or upper;
-     for these, produce a type like float[][].  */
-
-    {
-      index_type = read_type (pp, objfile);
-      if (**pp != ';')
-	/* Improper format of array type decl.  */
-	return error_type (pp, objfile);
-      ++*pp;
-    }
-
-  if (!(**pp >= '0' && **pp <= '9') && **pp != '-')
-    {
-      (*pp)++;
-      adjustable = 1;
-    }
-  lower = read_huge_number (pp, ';', &nbits, 0);
-
-  if (nbits != 0)
-    return error_type (pp, objfile);
-
-  if (!(**pp >= '0' && **pp <= '9') && **pp != '-')
-    {
-      (*pp)++;
-      adjustable = 1;
-    }
-  upper = read_huge_number (pp, ';', &nbits, 0);
-  if (nbits != 0)
-    return error_type (pp, objfile);
-
-  element_type = read_type (pp, objfile);
-
-  if (adjustable)
-    {
-      lower = 0;
-      upper = -1;
-    }
-
-  type_allocator alloc (objfile, get_current_subfile ()->language);
-  range_type =
-    create_static_range_type (alloc, index_type, lower, upper);
-  type_allocator smash_alloc (type, type_allocator::SMASH);
-  type = create_array_type (smash_alloc, element_type, range_type);
-
-  return type;
-}
-
-
-/* Read a definition of an enumeration type,
-   and create and return a suitable type object.
-   Also defines the symbols that represent the values of the type.  */
-
-static struct type *
-read_enum_type (const char **pp, struct type *type,
-		struct objfile *objfile)
-{
-  struct gdbarch *gdbarch = objfile->arch ();
-  const char *p;
-  char *name;
-  long n;
-  struct symbol *sym;
-  int nsyms = 0;
-  struct pending **symlist;
-  struct pending *osyms, *syms;
-  int o_nsyms;
-  int nbits;
-  int unsigned_enum = 1;
-
-#if 0
-  /* FIXME!  The stabs produced by Sun CC merrily define things that ought
-     to be file-scope, between N_FN entries, using N_LSYM.  What's a mother
-     to do?  For now, force all enum values to file scope.  */
-  if (within_function)
-    symlist = get_local_symbols ();
-  else
-#endif
-    symlist = get_file_symbols ();
-  osyms = *symlist;
-  o_nsyms = osyms ? osyms->nsyms : 0;
-
-  /* The aix4 compiler emits an extra field before the enum members;
-     my guess is it's a type of some sort.  Just ignore it.  */
-  if (**pp == '-')
-    {
-      /* Skip over the type.  */
-      while (**pp != ':')
-	(*pp)++;
-
-      /* Skip over the colon.  */
-      (*pp)++;
-    }
-
-  /* Read the value-names and their values.
-     The input syntax is NAME:VALUE,NAME:VALUE, and so on.
-     A semicolon or comma instead of a NAME means the end.  */
-  while (**pp && **pp != ';' && **pp != ',')
-    {
-      STABS_CONTINUE (pp, objfile);
-      p = *pp;
-      while (*p != ':')
-	p++;
-      name = obstack_strndup (&objfile->objfile_obstack, *pp, p - *pp);
-      *pp = p + 1;
-      n = read_huge_number (pp, ',', &nbits, 0);
-      if (nbits != 0)
-	return error_type (pp, objfile);
-
-      sym = new (&objfile->objfile_obstack) symbol;
-      sym->set_linkage_name (name);
-      sym->set_language (get_current_subfile ()->language,
-			 &objfile->objfile_obstack);
-      sym->set_loc_class_index (LOC_CONST);
-      sym->set_domain (VAR_DOMAIN);
-      sym->set_value_longest (n);
-      if (n < 0)
-	unsigned_enum = 0;
-      add_symbol_to_list (sym, symlist);
-      nsyms++;
-    }
-
-  if (**pp == ';')
-    (*pp)++;			/* Skip the semicolon.  */
-
-  /* Now fill in the fields of the type-structure.  */
-
-  type->set_length (gdbarch_int_bit (gdbarch) / HOST_CHAR_BIT);
-  set_length_in_type_chain (type);
-  type->set_code (TYPE_CODE_ENUM);
-  type->set_is_stub (false);
-  if (unsigned_enum)
-    type->set_is_unsigned (true);
-  type->alloc_fields (nsyms);
-
-  /* Find the symbols for the values and put them into the type.
-     The symbols can be found in the symlist that we put them on
-     to cause them to be defined.  osyms contains the old value
-     of that symlist; everything up to there was defined by us.  */
-  /* Note that we preserve the order of the enum constants, so
-     that in something like "enum {FOO, LAST_THING=FOO}" we print
-     FOO, not LAST_THING.  */
-
-  for (syms = *symlist, n = nsyms - 1; syms; syms = syms->next)
-    {
-      int last = syms == osyms ? o_nsyms : 0;
-      int j = syms->nsyms;
-
-      for (; --j >= last; --n)
-	{
-	  struct symbol *xsym = syms->symbol[j];
-
-	  xsym->set_type (type);
-	  type->field (n).set_name (xsym->linkage_name ());
-	  type->field (n).set_loc_enumval (xsym->value_longest ());
-	  type->field (n).set_bitsize (0);
-	}
-      if (syms == osyms)
-	break;
-    }
-
-  return type;
-}
-
-/* Sun's ACC uses a somewhat saner method for specifying the builtin
-   typedefs in every file (for int, long, etc):
-
-   type = b <signed> <width> <format type>; <offset>; <nbits>
-   signed = u or s.
-   optional format type = c or b for char or boolean.
-   offset = offset from high order bit to start bit of type.
-   width is # bytes in object of this type, nbits is # bits in type.
-
-   The width/offset stuff appears to be for small objects stored in
-   larger ones (e.g. `shorts' in `int' registers).  We ignore it for now,
-   FIXME.  */
-
-static struct type *
-read_sun_builtin_type (const char **pp, int typenums[2], struct objfile *objfile)
-{
-  int type_bits;
-  int nbits;
-  int unsigned_type;
-  int boolean_type = 0;
-
-  switch (**pp)
-    {
-    case 's':
-      unsigned_type = 0;
-      break;
-    case 'u':
-      unsigned_type = 1;
-      break;
-    default:
-      return error_type (pp, objfile);
-    }
-  (*pp)++;
-
-  /* For some odd reason, all forms of char put a c here.  This is strange
-     because no other type has this honor.  We can safely ignore this because
-     we actually determine 'char'acterness by the number of bits specified in
-     the descriptor.
-     Boolean forms, e.g Fortran logical*X, put a b here.  */
-
-  if (**pp == 'c')
-    (*pp)++;
-  else if (**pp == 'b')
-    {
-      boolean_type = 1;
-      (*pp)++;
-    }
-
-  /* The first number appears to be the number of bytes occupied
-     by this type, except that unsigned short is 4 instead of 2.
-     Since this information is redundant with the third number,
-     we will ignore it.  */
-  read_huge_number (pp, ';', &nbits, 0);
-  if (nbits != 0)
-    return error_type (pp, objfile);
-
-  /* The second number is always 0, so ignore it too.  */
-  read_huge_number (pp, ';', &nbits, 0);
-  if (nbits != 0)
-    return error_type (pp, objfile);
-
-  /* The third number is the number of bits for this type.  */
-  type_bits = read_huge_number (pp, 0, &nbits, 0);
-  if (nbits != 0)
-    return error_type (pp, objfile);
-  /* The type *should* end with a semicolon.  If it are embedded
-     in a larger type the semicolon may be the only way to know where
-     the type ends.  If this type is at the end of the stabstring we
-     can deal with the omitted semicolon (but we don't have to like
-     it).  Don't bother to complain(), Sun's compiler omits the semicolon
-     for "void".  */
-  if (**pp == ';')
-    ++(*pp);
-
-  type_allocator alloc (objfile, get_current_subfile ()->language);
-  if (type_bits == 0)
-    {
-      struct type *type = alloc.new_type (TYPE_CODE_VOID,
-					  TARGET_CHAR_BIT, nullptr);
-      if (unsigned_type)
-	type->set_is_unsigned (true);
-
-      return type;
-    }
-
-  if (boolean_type)
-    return init_boolean_type (alloc, type_bits, unsigned_type, NULL);
-  else
-    return init_integer_type (alloc, type_bits, unsigned_type, NULL);
-}
-
-static struct type *
-read_sun_floating_type (const char **pp, int typenums[2],
-			struct objfile *objfile)
-{
-  int nbits;
-  int details;
-  int nbytes;
-  struct type *rettype;
-
-  /* The first number has more details about the type, for example
-     FN_COMPLEX.  */
-  details = read_huge_number (pp, ';', &nbits, 0);
-  if (nbits != 0)
-    return error_type (pp, objfile);
-
-  /* The second number is the number of bytes occupied by this type.  */
-  nbytes = read_huge_number (pp, ';', &nbits, 0);
-  if (nbits != 0)
-    return error_type (pp, objfile);
-
-  nbits = nbytes * TARGET_CHAR_BIT;
-
-  if (details == NF_COMPLEX || details == NF_COMPLEX16
-      || details == NF_COMPLEX32)
-    {
-      rettype = dbx_init_float_type (objfile, nbits / 2);
-      return init_complex_type (NULL, rettype);
-    }
-
-  return dbx_init_float_type (objfile, nbits);
-}
-
-/* Read a number from the string pointed to by *PP.
-   The value of *PP is advanced over the number.
-   If END is nonzero, the character that ends the
-   number must match END, or an error happens;
-   and that character is skipped if it does match.
-   If END is zero, *PP is left pointing to that character.
-
-   If TWOS_COMPLEMENT_BITS is set to a strictly positive value and if
-   the number is represented in an octal representation, assume that
-   it is represented in a 2's complement representation with a size of
-   TWOS_COMPLEMENT_BITS.
-
-   If the number fits in a long, set *BITS to 0 and return the value.
-   If not, set *BITS to be the number of bits in the number and return 0.
-
-   If encounter garbage, set *BITS to -1 and return 0.  */
-
-static long
-read_huge_number (const char **pp, int end, int *bits,
-		  int twos_complement_bits)
-{
-  const char *p = *pp;
-  int sign = 1;
-  int sign_bit = 0;
-  long n = 0;
-  int radix = 10;
-  char overflow = 0;
-  int nbits = 0;
-  int c;
-  long upper_limit;
-  int twos_complement_representation = 0;
-
-  if (*p == '-')
-    {
-      sign = -1;
-      p++;
-    }
-
-  /* Leading zero means octal.  GCC uses this to output values larger
-     than an int (because that would be hard in decimal).  */
-  if (*p == '0')
-    {
-      radix = 8;
-      p++;
-    }
-
-  /* Skip extra zeros.  */
-  while (*p == '0')
-    p++;
-
-  if (sign > 0 && radix == 8 && twos_complement_bits > 0)
-    {
-      /* Octal, possibly signed.  Check if we have enough chars for a
-	 negative number.  */
-
-      size_t len;
-      const char *p1 = p;
-
-      while ((c = *p1) >= '0' && c < '8')
-	p1++;
-
-      len = p1 - p;
-      if (len > twos_complement_bits / 3
-	  || (twos_complement_bits % 3 == 0
-	      && len == twos_complement_bits / 3))
-	{
-	  /* Ok, we have enough characters for a signed value, check
-	     for signedness by testing if the sign bit is set.  */
-	  sign_bit = (twos_complement_bits % 3 + 2) % 3;
-	  c = *p - '0';
-	  if (c & (1 << sign_bit))
-	    {
-	      /* Definitely signed.  */
-	      twos_complement_representation = 1;
-	      sign = -1;
-	    }
-	}
-    }
-
-  upper_limit = LONG_MAX / radix;
-
-  while ((c = *p++) >= '0' && c < ('0' + radix))
-    {
-      if (n <= upper_limit)
-	{
-	  if (twos_complement_representation)
-	    {
-	      /* Octal, signed, twos complement representation.  In
-		 this case, n is the corresponding absolute value.  */
-	      if (n == 0)
-		{
-		  long sn = c - '0' - ((2 * (c - '0')) | (2 << sign_bit));
-
-		  n = -sn;
-		}
-	      else
-		{
-		  n *= radix;
-		  n -= c - '0';
-		}
-	    }
-	  else
-	    {
-	      /* unsigned representation */
-	      n *= radix;
-	      n += c - '0';		/* FIXME this overflows anyway.  */
-	    }
-	}
-      else
-	overflow = 1;
-
-      /* This depends on large values being output in octal, which is
-	 what GCC does.  */
-      if (radix == 8)
-	{
-	  if (nbits == 0)
-	    {
-	      if (c == '0')
-		/* Ignore leading zeroes.  */
-		;
-	      else if (c == '1')
-		nbits = 1;
-	      else if (c == '2' || c == '3')
-		nbits = 2;
-	      else
-		nbits = 3;
-	    }
-	  else
-	    nbits += 3;
-	}
-    }
-  if (end)
-    {
-      if (c && c != end)
-	{
-	  if (bits != NULL)
-	    *bits = -1;
-	  return 0;
-	}
-    }
-  else
-    --p;
-
-  if (radix == 8 && twos_complement_bits > 0 && nbits > twos_complement_bits)
-    {
-      /* We were supposed to parse a number with maximum
-	 TWOS_COMPLEMENT_BITS bits, but something went wrong.  */
-      if (bits != NULL)
-	*bits = -1;
-      return 0;
-    }
-
-  *pp = p;
-  if (overflow)
-    {
-      if (nbits == 0)
-	{
-	  /* Large decimal constants are an error (because it is hard to
-	     count how many bits are in them).  */
-	  if (bits != NULL)
-	    *bits = -1;
-	  return 0;
-	}
-
-      /* -0x7f is the same as 0x80.  So deal with it by adding one to
-	 the number of bits.  Two's complement representation octals
-	 can't have a '-' in front.  */
-      if (sign == -1 && !twos_complement_representation)
-	++nbits;
-      if (bits)
-	*bits = nbits;
-    }
-  else
-    {
-      if (bits)
-	*bits = 0;
-      return n * sign;
-    }
-  /* It's *BITS which has the interesting information.  */
-  return 0;
-}
-
-static struct type *
-read_range_type (const char **pp, int typenums[2], int type_size,
-		 struct objfile *objfile)
-{
-  struct gdbarch *gdbarch = objfile->arch ();
-  const char *orig_pp = *pp;
-  int rangenums[2];
-  long n2, n3;
-  int n2bits, n3bits;
-  int self_subrange;
-  struct type *result_type;
-  struct type *index_type = NULL;
-
-  /* First comes a type we are a subrange of.
-     In C it is usually 0, 1 or the type being defined.  */
-  if (read_type_number (pp, rangenums) != 0)
-    return error_type (pp, objfile);
-  self_subrange = (rangenums[0] == typenums[0] &&
-		   rangenums[1] == typenums[1]);
-
-  if (**pp == '=')
-    {
-      *pp = orig_pp;
-      index_type = read_type (pp, objfile);
-    }
-
-  /* A semicolon should now follow; skip it.  */
-  if (**pp == ';')
-    (*pp)++;
-
-  /* The remaining two operands are usually lower and upper bounds
-     of the range.  But in some special cases they mean something else.  */
-  n2 = read_huge_number (pp, ';', &n2bits, type_size);
-  n3 = read_huge_number (pp, ';', &n3bits, type_size);
-
-  if (n2bits == -1 || n3bits == -1)
-    return error_type (pp, objfile);
-
-  type_allocator alloc (objfile, get_current_subfile ()->language);
-
-  if (index_type)
-    goto handle_true_range;
-
-  /* If limits are huge, must be large integral type.  */
-  if (n2bits != 0 || n3bits != 0)
-    {
-      char got_signed = 0;
-      char got_unsigned = 0;
-      /* Number of bits in the type.  */
-      int nbits = 0;
-
-      /* If a type size attribute has been specified, the bounds of
-	 the range should fit in this size.  If the lower bounds needs
-	 more bits than the upper bound, then the type is signed.  */
-      if (n2bits <= type_size && n3bits <= type_size)
-	{
-	  if (n2bits == type_size && n2bits > n3bits)
-	    got_signed = 1;
-	  else
-	    got_unsigned = 1;
-	  nbits = type_size;
-	}
-      /* Range from 0 to <large number> is an unsigned large integral type.  */
-      else if ((n2bits == 0 && n2 == 0) && n3bits != 0)
-	{
-	  got_unsigned = 1;
-	  nbits = n3bits;
-	}
-      /* Range from <large number> to <large number>-1 is a large signed
-	 integral type.  Take care of the case where <large number> doesn't
-	 fit in a long but <large number>-1 does.  */
-      else if ((n2bits != 0 && n3bits != 0 && n2bits == n3bits + 1)
-	       || (n2bits != 0 && n3bits == 0
-		   && (n2bits == sizeof (long) * HOST_CHAR_BIT)
-		   && n3 == LONG_MAX))
-	{
-	  got_signed = 1;
-	  nbits = n2bits;
-	}
-
-      if (got_signed || got_unsigned)
-	return init_integer_type (alloc, nbits, got_unsigned, NULL);
-      else
-	return error_type (pp, objfile);
-    }
-
-  /* A type defined as a subrange of itself, with bounds both 0, is void.  */
-  if (self_subrange && n2 == 0 && n3 == 0)
-    return alloc.new_type (TYPE_CODE_VOID, TARGET_CHAR_BIT, nullptr);
-
-  /* If n3 is zero and n2 is positive, we want a floating type, and n2
-     is the width in bytes.
-
-     Fortran programs appear to use this for complex types also.  To
-     distinguish between floats and complex, g77 (and others?)  seem
-     to use self-subranges for the complexes, and subranges of int for
-     the floats.
-
-     Also note that for complexes, g77 sets n2 to the size of one of
-     the member floats, not the whole complex beast.  My guess is that
-     this was to work well with pre-COMPLEX versions of gdb.  */
-
-  if (n3 == 0 && n2 > 0)
-    {
-      struct type *float_type
-	= dbx_init_float_type (objfile, n2 * TARGET_CHAR_BIT);
-
-      if (self_subrange)
-	return init_complex_type (NULL, float_type);
-      else
-	return float_type;
-    }
-
-  /* If the upper bound is -1, it must really be an unsigned integral.  */
-
-  else if (n2 == 0 && n3 == -1)
-    {
-      int bits = type_size;
-
-      if (bits <= 0)
-	{
-	  /* We don't know its size.  It is unsigned int or unsigned
-	     long.  GCC 2.3.3 uses this for long long too, but that is
-	     just a GDB 3.5 compatibility hack.  */
-	  bits = gdbarch_int_bit (gdbarch);
-	}
-
-      return init_integer_type (alloc, bits, 1, NULL);
-    }
-
-  /* Special case: char is defined (Who knows why) as a subrange of
-     itself with range 0-127.  */
-  else if (self_subrange && n2 == 0 && n3 == 127)
-    {
-      struct type *type = init_integer_type (alloc, TARGET_CHAR_BIT,
-					     0, NULL);
-      type->set_has_no_signedness (true);
-      return type;
-    }
-  /* We used to do this only for subrange of self or subrange of int.  */
-  else if (n2 == 0)
-    {
-      /* -1 is used for the upper bound of (4 byte) "unsigned int" and
-	 "unsigned long", and we already checked for that,
-	 so don't need to test for it here.  */
-
-      if (n3 < 0)
-	/* n3 actually gives the size.  */
-	return init_integer_type (alloc, -n3 * TARGET_CHAR_BIT, 1, NULL);
-
-      /* Is n3 == 2**(8n)-1 for some integer n?  Then it's an
-	 unsigned n-byte integer.  But do require n to be a power of
-	 two; we don't want 3- and 5-byte integers flying around.  */
-      {
-	int bytes;
-	unsigned long bits;
-
-	bits = n3;
-	for (bytes = 0; (bits & 0xff) == 0xff; bytes++)
-	  bits >>= 8;
-	if (bits == 0
-	    && ((bytes - 1) & bytes) == 0) /* "bytes is a power of two" */
-	  return init_integer_type (alloc, bytes * TARGET_CHAR_BIT, 1, NULL);
-      }
-    }
-  /* I think this is for Convex "long long".  Since I don't know whether
-     Convex sets self_subrange, I also accept that particular size regardless
-     of self_subrange.  */
-  else if (n3 == 0 && n2 < 0
-	   && (self_subrange
-	       || n2 == -gdbarch_long_long_bit
-			  (gdbarch) / TARGET_CHAR_BIT))
-    return init_integer_type (alloc, -n2 * TARGET_CHAR_BIT, 0, NULL);
-  else if (n2 == -n3 - 1)
-    {
-      if (n3 == 0x7f)
-	return init_integer_type (alloc, 8, 0, NULL);
-      if (n3 == 0x7fff)
-	return init_integer_type (alloc, 16, 0, NULL);
-      if (n3 == 0x7fffffff)
-	return init_integer_type (alloc, 32, 0, NULL);
-    }
-
-  /* We have a real range type on our hands.  Allocate space and
-     return a real pointer.  */
-handle_true_range:
-
-  if (self_subrange)
-    index_type = builtin_type (objfile)->builtin_int;
-  else
-    index_type = *dbx_lookup_type (rangenums, objfile);
-  if (index_type == NULL)
-    {
-      /* Does this actually ever happen?  Is that why we are worrying
-	 about dealing with it rather than just calling error_type?  */
-
-      complaint (_("base type %d of range type is not defined"), rangenums[1]);
-
-      index_type = builtin_type (objfile)->builtin_int;
-    }
-
-  result_type
-    = create_static_range_type (alloc, index_type, n2, n3);
-  return (result_type);
-}
-
-/* Read in an argument list.  This is a list of types, separated by commas
-   and terminated with END.  Return the list of types read in, or NULL
-   if there is an error.  */
-
-static struct field *
-read_args (const char **pp, int end, struct objfile *objfile, int *nargsp,
-	   int *varargsp)
-{
-  /* FIXME!  Remove this arbitrary limit!  */
-  struct type *types[1024];	/* Allow for fns of 1023 parameters.  */
-  int n = 0, i;
-  struct field *rval;
-
-  while (**pp != end)
-    {
-      if (**pp != ',')
-	/* Invalid argument list: no ','.  */
-	return NULL;
-      (*pp)++;
-      STABS_CONTINUE (pp, objfile);
-      types[n++] = read_type (pp, objfile);
-    }
-  (*pp)++;			/* get past `end' (the ':' character).  */
-
-  if (n == 0)
-    {
-      /* We should read at least the THIS parameter here.  Some broken stabs
-	 output contained `(0,41),(0,42)=@s8;-16;,(0,43),(0,1);' where should
-	 have been present ";-16,(0,43)" reference instead.  This way the
-	 excessive ";" marker prematurely stops the parameters parsing.  */
-
-      complaint (_("Invalid (empty) method arguments"));
-      *varargsp = 0;
-    }
-  else if (types[n - 1]->code () != TYPE_CODE_VOID)
-    *varargsp = 1;
-  else
-    {
-      n--;
-      *varargsp = 0;
-    }
-
-  rval = XCNEWVEC (struct field, n);
-  for (i = 0; i < n; i++)
-    rval[i].set_type (types[i]);
-  *nargsp = n;
-  return rval;
-}
-\f
-/* Common block handling.  */
-
-/* List of symbols declared since the last BCOMM.  This list is a tail
-   of local_symbols.  When ECOMM is seen, the symbols on the list
-   are noted so their proper addresses can be filled in later,
-   using the common block base address gotten from the assembler
-   stabs.  */
-
-static struct pending *common_block;
-static int common_block_i;
-
-/* Name of the current common block.  We get it from the BCOMM instead of the
-   ECOMM to match IBM documentation (even though IBM puts the name both places
-   like everyone else).  */
-static char *common_block_name;
-
-/* Process a N_BCOMM symbol.  The storage for NAME is not guaranteed
-   to remain after this function returns.  */
-
-void
-common_block_start (const char *name, struct objfile *objfile)
-{
-  if (common_block_name != NULL)
-    {
-      complaint (_("Invalid symbol data: common block within common block"));
-    }
-  common_block = *get_local_symbols ();
-  common_block_i = common_block ? common_block->nsyms : 0;
-  common_block_name = obstack_strdup (&objfile->objfile_obstack, name);
-}
-
-/* Process a N_ECOMM symbol.  */
-
-void
-common_block_end (struct objfile *objfile)
-{
-  /* Symbols declared since the BCOMM are to have the common block
-     start address added in when we know it.  common_block and
-     common_block_i point to the first symbol after the BCOMM in
-     the local_symbols list; copy the list and hang it off the
-     symbol for the common block name for later fixup.  */
-  int i;
-  struct symbol *sym;
-  struct pending *newobj = 0;
-  struct pending *next;
-  int j;
-
-  if (common_block_name == NULL)
-    {
-      complaint (_("ECOMM symbol unmatched by BCOMM"));
-      return;
-    }
-
-  sym = new (&objfile->objfile_obstack) symbol;
-  /* Note: common_block_name already saved on objfile_obstack.  */
-  sym->set_linkage_name (common_block_name);
-  sym->set_loc_class_index (LOC_BLOCK);
-
-  /* Now we copy all the symbols which have been defined since the BCOMM.  */
-
-  /* Copy all the struct pendings before common_block.  */
-  for (next = *get_local_symbols ();
-       next != NULL && next != common_block;
-       next = next->next)
-    {
-      for (j = 0; j < next->nsyms; j++)
-	add_symbol_to_list (next->symbol[j], &newobj);
-    }
-
-  /* Copy however much of COMMON_BLOCK we need.  If COMMON_BLOCK is
-     NULL, it means copy all the local symbols (which we already did
-     above).  */
-
-  if (common_block != NULL)
-    for (j = common_block_i; j < common_block->nsyms; j++)
-      add_symbol_to_list (common_block->symbol[j], &newobj);
-
-  sym->set_type ((struct type *) newobj);
-
-  /* Should we be putting local_symbols back to what it was?
-     Does it matter?  */
-
-  i = hashname (sym->linkage_name ());
-  sym->set_value_chain (global_sym_chain[i]);
-  global_sym_chain[i] = sym;
-  common_block_name = NULL;
-}
-
-/* Add a common block's start address to the offset of each symbol
-   declared to be in it (by being between a BCOMM/ECOMM pair that uses
-   the common block name).  */
-
-static void
-fix_common_block (struct symbol *sym, CORE_ADDR valu, int section_index)
-{
-  struct pending *next = (struct pending *) sym->type ();
-
-  for (; next; next = next->next)
-    {
-      int j;
-
-      for (j = next->nsyms - 1; j >= 0; j--)
-	{
-	  next->symbol[j]->set_value_address
-	    (next->symbol[j]->value_address () + valu);
-	  next->symbol[j]->set_section_index (section_index);
-	}
-    }
-}
-\f
-
-
-/* Add {TYPE, TYPENUMS} to the NONAME_UNDEFS vector.
-   See add_undefined_type for more details.  */
-
-static void
-add_undefined_type_noname (struct type *type, int typenums[2])
-{
-  struct nat nat;
-
-  nat.typenums[0] = typenums [0];
-  nat.typenums[1] = typenums [1];
-  nat.type = type;
-
-  if (noname_undefs_length == noname_undefs_allocated)
-    {
-      noname_undefs_allocated *= 2;
-      noname_undefs = (struct nat *)
-	xrealloc ((char *) noname_undefs,
-		  noname_undefs_allocated * sizeof (struct nat));
-    }
-  noname_undefs[noname_undefs_length++] = nat;
-}
-
-/* Add TYPE to the UNDEF_TYPES vector.
-   See add_undefined_type for more details.  */
-
-static void
-add_undefined_type_1 (struct type *type)
-{
-  if (undef_types_length == undef_types_allocated)
-    {
-      undef_types_allocated *= 2;
-      undef_types = (struct type **)
-	xrealloc ((char *) undef_types,
-		  undef_types_allocated * sizeof (struct type *));
-    }
-  undef_types[undef_types_length++] = type;
-}
-
-/* What about types defined as forward references inside of a small lexical
-   scope?  */
-/* Add a type to the list of undefined types to be checked through
-   once this file has been read in.
-   
-   In practice, we actually maintain two such lists: The first list
-   (UNDEF_TYPES) is used for types whose name has been provided, and
-   concerns forward references (eg 'xs' or 'xu' forward references);
-   the second list (NONAME_UNDEFS) is used for types whose name is
-   unknown at creation time, because they were referenced through
-   their type number before the actual type was declared.
-   This function actually adds the given type to the proper list.  */
-
-static void
-add_undefined_type (struct type *type, int typenums[2])
-{
-  if (type->name () == NULL)
-    add_undefined_type_noname (type, typenums);
-  else
-    add_undefined_type_1 (type);
-}
-
-/* Try to fix all undefined types pushed on the UNDEF_TYPES vector.  */
-
-static void
-cleanup_undefined_types_noname (struct objfile *objfile)
-{
-  int i;
-
-  for (i = 0; i < noname_undefs_length; i++)
-    {
-      struct nat nat = noname_undefs[i];
-      struct type **type;
-
-      type = dbx_lookup_type (nat.typenums, objfile);
-      if (nat.type != *type && (*type)->code () != TYPE_CODE_UNDEF)
-	{
-	  /* The instance flags of the undefined type are still unset,
-	     and needs to be copied over from the reference type.
-	     Since replace_type expects them to be identical, we need
-	     to set these flags manually before hand.  */
-	  nat.type->set_instance_flags ((*type)->instance_flags ());
-	  replace_type (nat.type, *type);
-	}
-    }
-
-  noname_undefs_length = 0;
-}
-
-/* Go through each undefined type, see if it's still undefined, and fix it
-   up if possible.  We have two kinds of undefined types:
-
-   TYPE_CODE_ARRAY:  Array whose target type wasn't defined yet.
-   Fix:  update array length using the element bounds
-   and the target type's length.
-   TYPE_CODE_STRUCT, TYPE_CODE_UNION:  Structure whose fields were not
-   yet defined at the time a pointer to it was made.
-   Fix:  Do a full lookup on the struct/union tag.  */
-
-static void
-cleanup_undefined_types_1 (void)
-{
-  struct type **type;
-
-  /* Iterate over every undefined type, and look for a symbol whose type
-     matches our undefined type.  The symbol matches if:
-       1. It is a typedef in the STRUCT domain;
-       2. It has the same name, and same type code;
-       3. The instance flags are identical.
-     
-     It is important to check the instance flags, because we have seen
-     examples where the debug info contained definitions such as:
-
-	 "foo_t:t30=B31=xefoo_t:"
-
-     In this case, we have created an undefined type named "foo_t" whose
-     instance flags is null (when processing "xefoo_t"), and then created
-     another type with the same name, but with different instance flags
-     ('B' means volatile).  I think that the definition above is wrong,
-     since the same type cannot be volatile and non-volatile at the same
-     time, but we need to be able to cope with it when it happens.  The
-     approach taken here is to treat these two types as different.  */
-
-  for (type = undef_types; type < undef_types + undef_types_length; type++)
-    {
-      switch ((*type)->code ())
-	{
-
-	case TYPE_CODE_STRUCT:
-	case TYPE_CODE_UNION:
-	case TYPE_CODE_ENUM:
-	  {
-	    /* Check if it has been defined since.  Need to do this here
-	       as well as in check_typedef to deal with the (legitimate in
-	       C though not C++) case of several types with the same name
-	       in different source files.  */
-	    if ((*type)->is_stub ())
-	      {
-		struct pending *ppt;
-		int i;
-		/* Name of the type, without "struct" or "union".  */
-		const char *type_name = (*type)->name ();
-
-		if (type_name == NULL)
-		  {
-		    complaint (_("need a type name"));
-		    break;
-		  }
-		for (ppt = *get_file_symbols (); ppt; ppt = ppt->next)
-		  {
-		    for (i = 0; i < ppt->nsyms; i++)
-		      {
-			struct symbol *sym = ppt->symbol[i];
-
-			if (sym->loc_class () == LOC_TYPEDEF
-			    && sym->domain () == STRUCT_DOMAIN
-			    && (sym->type ()->code () == (*type)->code ())
-			    && ((*type)->instance_flags ()
-				== sym->type ()->instance_flags ())
-			    && strcmp (sym->linkage_name (), type_name) == 0)
-			  replace_type (*type, sym->type ());
-		      }
-		  }
-	      }
-	  }
-	  break;
-
-	default:
-	  {
-	    complaint (_("forward-referenced types left unresolved, "
-		       "type code %d."),
-		       (*type)->code ());
-	  }
-	  break;
-	}
-    }
-
-  undef_types_length = 0;
-}
-
-/* Try to fix all the undefined types we encountered while processing
-   this unit.  */
-
-void
-cleanup_undefined_stabs_types (struct objfile *objfile)
-{
-  cleanup_undefined_types_1 ();
-  cleanup_undefined_types_noname (objfile);
-}
-
-/* See stabsread.h.  */
-
-void
-scan_file_globals (struct objfile *objfile)
-{
-  int hash;
-  struct symbol *sym, *prev;
-  struct objfile *resolve_objfile;
-
-  /* SVR4 based linkers copy referenced global symbols from shared
-     libraries to the main executable.
-     If we are scanning the symbols for a shared library, try to resolve
-     them from the minimal symbols of the main executable first.  */
-
-  if (current_program_space->symfile_object_file
-      && objfile != current_program_space->symfile_object_file)
-    resolve_objfile = current_program_space->symfile_object_file;
-  else
-    resolve_objfile = objfile;
-
-  while (1)
-    {
-      /* Avoid expensive loop through all minimal symbols if there are
-	 no unresolved symbols.  */
-      for (hash = 0; hash < HASHSIZE; hash++)
-	{
-	  if (global_sym_chain[hash])
-	    break;
-	}
-      if (hash >= HASHSIZE)
-	return;
-
-      for (minimal_symbol *msymbol : resolve_objfile->msymbols ())
-	{
-	  QUIT;
-
-	  /* Skip static symbols.  */
-	  switch (msymbol->type ())
-	    {
-	    case mst_file_text:
-	    case mst_file_data:
-	    case mst_file_bss:
-	      continue;
-	    default:
-	      break;
-	    }
-
-	  prev = NULL;
-
-	  /* Get the hash index and check all the symbols
-	     under that hash index.  */
-
-	  hash = hashname (msymbol->linkage_name ());
-
-	  for (sym = global_sym_chain[hash]; sym;)
-	    {
-	      if (strcmp (msymbol->linkage_name (), sym->linkage_name ()) == 0)
-		{
-		  /* Splice this symbol out of the hash chain and
-		     assign the value we have to it.  */
-		  if (prev)
-		    {
-		      prev->set_value_chain (sym->value_chain ());
-		    }
-		  else
-		    {
-		      global_sym_chain[hash] = sym->value_chain ();
-		    }
-
-		  /* Check to see whether we need to fix up a common block.  */
-		  /* Note: this code might be executed several times for
-		     the same symbol if there are multiple references.  */
-		  if (sym)
-		    {
-		      if (sym->loc_class () == LOC_BLOCK)
-			fix_common_block
-			  (sym, msymbol->value_address (resolve_objfile),
-			   msymbol->section_index ());
-		      else
-			sym->set_value_address
-			  (msymbol->value_address (resolve_objfile));
-		      sym->set_section_index (msymbol->section_index ());
-		    }
-
-		  if (prev)
-		    {
-		      sym = prev->value_chain ();
-		    }
-		  else
-		    {
-		      sym = global_sym_chain[hash];
-		    }
-		}
-	      else
-		{
-		  prev = sym;
-		  sym = sym->value_chain ();
-		}
-	    }
-	}
-      if (resolve_objfile == objfile)
-	break;
-      resolve_objfile = objfile;
-    }
-
-  /* Change the storage class of any remaining unresolved globals to
-     LOC_UNRESOLVED and remove them from the chain.  */
-  for (hash = 0; hash < HASHSIZE; hash++)
-    {
-      sym = global_sym_chain[hash];
-      while (sym)
-	{
-	  prev = sym;
-	  sym = sym->value_chain ();
-
-	  /* Change the symbol address from the misleading chain value
-	     to address zero.  */
-	  prev->set_value_address (0);
-
-	  /* Complain about unresolved common block symbols.  */
-	  if (prev->loc_class () == LOC_STATIC)
-	    prev->set_loc_class_index (LOC_UNRESOLVED);
-	  else
-	    complaint (_("%s: common block `%s' from "
-			 "global_sym_chain unresolved"),
-		       objfile_name (objfile), prev->print_name ());
-	}
-    }
-  memset (global_sym_chain, 0, sizeof (global_sym_chain));
-}
-
-/* Initialize anything that needs initializing when starting to read
-   a fresh piece of a symbol file, e.g. reading in the stuff corresponding
-   to a psymtab.  */
-
-void
-stabsread_init (void)
-{
-}
-
-/* Initialize anything that needs initializing when a completely new
-   symbol file is specified (not just adding some symbols from another
-   file, e.g. a shared library).  */
-
-void
-stabsread_new_init (void)
-{
-  /* Empty the hash table of global syms looking for values.  */
-  memset (global_sym_chain, 0, sizeof (global_sym_chain));
-}
-
-/* Initialize anything that needs initializing at the same time as
-   start_compunit_symtab() is called.  */
-
-void
-start_stabs (void)
-{
-  global_stabs = NULL;		/* AIX COFF */
-  /* Leave FILENUM of 0 free for builtin types and this file's types.  */
-  n_this_object_header_files = 1;
-  type_vector_length = 0;
-  type_vector = (struct type **) 0;
-  within_function = 0;
-
-  /* FIXME: If common_block_name is not already NULL, we should complain().  */
-  common_block_name = NULL;
-}
-
-/* Call after end_compunit_symtab().  */
-
-void
-end_stabs (void)
-{
-  if (type_vector)
-    {
-      xfree (type_vector);
-    }
-  type_vector = 0;
-  type_vector_length = 0;
-  previous_stab_code = 0;
-}
-
-void
-finish_global_stabs (struct objfile *objfile)
-{
-  if (global_stabs)
-    {
-      patch_block_stabs (*get_global_symbols (), global_stabs, objfile);
-      xfree (global_stabs);
-      global_stabs = NULL;
-    }
-}
-
-/* Find the end of the name, delimited by a ':', but don't match
-   ObjC symbols which look like -[Foo bar::]:bla.  */
-static const char *
-find_name_end (const char *name)
-{
-  const char *s = name;
-
-  if (s[0] == '-' || *s == '+')
-    {
-      /* Must be an ObjC method symbol.  */
-      if (s[1] != '[')
-	{
-	  error (_("invalid symbol name \"%s\""), name);
-	}
-      s = strchr (s, ']');
-      if (s == NULL)
-	{
-	  error (_("invalid symbol name \"%s\""), name);
-	}
-      return strchr (s, ':');
-    }
-  else
-    {
-      return strchr (s, ':');
-    }
-}
-
-/* Initializer for this module.  */
-
-INIT_GDB_FILE (stabsread)
-{
-  undef_types_allocated = 20;
-  undef_types_length = 0;
-  undef_types = XNEWVEC (struct type *, undef_types_allocated);
-
-  noname_undefs_allocated = 20;
-  noname_undefs_length = 0;
-  noname_undefs = XNEWVEC (struct nat, noname_undefs_allocated);
-
-  stab_register_index = register_symbol_register_impl (LOC_REGISTER,
-						       &stab_register_funcs);
-  stab_regparm_index = register_symbol_register_impl (LOC_REGPARM_ADDR,
-						      &stab_register_funcs);
-}
diff --git a/gdb/stabsread.h b/gdb/stabsread.h
deleted file mode 100644
index 1c9ce854dff..00000000000
--- a/gdb/stabsread.h
+++ /dev/null
@@ -1,309 +0,0 @@
-/* Include file for stabs debugging format support functions.
-   Copyright (C) 1986-2025 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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef GDB_STABSREAD_H
-#define GDB_STABSREAD_H
-
-#include "buildsym-legacy.h"
-
-struct objfile;
-struct legacy_psymtab;
-enum language;
-
-/* Definitions, prototypes, etc for stabs debugging format support
-   functions.  */
-
-/* Count symbols as they are processed, for error messages.  */
-
-extern unsigned int symnum;
-
-#define next_symbol_text(objfile) (*next_symbol_text_func)(objfile)
-
-/* Function to invoke get the next symbol.  Return the symbol name.  */
-
-extern const char *(*next_symbol_text_func) (struct objfile *);
-
-/* Global variable which, when set, indicates that we are processing a
-   .o file compiled with gcc */
-
-extern unsigned char processing_gcc_compilation;
-
-/* Nonzero if within a function (so symbols should be local, if
-   nothing says specifically).  */
-
-extern int within_function;
-
-/* Hash table of global symbols whose values are not known yet.
-   They are chained through the SYMBOL_VALUE_CHAIN, since we don't
-   have the correct data for that slot yet.
-
-   The use of the LOC_BLOCK code in this chain is nonstandard--
-   it refers to a FORTRAN common block rather than the usual meaning, and
-   the such LOC_BLOCK symbols use their fields in nonstandard ways.  */
-
-extern struct symbol *global_sym_chain[HASHSIZE];
-
-extern void common_block_start (const char *, struct objfile *);
-extern void common_block_end (struct objfile *);
-
-/* Kludge for xcoffread.c */
-
-struct pending_stabs
-  {
-    int count;
-    int length;
-    char *stab[1];
-  };
-
-extern struct pending_stabs *global_stabs;
-
-/* 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;
-\f
-/* Support for Sun changes to dbx symbol format.  */
-
-/* For each identified header file, we have a table of types defined
-   in that header file.
-
-   header_files maps header file names to their type tables.
-   It is a vector of n_header_files elements.
-   Each element describes one header file.
-   It contains a vector of types.
-
-   Sometimes it can happen that the same header file produces
-   different results when included in different places.
-   This can result from conditionals or from different
-   things done before including the file.
-   When this happens, there are multiple entries for the file in this table,
-   one entry for each distinct set of results.
-   The entries are distinguished by the INSTANCE field.
-   The INSTANCE field appears in the N_BINCL and N_EXCL symbol table and is
-   used to match header-file references to their corresponding data.  */
-
-struct header_file
-  {
-
-    /* Name of header file */
-
-    char *name;
-
-    /* Numeric code distinguishing instances of one header file that
-       produced different results when included.  It comes from the
-       N_BINCL or N_EXCL.  */
-
-    int instance;
-
-    /* Pointer to vector of types */
-
-    struct type **vector;
-
-    /* Allocated length (# elts) of that vector */
-
-    int length;
-
-  };
-
-/* The table of header_files of this OBJFILE.  */
-#define HEADER_FILES(OBJFILE) (DBX_SYMFILE_INFO (OBJFILE)->header_files)
-
-/* The actual length of HEADER_FILES.  */
-#define N_HEADER_FILES(OBJFILE) (DBX_SYMFILE_INFO (OBJFILE)->n_header_files)
-
-/* The allocated length of HEADER_FILES.  */
-#define N_ALLOCATED_HEADER_FILES(OBJFILE) \
-  (DBX_SYMFILE_INFO (OBJFILE)->n_allocated_header_files)
-
-/* Within each object file, various header files are assigned numbers.
-   A type is defined or referred to with a pair of numbers
-   (FILENUM,TYPENUM) where FILENUM is the number of the header file
-   and TYPENUM is the number within that header file.
-   TYPENUM is the index within the vector of types for that header file.
-
-   FILENUM == 0 is special; it refers to the main source of the object file,
-   and not to any header file.  FILENUM != 1 is interpreted by looking it up
-   in the following table, which contains indices in header_files.  */
-
-extern int *this_object_header_files;
-
-extern int n_this_object_header_files;
-
-extern int n_allocated_this_object_header_files;
-
-extern void cleanup_undefined_stabs_types (struct objfile *);
-
-extern long read_number (char **, int);
-
-extern struct symbol *define_symbol (CORE_ADDR, const char *, int, int,
-				     struct objfile *);
-
-extern void stabsread_init (void);
-
-extern void stabsread_new_init (void);
-
-extern void start_stabs (void);
-
-extern void end_stabs (void);
-
-extern void finish_global_stabs (struct objfile *objfile);
-\f
-class psymtab_storage;
-
-/* Functions exported by dbxread.c.  These are not in stabsread.c because
-   they are only used by some stabs readers.  */
-
-extern legacy_psymtab *stabs_end_psymtab
-  (struct objfile *objfile, psymtab_storage *partial_symtabs,
-   legacy_psymtab *pst,
-   const char **include_list, int num_includes,
-   int capping_symbol_offset, unrelocated_addr capping_text,
-   legacy_psymtab **dependency_list, int number_dependencies,
-   int textlow_not_set);
-
-extern void process_one_symbol (int, int, CORE_ADDR, const char *,
-				const section_offsets &,
-				struct objfile *, enum language);
-
-/* Setup partial_symtab's describing each source file for which
-   debugging information is available.  */
-
-void
-read_stabs_symtab (struct objfile *, symfile_add_flags);
-
-extern void elfstab_build_psymtabs (struct objfile *objfile,
-				    asection *stabsect,
-				    file_ptr stabstroffset,
-				    unsigned int stabstrsize);
-
-extern void coffstab_build_psymtabs
-  (struct objfile *objfile,
-   CORE_ADDR textaddr, unsigned int textsize,
-   const std::vector<asection *> &stabs,
-   file_ptr stabstroffset, unsigned int stabstrsize);
-
-extern int symbol_reference_defined (const char **);
-
-extern void ref_add (int, struct symbol *, const char *, CORE_ADDR);
-
-extern struct symbol *ref_search (int);
-
-extern void free_header_files (void);
-
-extern void init_header_files (void);
-
-/* Scan through all of the global symbols defined in the object file,
-   assigning values to the debugging symbols that need to be assigned
-   to.  Get these symbols from the minimal symbol table.  */
-
-extern void scan_file_globals (struct objfile *objfile);
-
-/* Complaints about the symbols we have encountered.  */
-
-void
-unknown_symtype_complaint (const char *);
-
-void
-lbrac_mismatch_complaint (int);
-
-void
-repeated_header_complaint (const char *, int);
-
-bound_minimal_symbol
-find_stab_function (const char *, const char *, struct objfile *);
-
-/* This handles a single symbol from the symbol-file, building symbols
-   into a GDB symtab.  It takes these arguments and an implicit argument.
-
-   TYPE is the type field of the ".stab" symbol entry.
-   DESC is the desc field of the ".stab" entry.
-   VALU is the value field of the ".stab" entry.
-   NAME is the symbol name, in our address space.
-   SECTION_OFFSETS is a set of amounts by which the sections of this
-   object file were relocated when it was loaded into memory.  Note
-   that these section_offsets are not the objfile->section_offsets but
-   the pst->section_offsets.  All symbols that refer to memory
-   locations need to be offset by these amounts.
-   OBJFILE is the object file from which we are reading symbols.  It
-   is used in end_compunit_symtab.
-   LANGUAGE is the language of the symtab.
-*/
-
-void
-process_one_symbol (int, int, CORE_ADDR, const char *,
-		    const section_offsets &,
-		    struct objfile *, enum language);
-
-#define LDSYMOFF(p) (((struct symloc *)((p)->read_symtab_private))->ldsymoff)
-#define LDSYMLEN(p) (((struct symloc *)((p)->read_symtab_private))->ldsymlen)
-#define SYMLOC(p) ((struct symloc *)((p)->read_symtab_private))
-#define SYMBOL_SIZE(p) (SYMLOC(p)->symbol_size)
-#define SYMBOL_OFFSET(p) (SYMLOC(p)->symbol_offset)
-#define STRING_OFFSET(p) (SYMLOC(p)->string_offset)
-#define FILE_STRING_OFFSET(p) (SYMLOC(p)->file_string_offset)
-#define PST_LANGUAGE(p) (SYMLOC(p)->pst_language)
-
-#define INTERNALIZE_SYMBOL(intern, extern, abfd)			\
-  {									\
-    (intern).n_strx = bfd_h_get_32 (abfd, (extern)->e_strx);		\
-    (intern).n_type = bfd_h_get_8 (abfd, (extern)->e_type);		\
-    (intern).n_other = 0;						\
-    (intern).n_desc = bfd_h_get_16 (abfd, (extern)->e_desc);  		\
-    if (bfd_get_sign_extend_vma (abfd))					\
-      (intern).n_value = bfd_h_get_signed_32 (abfd, (extern)->e_value);	\
-    else								\
-      (intern).n_value = bfd_h_get_32 (abfd, (extern)->e_value);	\
-  }
-
-/* We put a pointer to this structure in the read_symtab_private field
-   of the psymtab.  */
-
-struct symloc
-  {
-    /* Offset within the file symbol table of first local symbol for this
-       file.  */
-
-    int ldsymoff;
-
-    /* Length (in bytes) of the section of the symbol table devoted to
-       this file's symbols (actually, the section bracketed may contain
-       more than just this file's symbols).  If ldsymlen is 0, the only
-       reason for this thing's existence is the dependency list.  Nothing
-       else will happen when it is read in.  */
-
-    int ldsymlen;
-
-    /* The size of each symbol in the symbol file (in external form).  */
-
-    int symbol_size;
-
-    /* Further information needed to locate the symbols if they are in
-       an ELF file.  */
-
-    int symbol_offset;
-    int string_offset;
-    int file_string_offset;
-    enum language pst_language;
-  };
-
-static inline void
-stabs_deprecated_warning ()
-{
-  warning (_("Stabs support is deprecated and will be removed soon."));
-}
-#endif /* GDB_STABSREAD_H */
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index 2ad3620c9f2..2447737d87f 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -59,9 +59,6 @@ print_objfile_statistics (void)
       {
 	QUIT;
 	gdb_printf (_("Statistics for '%s':\n"), objfile_name (&objfile));
-	if (OBJSTAT ((&objfile), n_stabs) > 0)
-	  gdb_printf (_("  Number of \"stab\" symbols read: %d\n"),
-		      OBJSTAT ((&objfile), n_stabs));
 	if (objfile.per_bfd->n_minsyms > 0)
 	  gdb_printf (_("  Number of \"minimal\" symbols read: %d\n"),
 		      objfile.per_bfd->n_minsyms);
diff --git a/gdb/testsuite/gdb.stabs/aout.sed b/gdb/testsuite/gdb.stabs/aout.sed
deleted file mode 100644
index 1bc5b1d7bc3..00000000000
--- a/gdb/testsuite/gdb.stabs/aout.sed
+++ /dev/null
@@ -1,16 +0,0 @@
-s/# Irix4 sed blows up if you have a sed command starting with "#"//
-s/# Avoid it by putting the comments within real sed commands.//
-s/# GDB legitimately expects a file name.//
-s/# The sun3 assembler bogusly requires that the value of this stab be a//
-s/# label.  Placate it.//
-1i\
-	.stabs "weird.c",0x64,0,0,Label0\
-Label0:
-s/N_LSYM/0x80/
-s/N_GSYM/0x20/
-s/# Replace a single backslash with a doubled backslash//
-/\.stabs/s/\\\([^"]\)/\\\\\1/g
-s/\.begin_common\(.*\)/.stabs \1,0xe2,0,0,0/
-s/\.end_common\(.*\)/.stabs \1,0xe4,0,0,0/
-s/\.align_it/.align 2/
-/^#/d
diff --git a/gdb/testsuite/gdb.stabs/ecoff.sed b/gdb/testsuite/gdb.stabs/ecoff.sed
deleted file mode 100644
index 3411c294198..00000000000
--- a/gdb/testsuite/gdb.stabs/ecoff.sed
+++ /dev/null
@@ -1,17 +0,0 @@
-# GDB legitimately expects a file name.
-1i\
- .file	1 "weird.c"\
-\ #@stabs\
-\ #.stabs "weird.c",0x64,0,0,0
-/^#/d
-s/" *, */",/g
-s/\([0-9]\) *, */\1,/g
-s/  *$//
-s/N_LSYM/0x80/
-s/N_GSYM/0x20/
-s/\.begin_common\(.*\)/.stabs \1,0xe2,0,0,0/
-s/\.end_common\(.*\)/.stabs \1,0xe4,0,0,0/
-s/\.align_it/.align 2/
-/.if/d
-/.endif/d
-s/\.stabs/ #.stabs/
diff --git a/gdb/testsuite/gdb.stabs/exclfwd.exp b/gdb/testsuite/gdb.stabs/exclfwd.exp
deleted file mode 100644
index b2adbf87e8e..00000000000
--- a/gdb/testsuite/gdb.stabs/exclfwd.exp
+++ /dev/null
@@ -1,57 +0,0 @@
-#   Copyright 2004-2025 Free Software Foundation, Inc.
-
-# 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 3 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, see <http://www.gnu.org/licenses/>.
-
-# Please email any bugs, comments, and/or additions to this file to:
-# bug-gdb@gnu.org
-
-#
-# test running programs
-#
-
-standard_testfile exclfwd1.c exclfwd2.c
-
-include_file exclfwd.h
-
-if {[prepare_for_testing "failed to prepare" $testfile \
-	 [list $srcfile $srcfile2] debug]} {
-    return -1
-}
-
-if {![runto_main]} {
-    return
-}
-
-get_debug_format
-
-gdb_test "ptype v1" \
-    [multi_line \
-	 "type = struct a {" \
-	 "    int x;" \
-	 "    int y;" \
-	 "}"]
-
-if {[test_debug_format "stabs"]} {
-    setup_kfail "gdb/1602" *-*-*
-}
-gdb_test "ptype v2" \
-    [multi_line \
-	 "type = struct a {" \
-	 "    const char .c;" \
-	 "}"]
-
-if {[test_debug_format "stabs"]} {
-    setup_kfail "gdb/1603" *-*-*
-}
-gdb_test "ptype v3" "type = const char ."
diff --git a/gdb/testsuite/gdb.stabs/exclfwd.h b/gdb/testsuite/gdb.stabs/exclfwd.h
deleted file mode 100644
index d9ce9ffc36b..00000000000
--- a/gdb/testsuite/gdb.stabs/exclfwd.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* This testcase is part of GDB, the GNU debugger.
-
-   Copyright 2004-2025 Free Software Foundation, Inc.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.
-
-   Please email any bugs, comments, and/or additions to this file to:
-   bug-gdb@gnu.org  */
-
-typedef struct a a_t;
diff --git a/gdb/testsuite/gdb.stabs/exclfwd1.c b/gdb/testsuite/gdb.stabs/exclfwd1.c
deleted file mode 100644
index 45fbd65b76b..00000000000
--- a/gdb/testsuite/gdb.stabs/exclfwd1.c
+++ /dev/null
@@ -1,34 +0,0 @@
-/* This testcase is part of GDB, the GNU debugger.
-
-   Copyright 2004-2025 Free Software Foundation, Inc.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.
-
-   Please email any bugs, comments, and/or additions to this file to:
-   bug-gdb@gnu.org  */
-
-#include "exclfwd.h"
-
-struct a 
-{
-  int x, y;
-};
-
-a_t v1;
-
-int
-main ()
-{
-  return 0;
-}
diff --git a/gdb/testsuite/gdb.stabs/exclfwd2.c b/gdb/testsuite/gdb.stabs/exclfwd2.c
deleted file mode 100644
index 9bd4a7065d9..00000000000
--- a/gdb/testsuite/gdb.stabs/exclfwd2.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* This testcase is part of GDB, the GNU debugger.
-
-   Copyright 2004-2025 Free Software Foundation, Inc.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.
-
-   Please email any bugs, comments, and/or additions to this file to:
-   bug-gdb@gnu.org  */
-
-#include "exclfwd.h"
-
-struct a
-{
-  const char *c;
-};
-
-a_t v2;
-const char *v3;
diff --git a/gdb/testsuite/gdb.stabs/gdb11479.c b/gdb/testsuite/gdb.stabs/gdb11479.c
deleted file mode 100644
index d094899d7f8..00000000000
--- a/gdb/testsuite/gdb.stabs/gdb11479.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* This testcase is part of GDB, the GNU debugger.
-
-   Copyright 2010-2025 Free Software Foundation, Inc.
-
-   Contributed by Pierre Muller.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.
-
-   Qualifiers of forward types are not resolved correctly with stabs.  */
-
-struct dummy;
-
-enum dummy_enum;
-
-/* This function prevents the compiler from dropping local variables
-   we need for the test.  */
-void *hack (const struct dummy *t, const enum dummy_enum *e);
-
-const void *
-test (const struct dummy *t)
-{
-  const struct dummy *tt;
-  enum dummy_enum *e;
-  tt = t;
-  return hack (t, e);
-}
-
-void *
-test2 (struct dummy *t)
-{
-  struct dummy *tt;
-  const enum dummy_enum *e;
-  tt = t;
-  return hack (t, e);
-}
-
-
-struct dummy {
- int x;
- int y;
- double b;
-} tag_dummy;
-
-enum dummy_enum {
-  enum1,
-  enum2
-} tag_dummy_enum;
-
-void *
-hack (const struct dummy *t, const enum dummy_enum *e)
-{
-  return (void *) t;
-}
-
-int
-main ()
-{
-  struct dummy tt;
-  tt.x = 5;
-  tt.y = 25;
-  tt.b = 2.5;
-  test2 (&tt);
-  test (&tt);
-  return 0;
-}
diff --git a/gdb/testsuite/gdb.stabs/gdb11479.exp b/gdb/testsuite/gdb.stabs/gdb11479.exp
deleted file mode 100644
index 2318c0f6cdc..00000000000
--- a/gdb/testsuite/gdb.stabs/gdb11479.exp
+++ /dev/null
@@ -1,59 +0,0 @@
-# This testcase is part of GDB, the GNU debugger.
-
-# Copyright 2010-2025 Free Software Foundation, Inc.
-
-# 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 3 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, see <http://www.gnu.org/licenses/>.
-
-# Test GDB stabs problem with qualified parameter of forward types.
-
-standard_testfile
-
-proc do_test {version} {
-    with_test_prefix "$version" {
-	if { ![runto_main] } {
-	    return -1
-	}
-	gdb_test "rb test" "" "set breakpoints"
-	gdb_test "continue" "Breakpoint .* test2 .*" \
-	    "stop at first breakpoint in test2 function"
-
-	# Check that the struct is read in correctly.
-	gdb_test "print *t" ".*\{x = 5, y = 25, b = 2.5\}.*" \
-	    "Inspect t in test2"
-
-	# Check that the enum type length has been set to a non-zero value.
-	gdb_test "print sizeof (*e)" "= \[1-9\]*" "sizeof (*e) in test2"
-
-	gdb_test "continue" "Breakpoint .* test .*" \
-	    "Stop at first breakpoint test function"
-
-	gdb_test "print *t" ".*\{x = 5, y = 25, b = 2.5\}.*" \
-	    "Inspect t in test"
-
-	# Check that the enum type length has been set to a non-zero value.
-	gdb_test "print sizeof (*e)" "= \[1-9\]*" "sizeof (*e) in test"
-    }
-}
-
-# Compile and test with stabs debug format.
-if { [prepare_for_testing "failed to prepare" ${testfile}-stabs $srcfile \
-	  {debug additional_flags=-gstabs quiet}] == 0 } {
-    do_test forced_stabs
-}
-
-# Compile and test with the default debug format.
-if { [prepare_for_testing "failed to prepare" ${testfile}-default \
-	  $srcfile] == 0 } {
-    do_test natural_debug_format
-}
diff --git a/gdb/testsuite/gdb.stabs/hppa.sed b/gdb/testsuite/gdb.stabs/hppa.sed
deleted file mode 100644
index bc1cf90f7b2..00000000000
--- a/gdb/testsuite/gdb.stabs/hppa.sed
+++ /dev/null
@@ -1,20 +0,0 @@
-s/# Old OSF sed blows up if you have a sed command starting with "#"//
-s/# Avoid it by putting the comments within real sed commands.//
-s/# GDB legitimately expects a file name.//
-s/# The sun3 assembler bogusly requires that the value of this stab be a//
-s/# label.  Placate it.//
-1i\
-\	.stabs "weird.c",0x64,0,0,Label0\
-Label0:
-s/N_LSYM/0x80/
-s/N_GSYM/0x20/
-s/# Replace a single backslash with a doubled backslash//
-/\.stabs/s/\\/\\\\/g
-s/# Only labels should be at the beginning of a line, assembler directives//
-s/# and instructions should start somewhere after column zero.//
-/^\./s/^\./	./
-s/\.begin_common\(.*\)/.stabs \1,0xe2,0,0,0/
-s/\.end_common\(.*\)/.stabs \1,0xe4,0,0,0/
-s/\.align_it/.align 4/
-s/\.globl/.export/
-/^#/d
diff --git a/gdb/testsuite/gdb.stabs/weird.def b/gdb/testsuite/gdb.stabs/weird.def
deleted file mode 100644
index f809963e82f..00000000000
--- a/gdb/testsuite/gdb.stabs/weird.def
+++ /dev/null
@@ -1,900 +0,0 @@
-# We'll need an integer type.
-.stabs "inttype:t1=bu4;0;32;",N_LSYM,0,0,0
-
-# There are several kinds of tests in here.  We mix up the order to see
-# if we can test for poor handling of a stab affecting the next or previous
-# stab.
-
-# Try all possible symbol descriptors.  Note that GDB should merely
-# complain() even though these strings are totally bogus.  This allows
-# future compilers to define new syntaxes.
-.stabs "sym32:  !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-# Type descriptors.
-.stabs "type32:t32=  !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-# Note that a 'G', N_GSYM symbol needs no value.  The name of the stab
-# is used to look up a non-stab symbol with the same name.  On some
-# machines, the non-stab symbols will normally have underscores, but
-# if they lack the underscores, then GDB will simply put the symbol in
-# the minimal symbol table all the same.  So we can use them without
-# underscores and that way we don't need to worry about which machines
-# need underscores.
-
-# Type attributes.
-.stabs "attr104:G404=@h !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr105:G405=@i !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-# A few real type attributes.
-# Alignment.
-.stabs "var0:G300=@a8;1",N_GSYM,0,0, 0
-.globl var0
-.data
-.align_it
-var0:
-.long 42
-
-.stabs "sym33:! !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym35:# !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym36:$ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym37:% !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym38:& !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym39:' !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym40:( !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym41:) !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym42:* !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym43:+ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym44:, !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym45:- !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.globl attr122
-.data
-.align_it
-attr122:
-.long 42
-.globl attr123
-.data
-.align_it
-attr123:
-.long 42
-.globl attr124
-.data
-.align_it
-attr124:
-.long 42
-
-.stabs "sym46:. !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym47:/ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym48:0 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym49:1 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym50:2 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.stabs "attr96:G396=@` !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr97:G397=@a !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr98:G398=@b !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr99:G399=@c !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-.stabs "sym51:3 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym52:4 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym53:5 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym54:6 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym55:7 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym56:8 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym57:9 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym58:: !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym59:; !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym60:< !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym61:= !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym62:> !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym63:? !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym64:@ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym65:A !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym66:B !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym67:C !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym68:D !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym69:E !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym70:F !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym71:G !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym72:H !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym73:I !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym74:J !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym75:K !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym76:L !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym77:M !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym78:N !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym79:O !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym80:P !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym81:Q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym82:R !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym83:S !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym84:T !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym85:U !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym86:V !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym87:W !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym88:X !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym89:Y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym90:Z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym91:[ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.stabs "sym93:] !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym94:^ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym95:_ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym96:` !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym97:a !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym98:b !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym99:c !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym100:d !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym101:e !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym102:f !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym103:g !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym104:h !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym105:i !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym106:j !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym107:k !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym108:l !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym109:m !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym110:n !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym111:o !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym112:p !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym113:q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym114:r !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym115:s !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym116:t !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym117:u !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym118:v !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym119:w !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym120:x !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym121:y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym122:z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym123:{ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym124:| !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym125:} !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "sym126:~ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.stabs "type33:t33=! !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type35:t35=# !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type36:t36=$ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type37:t37=% !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type38:t38=& !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type39:t39=' !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type40:t40=( !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type41:t41=) !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type42:t42=* !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type43:t43=+ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type44:t44=, !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type45:t45=- !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type46:t46=. !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type47:t47=/ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type48:t48=0 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type49:t49=1 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type50:t50=2 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type51:t51=3 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type52:t52=4 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type53:t53=5 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type54:t54=6 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type55:t55=7 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type56:t56=8 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type57:t57=9 !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type58:t58=: !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type59:t59=; !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type60:t60=< !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type61:t61== !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type62:t62=> !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type63:t63=? !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type64:t64=@ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type65:t65=A !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type66:t66=B !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type67:t67=C !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.globl attr66
-.data
-.align_it
-attr66:
-.long 42
-.globl attr67
-.data
-.align_it
-attr67:
-.long 42
-.globl attr68
-.data
-.align_it
-attr68:
-.long 42
-.globl attr69
-.data
-.align_it
-attr69:
-.long 42
-
-.stabs "type68:t68=D !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type69:t69=E !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type70:t70=F !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type71:t71=G !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type72:t72=H !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type73:t73=I !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type74:t74=J !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type75:t75=K !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type76:t76=L !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type77:t77=M !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type78:t78=N !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type79:t79=O !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type80:t80=P !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type81:t81=Q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type82:t82=R !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type83:t83=S !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type84:t84=T !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type85:t85=U !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type86:t86=V !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type87:t87=W !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.stabs "attr69:G369=@E !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr70:G370=@F !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr71:G371=@G !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-.stabs "type88:t88=X !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type89:t89=Y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type90:t90=Z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type91:t91=[ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.stabs "type93:t93=] !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type94:t94=^ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type95:t95=_ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type96:t96=` !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type97:t97=a !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type98:t98=b !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type99:t99=c !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type100:t100=d !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type101:t101=e !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type102:t102=f !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type103:t103=g !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type104:t104=h !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type105:t105=i !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type106:t106=j !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type107:t107=k !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type108:t108=l !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type109:t109=m !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type110:t110=n !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type111:t111=o !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type112:t112=p !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type113:t113=q !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type114:t114=r !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type115:t115=s !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type116:t116=t !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type117:t117=u !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type118:t118=v !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type119:t119=w !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type120:t120=x !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type121:t121=y !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type122:t122=z !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type123:t123={ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type124:t124=| !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type125:t125=} !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type126:t126=~ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-
-.stabs "attr32:G332=@  !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr33:G333=@! !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr35:G334=@# !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-.stabs "attr36:G335=@$ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-.stabs "attr37:G337=@% !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-# Test 'e' constant on non-enum type.  
-.stabs "const69:c=e1,69", N_LSYM,0,0, 0
-
-# Test constant with the type embedded.  
-.stabs "const70:c=e190=bs2;0;16;,70", N_LSYM,0,0, 0
-
-# Test char constant
-.stabs "constchar:c=c97", N_LSYM,0,0, 0
-
-# Test string constant
-.stabs "constString1:c=s'Single quote String1'", N_LSYM,0,0, 0
-# Using double quotes requires an escaping, as the stabs string
-# is a double quote delimited string.
-.stabs "constString2:c=s\"Double quote String2\"", N_LSYM,0,0, 0
-# Escaping single quote with is easy
-.stabs "constString3:c=s'String3 with embedded quote \' in the middle'", N_LSYM,0,0, 0
-# Esaping double quotes is less clear...
-.stabs "constString4:c=s\"String4 with embedded quote \\" in the middle\"", N_LSYM,0,0, 0
-
-
-.stabs "attr38:G338=@& !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-# Unrecognized negative type number.  
-.stabs "bad_neg0type:t201=s16field0:1,0,32;field2:-534,32,64;field3:-1,96,32;;", N_LSYM,0,0, 0
-
-.stabs "bad_neg0:G201", N_GSYM,0,0, 0
-
-.globl bad_neg0
-.data
-.align_it
-bad_neg0:
-.long 42
-     .long 43, 44, 45
-
-.stabs "attr39:G339=@' !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr41:G341=@) !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr42:G342=@* !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr43:G343=@+ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr44:G344=@, !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr46:G346=@. !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr47:G347=@/ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr58:G358=@: !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-# Test two type attributes for one type.  
-.stabs "attr59:G359=@;@ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-.stabs "attr60:G360=@< !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr61:G361=@= !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr62:G362=@> !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr63:G363=@? !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr64:G364=@@ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr65:G365=@A !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr66:G366=@B !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr67:G367=@C !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr68:G368=@D !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr72:G372=@H !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr73:G373=@I !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr74:G374=@J !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr75:G375=@K !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr76:G376=@L !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr77:G377=@M !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr78:G378=@N !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr79:G379=@O !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr80:G380=@P !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr81:G381=@Q !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr82:G382=@R !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr83:G383=@S !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr84:G384=@T !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr85:G385=@U !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr86:G386=@V !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr87:G387=@W !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr88:G388=@X !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr89:G389=@Y !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr90:G390=@Z !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr91:G391=@[ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-.stabs "attr93:G393=@] !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-# Do with and without underscore, so this wins regardless of whether
-# names have underscores.
-
-.globl _common0
-.data
-.align_it
-_common0:
-.long 42
-     .long 24
-     .long 22
-.globl common0
-.data
-.align_it
-common0:
-.long 42
-     .long 24
-     .long 22
-.begin_common "common0"
-.stabs "common0var0:S1", N_GSYM,0,0, 0
-.stabs "common0var1:S1", N_GSYM,0,0, 4
-.stabs "common0var2:S1", N_GSYM,0,0, 8
-.end_common "common0"
-
-.stabs "attr94:G394=@^ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr95:G395=@_ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr100:G400=@d !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr101:G401=@e !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr102:G402=@f !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr103:G403=@g !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr106:G406=@j !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr107:G407=@k !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr108:G408=@l !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr109:G409=@m !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr110:G410=@n !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr111:G411=@o !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr112:G412=@p !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr113:G413=@q !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr114:G414=@r !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr115:G415=@s !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr116:G416=@t !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr117:G417=@u !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr118:G418=@v !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr119:G419=@w !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr120:G420=@x !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr121:G421=@y !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr122:G422=@z !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr123:G423=@{ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr124:G424=@| !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr125:G425=@} !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-.stabs "attr126:G426=@~ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-# Define a variable for all the above stabs.  
-.globl attr32
-.data
-.align_it
-attr32:
-.long 42
-.globl attr33
-.data
-.align_it
-attr33:
-.long 42
-.globl attr35
-.data
-.align_it
-attr35:
-.long 42
-.globl attr36
-.data
-.align_it
-attr36:
-.long 42
-.globl attr37
-.data
-.align_it
-attr37:
-.long 42
-.globl attr38
-.data
-.align_it
-attr38:
-.long 42
-.globl attr39
-.data
-.align_it
-attr39:
-.long 42
-.globl attr41
-.data
-.align_it
-attr41:
-.long 42
-.globl attr42
-.data
-.align_it
-attr42:
-.long 42
-.globl attr43
-.data
-.align_it
-attr43:
-.long 42
-.globl attr44
-.data
-.align_it
-attr44:
-.long 42
-.globl attr46
-.data
-.align_it
-attr46:
-.long 42
-.globl attr47
-.data
-.align_it
-attr47:
-.long 42
-.globl attr58
-.data
-.align_it
-attr58:
-.long 42
-.globl attr59
-.data
-.align_it
-attr59:
-.long 42
-.globl attr60
-.data
-.align_it
-attr60:
-.long 42
-.globl attr61
-.data
-.align_it
-attr61:
-.long 42
-.globl attr62
-.data
-.align_it
-attr62:
-.long 42
-.globl attr63
-.data
-.align_it
-attr63:
-.long 42
-.globl attr64
-.data
-.align_it
-attr64:
-.long 42
-.globl attr65
-.data
-.align_it
-attr65:
-.long 42
-.globl attr70
-.data
-.align_it
-attr70:
-.long 42
-.globl attr71
-.data
-.align_it
-attr71:
-.long 42
-.globl attr72
-.data
-.align_it
-attr72:
-.long 42
-.globl attr73
-.data
-.align_it
-attr73:
-.long 42
-.globl attr74
-.data
-.align_it
-attr74:
-.long 42
-.globl attr75
-.data
-.align_it
-attr75:
-.long 42
-.globl attr76
-.data
-.align_it
-attr76:
-.long 42
-.globl attr77
-.data
-.align_it
-attr77:
-.long 42
-.globl attr78
-.data
-.align_it
-attr78:
-.long 42
-.globl attr79
-.data
-.align_it
-attr79:
-.long 42
-.globl attr80
-.data
-.align_it
-attr80:
-.long 42
-.globl attr81
-.data
-.align_it
-attr81:
-.long 42
-.globl attr82
-.data
-.align_it
-attr82:
-.long 42
-.globl attr83
-.data
-.align_it
-attr83:
-.long 42
-.globl attr84
-.data
-.align_it
-attr84:
-.long 42
-
-# Unrecognized floating point code.  
-.stabs "float72type:t202=R87;9;", N_LSYM,0,0, 0
-
-# 256-bit integer.  The point is obviously not that GDB should have a
-# special case for this size, but that an integer of any size should
-# work (at least for printing in hex, not necessarily for arithmetic.  
-.stabs "int256var:G203=bu32;0;256;", N_GSYM,0,0, 0
-# The value is palindromic, so it works whether words are big or little
-# endian.  
-.globl int256var
-.data
-.align_it
-     int256var:
-.long 42
-     .long 0x2b, 0x2c, 0x2d, 0x2d, 0x2c, 0x2b, 0x2a
-
-# Huge value in constant should at least get the type right.  
-
-# This value is just big enough not to fit in 32 bits.  
-.stabs "consth:c=e1,4294967296", N_LSYM,0,0, 0
-
-.stabs "consth2:c=e1,-734723985732642758928475678987234563284937456", N_LSYM,0,0, 0
-
-# Test a struct constant using S.  
-.stabs "bad_neg0const:c=S201,128,128,11222211343434345656565677888877", N_LSYM,0,0, 0
-
-# Bad filenumbers.  
-# This one is totally bogus.  
-.stabs "bad_type0:t(-3,7)", N_LSYM,0,0, 0
-# This one probably gets interpreted as a forward reference.  
-.stabs "bad_type1:t(42,6)", N_LSYM,0,0, 0
-
-# Arrays indexed by weird things.  
-.stabs "array_index0:t205=r1;0;5;", N_LSYM,0,0, 0
-.stabs "array0:G206=a205;1", N_GSYM,0,0, 0
-.globl array0
-.data
-.align_it
-     array0:
-.long 42
-     .long 43, 44, 45, 46, 47
-
-.stabs "array_index1:t207=", N_LSYM,0,0, 0
-.stabs "array1:G208=aeai1_red:0,ai1_green:1,ai1_blue:2,;;1", N_GSYM,0,0, 0
-.globl array1
-.data
-.align_it
-     array1:
-.long 42
-     .long 43, 44
-
-# See if GDB can deal with it if the compiler gets smarter about saying
-# which variables were defined with which types.  
-.stabs "inttype_one:t209=1", N_LSYM,0,0, 0
-.stabs "inttype_two:t210=1", N_LSYM,0,0, 0
-.stabs "one_var:G209", N_GSYM,0,0, 0
-.globl one_var
-.data
-.align_it
-one_var:
-.long 42
-.stabs "two_var:G210", N_GSYM,0,0, 0
-.globl two_var
-.data
-.align_it
-two_var:
-.long 42
-
-# And see if the caddr_t hack can deal with the same thing.
-.stabs "intp:t211=*1", N_LSYM,0,0, 0
-# If it weren't for this variable, we'd need to ignore the intp name.  
-.stabs "pointer_to_int_var:G212=*1", N_LSYM,0,0, 0
-.stabs "intp_var:G211", N_GSYM,0,0, 0
-.globl intp_var
-.data
-.align_it
-intp_var:
-.long 42
-
-# Unrecognized constant code.  
-.stabs "unrecog_const:c=xjksdflskd33,4;473;", N_LSYM,0,0, 0
-
-.globl attr85
-.data
-.align_it
-attr85:
-.long 42
-.globl attr86
-.data
-.align_it
-attr86:
-.long 42
-.globl attr87
-.data
-.align_it
-attr87:
-.long 42
-.globl attr88
-.data
-.align_it
-attr88:
-.long 42
-.globl attr89
-.data
-.align_it
-attr89:
-.long 42
-.globl attr90
-.data
-.align_it
-attr90:
-.long 42
-.globl attr91
-.data
-.align_it
-attr91:
-.long 42
-.globl attr92
-.data
-.align_it
-attr92:
-.long 42
-.globl attr93
-.data
-.align_it
-attr93:
-.long 42
-.globl attr94
-.data
-.align_it
-attr94:
-.long 42
-.globl attr95
-.data
-.align_it
-attr95:
-.long 42
-.globl attr96
-.data
-.align_it
-attr96:
-.long 42
-.globl attr97
-.data
-.align_it
-attr97:
-.long 42
-.globl attr98
-.data
-.align_it
-attr98:
-.long 42
-.globl attr99
-.data
-.align_it
-attr99:
-.long 42
-.globl attr100
-.data
-.align_it
-attr100:
-.long 42
-.globl attr101
-.data
-.align_it
-attr101:
-.long 42
-.globl attr102
-.data
-.align_it
-attr102:
-.long 42
-.globl attr103
-.data
-.align_it
-attr103:
-.long 42
-.globl attr104
-.data
-.align_it
-attr104:
-.long 42
-.globl attr105
-.data
-.align_it
-attr105:
-.long 42
-.globl attr106
-.data
-.align_it
-attr106:
-.long 42
-.globl attr107
-.data
-.align_it
-attr107:
-.long 42
-.globl attr108
-.data
-.align_it
-attr108:
-.long 42
-.globl attr109
-.data
-.align_it
-attr109:
-.long 42
-.globl attr110
-.data
-.align_it
-attr110:
-.long 42
-.globl attr111
-.data
-.align_it
-attr111:
-.long 42
-.globl attr112
-.data
-.align_it
-attr112:
-.long 42
-.globl attr113
-.data
-.align_it
-attr113:
-.long 42
-.globl attr114
-.data
-.align_it
-attr114:
-.long 42
-.globl attr115
-.data
-.align_it
-attr115:
-.long 42
-.globl attr116
-.data
-.align_it
-attr116:
-.long 42
-.globl attr117
-.data
-.align_it
-attr117:
-.long 42
-.globl attr118
-.data
-.align_it
-attr118:
-.long 42
-.globl attr119
-.data
-.align_it
-attr119:
-.long 42
-.globl attr120
-.data
-.align_it
-attr120:
-.long 42
-.globl attr121
-.data
-.align_it
-attr121:
-.long 42
-.globl attr125
-.data
-.align_it
-attr125:
-.long 42
-.globl attr126
-.data
-.align_it
-attr126:
-.long 42
-
-# Size.  
-.stabs "var1:G301=@s32;1",N_GSYM,0,0, 0
-.globl var1
-.data
-.align_it
-var1:
-.long 42
-# Pointer class.  
-.stabs "var2:G302=@p42;1",N_GSYM,0,0, 0
-.globl var2
-.data
-.align_it
-var2:
-.long 42
-# Packed type.  
-.stabs "var3:G303=@P;1",N_GSYM,0,0, 0
-.globl var3
-.data
-.align_it
-var3:
-.long 42
-
-.stabs "sym92:\ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "type92:t92=\ !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~",N_LSYM,0,0,0
-.stabs "attr92:G392=@\ !#$%&'()*+,-./0123456789:<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~;1",N_GSYM,0,0, 0
-
-# See read_args "Invalid (empty) method arguments" error; there is an
-# unexpected semi-colon after =@s8;-16 that used to cause a GDB crash.
-.stabs "args93:G93=#(0,93),(0,93)=@s8;-16;,(0,93),(0,93);",N_GSYM,0,0,0
diff --git a/gdb/testsuite/gdb.stabs/xcoff.sed b/gdb/testsuite/gdb.stabs/xcoff.sed
deleted file mode 100644
index 6dc81985096..00000000000
--- a/gdb/testsuite/gdb.stabs/xcoff.sed
+++ /dev/null
@@ -1,17 +0,0 @@
-# Put everything in this csect, which seems to make things work.
-# The compiler actually puts the stabs in .csect [PR], but that didn't
-# work here (I guess because there is no text section).
-1i\
-	.csect .data[RW]
-# .stabs string,type,0,0,value  ->  .stabx string,value,type,0
-s/^[ 	]*\.stabs[ 	]*("(\"|[^"])*"),[ 	]*([^,]*),[ 	]*0,0,[ 	]*(.*)$/.stabx \1,\4,\3,0/
-s/N_GSYM/128/
-# This needs to be C_DECL, which is used for types, not C_LSYM, which is
-# ignored on the initial scan.
-s/N_LSYM/140/
-s/\.begin_common/.bc/
-# The AIX assembler doesn't want the name in a .ec directive
-s/\.end_common.*/.ec/
-s/\.align_it/.align 1/
-/\.data/d
-/^#/d
-- 
2.51.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* [PATCH v2 8/8] gdb: remove support for dbx from GDB
  2025-10-20 15:28 [PATCH v2 0/8] Remove stabs support from GDB Guinevere Larsen
                   ` (6 preceding siblings ...)
  2025-10-20 15:28 ` [PATCH v2 7/8] gdb: Fully remove stabs code from GDB Guinevere Larsen
@ 2025-10-20 15:28 ` Guinevere Larsen
  2025-10-21 19:14 ` [PATCH v2 0/8] Remove stabs support " Tom Tromey
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 24+ messages in thread
From: Guinevere Larsen @ 2025-10-20 15:28 UTC (permalink / raw)
  To: gdb-patches; +Cc: Guinevere Larsen, Eli Zaretskii, Tom Tromey

With the removal of stabs support, reading a dbx inferior has become a
no-op and GDB is unable to perform sybmolic debugging in such inferiors.
As such, this commit removes the files that work on it with spotty
support.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>
Approved-By: Tom Tromey <tom@tromey.com>
---
 gdb/Makefile.in  |   6 +-
 gdb/NEWS         |   2 +
 gdb/configure    |   6 +-
 gdb/configure.ac |   4 +-
 gdb/dbxread.c    | 260 -----------------------------------------------
 gdb/gdb-stabs.h  | 176 --------------------------------
 6 files changed, 11 insertions(+), 443 deletions(-)
 delete mode 100644 gdb/dbxread.c
 delete mode 100644 gdb/gdb-stabs.h

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 381c064bc4e..c9cd98a75a8 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -917,7 +917,6 @@ ALL_TARGET_OBS = \
 
 # Object files for reading specific types of debug information.
 coff_SRCS = coffread.c coff-pe-read.c
-dbx_SRCS = dbxread.c
 elf_SRCS = elfread.c stap-probe.c dtrace-probe.c
 macho_SRCS = machoread.c
 mips_SRCS = mipsread.c
@@ -1469,7 +1468,10 @@ HFILES_NO_SRCDIR = \
 	gdb-demangle.h \
 	gdb_expat.h \
 	gdb_proc_service.h \
-	gdb-stabs.h \
+	gdb_vfork.h \
+	gdb_wchar.h \
+	gdbarch.h \
+	gdbcore.h \
 	gdbthread.h \
 	gdbtypes.h \
 	gdb_vfork.h \
diff --git a/gdb/NEWS b/gdb/NEWS
index 2c94e786f41..097d8da350b 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -33,6 +33,8 @@
 
 * Support for stabs debug information has been removed.
 
+* Support for the binary file format dbx has been removed.
+
 * New targets
 
 GNU/Linux/MicroBlaze (gdbserver) microblazeel-*linux*
diff --git a/gdb/configure b/gdb/configure
index 04bb60f9f1f..fa86e67a690 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -1651,8 +1651,8 @@ Optional Features:
                           alternative target configurations
   --enable-binary-file-formats=FORMATS
                           enable support for selected file formats (default
-                          'all') available formats: coff, dbx, elf, macho,
-                          mips, xcoff, all
+                          'all') available formats: coff, elf, macho, mips,
+                          xcoff, all
   --enable-gdb-mdebug-support
                           Enable support for the mdebug debuginfo format
                           (default 'yes')
@@ -31848,7 +31848,7 @@ WIN32LIBS="$WIN32LIBS $WIN32APILIBS"
 # Object files to be used when building with support for all file formats.
 # This should not have elf or macho, as support for those formats depends
 # on BFD enabling them as well.
-all_binary_file_srcs="\$(dbx_SRCS) \$(mips_SRCS) \$(coff_SRCS) \$(xcoff_SRCS)"
+all_binary_file_srcs="\$(mips_SRCS) \$(coff_SRCS) \$(xcoff_SRCS)"
 
 bfd_supports_elf=no
 # Add ELF support to GDB, but only if BFD includes ELF support.
diff --git a/gdb/configure.ac b/gdb/configure.ac
index 5e5a3a01d06..b0db7fef6f0 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -194,7 +194,7 @@ esac])
 AC_ARG_ENABLE(binary_file_formats,
 	      AS_HELP_STRING([--enable-binary-file-formats=FORMATS],
 			     [enable support for selected file formats (default 'all')
-			      available formats: coff, dbx, elf, macho, mips, xcoff, all]),
+			      available formats: coff, elf, macho, mips, xcoff, all]),
 [case "${enableval}" in
  yes | "") AC_MSG_ERROR(enable-binary-file-formats option must specify file formats or 'all')
             ;;
@@ -1998,7 +1998,7 @@ WIN32LIBS="$WIN32LIBS $WIN32APILIBS"
 # Object files to be used when building with support for all file formats.
 # This should not have elf or macho, as support for those formats depends
 # on BFD enabling them as well.
-all_binary_file_srcs="\$(dbx_SRCS) \$(mips_SRCS) \$(coff_SRCS) \$(xcoff_SRCS)"
+all_binary_file_srcs="\$(mips_SRCS) \$(coff_SRCS) \$(xcoff_SRCS)"
 
 bfd_supports_elf=no
 # Add ELF support to GDB, but only if BFD includes ELF support.
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
deleted file mode 100644
index e003a909fe8..00000000000
--- a/gdb/dbxread.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/* Read dbx symbol tables and convert to internal format, for GDB.
-   Copyright (C) 1986-2025 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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-/* This module provides three functions: dbx_symfile_init,
-   which initializes to read a symbol file; dbx_new_init, which 
-   discards existing cached information when all symbols are being
-   discarded; and dbx_symfile_read, which reads a symbol table
-   from a file.
-
-   dbx_symfile_read only does the minimum work necessary for letting the
-   user "name" things symbolically; it does not read the entire symtab.
-   Instead, it reads the external and static symbols and puts them in partial
-   symbol tables.  When more extensive information is requested of a
-   file, the corresponding partial symbol table is mutated into a full
-   fledged symbol table by going back and reading the symbols
-   for real.  dbx_psymtab_to_symtab() is the function that does this */
-
-
-#include <sys/stat.h>
-#include "symtab.h"
-#include "target.h"
-#include "libaout.h"
-#include "objfiles.h"
-#include "buildsym-legacy.h"
-#include "gdb-stabs.h"
-#include "cp-support.h"
-#include "c-lang.h"
-#include "psymtab.h"
-#include "block.h"
-#include "aout/aout64.h"
-#include "aout/stab_gnu.h"
-
-/* Local function prototypes.  */
-
-static void dbx_symfile_init (struct objfile *);
-
-static void dbx_new_init (struct objfile *);
-
-static void dbx_symfile_read (struct objfile *, symfile_add_flags);
-
-static void dbx_symfile_finish (struct objfile *);
-
-
-#if 0
-static struct type **
-explicit_lookup_type (int real_filenum, int index)
-{
-  struct header_file *f = &HEADER_FILES (dbxread_objfile)[real_filenum];
-
-  if (index >= f->length)
-    {
-      f->length *= 2;
-      f->vector = (struct type **)
-	xrealloc (f->vector, f->length * sizeof (struct type *));
-      memset (&f->vector[f->length / 2],
-	      '\0', f->length * sizeof (struct type *) / 2);
-    }
-  return &f->vector[index];
-}
-#endif
-\f
-
-const registry<objfile>::key<dbx_symfile_info> dbx_objfile_data_key;
-
-/* This could leak memory, but it will be removed soon, so it
-   shouldn't have a large impact.  */
-dbx_symfile_info::~dbx_symfile_info ()
-{
-}
-
-/* Scan and build partial symbols for a symbol file.
-   We have been initialized by a call to dbx_symfile_init, which 
-   put all the relevant info into a "struct dbx_symfile_info",
-   hung off the objfile structure.  */
-
-static void
-dbx_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
-{
-}
-
-/* Initialize anything that needs initializing when a completely new
-   symbol file is specified (not just adding some symbols from another
-   file, e.g. a shared library).  */
-
-static void
-dbx_new_init (struct objfile *ignore)
-{
-}
-
-
-/* dbx_symfile_init ()
-   is the dbx-specific initialization routine for reading symbols.
-   It is passed a struct objfile which contains, among other things,
-   the BFD for the file whose symbols are being read, and a slot for a pointer
-   to "private data" which we fill with goodies.
-
-   We read the string table into malloc'd space and stash a pointer to it.
-
-   Since BFD doesn't know how to read debug symbols in a format-independent
-   way (and may never do so...), we have to do it ourselves.  We will never
-   be called unless this is an a.out (or very similar) file.
-   FIXME, there should be a cleaner peephole into the BFD environment here.  */
-
-#define DBX_STRINGTAB_SIZE_SIZE sizeof(long)	/* FIXME */
-
-static void
-dbx_symfile_init (struct objfile *objfile)
-{
-  int val;
-  bfd *sym_bfd = objfile->obfd.get ();
-  const char *name = bfd_get_filename (sym_bfd);
-  asection *text_sect;
-  unsigned char size_temp[DBX_STRINGTAB_SIZE_SIZE];
-
-  /* Allocate struct to keep track of the symfile.  */
-  dbx_objfile_data_key.emplace (objfile);
-
-  DBX_TEXT_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".text");
-  DBX_DATA_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".data");
-  DBX_BSS_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".bss");
-
-  /* FIXME POKING INSIDE BFD DATA STRUCTURES.  */
-#define	STRING_TABLE_OFFSET	(sym_bfd->origin + obj_str_filepos (sym_bfd))
-#define	SYMBOL_TABLE_OFFSET	(sym_bfd->origin + obj_sym_filepos (sym_bfd))
-
-  /* FIXME POKING INSIDE BFD DATA STRUCTURES.  */
-
-  text_sect = bfd_get_section_by_name (sym_bfd, ".text");
-  if (!text_sect)
-    error (_("Can't find .text section in symbol file"));
-  DBX_TEXT_ADDR (objfile) = bfd_section_vma (text_sect);
-  DBX_TEXT_SIZE (objfile) = bfd_section_size (text_sect);
-
-  DBX_SYMBOL_SIZE (objfile) = obj_symbol_entry_size (sym_bfd);
-  DBX_SYMCOUNT (objfile) = bfd_get_symcount (sym_bfd);
-  DBX_SYMTAB_OFFSET (objfile) = SYMBOL_TABLE_OFFSET;
-
-  /* Read the string table and stash it away in the objfile_obstack.
-     When we blow away the objfile the string table goes away as well.
-     Note that gdb used to use the results of attempting to malloc the
-     string table, based on the size it read, as a form of sanity check
-     for botched byte swapping, on the theory that a byte swapped string
-     table size would be so totally bogus that the malloc would fail.  Now
-     that we put in on the objfile_obstack, we can't do this since gdb gets
-     a fatal error (out of virtual memory) if the size is bogus.  We can
-     however at least check to see if the size is less than the size of
-     the size field itself, or larger than the size of the entire file.
-     Note that all valid string tables have a size greater than zero, since
-     the bytes used to hold the size are included in the count.  */
-
-  if (STRING_TABLE_OFFSET == 0)
-    {
-      /* It appears that with the existing bfd code, STRING_TABLE_OFFSET
-	 will never be zero, even when there is no string table.  This
-	 would appear to be a bug in bfd.  */
-      DBX_STRINGTAB_SIZE (objfile) = 0;
-      DBX_STRINGTAB (objfile) = NULL;
-    }
-  else
-    {
-      val = bfd_seek (sym_bfd, STRING_TABLE_OFFSET, SEEK_SET);
-      if (val < 0)
-	perror_with_name (name);
-
-      memset (size_temp, 0, sizeof (size_temp));
-      val = bfd_read (size_temp, sizeof (size_temp), sym_bfd);
-      if (val < 0)
-	{
-	  perror_with_name (name);
-	}
-      else if (val == 0)
-	{
-	  /* With the existing bfd code, STRING_TABLE_OFFSET will be set to
-	     EOF if there is no string table, and attempting to read the size
-	     from EOF will read zero bytes.  */
-	  DBX_STRINGTAB_SIZE (objfile) = 0;
-	  DBX_STRINGTAB (objfile) = NULL;
-	}
-      else
-	{
-	  /* Read some data that would appear to be the string table size.
-	     If there really is a string table, then it is probably the right
-	     size.  Byteswap if necessary and validate the size.  Note that
-	     the minimum is DBX_STRINGTAB_SIZE_SIZE.  If we just read some
-	     random data that happened to be at STRING_TABLE_OFFSET, because
-	     bfd can't tell us there is no string table, the sanity checks may
-	     or may not catch this.  */
-	  DBX_STRINGTAB_SIZE (objfile) = bfd_h_get_32 (sym_bfd, size_temp);
-
-	  if (DBX_STRINGTAB_SIZE (objfile) < sizeof (size_temp)
-	      || DBX_STRINGTAB_SIZE (objfile) > bfd_get_size (sym_bfd))
-	    error (_("ridiculous string table size (%d bytes)."),
-		   DBX_STRINGTAB_SIZE (objfile));
-
-	  DBX_STRINGTAB (objfile) =
-	    (char *) obstack_alloc (&objfile->objfile_obstack,
-				    DBX_STRINGTAB_SIZE (objfile));
-	  OBJSTAT (objfile, sz_strtab += DBX_STRINGTAB_SIZE (objfile));
-
-	  /* Now read in the string table in one big gulp.  */
-
-	  val = bfd_seek (sym_bfd, STRING_TABLE_OFFSET, SEEK_SET);
-	  if (val < 0)
-	    perror_with_name (name);
-	  val = bfd_read (DBX_STRINGTAB (objfile),
-			  DBX_STRINGTAB_SIZE (objfile),
-			  sym_bfd);
-	  if (val != DBX_STRINGTAB_SIZE (objfile))
-	    perror_with_name (name);
-	}
-    }
-}
-
-/* Perform any local cleanups required when we are done with a particular
-   objfile.  I.E, we are in the process of discarding all symbol information
-   for an objfile, freeing up all memory held for it, and unlinking the
-   objfile struct from the global list of known objfiles.  */
-
-static void
-dbx_symfile_finish (struct objfile *objfile)
-{
-}
-
-\f
-
-\f
-\f
-\f
-static const struct sym_fns aout_sym_fns =
-{
-  dbx_new_init,			/* init anything gbl to entire symtab */
-  dbx_symfile_init,		/* read initial info, setup for sym_read() */
-  dbx_symfile_read,		/* read a symbol file into symtab */
-  dbx_symfile_finish,		/* finished with file, cleanup */
-  default_symfile_offsets, 	/* parse user's offsets to internal form */
-  default_symfile_segments,	/* Get segment information from a file.  */
-  NULL,
-  default_symfile_relocate,	/* Relocate a debug section.  */
-  NULL,				/* sym_probe_fns */
-};
-
-INIT_GDB_FILE (dbxread)
-{
-  add_symtab_fns (bfd_target_aout_flavour, &aout_sym_fns);
-}
diff --git a/gdb/gdb-stabs.h b/gdb/gdb-stabs.h
deleted file mode 100644
index 99091295773..00000000000
--- a/gdb/gdb-stabs.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/* Definitions for symbol-reading containing "stabs", for GDB.
-   Copyright (C) 1992-2025 Free Software Foundation, Inc.
-   Contributed by Cygnus Support.  Written by John Gilmore.
-
-   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 3 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, see <http://www.gnu.org/licenses/>.  */
-
-#ifndef GDB_GDB_STABS_H
-#define GDB_GDB_STABS_H
-
-/* During initial symbol reading, we need to have a structure to keep
-   track of which psymtabs have which bincls in them.  This structure
-   is used during reading to setup the list of dependencies within each
-   partial symbol table.  */
-struct legacy_psymtab;
-
-struct header_file_location
-{
-  header_file_location (const char *name_, int instance_,
-			legacy_psymtab *pst_)
-    : name (name_),
-      instance (instance_),
-      pst (pst_)
-  {
-  }
-
-  const char *name;		/* Name of header file */
-  int instance;			/* See above */
-  legacy_psymtab *pst;	/* Partial symtab that has the
-				   BINCL/EINCL defs for this file.  */
-};
-
-/* This file exists to hold the common definitions required of most of
-   the symbol-readers that end up using stabs.  The common use of
-   these `symbol-type-specific' customizations of the generic data
-   structures makes the stabs-oriented symbol readers able to call
-   each others' functions as required.  */
-
-struct stabsread_context {
-  /* Remember what we deduced to be the source language of this psymtab.  */
-  enum language psymtab_language = language_unknown;
-
-  /* The size of each symbol in the symbol file (in external form).
-     This is set by dbx_symfile_read when building psymtabs, and by
-     dbx_psymtab_to_symtab when building symtabs.  */
-  unsigned symbol_size = 0;
-
-  /* This is the offset of the symbol table in the executable file.  */
-  unsigned symbol_table_offset = 0;
-
-  /* This is the offset of the string table in the executable file.  */
-  unsigned string_table_offset = 0;
-
-  /* For elf+stab executables, the n_strx field is not a simple index
-     into the string table.  Instead, each .o file has a base offset in
-     the string table, and the associated symbols contain offsets from
-     this base.  The following two variables contain the base offset for
-     the current and next .o files.  */
-  unsigned int file_string_table_offset = 0;
-
-  /* .o and NLM files contain unrelocated addresses which are based at
-     0.  When non-zero, this flag disables some of the special cases for
-     Solaris elf+stab text addresses at location 0.  */
-  int symfile_relocatable = 0;
-
-  /* When set, we are processing a .o file compiled by sun acc.  This is
-     misnamed; it refers to all stabs-in-elf implementations which use
-     N_UNDF the way Sun does, including Solaris gcc.  Hopefully all
-     stabs-in-elf implementations ever invented will choose to be
-     compatible.  */
-  unsigned char processing_acc_compilation = 0;
-
-  /* The lowest text address we have yet encountered.  This is needed
-     because in an a.out file, there is no header field which tells us
-     what address the program is actually going to be loaded at, so we
-     need to make guesses based on the symbols (which *are* relocated to
-     reflect the address it will be loaded at).  */
-  unrelocated_addr lowest_text_address;
-
-  /* Non-zero if there is any line number info in the objfile.  Prevents
-     dbx_end_psymtab from discarding an otherwise empty psymtab.  */
-  int has_line_numbers = 0;
-
-  /* The list of bincls.  */
-  std::vector<struct header_file_location> bincl_list;
-
-  /* Name of last function encountered.  Used in Solaris to approximate
-     object file boundaries.  */
-  const char *last_function_name = nullptr;
-
-  /* The address in memory of the string table of the object file we are
-     reading (which might not be the "main" object file, but might be a
-     shared library or some other dynamically loaded thing).  This is
-     set by read_dbx_symtab when building psymtabs, and by
-     read_ofile_symtab when building symtabs, and is used only by
-     next_symbol_text.  FIXME: If that is true, we don't need it when
-     building psymtabs, right?  */
-  char *stringtab_global = nullptr;
-
-  /* These variables are used to control fill_symbuf when the stabs
-     symbols are not contiguous (as may be the case when a COFF file is
-     linked using --split-by-reloc).  */
-  const std::vector<asection *> *symbuf_sections;
-  size_t sect_idx = 0;
-  unsigned int symbuf_left = 0;
-  unsigned int symbuf_read = 0;
-
-  /* This variable stores a global stabs buffer, if we read stabs into
-     memory in one chunk in order to process relocations.  */
-  bfd_byte *stabs_data = nullptr;
-};
-
-
-/* Information is passed among various dbxread routines for accessing
-   symbol files.  A pointer to this structure is kept in the objfile,
-   using the dbx_objfile_data_key.  */
-
-struct dbx_symfile_info
-  {
-    ~dbx_symfile_info ();
-
-    CORE_ADDR text_addr = 0;	/* Start of text section */
-    int text_size = 0;		/* Size of text section */
-    int symcount = 0;		/* How many symbols are there in the file */
-    char *stringtab = nullptr;		/* The actual string table */
-    int stringtab_size = 0;		/* Its size */
-    file_ptr symtab_offset = 0;	/* Offset in file to symbol table */
-    int symbol_size = 0;		/* Bytes in a single symbol */
-
-    stabsread_context ctx; /* Context for the symfile being read.  */
-
-    /* See stabsread.h for the use of the following.  */
-    struct header_file *header_files = nullptr;
-    int n_header_files = 0;
-    int n_allocated_header_files = 0;
-
-    /* Pointers to BFD sections.  These are used to speed up the building of
-       minimal symbols.  */
-    asection *text_section = nullptr;
-    asection *data_section = nullptr;
-    asection *bss_section = nullptr;
-
-    /* Pointer to the separate ".stab" section, if there is one.  */
-    asection *stab_section = nullptr;
-  };
-
-/* The tag used to find the DBX info attached to an objfile.  This is
-   global because it is referenced by several modules.  */
-extern const registry<objfile>::key<dbx_symfile_info> dbx_objfile_data_key;
-
-#define DBX_SYMFILE_INFO(o)	(dbx_objfile_data_key.get (o))
-#define DBX_TEXT_ADDR(o)	(DBX_SYMFILE_INFO(o)->text_addr)
-#define DBX_TEXT_SIZE(o)	(DBX_SYMFILE_INFO(o)->text_size)
-#define DBX_SYMCOUNT(o)		(DBX_SYMFILE_INFO(o)->symcount)
-#define DBX_STRINGTAB(o)	(DBX_SYMFILE_INFO(o)->stringtab)
-#define DBX_STRINGTAB_SIZE(o)	(DBX_SYMFILE_INFO(o)->stringtab_size)
-#define DBX_SYMTAB_OFFSET(o)	(DBX_SYMFILE_INFO(o)->symtab_offset)
-#define DBX_SYMBOL_SIZE(o)	(DBX_SYMFILE_INFO(o)->symbol_size)
-#define DBX_TEXT_SECTION(o)	(DBX_SYMFILE_INFO(o)->text_section)
-#define DBX_DATA_SECTION(o)	(DBX_SYMFILE_INFO(o)->data_section)
-#define DBX_BSS_SECTION(o)	(DBX_SYMFILE_INFO(o)->bss_section)
-#define DBX_STAB_SECTION(o)	(DBX_SYMFILE_INFO(o)->stab_section)
-
-#endif /* GDB_GDB_STABS_H */
-- 
2.51.0


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 1/8] gdb: move some stabs functions to gdb/buildsym-legacy.h
  2025-10-20 15:28 ` [PATCH v2 1/8] gdb: move some stabs functions to gdb/buildsym-legacy.h Guinevere Larsen
@ 2025-10-20 16:25   ` Tom Tromey
  0 siblings, 0 replies; 24+ messages in thread
From: Tom Tromey @ 2025-10-20 16:25 UTC (permalink / raw)
  To: Guinevere Larsen; +Cc: gdb-patches

>>>>> "Guinevere" == Guinevere Larsen <guinevere@redhat.com> writes:

Guinevere> The gdb/stabsread.h and .c files define 2 things that, while originally
Guinevere> intended only for stabs reading, actually end up being used for coff,
Guinevere> ecoff and maybe more debuginfo formats. That is the function "hashname",
Guinevere> and the macro HASHSIZE.  Both are used for small hashtables when reading
Guinevere> some symbols with incomplete information.

Guinevere> With the upcoming removal of stabs code, this code should be moved
Guinevere> somewhere, and the location that looked most reasonable was
Guinevere> gdb/buildsym-legacy.  No change in behavior is expected after this
Guinevere> commit.

Ok.
Approved-By: Tom Tromey <tom@tromey.com>

Tom

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 7/8] gdb: Fully remove stabs code from GDB
  2025-10-20 15:28 ` [PATCH v2 7/8] gdb: Fully remove stabs code from GDB Guinevere Larsen
@ 2025-10-20 16:39   ` Eli Zaretskii
  2025-10-20 19:12     ` Guinevere Larsen
  0 siblings, 1 reply; 24+ messages in thread
From: Eli Zaretskii @ 2025-10-20 16:39 UTC (permalink / raw)
  To: Guinevere Larsen; +Cc: gdb-patches, tom

> From: Guinevere Larsen <guinevere@redhat.com>
> Cc: Guinevere Larsen <guinevere@redhat.com>,
> 	Tom Tromey <tom@tromey.com>
> Date: Mon, 20 Oct 2025 12:28:51 -0300
> 
> This commit is the last in the series removing GDB's support for stabs.
> It removes the stabsread.{c|h} files, and removes the last usage of
> stabsread stuff in buildsym.  Notably, the header file gdb-stabs.h
> remains in the tree as it is misnamed at this point - it is used for
> reading dbx objfiles.  It (and dbxread) will be removed in a future
> commit.
> 
> Approved-By: Tom Tromey <tom@tromey.com>
> ---
>  gdb/Makefile.in                      |    2 -
>  gdb/NEWS                             |    2 +
>  gdb/arch-utils.c                     |    6 -
>  gdb/arch-utils.h                     |    3 -
>  gdb/buildsym.c                       |   18 -
>  gdb/dbxread.c                        |    9 +
>  gdb/doc/Makefile.in                  |   46 +-
>  gdb/doc/gdb.texinfo                  |   23 +-
>  gdb/doc/stabs.texinfo                | 4130 ---------------
>  gdb/gdbarch-gen.c                    |   22 -
>  gdb/gdbarch-gen.h                    |    4 -
>  gdb/gdbarch_components.py            |    8 -
>  gdb/microblaze-tdep.c                |    8 -
>  gdb/objfiles.h                       |    3 -
>  gdb/sparc-tdep.c                     |   10 -
>  gdb/sparc64-tdep.c                   |    2 -
>  gdb/stabsread.c                      | 7209 --------------------------
>  gdb/stabsread.h                      |  309 --
>  gdb/symmisc.c                        |    3 -
>  gdb/testsuite/gdb.stabs/aout.sed     |   16 -
>  gdb/testsuite/gdb.stabs/ecoff.sed    |   17 -
>  gdb/testsuite/gdb.stabs/exclfwd.exp  |   57 -
>  gdb/testsuite/gdb.stabs/exclfwd.h    |   21 -
>  gdb/testsuite/gdb.stabs/exclfwd1.c   |   34 -
>  gdb/testsuite/gdb.stabs/exclfwd2.c   |   29 -
>  gdb/testsuite/gdb.stabs/gdb11479.c   |   76 -
>  gdb/testsuite/gdb.stabs/gdb11479.exp |   59 -
>  gdb/testsuite/gdb.stabs/hppa.sed     |   20 -
>  gdb/testsuite/gdb.stabs/weird.def    |  900 ----
>  gdb/testsuite/gdb.stabs/xcoff.sed    |   17 -
>  30 files changed, 27 insertions(+), 13036 deletions(-)
>  delete mode 100644 gdb/doc/stabs.texinfo
>  delete mode 100644 gdb/stabsread.c
>  delete mode 100644 gdb/stabsread.h
>  delete mode 100644 gdb/testsuite/gdb.stabs/aout.sed
>  delete mode 100644 gdb/testsuite/gdb.stabs/ecoff.sed
>  delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd.exp
>  delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd.h
>  delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd1.c
>  delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd2.c
>  delete mode 100644 gdb/testsuite/gdb.stabs/gdb11479.c
>  delete mode 100644 gdb/testsuite/gdb.stabs/gdb11479.exp
>  delete mode 100644 gdb/testsuite/gdb.stabs/hppa.sed
>  delete mode 100644 gdb/testsuite/gdb.stabs/weird.def
>  delete mode 100644 gdb/testsuite/gdb.stabs/xcoff.sed

Thanks, but didn't I already approve the documentation parts of this?
They are almost entirely trivial anyway.

Reviewed-By: Eli Zaretskii <eliz@gnu.org>

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 7/8] gdb: Fully remove stabs code from GDB
  2025-10-20 16:39   ` Eli Zaretskii
@ 2025-10-20 19:12     ` Guinevere Larsen
  0 siblings, 0 replies; 24+ messages in thread
From: Guinevere Larsen @ 2025-10-20 19:12 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches, tom

On 10/20/25 1:39 PM, Eli Zaretskii wrote:
>> From: Guinevere Larsen <guinevere@redhat.com>
>> Cc: Guinevere Larsen <guinevere@redhat.com>,
>> 	Tom Tromey <tom@tromey.com>
>> Date: Mon, 20 Oct 2025 12:28:51 -0300
>>
>> This commit is the last in the series removing GDB's support for stabs.
>> It removes the stabsread.{c|h} files, and removes the last usage of
>> stabsread stuff in buildsym.  Notably, the header file gdb-stabs.h
>> remains in the tree as it is misnamed at this point - it is used for
>> reading dbx objfiles.  It (and dbxread) will be removed in a future
>> commit.
>>
>> Approved-By: Tom Tromey <tom@tromey.com>
>> ---
>>   gdb/Makefile.in                      |    2 -
>>   gdb/NEWS                             |    2 +
>>   gdb/arch-utils.c                     |    6 -
>>   gdb/arch-utils.h                     |    3 -
>>   gdb/buildsym.c                       |   18 -
>>   gdb/dbxread.c                        |    9 +
>>   gdb/doc/Makefile.in                  |   46 +-
>>   gdb/doc/gdb.texinfo                  |   23 +-
>>   gdb/doc/stabs.texinfo                | 4130 ---------------
>>   gdb/gdbarch-gen.c                    |   22 -
>>   gdb/gdbarch-gen.h                    |    4 -
>>   gdb/gdbarch_components.py            |    8 -
>>   gdb/microblaze-tdep.c                |    8 -
>>   gdb/objfiles.h                       |    3 -
>>   gdb/sparc-tdep.c                     |   10 -
>>   gdb/sparc64-tdep.c                   |    2 -
>>   gdb/stabsread.c                      | 7209 --------------------------
>>   gdb/stabsread.h                      |  309 --
>>   gdb/symmisc.c                        |    3 -
>>   gdb/testsuite/gdb.stabs/aout.sed     |   16 -
>>   gdb/testsuite/gdb.stabs/ecoff.sed    |   17 -
>>   gdb/testsuite/gdb.stabs/exclfwd.exp  |   57 -
>>   gdb/testsuite/gdb.stabs/exclfwd.h    |   21 -
>>   gdb/testsuite/gdb.stabs/exclfwd1.c   |   34 -
>>   gdb/testsuite/gdb.stabs/exclfwd2.c   |   29 -
>>   gdb/testsuite/gdb.stabs/gdb11479.c   |   76 -
>>   gdb/testsuite/gdb.stabs/gdb11479.exp |   59 -
>>   gdb/testsuite/gdb.stabs/hppa.sed     |   20 -
>>   gdb/testsuite/gdb.stabs/weird.def    |  900 ----
>>   gdb/testsuite/gdb.stabs/xcoff.sed    |   17 -
>>   30 files changed, 27 insertions(+), 13036 deletions(-)
>>   delete mode 100644 gdb/doc/stabs.texinfo
>>   delete mode 100644 gdb/stabsread.c
>>   delete mode 100644 gdb/stabsread.h
>>   delete mode 100644 gdb/testsuite/gdb.stabs/aout.sed
>>   delete mode 100644 gdb/testsuite/gdb.stabs/ecoff.sed
>>   delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd.exp
>>   delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd.h
>>   delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd1.c
>>   delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd2.c
>>   delete mode 100644 gdb/testsuite/gdb.stabs/gdb11479.c
>>   delete mode 100644 gdb/testsuite/gdb.stabs/gdb11479.exp
>>   delete mode 100644 gdb/testsuite/gdb.stabs/hppa.sed
>>   delete mode 100644 gdb/testsuite/gdb.stabs/weird.def
>>   delete mode 100644 gdb/testsuite/gdb.stabs/xcoff.sed
> Thanks, but didn't I already approve the documentation parts of this?
> They are almost entirely trivial anyway.
>
> Reviewed-By: Eli Zaretskii <eliz@gnu.org>
>
You're right, I must've forgotten to add your tag. Sorry about that

-- 
Cheers,
Guinevere Larsen
It/she


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 0/8] Remove stabs support from GDB
  2025-10-20 15:28 [PATCH v2 0/8] Remove stabs support from GDB Guinevere Larsen
                   ` (7 preceding siblings ...)
  2025-10-20 15:28 ` [PATCH v2 8/8] gdb: remove support for dbx " Guinevere Larsen
@ 2025-10-21 19:14 ` Tom Tromey
  2025-10-21 19:42   ` Guinevere Larsen
  2025-10-22  9:48 ` Luis
  2025-10-23 18:11 ` Simon Marchi
  10 siblings, 1 reply; 24+ messages in thread
From: Tom Tromey @ 2025-10-21 19:14 UTC (permalink / raw)
  To: Guinevere Larsen; +Cc: gdb-patches

>>>>> "Guinevere" == Guinevere Larsen <guinevere@redhat.com> writes:

Guinevere> Now that GDB 17 has branched, I think we're ready to remov stabs from
Guinevere> GDB entirely, and the sooner this is merged, the earlier we'll spot any
Guinevere> problems and the more time will be there to fix them.

Guinevere> This series does just that.

Thanks, I think it is time to land this.

Approved-By: Tom Tromey <tom@tromey.com>

Tom

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 0/8] Remove stabs support from GDB
  2025-10-21 19:14 ` [PATCH v2 0/8] Remove stabs support " Tom Tromey
@ 2025-10-21 19:42   ` Guinevere Larsen
  0 siblings, 0 replies; 24+ messages in thread
From: Guinevere Larsen @ 2025-10-21 19:42 UTC (permalink / raw)
  To: Tom Tromey; +Cc: gdb-patches

On 10/21/25 4:14 PM, Tom Tromey wrote:
>>>>>> "Guinevere" == Guinevere Larsen <guinevere@redhat.com> writes:
> Guinevere> Now that GDB 17 has branched, I think we're ready to remov stabs from
> Guinevere> GDB entirely, and the sooner this is merged, the earlier we'll spot any
> Guinevere> problems and the more time will be there to fix them.
>
> Guinevere> This series does just that.
>
> Thanks, I think it is time to land this.
>
> Approved-By: Tom Tromey <tom@tromey.com>
>
> Tom
>
Thank you! It has (finally) been pushed. One less branch to baby around!

-- 
Cheers,
Guinevere Larsen
It/she


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 0/8] Remove stabs support from GDB
  2025-10-20 15:28 [PATCH v2 0/8] Remove stabs support from GDB Guinevere Larsen
                   ` (8 preceding siblings ...)
  2025-10-21 19:14 ` [PATCH v2 0/8] Remove stabs support " Tom Tromey
@ 2025-10-22  9:48 ` Luis
  2025-10-22 13:08   ` Tom Tromey
  2025-10-23 18:11 ` Simon Marchi
  10 siblings, 1 reply; 24+ messages in thread
From: Luis @ 2025-10-22  9:48 UTC (permalink / raw)
  To: Guinevere Larsen, gdb-patches

Hi,

On 20/10/2025 16:28, Guinevere Larsen wrote:
> Now that GDB 17 has branched, I think we're ready to remov stabs from
> GDB entirely, and the sooner this is merged, the earlier we'll spot any
> problems and the more time will be there to fix them.
> 
> This series does just that.
> 
> Guinevere Larsen (8):
>    gdb: move some stabs functions to gdb/buildsym-legacy.h
>    gdb/mdebug: Remove stabs support from mips inferiors
>    gdb: Remove stabs support from ELF files
>    gdb: Remove stabs support from dbx
>    gdb: Remove stabs support for COFF files
>    gdb: Remove stabs support from XCOFF inferiors
>    gdb: Fully remove stabs code from GDB
>    gdb: remove support for dbx from GDB
> 
>   gdb/Makefile.in                      |    8 +-
>   gdb/NEWS                             |    4 +
>   gdb/arch-utils.c                     |    6 -
>   gdb/arch-utils.h                     |    3 -
>   gdb/buildsym-legacy.h                |   10 +
>   gdb/buildsym.c                       |   18 -
>   gdb/coffread.c                       |  133 +-
>   gdb/configure                        |    6 +-
>   gdb/configure.ac                     |    4 +-
>   gdb/dbxread.c                        |  254 -
>   gdb/doc/Makefile.in                  |   46 +-
>   gdb/doc/gdb.texinfo                  |   23 +-
>   gdb/doc/stabs.texinfo                | 4130 ---------------
>   gdb/elfread.c                        |  146 +-
>   gdb/gdb-stabs.h                      |  176 -
>   gdb/gdbarch-gen.c                    |   22 -
>   gdb/gdbarch-gen.h                    |    4 -
>   gdb/gdbarch_components.py            |    8 -
>   gdb/mdebugread.c                     | 1781 ++-----
>   gdb/microblaze-tdep.c                |    8 -
>   gdb/mipsread.c                       |    2 -
>   gdb/objfiles.h                       |    3 -
>   gdb/rs6000-aix-nat.c                 |    1 -
>   gdb/sparc-tdep.c                     |   10 -
>   gdb/sparc64-tdep.c                   |    2 -
>   gdb/stabsread.c                      | 7217 --------------------------
>   gdb/stabsread.h                      |  314 --
>   gdb/symmisc.c                        |    3 -
>   gdb/testsuite/gdb.stabs/aout.sed     |   16 -
>   gdb/testsuite/gdb.stabs/ecoff.sed    |   17 -
>   gdb/testsuite/gdb.stabs/exclfwd.exp  |   57 -
>   gdb/testsuite/gdb.stabs/exclfwd.h    |   21 -
>   gdb/testsuite/gdb.stabs/exclfwd1.c   |   34 -
>   gdb/testsuite/gdb.stabs/exclfwd2.c   |   29 -
>   gdb/testsuite/gdb.stabs/gdb11479.c   |   76 -
>   gdb/testsuite/gdb.stabs/gdb11479.exp |   59 -
>   gdb/testsuite/gdb.stabs/hppa.sed     |   20 -
>   gdb/testsuite/gdb.stabs/weird.def    |  900 ----
>   gdb/testsuite/gdb.stabs/weird.exp    |  309 --
>   gdb/testsuite/gdb.stabs/xcoff.sed    |   17 -
>   gdb/testsuite/lib/gdb.exp            |    6 +
>   gdb/xcoffread.c                      | 2014 +------
>   42 files changed, 544 insertions(+), 17373 deletions(-)
>   delete mode 100644 gdb/dbxread.c
>   delete mode 100644 gdb/doc/stabs.texinfo
>   delete mode 100644 gdb/gdb-stabs.h
>   delete mode 100644 gdb/stabsread.c
>   delete mode 100644 gdb/stabsread.h
>   delete mode 100644 gdb/testsuite/gdb.stabs/aout.sed
>   delete mode 100644 gdb/testsuite/gdb.stabs/ecoff.sed
>   delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd.exp
>   delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd.h
>   delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd1.c
>   delete mode 100644 gdb/testsuite/gdb.stabs/exclfwd2.c
>   delete mode 100644 gdb/testsuite/gdb.stabs/gdb11479.c
>   delete mode 100644 gdb/testsuite/gdb.stabs/gdb11479.exp
>   delete mode 100644 gdb/testsuite/gdb.stabs/hppa.sed
>   delete mode 100644 gdb/testsuite/gdb.stabs/weird.def
>   delete mode 100644 gdb/testsuite/gdb.stabs/weird.exp
>   delete mode 100644 gdb/testsuite/gdb.stabs/xcoff.sed
> 
> 
> base-commit: b9e48061e06ec0c181757c9e80cc4dc72d614f4f

Looks like gcc (13.3.0 at least) is a bit grumpy with this and there are 
a few -Werror=array-bounds= warnings stopping the build, apparently from 
changes to gdb/xcoffread.c.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 0/8] Remove stabs support from GDB
  2025-10-22  9:48 ` Luis
@ 2025-10-22 13:08   ` Tom Tromey
  2025-10-22 13:19     ` Guinevere Larsen
  0 siblings, 1 reply; 24+ messages in thread
From: Tom Tromey @ 2025-10-22 13:08 UTC (permalink / raw)
  To: Luis; +Cc: Guinevere Larsen, gdb-patches

>>>>> "Luis" == Luis  <luis.machado.foss@gmail.com> writes:

Luis> Looks like gcc (13.3.0 at least) is a bit grumpy with this and there
Luis> are a few -Werror=array-bounds= warnings stopping the build,
Luis> apparently from changes to gdb/xcoffread.c.

Could you post them here?

IIRC some versions of GCC issued these kinds of errors incorrectly.
So it's possible the fix might be just to disable the warning for that build.

Tom

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 0/8] Remove stabs support from GDB
  2025-10-22 13:08   ` Tom Tromey
@ 2025-10-22 13:19     ` Guinevere Larsen
  2025-10-22 19:19       ` Luis
  0 siblings, 1 reply; 24+ messages in thread
From: Guinevere Larsen @ 2025-10-22 13:19 UTC (permalink / raw)
  To: Tom Tromey, Luis; +Cc: gdb-patches

On 10/22/25 10:08 AM, Tom Tromey wrote:
>>>>>> "Luis" == Luis  <luis.machado.foss@gmail.com> writes:
> Luis> Looks like gcc (13.3.0 at least) is a bit grumpy with this and there
> Luis> are a few -Werror=array-bounds= warnings stopping the build,
> Luis> apparently from changes to gdb/xcoffread.c.
>
> Could you post them here?
>
> IIRC some versions of GCC issued these kinds of errors incorrectly.
> So it's possible the fix might be just to disable the warning for that build.
>
> Tom
>
I believe that is the case, since I just installed gcc-13.3.1-2 from 
fedora 40 and upstream built fine, so I think either the .1 shame 
release  (see pride versioning: https://pridever.org/ :p), or some 
fedora patch, fixed a gcc bug related to that.

-- 
Cheers,
Guinevere Larsen
It/she


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 0/8] Remove stabs support from GDB
  2025-10-22 13:19     ` Guinevere Larsen
@ 2025-10-22 19:19       ` Luis
  2025-10-23  0:58         ` Luis
  0 siblings, 1 reply; 24+ messages in thread
From: Luis @ 2025-10-22 19:19 UTC (permalink / raw)
  To: Guinevere Larsen; +Cc: Tom Tromey, gdb-patches

[-- Attachment #1: Type: text/plain, Size: 1130 bytes --]

Hi,

On Wed, Oct 22, 2025, 14:19 Guinevere Larsen <guinevere@redhat.com> wrote:

> On 10/22/25 10:08 AM, Tom Tromey wrote:
> >>>>>> "Luis" == Luis  <luis.machado.foss@gmail.com> writes:
> > Luis> Looks like gcc (13.3.0 at least) is a bit grumpy with this and
> there
> > Luis> are a few -Werror=array-bounds= warnings stopping the build,
> > Luis> apparently from changes to gdb/xcoffread.c.
> >
> > Could you post them here?
> >
> > IIRC some versions of GCC issued these kinds of errors incorrectly.
> > So it's possible the fix might be just to disable the warning for that
> build.
> >
> > Tom
> >
> I believe that is the case, since I just installed gcc-13.3.1-2 from
> fedora 40 and upstream built fine, so I think either the .1 shame
> release  (see pride versioning: https://pridever.org/ :p), or some
> fedora patch, fixed a gcc bug related to that.
>

Yeah, sorry for the poor report. It happened on a different machine
unreachable from the one I sent the message.

I'll reproduce it and paste the exact messages. I tried to make sense of it
a bit, but seemed a bit odd.


> --
> Cheers,
> Guinevere Larsen
> It/she
>
>

[-- Attachment #2: Type: text/html, Size: 2052 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 0/8] Remove stabs support from GDB
  2025-10-22 19:19       ` Luis
@ 2025-10-23  0:58         ` Luis
  2025-10-23  2:03           ` Andrew Pinski
  0 siblings, 1 reply; 24+ messages in thread
From: Luis @ 2025-10-23  0:58 UTC (permalink / raw)
  To: Guinevere Larsen; +Cc: Tom Tromey, gdb-patches

On 22/10/2025 20:19, Luis wrote:
> Hi,
> 
> On Wed, Oct 22, 2025, 14:19 Guinevere Larsen <guinevere@redhat.com 
> <mailto:guinevere@redhat.com>> wrote:
> 
>     On 10/22/25 10:08 AM, Tom Tromey wrote:
>      >>>>>> "Luis" == Luis  <luis.machado.foss@gmail.com
>     <mailto:luis.machado.foss@gmail.com>> writes:
>      > Luis> Looks like gcc (13.3.0 at least) is a bit grumpy with this
>     and there
>      > Luis> are a few -Werror=array-bounds= warnings stopping the build,
>      > Luis> apparently from changes to gdb/xcoffread.c.
>      >
>      > Could you post them here?
>      >
>      > IIRC some versions of GCC issued these kinds of errors incorrectly.
>      > So it's possible the fix might be just to disable the warning for
>     that build.
>      >
>      > Tom
>      >
>     I believe that is the case, since I just installed gcc-13.3.1-2 from
>     fedora 40 and upstream built fine, so I think either the .1 shame
>     release  (see pride versioning: https://pridever.org/ <https://
>     pridever.org/> :p), or some
>     fedora patch, fixed a gcc bug related to that.
> 
> 
> Yeah, sorry for the poor report. It happened on a different machine 
> unreachable from the one I sent the message.
> 
> I'll reproduce it and paste the exact messages. I tried to make sense of 
> it a bit, but seemed a bit odd.
> 
> 
>     -- 
>     Cheers,
>     Guinevere Larsen
>     It/she
> 

Ok, I played with this a bit more and reproduced it again on my end. The 
problem seems to be related to enabling ubsan in configure for the build.

So if I configure with the following...

./configure --enable-targets=all --with-python=python3 --without-guile 
--enable-ubsan

I get these errors...

---

In file included from /usr/include/c++/13/vector:66,
                  from /usr/include/c++/13/functional:64,
                  from 
../../../repos/binutils-gdb/gdb/../gdbsupport/ptid.h:35,
                  from 
../../../repos/binutils-gdb/gdb/../gdbsupport/common-defs.h:212,
                  from ./../../../repos/binutils-gdb/gdb/defs.h:26,
                  from <command-line>:
In member function ‘std::vector<_Tp, _Alloc>::reference std::vector<_Tp, 
_Alloc>::operator[](size_type) [with _Tp = void*; _Alloc = 
std::allocator<void*>]’,
     inlined from ‘void* registry<T>::get(unsigned int) [with T = 
objfile]’ at ../../../repos/binutils-gdb/gdb/registry.h:213:24,
     inlined from ‘DATA* registry<T>::key<DATA, Deleter>::get(T*) const 
[with DATA = xcoff_symfile_info; Deleter = 
std::default_delete<xcoff_symfile_info>; T = objfile]’ at 
../../../repos/binutils-gdb/gdb/registry.h:111:36,
     inlined from ‘void enter_line_range(subfile*, unsigned int, 
unsigned int, CORE_ADDR, CORE_ADDR, unsigned int*)’ at 
../../../repos/binutils-gdb/gdb/xcoffread.c:544:18:
/usr/include/c++/13/bits/stl_vector.h:1129:32: error: array subscript 0 
is outside array bounds of ‘registry<objfile> [0]’ [-Werror=array-bounds=]
  1129 |         return *(this->_M_impl._M_start + __n);
       |                  ~~~~~~~~~~~~~~^~~~~~~~
In function ‘void enter_line_range(subfile*, unsigned int, unsigned int, 
CORE_ADDR, CORE_ADDR, unsigned int*)’:
cc1plus: note: source object is likely at address zero
In member function ‘std::vector<_Tp, _Alloc>::reference std::vector<_Tp, 
_Alloc>::operator[](size_type) [with _Tp = void*; _Alloc = 
std::allocator<void*>]’,
     inlined from ‘void* registry<T>::get(unsigned int) [with T = 
objfile]’ at ../../../repos/binutils-gdb/gdb/registry.h:213:24,
     inlined from ‘DATA* registry<T>::key<DATA, Deleter>::get(T*) const 
[with DATA = xcoff_symfile_info; Deleter = 
std::default_delete<xcoff_symfile_info>; T = objfile]’ at 
../../../repos/binutils-gdb/gdb/registry.h:111:36,
     inlined from ‘void enter_line_range(subfile*, unsigned int, 
unsigned int, CORE_ADDR, CORE_ADDR, unsigned int*)’ at 
../../../repos/binutils-gdb/gdb/xcoffread.c:544:18:
/usr/include/c++/13/bits/stl_vector.h:1129:32: error: array subscript 0 
is outside array bounds of ‘registry<objfile> [0]’ [-Werror=array-bounds=]
In function ‘void enter_line_range(subfile*, unsigned int, unsigned int, 
CORE_ADDR, CORE_ADDR, unsigned int*)’:
cc1plus: note: source object is likely at address zero
In member function ‘std::vector<_Tp, _Alloc>::reference std::vector<_Tp, 
_Alloc>::operator[](size_type) [with _Tp = void*; _Alloc = 
std::allocator<void*>]’,
     inlined from ‘void* registry<T>::get(unsigned int) [with T = 
objfile]’ at ../../../repos/binutils-gdb/gdb/registry.h:213:24,
     inlined from ‘DATA* registry<T>::key<DATA, Deleter>::get(T*) const 
[with DATA = xcoff_symfile_info; Deleter = 
std::default_delete<xcoff_symfile_info>; T = objfile]’ at 
../../../repos/binutils-gdb/gdb/registry.h:111:36,
     inlined from ‘void read_symbol(internal_syment*, int)’ at 
../../../repos/binutils-gdb/gdb/xcoffread.c:612:38,
     inlined from ‘CORE_ADDR read_symbol_nvalue(int)’ at 
../../../repos/binutils-gdb/gdb/xcoffread.c:635:15,
     inlined from ‘void enter_line_range(subfile*, unsigned int, 
unsigned int, CORE_ADDR, CORE_ADDR, unsigned int*)’ at 
../../../repos/binutils-gdb/gdb/xcoffread.c:572:29:
/usr/include/c++/13/bits/stl_vector.h:1129:32: error: array subscript 0 
is outside array bounds of ‘registry<objfile> [0]’ [-Werror=array-bounds=]
  1129 |         return *(this->_M_impl._M_start + __n);
       |                  ~~~~~~~~~~~~~~^~~~~~~~
In function ‘void enter_line_range(subfile*, unsigned int, unsigned int, 
CORE_ADDR, CORE_ADDR, unsigned int*)’:
cc1plus: note: source object is likely at address zero
In member function ‘std::vector<_Tp, _Alloc>::reference std::vector<_Tp, 
_Alloc>::operator[](size_type) [with _Tp = void*; _Alloc = 
std::allocator<void*>]’,
     inlined from ‘void* registry<T>::get(unsigned int) [with T = 
objfile]’ at ../../../repos/binutils-gdb/gdb/registry.h:213:24,
     inlined from ‘DATA* registry<T>::key<DATA, Deleter>::get(T*) const 
[with DATA = xcoff_symfile_info; Deleter = 
std::default_delete<xcoff_symfile_info>; T = objfile]’ at 
../../../repos/binutils-gdb/gdb/registry.h:111:36,
     inlined from ‘int read_symbol_lineno(int)’ at 
../../../repos/binutils-gdb/gdb/xcoffread.c:649:37,
     inlined from ‘void enter_line_range(subfile*, unsigned int, 
unsigned int, CORE_ADDR, CORE_ADDR, unsigned int*)’ at 
../../../repos/binutils-gdb/gdb/xcoffread.c:582:36:
/usr/include/c++/13/bits/stl_vector.h:1129:32: error: array subscript 0 
is outside array bounds of ‘registry<objfile> [0]’ [-Werror=array-bounds=]
  1129 |         return *(this->_M_impl._M_start + __n);
       |                  ~~~~~~~~~~~~~~^~~~~~~~
In function ‘void enter_line_range(subfile*, unsigned int, unsigned int, 
CORE_ADDR, CORE_ADDR, unsigned int*)’:
cc1plus: note: source object is likely at address zero

---

If I drop the --enable-ubsan from configure, then the build completes 
just fine.

Maybe not a show stopper, but would be nice to have working builds with 
ubsan.

For reference, the system is using Mint 22.2, which might be equivalent 
to Ubuntu 24.04.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 0/8] Remove stabs support from GDB
  2025-10-23  0:58         ` Luis
@ 2025-10-23  2:03           ` Andrew Pinski
  0 siblings, 0 replies; 24+ messages in thread
From: Andrew Pinski @ 2025-10-23  2:03 UTC (permalink / raw)
  To: Luis; +Cc: Guinevere Larsen, Tom Tromey, gdb-patches

On Wed, Oct 22, 2025 at 5:59 PM Luis <luis.machado.foss@gmail.com> wrote:
>
> On 22/10/2025 20:19, Luis wrote:
> > Hi,
> >
> > On Wed, Oct 22, 2025, 14:19 Guinevere Larsen <guinevere@redhat.com
> > <mailto:guinevere@redhat.com>> wrote:
> >
> >     On 10/22/25 10:08 AM, Tom Tromey wrote:
> >      >>>>>> "Luis" == Luis  <luis.machado.foss@gmail.com
> >     <mailto:luis.machado.foss@gmail.com>> writes:
> >      > Luis> Looks like gcc (13.3.0 at least) is a bit grumpy with this
> >     and there
> >      > Luis> are a few -Werror=array-bounds= warnings stopping the build,
> >      > Luis> apparently from changes to gdb/xcoffread.c.
> >      >
> >      > Could you post them here?
> >      >
> >      > IIRC some versions of GCC issued these kinds of errors incorrectly.
> >      > So it's possible the fix might be just to disable the warning for
> >     that build.
> >      >
> >      > Tom
> >      >
> >     I believe that is the case, since I just installed gcc-13.3.1-2 from
> >     fedora 40 and upstream built fine, so I think either the .1 shame
> >     release  (see pride versioning: https://pridever.org/ <https://
> >     pridever.org/> :p), or some
> >     fedora patch, fixed a gcc bug related to that.
> >
> >
> > Yeah, sorry for the poor report. It happened on a different machine
> > unreachable from the one I sent the message.
> >
> > I'll reproduce it and paste the exact messages. I tried to make sense of
> > it a bit, but seemed a bit odd.
> >
> >
> >     --
> >     Cheers,
> >     Guinevere Larsen
> >     It/she
> >
>
> Ok, I played with this a bit more and reproduced it again on my end. The
> problem seems to be related to enabling ubsan in configure for the build.
>
> So if I configure with the following...
>
> ./configure --enable-targets=all --with-python=python3 --without-guile
> --enable-ubsan
>
> I get these errors...
>
> ---
>
> In file included from /usr/include/c++/13/vector:66,
>                   from /usr/include/c++/13/functional:64,
>                   from
> ../../../repos/binutils-gdb/gdb/../gdbsupport/ptid.h:35,
>                   from
> ../../../repos/binutils-gdb/gdb/../gdbsupport/common-defs.h:212,
>                   from ./../../../repos/binutils-gdb/gdb/defs.h:26,
>                   from <command-line>:
> In member function ‘std::vector<_Tp, _Alloc>::reference std::vector<_Tp,
> _Alloc>::operator[](size_type) [with _Tp = void*; _Alloc =
> std::allocator<void*>]’,
>      inlined from ‘void* registry<T>::get(unsigned int) [with T =
> objfile]’ at ../../../repos/binutils-gdb/gdb/registry.h:213:24,
>      inlined from ‘DATA* registry<T>::key<DATA, Deleter>::get(T*) const
> [with DATA = xcoff_symfile_info; Deleter =
> std::default_delete<xcoff_symfile_info>; T = objfile]’ at
> ../../../repos/binutils-gdb/gdb/registry.h:111:36,
>      inlined from ‘void enter_line_range(subfile*, unsigned int,
> unsigned int, CORE_ADDR, CORE_ADDR, unsigned int*)’ at
> ../../../repos/binutils-gdb/gdb/xcoffread.c:544:18:
> /usr/include/c++/13/bits/stl_vector.h:1129:32: error: array subscript 0
> is outside array bounds of ‘registry<objfile> [0]’ [-Werror=array-bounds=]
>   1129 |         return *(this->_M_impl._M_start + __n);
>        |                  ~~~~~~~~~~~~~~^~~~~~~~
> In function ‘void enter_line_range(subfile*, unsigned int, unsigned int,
> CORE_ADDR, CORE_ADDR, unsigned int*)’:
> cc1plus: note: source object is likely at address zero
> In member function ‘std::vector<_Tp, _Alloc>::reference std::vector<_Tp,
> _Alloc>::operator[](size_type) [with _Tp = void*; _Alloc =
> std::allocator<void*>]’,
>      inlined from ‘void* registry<T>::get(unsigned int) [with T =
> objfile]’ at ../../../repos/binutils-gdb/gdb/registry.h:213:24,
>      inlined from ‘DATA* registry<T>::key<DATA, Deleter>::get(T*) const
> [with DATA = xcoff_symfile_info; Deleter =
> std::default_delete<xcoff_symfile_info>; T = objfile]’ at
> ../../../repos/binutils-gdb/gdb/registry.h:111:36,
>      inlined from ‘void enter_line_range(subfile*, unsigned int,
> unsigned int, CORE_ADDR, CORE_ADDR, unsigned int*)’ at
> ../../../repos/binutils-gdb/gdb/xcoffread.c:544:18:
> /usr/include/c++/13/bits/stl_vector.h:1129:32: error: array subscript 0
> is outside array bounds of ‘registry<objfile> [0]’ [-Werror=array-bounds=]
> In function ‘void enter_line_range(subfile*, unsigned int, unsigned int,
> CORE_ADDR, CORE_ADDR, unsigned int*)’:
> cc1plus: note: source object is likely at address zero
> In member function ‘std::vector<_Tp, _Alloc>::reference std::vector<_Tp,
> _Alloc>::operator[](size_type) [with _Tp = void*; _Alloc =
> std::allocator<void*>]’,
>      inlined from ‘void* registry<T>::get(unsigned int) [with T =
> objfile]’ at ../../../repos/binutils-gdb/gdb/registry.h:213:24,
>      inlined from ‘DATA* registry<T>::key<DATA, Deleter>::get(T*) const
> [with DATA = xcoff_symfile_info; Deleter =
> std::default_delete<xcoff_symfile_info>; T = objfile]’ at
> ../../../repos/binutils-gdb/gdb/registry.h:111:36,
>      inlined from ‘void read_symbol(internal_syment*, int)’ at
> ../../../repos/binutils-gdb/gdb/xcoffread.c:612:38,
>      inlined from ‘CORE_ADDR read_symbol_nvalue(int)’ at
> ../../../repos/binutils-gdb/gdb/xcoffread.c:635:15,
>      inlined from ‘void enter_line_range(subfile*, unsigned int,
> unsigned int, CORE_ADDR, CORE_ADDR, unsigned int*)’ at
> ../../../repos/binutils-gdb/gdb/xcoffread.c:572:29:
> /usr/include/c++/13/bits/stl_vector.h:1129:32: error: array subscript 0
> is outside array bounds of ‘registry<objfile> [0]’ [-Werror=array-bounds=]
>   1129 |         return *(this->_M_impl._M_start + __n);
>        |                  ~~~~~~~~~~~~~~^~~~~~~~
> In function ‘void enter_line_range(subfile*, unsigned int, unsigned int,
> CORE_ADDR, CORE_ADDR, unsigned int*)’:
> cc1plus: note: source object is likely at address zero
> In member function ‘std::vector<_Tp, _Alloc>::reference std::vector<_Tp,
> _Alloc>::operator[](size_type) [with _Tp = void*; _Alloc =
> std::allocator<void*>]’,
>      inlined from ‘void* registry<T>::get(unsigned int) [with T =
> objfile]’ at ../../../repos/binutils-gdb/gdb/registry.h:213:24,
>      inlined from ‘DATA* registry<T>::key<DATA, Deleter>::get(T*) const
> [with DATA = xcoff_symfile_info; Deleter =
> std::default_delete<xcoff_symfile_info>; T = objfile]’ at
> ../../../repos/binutils-gdb/gdb/registry.h:111:36,
>      inlined from ‘int read_symbol_lineno(int)’ at
> ../../../repos/binutils-gdb/gdb/xcoffread.c:649:37,
>      inlined from ‘void enter_line_range(subfile*, unsigned int,
> unsigned int, CORE_ADDR, CORE_ADDR, unsigned int*)’ at
> ../../../repos/binutils-gdb/gdb/xcoffread.c:582:36:
> /usr/include/c++/13/bits/stl_vector.h:1129:32: error: array subscript 0
> is outside array bounds of ‘registry<objfile> [0]’ [-Werror=array-bounds=]
>   1129 |         return *(this->_M_impl._M_start + __n);
>        |                  ~~~~~~~~~~~~~~^~~~~~~~
> In function ‘void enter_line_range(subfile*, unsigned int, unsigned int,
> CORE_ADDR, CORE_ADDR, unsigned int*)’:
> cc1plus: note: source object is likely at address zero
>
> ---
>
> If I drop the --enable-ubsan from configure, then the build completes
> just fine.
>
> Maybe not a show stopper, but would be nice to have working builds with
> ubsan.

Yes GCC warnings with -fsanitize=undefined are known to be worse.
This is documented at
https://gcc.gnu.org/onlinedocs/gcc-15.2.0/gcc/Instrumentation-Options.html#index-fsanitize_003dundefined
:
```
Note that sanitizers tend to increase the rate of false positive
warnings, most notably those around -Wmaybe-uninitialized. We
recommend against combining -Werror and [the use of] sanitizers.
```
Array bounds also have an increased amount of warnings too.
Yes, this is an area where GCC should be better at handling this; we
(GCC) have discussed this a few times but there is almost no consensus
of what should happen next and nothing changes.

Thanks,
Andrew


>
> For reference, the system is using Mint 22.2, which might be equivalent
> to Ubuntu 24.04.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 0/8] Remove stabs support from GDB
  2025-10-20 15:28 [PATCH v2 0/8] Remove stabs support from GDB Guinevere Larsen
                   ` (9 preceding siblings ...)
  2025-10-22  9:48 ` Luis
@ 2025-10-23 18:11 ` Simon Marchi
  10 siblings, 0 replies; 24+ messages in thread
From: Simon Marchi @ 2025-10-23 18:11 UTC (permalink / raw)
  To: Guinevere Larsen, gdb-patches

On 10/20/25 11:28 AM, Guinevere Larsen wrote:
> Now that GDB 17 has branched, I think we're ready to remov stabs from
> GDB entirely, and the sooner this is merged, the earlier we'll spot any
> problems and the more time will be there to fix them.
> 
> This series does just that.

Hello,

I got another build failure that is likely related to this series.  It's
a -Werror=nonnull error, when building with UBSan, but I think it's not
a false positive.

      CXX    xcoffread.o
    /home/smarchi/src/binutils-gdb/gdb/xcoffread.c: In function ‘void enter_line_range(subfile*, unsigned int, unsigned int, CORE_ADDR, CORE_ADDR, unsigned int*)’:
    /home/smarchi/src/binutils-gdb/gdb/xcoffread.c:573:44: error: ‘this’ pointer is null [-Werror=nonnull]
      573 |       addr += objfile->text_section_offset ();
          |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
    In file included from /home/smarchi/src/binutils-gdb/gdb/xcoffread.c:43:
    /home/smarchi/src/binutils-gdb/gdb/objfiles.h:512:13: note: in a call to non-static member function ‘CORE_ADDR objfile::text_section_offset() const’
      512 |   CORE_ADDR text_section_offset () const
          |             ^~~~~~~~~~~~~~~~~~~
    /home/smarchi/src/binutils-gdb/gdb/xcoffread.c:579:63: error: ‘this’ pointer is null [-Werror=nonnull]
      579 |                                - objfile->text_section_offset ());
          |                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
    /home/smarchi/src/binutils-gdb/gdb/objfiles.h:512:13: note: in a call to non-static member function ‘CORE_ADDR objfile::text_section_offset() const’
      512 |   CORE_ADDR text_section_offset () const
          |             ^~~~~~~~~~~~~~~~~~~

The full configure line is:

    $ ~/src/binutils-gdb/configure --prefix=/build --disable-binutils --disable-ld --disable-gold --disable-gas --disable-sim --disable-gprof --disable-gprofng --with-system-readline --with-system-zlib --enable-targets=all --with-expat=yes --with-python=python3 --with-guile --enable-libctf --enable-build-warnings --enable-gdb-building-warnings --enable-unit-tests --enable-ubsan 'CC=ccache gcc' 'CFLAGS=-O2 -g -fsanitize=address    ' 'LDFLAGS= -fsanitize=address' 'CXX=ccache g++' 'CXXFLAGS=-O2 -g -fsanitize=address -D_GLIBCXX_DEBUG=1 -Wno-error=array-bounds    '

GCC version 15.2.1.

I think it's correctly complaining, because this_symtab_objfile is never
ever set anymore.  And neither is this_symtab_psymtab.  I realized this
when trying to refactor the code to remove these globals, trying to pass
them as parameters instead.

Simon

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 6/8] gdb: Remove stabs support from XCOFF inferiors
  2025-10-20 15:28 ` [PATCH v2 6/8] gdb: Remove stabs support from XCOFF inferiors Guinevere Larsen
@ 2025-11-07 10:46   ` Andrew Burgess
  2025-11-07 12:09     ` Guinevere Larsen
  0 siblings, 1 reply; 24+ messages in thread
From: Andrew Burgess @ 2025-11-07 10:46 UTC (permalink / raw)
  To: Guinevere Larsen, gdb-patches; +Cc: Guinevere Larsen

Guinevere Larsen <guinevere@redhat.com> writes:

> This commit is the second to last in the series fully removing support
> for stabs in GDB, removing it from XCOFF inferiors.  According to IBM's
> AIX documentation[1], xcoff binaries can only have stabs or DWARF debug
> info, meaning removing stabs seems pretty trivial, as anything that
> isn't related to setting base information on the objfile or reading
> dwarf can be removed.
>
> The unfortunate part of this removal is that XCOFF minimal symbols are
> encoded in stabs, so if an inferior has not been compiled with dwarf
> debuginfo, GDB will only be able to do assembly-level debugging.  Due to
> this, the xcoff reader now emits a warning if no dwarf is read, saying:
> "No usable debug information found".  This change would also add a lot of
> regressions to to AIX, so the gdb_compile proc has been changed to not
> work when a test tries to compile a test with nodebug.
>
> As a sidenote, gdb-stabs.h can just be removed from rs6000-aix-nat, as
> none of the structs or macros defined in the header are used in the nat
> file, so that is an unnecessary include.
>
> This commit introduces some known regressions when testing GDB in AIX
> systems.  The main ones are:
> * inferior function calls now crash with a corrupted stack.  This seems
>   to be some fault of dwarf in explaining how to correctly set the frame
>   for a function.
> * fortran tests can't runto_main: the fortran compiler does not add any
>   symbol for MAIN__ in the dwarf information, only in stabs, so the
>   fortran_runto_main proc can't set the breakpoint correctly.
> * When dealing with c++ class methods, there are cases when we fail to
>   properly recognize a method call as a new function.
> * When dealing with c++ virtual inheritance, GDB has issues finding a
>   derived class's members when it has been downcast to a base class.

A colleague reported this build failure after this commit:

    CXX    gdb.o
  ../../../binutils-gdb/gdb/xcoffread.c: In function 'void enter_line_range(subfile*, unsigned int, unsigned int, CORE_ADDR, CORE_ADDR, unsigned int*)':
  ../../../binutils-gdb/gdb/xcoffread.c:573:44: error: 'this' pointer is null [-Werror=nonnull]
    573 |       addr += objfile->text_section_offset ();
        |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
  In file included from ../../../binutils-gdb/gdb/xcoffread.c:43:
  ../../../binutils-gdb/gdb/objfiles.h:512:13: note: in a call to non-static member function 'CORE_ADDR objfile::text_section_offset() const'
    512 |   CORE_ADDR text_section_offset () const
        |             ^~~~~~~~~~~~~~~~~~~
  ../../../binutils-gdb/gdb/xcoffread.c:579:63: error: 'this' pointer is null [-Werror=nonnull]
    579 |                                - objfile->text_section_offset ());
        |                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
  ../../../binutils-gdb/gdb/objfiles.h:512:13: note: in a call to non-static member function 'CORE_ADDR objfile::text_section_offset() const'
    512 |   CORE_ADDR text_section_offset () const
        |             ^~~~~~~~~~~~~~~~~~~
  cc1plus: all warnings being treated as errors

This was building GDB on current Fedora rawhide, with
gcc-15.2.1-2.fc44.x86_64.

The compiler is being pretty insightful here.  OBJFILE is initialised
within the function like this:

  struct objfile *objfile = this_symtab_objfile;

And THIS_SYMTAB_OBJFILE is a static variable within this file that is
initialised to NULL.

After this commit, there is now no longer any way that
THIS_SYMTAB_OBJFILE can be set to a non-null value, so the above
warning/error seems legit.

This opens a bigger question (in my mind).  Either the code in
xcoffread.c that depends on THIS_SYMTAB_OBJFILE needs deleting, or some
parts of this commit need restoring.

I've not had a chance to look into this yet, so don't currently have an
opinion either way.

Thanks,
Andrew


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 6/8] gdb: Remove stabs support from XCOFF inferiors
  2025-11-07 10:46   ` Andrew Burgess
@ 2025-11-07 12:09     ` Guinevere Larsen
  2025-11-07 14:46       ` Tom Tromey
  0 siblings, 1 reply; 24+ messages in thread
From: Guinevere Larsen @ 2025-11-07 12:09 UTC (permalink / raw)
  To: Andrew Burgess, gdb-patches

On 11/7/25 7:46 AM, Andrew Burgess wrote:
> Guinevere Larsen <guinevere@redhat.com> writes:
>
>> This commit is the second to last in the series fully removing support
>> for stabs in GDB, removing it from XCOFF inferiors.  According to IBM's
>> AIX documentation[1], xcoff binaries can only have stabs or DWARF debug
>> info, meaning removing stabs seems pretty trivial, as anything that
>> isn't related to setting base information on the objfile or reading
>> dwarf can be removed.
>>
>> The unfortunate part of this removal is that XCOFF minimal symbols are
>> encoded in stabs, so if an inferior has not been compiled with dwarf
>> debuginfo, GDB will only be able to do assembly-level debugging.  Due to
>> this, the xcoff reader now emits a warning if no dwarf is read, saying:
>> "No usable debug information found".  This change would also add a lot of
>> regressions to to AIX, so the gdb_compile proc has been changed to not
>> work when a test tries to compile a test with nodebug.
>>
>> As a sidenote, gdb-stabs.h can just be removed from rs6000-aix-nat, as
>> none of the structs or macros defined in the header are used in the nat
>> file, so that is an unnecessary include.
>>
>> This commit introduces some known regressions when testing GDB in AIX
>> systems.  The main ones are:
>> * inferior function calls now crash with a corrupted stack.  This seems
>>    to be some fault of dwarf in explaining how to correctly set the frame
>>    for a function.
>> * fortran tests can't runto_main: the fortran compiler does not add any
>>    symbol for MAIN__ in the dwarf information, only in stabs, so the
>>    fortran_runto_main proc can't set the breakpoint correctly.
>> * When dealing with c++ class methods, there are cases when we fail to
>>    properly recognize a method call as a new function.
>> * When dealing with c++ virtual inheritance, GDB has issues finding a
>>    derived class's members when it has been downcast to a base class.
> A colleague reported this build failure after this commit:
>
>      CXX    gdb.o
>    ../../../binutils-gdb/gdb/xcoffread.c: In function 'void enter_line_range(subfile*, unsigned int, unsigned int, CORE_ADDR, CORE_ADDR, unsigned int*)':
>    ../../../binutils-gdb/gdb/xcoffread.c:573:44: error: 'this' pointer is null [-Werror=nonnull]
>      573 |       addr += objfile->text_section_offset ();
>          |               ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
>    In file included from ../../../binutils-gdb/gdb/xcoffread.c:43:
>    ../../../binutils-gdb/gdb/objfiles.h:512:13: note: in a call to non-static member function 'CORE_ADDR objfile::text_section_offset() const'
>      512 |   CORE_ADDR text_section_offset () const
>          |             ^~~~~~~~~~~~~~~~~~~
>    ../../../binutils-gdb/gdb/xcoffread.c:579:63: error: 'this' pointer is null [-Werror=nonnull]
>      579 |                                - objfile->text_section_offset ());
>          |                                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
>    ../../../binutils-gdb/gdb/objfiles.h:512:13: note: in a call to non-static member function 'CORE_ADDR objfile::text_section_offset() const'
>      512 |   CORE_ADDR text_section_offset () const
>          |             ^~~~~~~~~~~~~~~~~~~
>    cc1plus: all warnings being treated as errors
>
> This was building GDB on current Fedora rawhide, with
> gcc-15.2.1-2.fc44.x86_64.
>
> The compiler is being pretty insightful here.  OBJFILE is initialised
> within the function like this:
>
>    struct objfile *objfile = this_symtab_objfile;
>
> And THIS_SYMTAB_OBJFILE is a static variable within this file that is
> initialised to NULL.
>
> After this commit, there is now no longer any way that
> THIS_SYMTAB_OBJFILE can be set to a non-null value, so the above
> warning/error seems legit.
>
> This opens a bigger question (in my mind).  Either the code in
> xcoffread.c that depends on THIS_SYMTAB_OBJFILE needs deleting, or some
> parts of this commit need restoring.
>
> I've not had a chance to look into this yet, so don't currently have an
> opinion either way.
>
> Thanks,
> Andrew
>
Simon also raised this with me yesterday on IRC and sent this email to 
the AIX folks: 
https://inbox.sourceware.org/gdb-patches/b3afe6c6-8dc3-49be-8fca-43d0b3bddd56@polymtl.ca/T/#u

I'd prefer to keep discussion to this on that thread, as it is more 
likely to be caught by the folk who are most likely to know what's going 
on. I'll take a look at this failure today either way and see if there 
is an easy out that doesn't require much AIX knowledge

-- 
Cheers,
Guinevere Larsen
It/she


^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [PATCH v2 6/8] gdb: Remove stabs support from XCOFF inferiors
  2025-11-07 12:09     ` Guinevere Larsen
@ 2025-11-07 14:46       ` Tom Tromey
  0 siblings, 0 replies; 24+ messages in thread
From: Tom Tromey @ 2025-11-07 14:46 UTC (permalink / raw)
  To: Guinevere Larsen; +Cc: Andrew Burgess, gdb-patches

Guinevere> Simon also raised this with me yesterday on IRC and sent this email to
Guinevere> the AIX folks:
Guinevere> https://inbox.sourceware.org/gdb-patches/b3afe6c6-8dc3-49be-8fca-43d0b3bddd56@polymtl.ca/T/#u

Additionally there's a bug for it

https://sourceware.org/bugzilla/show_bug.cgi?id=33606

Tom

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2025-11-07 14:49 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-10-20 15:28 [PATCH v2 0/8] Remove stabs support from GDB Guinevere Larsen
2025-10-20 15:28 ` [PATCH v2 1/8] gdb: move some stabs functions to gdb/buildsym-legacy.h Guinevere Larsen
2025-10-20 16:25   ` Tom Tromey
2025-10-20 15:28 ` [PATCH v2 2/8] gdb/mdebug: Remove stabs support from mips inferiors Guinevere Larsen
2025-10-20 15:28 ` [PATCH v2 3/8] gdb: Remove stabs support from ELF files Guinevere Larsen
2025-10-20 15:28 ` [PATCH v2 4/8] gdb: Remove stabs support from dbx Guinevere Larsen
2025-10-20 15:28 ` [PATCH v2 5/8] gdb: Remove stabs support for COFF files Guinevere Larsen
2025-10-20 15:28 ` [PATCH v2 6/8] gdb: Remove stabs support from XCOFF inferiors Guinevere Larsen
2025-11-07 10:46   ` Andrew Burgess
2025-11-07 12:09     ` Guinevere Larsen
2025-11-07 14:46       ` Tom Tromey
2025-10-20 15:28 ` [PATCH v2 7/8] gdb: Fully remove stabs code from GDB Guinevere Larsen
2025-10-20 16:39   ` Eli Zaretskii
2025-10-20 19:12     ` Guinevere Larsen
2025-10-20 15:28 ` [PATCH v2 8/8] gdb: remove support for dbx " Guinevere Larsen
2025-10-21 19:14 ` [PATCH v2 0/8] Remove stabs support " Tom Tromey
2025-10-21 19:42   ` Guinevere Larsen
2025-10-22  9:48 ` Luis
2025-10-22 13:08   ` Tom Tromey
2025-10-22 13:19     ` Guinevere Larsen
2025-10-22 19:19       ` Luis
2025-10-23  0:58         ` Luis
2025-10-23  2:03           ` Andrew Pinski
2025-10-23 18:11 ` Simon Marchi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox