x86: Adjust linker tests for --disable-separate-code
[binutils-gdb.git] / gdb / dbxread.c
index bdf4fb9c798394133237bdf54bb26be41d2034d3..4d846990a56b37e172af9bf9dc5b55fcf4c16a09 100644 (file)
@@ -1,5 +1,5 @@
 /* Read dbx symbol tables and convert to internal format, for GDB.
 /* Read dbx symbol tables and convert to internal format, for GDB.
-   Copyright (C) 1986-2018 Free Software Foundation, Inc.
+   Copyright (C) 1986-2021 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
    This file is part of GDB.
 
    for real.  dbx_psymtab_to_symtab() is the function that does this */
 
 #include "defs.h"
    for real.  dbx_psymtab_to_symtab() is the function that does this */
 
 #include "defs.h"
-#if defined(__CYGNUSCLIB__)
-#include <sys/types.h>
-#include <fcntl.h>
-#endif
 
 #include "gdb_obstack.h"
 #include <sys/stat.h>
 
 #include "gdb_obstack.h"
 #include <sys/stat.h>
@@ -45,7 +41,7 @@
 #include "libaout.h"           /* FIXME Secret internal BFD stuff for a.out */
 #include "filenames.h"
 #include "objfiles.h"
 #include "libaout.h"           /* FIXME Secret internal BFD stuff for a.out */
 #include "filenames.h"
 #include "objfiles.h"
-#include "buildsym.h"
+#include "buildsym-legacy.h"
 #include "stabsread.h"
 #include "gdb-stabs.h"
 #include "demangle.h"
 #include "stabsread.h"
 #include "gdb-stabs.h"
 #include "demangle.h"
@@ -61,7 +57,7 @@
 
 /* Key for dbx-associated data.  */
 
 
 /* Key for dbx-associated data.  */
 
-const struct objfile_data *dbx_objfile_data_key;
+objfile_key<dbx_symfile_info> dbx_objfile_data_key;
 
 /* We put a pointer to this structure in the read_symtab_private field
    of the psymtab.  */
 
 /* We put a pointer to this structure in the read_symtab_private field
    of the psymtab.  */
@@ -145,6 +141,14 @@ static unsigned int next_file_string_table_offset;
 
 static int symfile_relocatable = 0;
 
 
 static 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.  */
+
+static unsigned char processing_acc_compilation;
+
 \f
 /* 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
 \f
 /* 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
@@ -164,21 +168,19 @@ static int has_line_numbers;
 static void
 unknown_symtype_complaint (const char *arg1)
 {
 static void
 unknown_symtype_complaint (const char *arg1)
 {
-  complaint (&symfile_complaints, _("unknown symbol type %s"), arg1);
+  complaint (_("unknown symbol type %s"), arg1);
 }
 
 static void
 lbrac_mismatch_complaint (int arg1)
 {
 }
 
 static void
 lbrac_mismatch_complaint (int arg1)
 {
-  complaint (&symfile_complaints,
-            _("N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d"), arg1);
+  complaint (_("N_LBRAC/N_RBRAC symbol mismatch at symtab pos %d"), arg1);
 }
 
 static void
 repeated_header_complaint (const char *arg1, int arg2)
 {
 }
 
 static void
 repeated_header_complaint (const char *arg1, int arg2)
 {
-  complaint (&symfile_complaints,
-            _("\"repeated\" header file %s not "
+  complaint (_("\"repeated\" header file %s not "
               "previously seen, at symtab pos %d"),
             arg1, arg2);
 }
               "previously seen, at symtab pos %d"),
             arg1, arg2);
 }
@@ -201,10 +203,10 @@ find_text_range (bfd * sym_bfd, struct objfile *objfile)
   CORE_ADDR end = 0;
 
   for (sec = sym_bfd->sections; sec; sec = sec->next)
   CORE_ADDR end = 0;
 
   for (sec = sym_bfd->sections; sec; sec = sec->next)
-    if (bfd_get_section_flags (sym_bfd, sec) & SEC_CODE)
+    if (bfd_section_flags (sec) & SEC_CODE)
       {
       {
-       CORE_ADDR sec_start = bfd_section_vma (sym_bfd, sec);
-       CORE_ADDR sec_end = sec_start + bfd_section_size (sym_bfd, sec);
+       CORE_ADDR sec_start = bfd_section_vma (sec);
+       CORE_ADDR sec_end = sec_start + bfd_section_size (sec);
 
        if (found_any)
          {
 
        if (found_any)
          {
@@ -238,36 +240,38 @@ find_text_range (bfd * sym_bfd, struct objfile *objfile)
 
 struct header_file_location
 {
 
 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 */
   const char *name;            /* Name of header file */
   int instance;                        /* See above */
-  struct partial_symtab *pst;  /* Partial symtab that has the
+  legacy_psymtab *pst; /* Partial symtab that has the
                                   BINCL/EINCL defs for this file.  */
 };
 
                                   BINCL/EINCL defs for this file.  */
 };
 
-/* The actual list and controling variables.  */
-static struct header_file_location *bincl_list, *next_bincl;
-static int bincls_allocated;
+/* The list of bincls.  */
+static std::vector<struct header_file_location> *bincl_list;
 
 /* Local function prototypes.  */
 
 
 /* Local function prototypes.  */
 
-static void read_ofile_symtab (struct objfile *, struct partial_symtab *);
+static void read_ofile_symtab (struct objfile *, legacy_psymtab *);
 
 
-static void dbx_read_symtab (struct partial_symtab *self,
+static void dbx_read_symtab (legacy_psymtab *self,
                             struct objfile *objfile);
 
                             struct objfile *objfile);
 
-static void dbx_psymtab_to_symtab_1 (struct objfile *, struct partial_symtab *);
+static void dbx_expand_psymtab (legacy_psymtab *, struct objfile *);
 
 
-static void read_dbx_symtab (minimal_symbol_reader &, struct objfile *);
+static void read_dbx_symtab (minimal_symbol_reader &, psymtab_storage *,
+                            struct objfile *);
 
 
-static void free_bincl_list (struct objfile *);
-
-static struct partial_symtab *find_corresponding_bincl_psymtab (const char *,
+static legacy_psymtab *find_corresponding_bincl_psymtab (const char *,
                                                                int);
 
                                                                int);
 
-static void add_bincl_to_list (struct partial_symtab *, const char *, int);
-
-static void init_bincl_list (int, struct objfile *);
-
 static const char *dbx_next_symbol_text (struct objfile *);
 
 static void fill_symbuf (bfd *);
 static const char *dbx_next_symbol_text (struct objfile *);
 
 static void fill_symbuf (bfd *);
@@ -290,10 +294,8 @@ static void add_old_header_file (const char *, int);
 
 static void add_this_object_header_file (int);
 
 
 static void add_this_object_header_file (int);
 
-static struct partial_symtab *start_psymtab (struct objfile *, const char *,
-                                            CORE_ADDR, int,
-                                            std::vector<partial_symbol *> &,
-                                            std::vector<partial_symbol *> &);
+static legacy_psymtab *start_psymtab (psymtab_storage *, struct objfile *,
+                                     const char *, CORE_ADDR, int);
 
 /* Free up old header file tables.  */
 
 
 /* Free up old header file tables.  */
 
@@ -456,8 +458,8 @@ record_minimal_symbol (minimal_symbol_reader &reader,
       break;
     case N_SETV:
       /* I don't think this type actually exists; since a N_SETV is the result
       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.  */
+        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;
       ms_type = mst_file_data;
       section = SECT_OFF_DATA (objfile);
       break;
@@ -473,9 +475,9 @@ record_minimal_symbol (minimal_symbol_reader &reader,
       ms_type = mst_file_data;
 
       /* Check for __DYNAMIC, which is used by Sun shared libraries. 
       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 '_'.  */
+        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 (name[8] == 'C' && strcmp ("__DYNAMIC", name) == 0)
        ms_type = mst_data;
 
       if (name[8] == 'C' && strcmp ("__DYNAMIC", name) == 0)
        ms_type = mst_data;
 
@@ -530,22 +532,19 @@ dbx_symfile_read (struct objfile *objfile, symfile_add_flags symfile_flags)
   if (val < 0)
     perror_with_name (objfile_name (objfile));
 
   if (val < 0)
     perror_with_name (objfile_name (objfile));
 
-  /* Size the symbol table.  */
-  if (objfile->global_psymbols.capacity () == 0
-      && objfile->static_psymbols.capacity () == 0)
-    init_psymbol_list (objfile, DBX_SYMCOUNT (objfile));
-
   symbol_size = DBX_SYMBOL_SIZE (objfile);
   symbol_table_offset = DBX_SYMTAB_OFFSET (objfile);
 
   symbol_size = DBX_SYMBOL_SIZE (objfile);
   symbol_table_offset = DBX_SYMTAB_OFFSET (objfile);
 
-  free_pending_blocks ();
   scoped_free_pendings free_pending;
 
   minimal_symbol_reader reader (objfile);
 
   /* Read stabs data from executable file and define symbols.  */
 
   scoped_free_pendings free_pending;
 
   minimal_symbol_reader reader (objfile);
 
   /* Read stabs data from executable file and define symbols.  */
 
-  read_dbx_symtab (reader, objfile);
+  psymbol_functions *psf = new psymbol_functions ();
+  psymtab_storage *partial_symtabs = psf->get_partial_symtabs ().get ();
+  objfile->qf.emplace_front (psf);
+  read_dbx_symtab (reader, partial_symtabs, objfile);
 
   /* Install any minimal symbols that have been collected as the current
      minimal symbols for this objfile.  */
 
   /* Install any minimal symbols that have been collected as the current
      minimal symbols for this objfile.  */
@@ -561,7 +560,6 @@ static void
 dbx_new_init (struct objfile *ignore)
 {
   stabsread_new_init ();
 dbx_new_init (struct objfile *ignore)
 {
   stabsread_new_init ();
-  buildsym_new_init ();
   init_header_files ();
 }
 
   init_header_files ();
 }
 
@@ -586,14 +584,12 @@ dbx_symfile_init (struct objfile *objfile)
 {
   int val;
   bfd *sym_bfd = objfile->obfd;
 {
   int val;
   bfd *sym_bfd = objfile->obfd;
-  char *name = bfd_get_filename (sym_bfd);
+  const char *name = bfd_get_filename (sym_bfd);
   asection *text_sect;
   unsigned char size_temp[DBX_STRINGTAB_SIZE_SIZE];
   asection *text_sect;
   unsigned char size_temp[DBX_STRINGTAB_SIZE_SIZE];
-  struct dbx_symfile_info *dbx;
 
   /* Allocate struct to keep track of the symfile.  */
 
   /* Allocate struct to keep track of the symfile.  */
-  dbx = XCNEW (struct dbx_symfile_info);
-  set_objfile_data (objfile, dbx_objfile_data_key, dbx);
+  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_TEXT_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".text");
   DBX_DATA_SECTION (objfile) = bfd_get_section_by_name (sym_bfd, ".data");
@@ -608,8 +604,8 @@ dbx_symfile_init (struct objfile *objfile)
   text_sect = bfd_get_section_by_name (sym_bfd, ".text");
   if (!text_sect)
     error (_("Can't find .text section in symbol file"));
   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 (sym_bfd, text_sect);
-  DBX_TEXT_SIZE (objfile) = bfd_section_size (sym_bfd, text_sect);
+  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_SYMBOL_SIZE (objfile) = obj_symbol_entry_size (sym_bfd);
   DBX_SYMCOUNT (objfile) = bfd_get_symcount (sym_bfd);
@@ -631,8 +627,8 @@ dbx_symfile_init (struct objfile *objfile)
   if (STRING_TABLE_OFFSET == 0)
     {
       /* It appears that with the existing bfd code, STRING_TABLE_OFFSET
   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.  */
+        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;
     }
       DBX_STRINGTAB_SIZE (objfile) = 0;
       DBX_STRINGTAB (objfile) = NULL;
     }
@@ -702,15 +698,12 @@ dbx_symfile_finish (struct objfile *objfile)
   free_header_files ();
 }
 
   free_header_files ();
 }
 
-static void
-dbx_free_symfile_info (struct objfile *objfile, void *arg)
+dbx_symfile_info::~dbx_symfile_info ()
 {
 {
-  struct dbx_symfile_info *dbx = (struct dbx_symfile_info *) arg;
-
-  if (dbx->header_files != NULL)
+  if (header_files != NULL)
     {
     {
-      int i = dbx->n_header_files;
-      struct header_file *hfiles = dbx->header_files;
+      int i = n_header_files;
+      struct header_file *hfiles = header_files;
 
       while (--i >= 0)
        {
 
       while (--i >= 0)
        {
@@ -719,8 +712,6 @@ dbx_free_symfile_info (struct objfile *objfile, void *arg)
        }
       xfree (hfiles);
     }
        }
       xfree (hfiles);
     }
-
-  xfree (dbx);
 }
 
 \f
 }
 
 \f
@@ -746,7 +737,8 @@ static char *stringtab_global;
 /* 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).  */
 /* 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).  */
-static struct stab_section_list *symbuf_sections;
+static const std::vector<asection *> *symbuf_sections;
+static size_t sect_idx;
 static unsigned int symbuf_left;
 static unsigned int symbuf_read;
 
 static unsigned int symbuf_left;
 static unsigned int symbuf_read;
 
@@ -770,7 +762,7 @@ fill_symbuf (bfd *sym_bfd)
     {
       nbytes = sizeof (symbuf);
       if (nbytes > symbuf_left)
     {
       nbytes = sizeof (symbuf);
       if (nbytes > symbuf_left)
-        nbytes = symbuf_left;
+       nbytes = symbuf_left;
       memcpy (symbuf, stabs_data + symbuf_read, nbytes);
     }
   else if (symbuf_sections == NULL)
       memcpy (symbuf, stabs_data + symbuf_read, nbytes);
     }
   else if (symbuf_sections == NULL)
@@ -782,13 +774,13 @@ fill_symbuf (bfd *sym_bfd)
     {
       if (symbuf_left <= 0)
        {
     {
       if (symbuf_left <= 0)
        {
-         file_ptr filepos = symbuf_sections->section->filepos;
+         file_ptr filepos = (*symbuf_sections)[sect_idx]->filepos;
 
          if (bfd_seek (sym_bfd, filepos, SEEK_SET) != 0)
            perror_with_name (bfd_get_filename (sym_bfd));
 
          if (bfd_seek (sym_bfd, filepos, SEEK_SET) != 0)
            perror_with_name (bfd_get_filename (sym_bfd));
-         symbuf_left = bfd_section_size (sym_bfd, symbuf_sections->section);
+         symbuf_left = bfd_section_size ((*symbuf_sections)[sect_idx]);
          symbol_table_offset = filepos - symbuf_read;
          symbol_table_offset = filepos - symbuf_read;
-         symbuf_sections = symbuf_sections->next;
+         ++sect_idx;
        }
 
       count = symbuf_left;
        }
 
       count = symbuf_left;
@@ -857,74 +849,21 @@ dbx_next_symbol_text (struct objfile *objfile)
   return nlist.n_strx + stringtab_global + file_string_table_offset;
 }
 \f
   return nlist.n_strx + stringtab_global + file_string_table_offset;
 }
 \f
-/* Initialize the list of bincls to contain none and have some
-   allocated.  */
-
-static void
-init_bincl_list (int number, struct objfile *objfile)
-{
-  bincls_allocated = number;
-  next_bincl = bincl_list = XNEWVEC (struct header_file_location,
-                                    bincls_allocated);
-}
-
-/* Add a bincl to the list.  */
-
-static void
-add_bincl_to_list (struct partial_symtab *pst, const char *name, int instance)
-{
-  if (next_bincl >= bincl_list + bincls_allocated)
-    {
-      int offset = next_bincl - bincl_list;
-
-      bincls_allocated *= 2;
-      bincl_list = (struct header_file_location *)
-       xrealloc ((char *) bincl_list,
-                 bincls_allocated * sizeof (struct header_file_location));
-      next_bincl = bincl_list + offset;
-    }
-  next_bincl->pst = pst;
-  next_bincl->instance = instance;
-  next_bincl++->name = name;
-}
 
 /* Given a name, value pair, find the corresponding
    bincl in the list.  Return the partial symtab associated
    with that header_file_location.  */
 
 
 /* Given a name, value pair, find the corresponding
    bincl in the list.  Return the partial symtab associated
    with that header_file_location.  */
 
-static struct partial_symtab *
+static legacy_psymtab *
 find_corresponding_bincl_psymtab (const char *name, int instance)
 {
 find_corresponding_bincl_psymtab (const char *name, int instance)
 {
-  struct header_file_location *bincl;
-
-  for (bincl = bincl_list; bincl < next_bincl; bincl++)
-    if (bincl->instance == instance
-       && strcmp (name, bincl->name) == 0)
-      return bincl->pst;
+  for (const header_file_location &bincl : *bincl_list)
+    if (bincl.instance == instance
+       && strcmp (name, bincl.name) == 0)
+      return bincl.pst;
 
   repeated_header_complaint (name, symnum);
 
   repeated_header_complaint (name, symnum);
-  return (struct partial_symtab *) 0;
-}
-
-/* Free the storage allocated for the bincl list.  */
-
-static void
-free_bincl_list (struct objfile *objfile)
-{
-  xfree (bincl_list);
-  bincls_allocated = 0;
-}
-
-static void
-do_free_bincl_list_cleanup (void *objfile)
-{
-  free_bincl_list ((struct objfile *) objfile);
-}
-
-static struct cleanup *
-make_cleanup_free_bincl_list (struct objfile *objfile)
-{
-  return make_cleanup (do_free_bincl_list_cleanup, objfile);
+  return (legacy_psymtab *) 0;
 }
 
 /* Set namestring based on nlist.  If the string table index is invalid, 
 }
 
 /* Set namestring based on nlist.  If the string table index is invalid, 
@@ -940,8 +879,7 @@ set_namestring (struct objfile *objfile, const struct internal_nlist *nlist)
       >= DBX_STRINGTAB_SIZE (objfile)
       || nlist->n_strx + file_string_table_offset < nlist->n_strx)
     {
       >= DBX_STRINGTAB_SIZE (objfile)
       || nlist->n_strx + file_string_table_offset < nlist->n_strx)
     {
-      complaint (&symfile_complaints,
-                _("bad string table offset in symbol %d"),
+      complaint (_("bad string table offset in symbol %d"),
                 symnum);
       namestring = "<bad string table offset>";
     } 
                 symnum);
       namestring = "<bad string table offset>";
     } 
@@ -951,9 +889,9 @@ set_namestring (struct objfile *objfile, const struct internal_nlist *nlist)
   return namestring;
 }
 
   return namestring;
 }
 
-static CORE_ADDR
-find_stab_function_addr (const char *namestring, const char *filename,
-                        struct objfile *objfile)
+static struct bound_minimal_symbol
+find_stab_function (const char *namestring, const char *filename,
+                   struct objfile *objfile)
 {
   struct bound_minimal_symbol msym;
   int n;
 {
   struct bound_minimal_symbol msym;
   int n;
@@ -972,8 +910,8 @@ find_stab_function_addr (const char *namestring, const char *filename,
   if (msym.minsym == NULL)
     {
       /* Sun Fortran appends an underscore to the minimal symbol name,
   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.  */
+        try again with an appended underscore if the minimal symbol
+        was not found.  */
       p[n] = '_';
       p[n + 1] = 0;
       msym = lookup_minimal_symbol (p, filename, objfile);
       p[n] = '_';
       p[n + 1] = 0;
       msym = lookup_minimal_symbol (p, filename, objfile);
@@ -993,14 +931,13 @@ find_stab_function_addr (const char *namestring, const char *filename,
       msym = lookup_minimal_symbol (p, NULL, objfile);
     }
 
       msym = lookup_minimal_symbol (p, NULL, objfile);
     }
 
-  return msym.minsym == NULL ? 0 : BMSYMBOL_VALUE_ADDRESS (msym);
+  return msym;
 }
 
 static void
 function_outside_compilation_unit_complaint (const char *arg1)
 {
 }
 
 static void
 function_outside_compilation_unit_complaint (const char *arg1)
 {
-  complaint (&symfile_complaints,
-            _("function `%s' appears to be defined "
+  complaint (_("function `%s' appears to be defined "
               "outside of all compilation units"),
             arg1);
 }
               "outside of all compilation units"),
             arg1);
 }
@@ -1009,9 +946,11 @@ function_outside_compilation_unit_complaint (const char *arg1)
    debugging information is available.  */
 
 static void
    debugging information is available.  */
 
 static void
-read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
+read_dbx_symtab (minimal_symbol_reader &reader,
+                psymtab_storage *partial_symtabs,
+                struct objfile *objfile)
 {
 {
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   struct external_nlist *bufp = 0;     /* =0 avoids gcc -Wall glitch.  */
   struct internal_nlist nlist;
   CORE_ADDR text_addr;
   struct external_nlist *bufp = 0;     /* =0 avoids gcc -Wall glitch.  */
   struct internal_nlist nlist;
   CORE_ADDR text_addr;
@@ -1023,13 +962,12 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
   int nsl;
   int past_first_source_file = 0;
   CORE_ADDR last_function_start = 0;
   int nsl;
   int past_first_source_file = 0;
   CORE_ADDR last_function_start = 0;
-  struct cleanup *back_to;
   bfd *abfd;
   int textlow_not_set;
   int data_sect_index;
 
   /* Current partial symtab.  */
   bfd *abfd;
   int textlow_not_set;
   int data_sect_index;
 
   /* Current partial symtab.  */
-  struct partial_symtab *pst;
+  legacy_psymtab *pst;
 
   /* List of current psymtab's include files.  */
   const char **psymtab_include_list;
 
   /* List of current psymtab's include files.  */
   const char **psymtab_include_list;
@@ -1037,7 +975,7 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
   int includes_used;
 
   /* Index within current psymtab dependency list.  */
   int includes_used;
 
   /* Index within current psymtab dependency list.  */
-  struct partial_symtab **dependency_list;
+  legacy_psymtab **dependency_list;
   int dependencies_used, dependencies_allocated;
 
   text_addr = DBX_TEXT_ADDR (objfile);
   int dependencies_used, dependencies_allocated;
 
   text_addr = DBX_TEXT_ADDR (objfile);
@@ -1050,7 +988,7 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
 
   stringtab_global = DBX_STRINGTAB (objfile);
 
 
   stringtab_global = DBX_STRINGTAB (objfile);
 
-  pst = (struct partial_symtab *) 0;
+  pst = (legacy_psymtab *) 0;
 
   includes_allocated = 30;
   includes_used = 0;
 
   includes_allocated = 30;
   includes_used = 0;
@@ -1060,12 +998,13 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
   dependencies_allocated = 30;
   dependencies_used = 0;
   dependency_list =
   dependencies_allocated = 30;
   dependencies_used = 0;
   dependency_list =
-    (struct partial_symtab **) alloca (dependencies_allocated *
-                                      sizeof (struct partial_symtab *));
+    (legacy_psymtab **) alloca (dependencies_allocated *
+                               sizeof (legacy_psymtab *));
 
   /* Init bincl list */
 
   /* Init bincl list */
-  init_bincl_list (20, objfile);
-  back_to = make_cleanup_free_bincl_list (objfile);
+  std::vector<struct header_file_location> bincl_storage;
+  scoped_restore restore_bincl_global
+    = make_scoped_restore (&bincl_list, &bincl_storage);
 
   set_last_source_file (NULL);
 
 
   set_last_source_file (NULL);
 
@@ -1106,9 +1045,7 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *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
 
   /* 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.  If it does, we will
-     get an internal error from an ANOFFSET macro below when we try to
-     use data_sect_index.  */
+     it also has no global or static variables.  */
 
   for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++)
     {
 
   for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++)
     {
@@ -1131,15 +1068,15 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
       OBJSTAT (objfile, n_stabs++);
 
       /* Ok.  There is a lot of code duplicated in the rest of this
       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:
+        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 imbedded it in the following macro.  */
+        *) 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 imbedded it in the following macro.  */
 
       switch (nlist.n_type)
        {
 
       switch (nlist.n_type)
        {
@@ -1187,21 +1124,19 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
              || (namestring[(nsl = strlen (namestring)) - 1] == 'o'
                  && namestring[nsl - 2] == '.'))
            {
              || (namestring[(nsl = strlen (namestring)) - 1] == 'o'
                  && namestring[nsl - 2] == '.'))
            {
-             nlist.n_value += ANOFFSET (objfile->section_offsets,
-                                        SECT_OFF_TEXT (objfile));
-
              if (past_first_source_file && pst
                  /* The gould NP1 uses low values for .o and -l symbols
                     which are not the address.  */
              if (past_first_source_file && pst
                  /* The gould NP1 uses low values for .o and -l symbols
                     which are not the address.  */
-                 && nlist.n_value >= pst->textlow)
+                 && nlist.n_value >= pst->raw_text_low ())
                {
                {
-                 dbx_end_psymtab (objfile, pst, psymtab_include_list,
+                 dbx_end_psymtab (objfile, partial_symtabs,
+                                  pst, psymtab_include_list,
                                   includes_used, symnum * symbol_size,
                                   includes_used, symnum * symbol_size,
-                                  nlist.n_value > pst->texthigh
-                                  ? nlist.n_value : pst->texthigh,
+                                  nlist.n_value > pst->raw_text_high ()
+                                  ? nlist.n_value : pst->raw_text_high (),
                                   dependency_list, dependencies_used,
                                   textlow_not_set);
                                   dependency_list, dependencies_used,
                                   textlow_not_set);
-                 pst = (struct partial_symtab *) 0;
+                 pst = (legacy_psymtab *) 0;
                  includes_used = 0;
                  dependencies_used = 0;
                  has_line_numbers = 0;
                  includes_used = 0;
                  dependencies_used = 0;
                  has_line_numbers = 0;
@@ -1285,8 +1220,7 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
            static const char *dirname_nso;
            int prev_textlow_not_set;
 
            static const char *dirname_nso;
            int prev_textlow_not_set;
 
-           valu = nlist.n_value + ANOFFSET (objfile->section_offsets,
-                                            SECT_OFF_TEXT (objfile));
+           valu = nlist.n_value;
 
            prev_textlow_not_set = textlow_not_set;
 
 
            prev_textlow_not_set = textlow_not_set;
 
@@ -1311,13 +1245,14 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
 
                if (pst)
                  {
 
                if (pst)
                  {
-                   dbx_end_psymtab (objfile, pst, psymtab_include_list,
+                   dbx_end_psymtab (objfile, partial_symtabs,
+                                    pst, psymtab_include_list,
                                     includes_used, symnum * symbol_size,
                                     includes_used, symnum * symbol_size,
-                                    valu > pst->texthigh
-                                    ? valu : pst->texthigh,
+                                    (valu > pst->raw_text_high ()
+                                     ? valu : pst->raw_text_high ()),
                                     dependency_list, dependencies_used,
                                     prev_textlow_not_set);
                                     dependency_list, dependencies_used,
                                     prev_textlow_not_set);
-                   pst = (struct partial_symtab *) 0;
+                   pst = (legacy_psymtab *) 0;
                    includes_used = 0;
                    dependencies_used = 0;
                    has_line_numbers = 0;
                    includes_used = 0;
                    dependencies_used = 0;
                    has_line_numbers = 0;
@@ -1344,8 +1279,8 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
              {
                /* Save the directory name SOs locally, then save it into
                   the psymtab when it's created below.  */
              {
                /* Save the directory name SOs locally, then save it into
                   the psymtab when it's created below.  */
-               dirname_nso = namestring;
-               continue;               
+               dirname_nso = namestring;
+               continue;               
              }
 
            /* Some other compilers (C++ ones in particular) emit useless
              }
 
            /* Some other compilers (C++ ones in particular) emit useless
@@ -1354,11 +1289,9 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
 
            if (!pst)
              {
 
            if (!pst)
              {
-               pst = start_psymtab (objfile,
+               pst = start_psymtab (partial_symtabs, objfile,
                                     namestring, valu,
                                     namestring, valu,
-                                    first_so_symnum * symbol_size,
-                                    objfile->global_psymbols,
-                                    objfile->static_psymbols);
+                                    first_so_symnum * symbol_size);
                pst->dirname = dirname_nso;
                dirname_nso = NULL;
              }
                pst->dirname = dirname_nso;
                dirname_nso = NULL;
              }
@@ -1389,13 +1322,12 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
              {
                /* FIXME: we should not get here without a PST to work on.
                   Attempt to recover.  */
              {
                /* FIXME: we should not get here without a PST to work on.
                   Attempt to recover.  */
-               complaint (&symfile_complaints,
-                          _("N_BINCL %s not in entries for "
+               complaint (_("N_BINCL %s not in entries for "
                             "any file, at symtab pos %d"),
                           namestring, symnum);
                continue;
              }
                             "any file, at symtab pos %d"),
                           namestring, symnum);
                continue;
              }
-           add_bincl_to_list (pst, namestring, nlist.n_value);
+           bincl_list->emplace_back (namestring, nlist.n_value, pst);
 
            /* Mark down an include file in the current psymtab.  */
 
 
            /* Mark down an include file in the current psymtab.  */
 
@@ -1489,8 +1421,8 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
                 function relative stabs, or the address of the function's
                 end for old style stabs.  */
              valu = nlist.n_value + last_function_start;
                 function relative stabs, or the address of the function's
                 end for old style stabs.  */
              valu = nlist.n_value + last_function_start;
-             if (pst->texthigh == 0 || valu > pst->texthigh)
-               pst->texthigh = valu;
+             if (pst->raw_text_high () == 0 || valu > pst->raw_text_high ())
+               pst->set_text_high (valu);
              break;
            }
 
              break;
            }
 
@@ -1498,26 +1430,26 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
          if (!p)
            continue;           /* Not a debugging symbol.   */
 
          if (!p)
            continue;           /* Not a debugging symbol.   */
 
-         sym_len = 0;
+         sym_len = 0;
          sym_name = NULL;      /* pacify "gcc -Werror" */
          sym_name = NULL;      /* pacify "gcc -Werror" */
-         if (psymtab_language == language_cplus)
-           {
+         if (psymtab_language == language_cplus)
+           {
              std::string name (namestring, p - namestring);
              std::string name (namestring, p - namestring);
-             std::string new_name = cp_canonicalize_string (name.c_str ());
-             if (!new_name.empty ())
+             gdb::unique_xmalloc_ptr<char> new_name
+               = cp_canonicalize_string (name.c_str ());
+             if (new_name != nullptr)
                {
                {
-                 sym_len = new_name.length ();
-                 sym_name = (char *) obstack_copy0 (&objfile->objfile_obstack,
-                                                    new_name.c_str (),
-                                                    sym_len);
+                 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;
-           }
+         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
 
          /* Main processing section for debugging symbols which
             the initial read through the symbol tables needs to worry
@@ -1529,27 +1461,23 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
          switch (p[1])
            {
            case 'S':
          switch (p[1])
            {
            case 'S':
-             nlist.n_value += ANOFFSET (objfile->section_offsets,
-                                        data_sect_index);
-
-             if (gdbarch_static_transform_name_p (gdbarch))
-               gdbarch_static_transform_name (gdbarch, namestring);
-
-             add_psymbol_to_list (sym_name, sym_len, 1,
-                                  VAR_DOMAIN, LOC_STATIC,
-                                  &objfile->static_psymbols,
-                                  nlist.n_value, psymtab_language, objfile);
+             pst->add_psymbol (gdb::string_view (sym_name, sym_len), true,
+                               VAR_DOMAIN, LOC_STATIC,
+                               data_sect_index,
+                               psymbol_placement::STATIC,
+                               nlist.n_value, psymtab_language,
+                               partial_symtabs, objfile);
              continue;
 
            case 'G':
              continue;
 
            case 'G':
-             nlist.n_value += ANOFFSET (objfile->section_offsets,
-                                        data_sect_index);
              /* The addresses in these entries are reported to be
                 wrong.  See the code that reads 'G's for symtabs.  */
              /* The addresses in these entries are reported to be
                 wrong.  See the code that reads 'G's for symtabs.  */
-             add_psymbol_to_list (sym_name, sym_len, 1,
-                                  VAR_DOMAIN, LOC_STATIC,
-                                  &objfile->global_psymbols,
-                                  nlist.n_value, psymtab_language, objfile);
+             pst->add_psymbol (gdb::string_view (sym_name, sym_len), true,
+                               VAR_DOMAIN, LOC_STATIC,
+                               data_sect_index,
+                               psymbol_placement::GLOBAL,
+                               nlist.n_value, psymtab_language,
+                               partial_symtabs, objfile);
              continue;
 
            case 'T':
              continue;
 
            case 'T':
@@ -1563,17 +1491,19 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
                  || (p == namestring + 1
                      && namestring[0] != ' '))
                {
                  || (p == namestring + 1
                      && namestring[0] != ' '))
                {
-                 add_psymbol_to_list (sym_name, sym_len, 1,
-                                      STRUCT_DOMAIN, LOC_TYPEDEF,
-                                      &objfile->static_psymbols,
-                                      0, psymtab_language, objfile);
+                 pst->add_psymbol (gdb::string_view (sym_name, sym_len),
+                                   true, STRUCT_DOMAIN, LOC_TYPEDEF, -1,
+                                   psymbol_placement::STATIC,
+                                   0, psymtab_language,
+                                   partial_symtabs, objfile);
                  if (p[2] == 't')
                    {
                      /* Also a typedef with the same name.  */
                  if (p[2] == 't')
                    {
                      /* Also a typedef with the same name.  */
-                     add_psymbol_to_list (sym_name, sym_len, 1,
-                                          VAR_DOMAIN, LOC_TYPEDEF,
-                                          &objfile->static_psymbols,
-                                          0, psymtab_language, objfile);
+                     pst->add_psymbol (gdb::string_view (sym_name, sym_len),
+                                       true, VAR_DOMAIN, LOC_TYPEDEF, -1,
+                                       psymbol_placement::STATIC,
+                                       0, psymtab_language,
+                                       partial_symtabs, objfile);
                      p += 1;
                    }
                }
                      p += 1;
                    }
                }
@@ -1582,10 +1512,11 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
            case 't':
              if (p != namestring)      /* a name is there, not just :T...  */
                {
            case 't':
              if (p != namestring)      /* a name is there, not just :T...  */
                {
-                 add_psymbol_to_list (sym_name, sym_len, 1,
-                                      VAR_DOMAIN, LOC_TYPEDEF,
-                                      &objfile->static_psymbols,
-                                      0, psymtab_language, objfile);
+                 pst->add_psymbol (gdb::string_view (sym_name, sym_len),
+                                   true, VAR_DOMAIN, LOC_TYPEDEF, -1,
+                                   psymbol_placement::STATIC,
+                                   0, psymtab_language,
+                                   partial_symtabs, objfile);
                }
            check_enum:
              /* If this is an enumerated type, we need to
                }
            check_enum:
              /* If this is an enumerated type, we need to
@@ -1643,10 +1574,11 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
                        ;
                      /* Note that the value doesn't matter for
                         enum constants in psymtabs, just in symtabs.  */
                        ;
                      /* Note that the value doesn't matter for
                         enum constants in psymtabs, just in symtabs.  */
-                     add_psymbol_to_list (p, q - p, 1,
-                                          VAR_DOMAIN, LOC_CONST,
-                                          &objfile->static_psymbols, 0,
-                                          psymtab_language, objfile);
+                     pst->add_psymbol (gdb::string_view (p, q - p), true,
+                                       VAR_DOMAIN, LOC_CONST, -1,
+                                       psymbol_placement::STATIC, 0,
+                                       psymtab_language,
+                                       partial_symtabs, objfile);
                      /* Point past the name.  */
                      p = q;
                      /* Skip over the value.  */
                      /* Point past the name.  */
                      p = q;
                      /* Skip over the value.  */
@@ -1661,10 +1593,11 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
 
            case 'c':
              /* Constant, e.g. from "const" in Pascal.  */
 
            case 'c':
              /* Constant, e.g. from "const" in Pascal.  */
-             add_psymbol_to_list (sym_name, sym_len, 1,
-                                  VAR_DOMAIN, LOC_CONST,
-                                  &objfile->static_psymbols, 0,
-                                  psymtab_language, objfile);
+             pst->add_psymbol (gdb::string_view (sym_name, sym_len), true,
+                               VAR_DOMAIN, LOC_CONST, -1,
+                               psymbol_placement::STATIC, 0,
+                               psymtab_language,
+                               partial_symtabs, objfile);
              continue;
 
            case 'f':
              continue;
 
            case 'f':
@@ -1678,33 +1611,24 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
                  function_outside_compilation_unit_complaint (name);
                  xfree (name);
                }
                  function_outside_compilation_unit_complaint (name);
                  xfree (name);
                }
-             nlist.n_value += ANOFFSET (objfile->section_offsets, 
-                                        SECT_OFF_TEXT (objfile));
              /* Kludges for ELF/STABS with Sun ACC.  */
              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.  */
              /* Kludges for ELF/STABS with Sun ACC.  */
              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 == ANOFFSET (objfile->section_offsets, 
-                                            SECT_OFF_TEXT (objfile))
+             if (nlist.n_value == 0
                  && gdbarch_sofun_address_maybe_missing (gdbarch))
                {
                  && gdbarch_sofun_address_maybe_missing (gdbarch))
                {
-                 CORE_ADDR minsym_valu = 
-                   find_stab_function_addr (namestring, 
-                                            pst ? pst->filename : NULL, 
-                                            objfile);
-
-                 /* find_stab_function_addr will return 0 if the minimal
-                    symbol wasn't found.  (Unfortunately, this might also
-                    be a valid address.)  Anyway, if it *does* return 0,
-                    it is likely that the value was set correctly to begin
-                    with...  */
-                 if (minsym_valu != 0)
-                   nlist.n_value = minsym_valu;
+                 struct bound_minimal_symbol minsym
+                   = find_stab_function (namestring,
+                                         pst ? pst->filename : NULL,
+                                         objfile);
+                 if (minsym.minsym != NULL)
+                   nlist.n_value = MSYMBOL_VALUE_RAW_ADDRESS (minsym.minsym);
                }
              if (pst && textlow_not_set
                  && gdbarch_sofun_address_maybe_missing (gdbarch))
                {
                }
              if (pst && textlow_not_set
                  && gdbarch_sofun_address_maybe_missing (gdbarch))
                {
-                 pst->textlow = nlist.n_value;
+                 pst->set_text_low (nlist.n_value);
                  textlow_not_set = 0;
                }
              /* End kludge.  */
                  textlow_not_set = 0;
                }
              /* End kludge.  */
@@ -1719,18 +1643,18 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
                 the partial symbol table.  */
              if (pst
                  && (textlow_not_set
                 the partial symbol table.  */
              if (pst
                  && (textlow_not_set
-                     || (nlist.n_value < pst->textlow
-                         && (nlist.n_value
-                             != ANOFFSET (objfile->section_offsets,
-                                          SECT_OFF_TEXT (objfile))))))
+                     || (nlist.n_value < pst->raw_text_low ()
+                         && (nlist.n_value != 0))))
                {
                {
-                 pst->textlow = nlist.n_value;
+                 pst->set_text_low (nlist.n_value);
                  textlow_not_set = 0;
                }
                  textlow_not_set = 0;
                }
-             add_psymbol_to_list (sym_name, sym_len, 1,
-                                  VAR_DOMAIN, LOC_BLOCK,
-                                  &objfile->static_psymbols,
-                                  nlist.n_value, psymtab_language, objfile);
+             pst->add_psymbol (gdb::string_view (sym_name, sym_len), true,
+                               VAR_DOMAIN, LOC_BLOCK,
+                               SECT_OFF_TEXT (objfile),
+                               psymbol_placement::STATIC,
+                               nlist.n_value, psymtab_language,
+                               partial_symtabs, objfile);
              continue;
 
              /* Global functions were ignored here, but now they
              continue;
 
              /* Global functions were ignored here, but now they
@@ -1747,33 +1671,24 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
                  function_outside_compilation_unit_complaint (name);
                  xfree (name);
                }
                  function_outside_compilation_unit_complaint (name);
                  xfree (name);
                }
-             nlist.n_value += ANOFFSET (objfile->section_offsets, 
-                                        SECT_OFF_TEXT (objfile));
              /* Kludges for ELF/STABS with Sun ACC.  */
              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.  */
              /* Kludges for ELF/STABS with Sun ACC.  */
              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 == ANOFFSET (objfile->section_offsets, 
-                                            SECT_OFF_TEXT (objfile))
+             if (nlist.n_value == 0
                  && gdbarch_sofun_address_maybe_missing (gdbarch))
                {
                  && gdbarch_sofun_address_maybe_missing (gdbarch))
                {
-                 CORE_ADDR minsym_valu = 
-                   find_stab_function_addr (namestring, 
-                                            pst ? pst->filename : NULL, 
-                                            objfile);
-
-                 /* find_stab_function_addr will return 0 if the minimal
-                    symbol wasn't found.  (Unfortunately, this might also
-                    be a valid address.)  Anyway, if it *does* return 0,
-                    it is likely that the value was set correctly to begin
-                    with...  */
-                 if (minsym_valu != 0)
-                   nlist.n_value = minsym_valu;
+                 struct bound_minimal_symbol minsym
+                   = find_stab_function (namestring,
+                                         pst ? pst->filename : NULL,
+                                         objfile);
+                 if (minsym.minsym != NULL)
+                   nlist.n_value = MSYMBOL_VALUE_RAW_ADDRESS (minsym.minsym);
                }
              if (pst && textlow_not_set
                  && gdbarch_sofun_address_maybe_missing (gdbarch))
                {
                }
              if (pst && textlow_not_set
                  && gdbarch_sofun_address_maybe_missing (gdbarch))
                {
-                 pst->textlow = nlist.n_value;
+                 pst->set_text_low (nlist.n_value);
                  textlow_not_set = 0;
                }
              /* End kludge.  */
                  textlow_not_set = 0;
                }
              /* End kludge.  */
@@ -1788,18 +1703,18 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
                 the partial symbol table.  */
              if (pst
                  && (textlow_not_set
                 the partial symbol table.  */
              if (pst
                  && (textlow_not_set
-                     || (nlist.n_value < pst->textlow
-                         && (nlist.n_value
-                             != ANOFFSET (objfile->section_offsets,
-                                          SECT_OFF_TEXT (objfile))))))
+                     || (nlist.n_value < pst->raw_text_low ()
+                         && (nlist.n_value != 0))))
                {
                {
-                 pst->textlow = nlist.n_value;
+                 pst->set_text_low (nlist.n_value);
                  textlow_not_set = 0;
                }
                  textlow_not_set = 0;
                }
-             add_psymbol_to_list (sym_name, sym_len, 1,
-                                  VAR_DOMAIN, LOC_BLOCK,
-                                  &objfile->global_psymbols,
-                                  nlist.n_value, psymtab_language, objfile);
+             pst->add_psymbol (gdb::string_view (sym_name, sym_len), true,
+                               VAR_DOMAIN, LOC_BLOCK,
+                               SECT_OFF_TEXT (objfile),
+                               psymbol_placement::GLOBAL,
+                               nlist.n_value, psymtab_language,
+                               partial_symtabs, objfile);
              continue;
 
              /* Two things show up here (hopefully); static symbols of
              continue;
 
              /* Two things show up here (hopefully); static symbols of
@@ -1839,8 +1754,7 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
                 time searching to the end of every string looking for
                 a backslash.  */
 
                 time searching to the end of every string looking for
                 a backslash.  */
 
-             complaint (&symfile_complaints,
-                        _("unknown symbol descriptor `%c'"),
+             complaint (_("unknown symbol descriptor `%c'"),
                         p[1]);
 
              /* Ignore it; perhaps it is an extension that we don't
                         p[1]);
 
              /* Ignore it; perhaps it is an extension that we don't
@@ -1856,7 +1770,7 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
          /* Find the corresponding bincl and mark that psymtab on the
             psymtab dependency list.  */
          {
          /* Find the corresponding bincl and mark that psymtab on the
             psymtab dependency list.  */
          {
-           struct partial_symtab *needed_pst =
+           legacy_psymtab *needed_pst =
              find_corresponding_bincl_psymtab (namestring, nlist.n_value);
 
            /* If this include file was defined earlier in this file,
              find_corresponding_bincl_psymtab (namestring, nlist.n_value);
 
            /* If this include file was defined earlier in this file,
@@ -1883,15 +1797,15 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
                dependency_list[dependencies_used++] = needed_pst;
                if (dependencies_used >= dependencies_allocated)
                  {
                dependency_list[dependencies_used++] = needed_pst;
                if (dependencies_used >= dependencies_allocated)
                  {
-                   struct partial_symtab **orig = dependency_list;
+                   legacy_psymtab **orig = dependency_list;
 
                    dependency_list =
 
                    dependency_list =
-                     (struct partial_symtab **)
+                     (legacy_psymtab **)
                      alloca ((dependencies_allocated *= 2)
                      alloca ((dependencies_allocated *= 2)
-                             * sizeof (struct partial_symtab *));
+                             * sizeof (legacy_psymtab *));
                    memcpy (dependency_list, orig,
                            (dependencies_used
                    memcpy (dependency_list, orig,
                            (dependencies_used
-                            * sizeof (struct partial_symtab *)));
+                            * sizeof (legacy_psymtab *)));
 #ifdef DEBUG_INFO
                    fprintf_unfiltered (gdb_stderr,
                                        "Had to reallocate "
 #ifdef DEBUG_INFO
                    fprintf_unfiltered (gdb_stderr,
                                        "Had to reallocate "
@@ -1906,18 +1820,18 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
          continue;
 
        case N_ENDM:
          continue;
 
        case N_ENDM:
-         /* Solaris 2 end of module, finish current partial symbol table.
-            dbx_end_psymtab will set pst->texthigh to the proper value, which
-            is necessary if a module compiled without debugging info
-            follows this module.  */
+         /* Solaris 2 end of module, finish current partial symbol
+            table.  dbx_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))
            {
          if (pst && gdbarch_sofun_address_maybe_missing (gdbarch))
            {
-             dbx_end_psymtab (objfile, pst,
+             dbx_end_psymtab (objfile, partial_symtabs, pst,
                               psymtab_include_list, includes_used,
                               symnum * symbol_size,
                               (CORE_ADDR) 0, dependency_list,
                               dependencies_used, textlow_not_set);
                               psymtab_include_list, includes_used,
                               symnum * symbol_size,
                               (CORE_ADDR) 0, dependency_list,
                               dependencies_used, textlow_not_set);
-             pst = (struct partial_symtab *) 0;
+             pst = (legacy_psymtab *) 0;
              includes_used = 0;
              dependencies_used = 0;
              has_line_numbers = 0;
              includes_used = 0;
              dependencies_used = 0;
              has_line_numbers = 0;
@@ -1970,21 +1884,21 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
   /* If there's stuff to be cleaned up, clean it up.  */
   if (pst)
     {
   /* If there's stuff to be cleaned up, clean it up.  */
   if (pst)
     {
-      /* Don't set pst->texthigh lower than it already is.  */
+      /* Don't set high text address of PST lower than it already
+        is.  */
       CORE_ADDR text_end =
        (lowest_text_address == (CORE_ADDR) -1
       CORE_ADDR text_end =
        (lowest_text_address == (CORE_ADDR) -1
-        ? (text_addr + ANOFFSET (objfile->section_offsets,
-                                 SECT_OFF_TEXT (objfile)))
+        ? text_addr
         : lowest_text_address)
        + text_size;
 
         : lowest_text_address)
        + text_size;
 
-      dbx_end_psymtab (objfile, pst, psymtab_include_list, includes_used,
+      dbx_end_psymtab (objfile, partial_symtabs,
+                      pst, psymtab_include_list, includes_used,
                       symnum * symbol_size,
                       symnum * symbol_size,
-                      text_end > pst->texthigh ? text_end : pst->texthigh,
+                      (text_end > pst->raw_text_high ()
+                       ? text_end : pst->raw_text_high ()),
                       dependency_list, dependencies_used, textlow_not_set);
     }
                       dependency_list, dependencies_used, textlow_not_set);
     }
-
-  do_cleanups (back_to);
 }
 
 /* Allocate and partially fill a partial symtab.  It will be
 }
 
 /* Allocate and partially fill a partial symtab.  It will be
@@ -1994,19 +1908,18 @@ read_dbx_symtab (minimal_symbol_reader &reader, struct objfile *objfile)
    is the address relative to which its symbols are (incremental) or 0
    (normal).  */
 
    is the address relative to which its symbols are (incremental) or 0
    (normal).  */
 
-static struct partial_symtab *
-start_psymtab (struct objfile *objfile, const char *filename, CORE_ADDR textlow,
-              int ldsymoff, std::vector<partial_symbol *> &global_psymbols,
-              std::vector<partial_symbol *> &static_psymbols)
+static legacy_psymtab *
+start_psymtab (psymtab_storage *partial_symtabs, struct objfile *objfile,
+              const char *filename, CORE_ADDR textlow, int ldsymoff)
 {
 {
-  struct partial_symtab *result =
-    start_psymtab_common (objfile, filename, textlow,
-                         global_psymbols, static_psymbols);
+  legacy_psymtab *result = new legacy_psymtab (filename, partial_symtabs,
+                                              objfile->per_bfd, textlow);
 
   result->read_symtab_private =
     XOBNEW (&objfile->objfile_obstack, struct symloc);
   LDSYMOFF (result) = ldsymoff;
 
   result->read_symtab_private =
     XOBNEW (&objfile->objfile_obstack, struct symloc);
   LDSYMOFF (result) = ldsymoff;
-  result->read_symtab = dbx_read_symtab;
+  result->legacy_read_symtab = dbx_read_symtab;
+  result->legacy_expand_psymtab = dbx_expand_psymtab;
   SYMBOL_SIZE (result) = symbol_size;
   SYMBOL_OFFSET (result) = symbol_table_offset;
   STRING_OFFSET (result) = string_table_offset;
   SYMBOL_SIZE (result) = symbol_size;
   SYMBOL_OFFSET (result) = symbol_table_offset;
   STRING_OFFSET (result) = string_table_offset;
@@ -2024,20 +1937,21 @@ start_psymtab (struct objfile *objfile, const char *filename, CORE_ADDR textlow,
 
    FIXME:  List variables and peculiarities of same.  */
 
 
    FIXME:  List variables and peculiarities of same.  */
 
-struct partial_symtab *
-dbx_end_psymtab (struct objfile *objfile, struct partial_symtab *pst,
+legacy_psymtab *
+dbx_end_psymtab (struct objfile *objfile, psymtab_storage *partial_symtabs,
+                legacy_psymtab *pst,
                 const char **include_list, int num_includes,
                 int capping_symbol_offset, CORE_ADDR capping_text,
                 const char **include_list, int num_includes,
                 int capping_symbol_offset, CORE_ADDR capping_text,
-                struct partial_symtab **dependency_list,
+                legacy_psymtab **dependency_list,
                 int number_dependencies,
                 int textlow_not_set)
 {
   int i;
                 int number_dependencies,
                 int textlow_not_set)
 {
   int i;
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
 
   if (capping_symbol_offset != -1)
     LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
 
   if (capping_symbol_offset != -1)
     LDSYMLEN (pst) = capping_symbol_offset - LDSYMOFF (pst);
-  pst->texthigh = capping_text;
+  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,
 
   /* Under Solaris, the N_SO symbols always have a value of 0,
      instead of the usual address of the .o file.  Therefore,
@@ -2054,7 +1968,7 @@ dbx_end_psymtab (struct objfile *objfile, struct partial_symtab *pst,
      a reliable texthigh by taking the address plus size of the
      last function in the file.  */
 
      a reliable texthigh by taking the address plus size of the
      last function in the file.  */
 
-  if (pst->texthigh == 0 && last_function_name
+  if (!pst->text_high_valid && last_function_name
       && gdbarch_sofun_address_maybe_missing (gdbarch))
     {
       int n;
       && gdbarch_sofun_address_maybe_missing (gdbarch))
     {
       int n;
@@ -2081,8 +1995,8 @@ dbx_end_psymtab (struct objfile *objfile, struct partial_symtab *pst,
        }
 
       if (minsym.minsym)
        }
 
       if (minsym.minsym)
-       pst->texthigh = (BMSYMBOL_VALUE_ADDRESS (minsym)
-                        + MSYMBOL_SIZE (minsym.minsym));
+       pst->set_text_high (MSYMBOL_VALUE_RAW_ADDRESS (minsym.minsym)
+                           + MSYMBOL_SIZE (minsym.minsym));
 
       last_function_name = NULL;
     }
 
       last_function_name = NULL;
     }
@@ -2091,90 +2005,68 @@ dbx_end_psymtab (struct objfile *objfile, struct partial_symtab *pst,
     ;
   /* This test will be true if the last .o file is only data.  */
   else if (textlow_not_set)
     ;
   /* This test will be true if the last .o file is only data.  */
   else if (textlow_not_set)
-    pst->textlow = pst->texthigh;
+    pst->set_text_low (pst->raw_text_high ());
   else
     {
   else
     {
-      struct partial_symtab *p1;
-
       /* If we know our own starting text address, then walk through all other
       /* 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, nor to set addresses on
-         `dependency' files that have both textlow and texthigh zero.  */
+        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.  */
 
 
-      ALL_OBJFILE_PSYMTABS (objfile, p1)
-      {
-       if (p1->texthigh == 0 && p1->textlow != 0 && p1 != pst)
-         {
-           p1->texthigh = pst->textlow;
-           /* If this file has only data, then make textlow match
-              texthigh.  */
-           if (p1->textlow == 0)
-             p1->textlow = p1->texthigh;
-         }
-      }
+      for (partial_symtab *p1 : partial_symtabs->range ())
+       if (!p1->text_high_valid && p1->text_low_valid && p1 != pst)
+         p1->set_text_high (pst->raw_text_low ());
     }
 
   /* End of kludge for patching Solaris textlow and texthigh.  */
 
     }
 
   /* End of kludge for patching Solaris textlow and texthigh.  */
 
-  end_psymtab_common (objfile, pst);
+  pst->end ();
 
   pst->number_of_dependencies = number_dependencies;
   if (number_dependencies)
     {
 
   pst->number_of_dependencies = number_dependencies;
   if (number_dependencies)
     {
-      pst->dependencies = XOBNEWVEC (&objfile->objfile_obstack,
-                                    struct partial_symtab *,
-                                    number_dependencies);
+      pst->dependencies
+       = partial_symtabs->allocate_dependencies (number_dependencies);
       memcpy (pst->dependencies, dependency_list,
       memcpy (pst->dependencies, dependency_list,
-             number_dependencies * sizeof (struct partial_symtab *));
+             number_dependencies * sizeof (legacy_psymtab *));
     }
   else
     pst->dependencies = 0;
 
   for (i = 0; i < num_includes; i++)
     {
     }
   else
     pst->dependencies = 0;
 
   for (i = 0; i < num_includes; i++)
     {
-      struct partial_symtab *subpst =
-       allocate_psymtab (include_list[i], objfile);
+      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) =
 
       subpst->read_symtab_private =
        XOBNEW (&objfile->objfile_obstack, struct symloc);
       LDSYMOFF (subpst) =
-       LDSYMLEN (subpst) =
-       subpst->textlow =
-       subpst->texthigh = 0;
+       LDSYMLEN (subpst) = 0;
 
       /* We could save slight bits of space by only making one of these,
 
       /* We could save slight bits of space by only making one of these,
-         shared by the entire set of include files.  FIXME-someday.  */
+        shared by the entire set of include files.  FIXME-someday.  */
       subpst->dependencies =
       subpst->dependencies =
-       XOBNEW (&objfile->objfile_obstack, struct partial_symtab *);
+       partial_symtabs->allocate_dependencies (1);
       subpst->dependencies[0] = pst;
       subpst->number_of_dependencies = 1;
 
       subpst->dependencies[0] = pst;
       subpst->number_of_dependencies = 1;
 
-      subpst->globals_offset =
-       subpst->n_global_syms =
-       subpst->statics_offset =
-       subpst->n_static_syms = 0;
-
-      subpst->readin = 0;
-      subpst->compunit_symtab = 0;
-      subpst->read_symtab = pst->read_symtab;
+      subpst->legacy_read_symtab = pst->legacy_read_symtab;
+      subpst->legacy_expand_psymtab = pst->legacy_expand_psymtab;
     }
 
   if (num_includes == 0
       && number_dependencies == 0
     }
 
   if (num_includes == 0
       && number_dependencies == 0
-      && pst->n_global_syms == 0
-      && pst->n_static_syms == 0
+      && pst->empty ()
       && has_line_numbers == 0)
     {
       && has_line_numbers == 0)
     {
-      /* Throw away this psymtab, it's empty.  We can't deallocate it, since
-         it is on the obstack, but we can forget to chain it on the list.  */
+      /* Throw away this psymtab, it's empty.  */
       /* Empty psymtabs happen as a result of header files which don't have
       /* 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.  */
+        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.  */
 
 
-      discard_psymtab (objfile, pst);
+      partial_symtabs->discard_psymtab (pst);
 
       /* Indicate that psymtab was thrown away.  */
       pst = NULL;
 
       /* Indicate that psymtab was thrown away.  */
       pst = NULL;
@@ -2183,41 +2075,17 @@ dbx_end_psymtab (struct objfile *objfile, struct partial_symtab *pst,
 }
 \f
 static void
 }
 \f
 static void
-dbx_psymtab_to_symtab_1 (struct objfile *objfile, struct partial_symtab *pst)
+dbx_expand_psymtab (legacy_psymtab *pst, struct objfile *objfile)
 {
 {
-  int i;
-
-  if (pst->readin)
-    {
-      fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in.  "
-                         "Shouldn't happen.\n",
-                         pst->filename);
-      return;
-    }
+  gdb_assert (!pst->readin);
 
   /* Read in all partial symtabs on which this one is dependent.  */
 
   /* Read in all partial symtabs on which this one is dependent.  */
-  for (i = 0; i < pst->number_of_dependencies; i++)
-    if (!pst->dependencies[i]->readin)
-      {
-       /* Inform about additional files that need to be read in.  */
-       if (info_verbose)
-         {
-           fputs_filtered (" ", gdb_stdout);
-           wrap_here ("");
-           fputs_filtered ("and ", gdb_stdout);
-           wrap_here ("");
-           printf_filtered ("%s...", pst->dependencies[i]->filename);
-           wrap_here ("");     /* Flush output.  */
-           gdb_flush (gdb_stdout);
-         }
-       dbx_psymtab_to_symtab_1 (objfile, pst->dependencies[i]);
-      }
+  pst->expand_dependencies (objfile);
 
   if (LDSYMLEN (pst))          /* Otherwise it's a dummy.  */
     {
       /* Init stuff necessary for reading in symbols */
       stabsread_init ();
 
   if (LDSYMLEN (pst))          /* Otherwise it's a dummy.  */
     {
       /* Init stuff necessary for reading in symbols */
       stabsread_init ();
-      buildsym_init ();
       scoped_free_pendings free_pending;
       file_string_table_offset = FILE_STRING_OFFSET (pst);
       symbol_size = SYMBOL_SIZE (pst);
       scoped_free_pendings free_pending;
       file_string_table_offset = FILE_STRING_OFFSET (pst);
       symbol_size = SYMBOL_SIZE (pst);
@@ -2227,68 +2095,46 @@ dbx_psymtab_to_symtab_1 (struct objfile *objfile, struct partial_symtab *pst)
       read_ofile_symtab (objfile, pst);
     }
 
       read_ofile_symtab (objfile, pst);
     }
 
-  pst->readin = 1;
+  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
 }
 
 /* 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
-dbx_read_symtab (struct partial_symtab *self, struct objfile *objfile)
+dbx_read_symtab (legacy_psymtab *self, struct objfile *objfile)
 {
 {
-  if (self->readin)
-    {
-      fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in.  "
-                         "Shouldn't happen.\n",
-                         self->filename);
-      return;
-    }
+  gdb_assert (!self->readin);
 
   if (LDSYMLEN (self) || self->number_of_dependencies)
     {
 
   if (LDSYMLEN (self) || self->number_of_dependencies)
     {
-      struct cleanup *back_to;
-
-      /* Print the message now, before reading the string table,
-         to avoid disconcerting pauses.  */
-      if (info_verbose)
-       {
-         printf_filtered ("Reading in symbols for %s...", self->filename);
-         gdb_flush (gdb_stdout);
-       }
-
       next_symbol_text_func = dbx_next_symbol_text;
 
       next_symbol_text_func = dbx_next_symbol_text;
 
-      back_to = make_cleanup (null_cleanup, NULL);
-
-      if (DBX_STAB_SECTION (objfile))
-       {
-         stabs_data
-           = symfile_relocate_debug_section (objfile,
-                                             DBX_STAB_SECTION (objfile),
-                                             NULL);
-
-         if (stabs_data)
-           make_cleanup (free_current_contents, (void *) &stabs_data);
-       }
-
-      dbx_psymtab_to_symtab_1 (objfile, self);
+      {
+       scoped_restore restore_stabs_data = make_scoped_restore (&stabs_data);
+       gdb::unique_xmalloc_ptr<gdb_byte> data_holder;
+       if (DBX_STAB_SECTION (objfile))
+         {
+           stabs_data
+             = symfile_relocate_debug_section (objfile,
+                                               DBX_STAB_SECTION (objfile),
+                                               NULL);
+           data_holder.reset (stabs_data);
+         }
 
 
-      do_cleanups (back_to);
+       self->expand_psymtab (objfile);
+      }
 
       /* Match with global symbols.  This only needs to be done once,
 
       /* Match with global symbols.  This only needs to be done once,
-         after all of the symtabs and dependencies have been read in.   */
+        after all of the symtabs and dependencies have been read in.   */
       scan_file_globals (objfile);
       scan_file_globals (objfile);
-
-      /* Finish up the debug error message.  */
-      if (info_verbose)
-       printf_filtered ("done.\n");
     }
 }
 
 /* Read in a defined section of a specific object file's symbols.  */
 
 static void
     }
 }
 
 /* Read in a defined section of a specific object file's symbols.  */
 
 static void
-read_ofile_symtab (struct objfile *objfile, struct partial_symtab *pst)
+read_ofile_symtab (struct objfile *objfile, legacy_psymtab *pst)
 {
   const char *namestring;
   struct external_nlist *bufp;
 {
   const char *namestring;
   struct external_nlist *bufp;
@@ -2300,13 +2146,12 @@ read_ofile_symtab (struct objfile *objfile, struct partial_symtab *pst)
   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 */
   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 section_offsets *section_offsets;
 
   sym_offset = LDSYMOFF (pst);
   sym_size = LDSYMLEN (pst);
 
   sym_offset = LDSYMOFF (pst);
   sym_size = LDSYMLEN (pst);
-  text_offset = pst->textlow;
-  text_size = pst->texthigh - pst->textlow;
-  section_offsets = objfile->section_offsets;
+  text_offset = pst->text_low (objfile);
+  text_size = pst->text_high (objfile) - pst->text_low (objfile);
+  const section_offsets &section_offsets = objfile->section_offsets;
 
   dbxread_objfile = objfile;
 
 
   dbxread_objfile = objfile;
 
@@ -2353,8 +2198,8 @@ read_ofile_symtab (struct objfile *objfile, struct partial_symtab *pst)
   else
     {
       /* The N_SO starting this symtab is the first symbol, so we
   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.  */
+        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);
       processing_gcc_compilation = 0;
     }
       stabs_seek (sym_offset);
       processing_gcc_compilation = 0;
     }
@@ -2402,7 +2247,7 @@ read_ofile_symtab (struct objfile *objfile, struct partial_symtab *pst)
                              PST_LANGUAGE (pst));
        }
       /* We skip checking for a new .o or -l file; that should never
                              PST_LANGUAGE (pst));
        }
       /* We skip checking for a new .o or -l file; that should never
-         happen in this routine.  */
+        happen in this routine.  */
       else if (type == N_TEXT)
        {
          /* I don't think this code will ever be executed, because
       else if (type == N_TEXT)
        {
          /* I don't think this code will ever be executed, because
@@ -2419,7 +2264,7 @@ read_ofile_symtab (struct objfile *objfile, struct partial_symtab *pst)
       else if (type & N_EXT || type == (unsigned char) N_TEXT
               || type == (unsigned char) N_NBTEXT)
        {
       else if (type & N_EXT || type == (unsigned char) N_TEXT
               || type == (unsigned char) N_NBTEXT)
        {
-         /* Global symbol: see if we came across a dbx defintion for
+         /* 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
             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
@@ -2432,17 +2277,17 @@ read_ofile_symtab (struct objfile *objfile, struct partial_symtab *pst)
        }
     }
 
        }
     }
 
-  /* 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 pst->textlow is correct.  */
-  if (last_source_start_addr == 0)
-    last_source_start_addr = text_offset;
+  /* 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
 
   /* In reordered executables last_source_start_addr may not be the
      lower bound for this symtab, instead use text_offset which comes
-     from pst->textlow which is correct.  */
-  if (last_source_start_addr > text_offset)
-    last_source_start_addr = text_offset;
+     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_symtab (text_offset + text_size,
                                     SECT_OFF_TEXT (objfile));
 
   pst->compunit_symtab = end_symtab (text_offset + text_size,
                                     SECT_OFF_TEXT (objfile));
@@ -2462,7 +2307,7 @@ cp_set_block_scope (const struct symbol *symbol,
                    struct block *block,
                    struct obstack *obstack)
 {
                    struct block *block,
                    struct obstack *obstack)
 {
-  if (SYMBOL_DEMANGLED_NAME (symbol) != NULL)
+  if (symbol->demangled_name () != NULL)
     {
       /* Try to figure out the appropriate namespace from the
         demangled name.  */
     {
       /* Try to figure out the appropriate namespace from the
         demangled name.  */
@@ -2472,11 +2317,10 @@ cp_set_block_scope (const struct symbol *symbol,
         name of the class as well.  This should be harmless, but
         is a little unfortunate.  */
 
         name of the class as well.  This should be harmless, but
         is a little unfortunate.  */
 
-      const char *name = SYMBOL_DEMANGLED_NAME (symbol);
+      const char *name = symbol->demangled_name ();
       unsigned int prefix_len = cp_entire_prefix_len (name);
 
       unsigned int prefix_len = cp_entire_prefix_len (name);
 
-      block_set_scope (block,
-                      (const char *) obstack_copy0 (obstack, name, prefix_len),
+      block_set_scope (block, obstack_strndup (obstack, name, prefix_len),
                       obstack);
     }
 }
                       obstack);
     }
 }
@@ -2500,11 +2344,12 @@ cp_set_block_scope (const struct symbol *symbol,
 
 void
 process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
 
 void
 process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
-                   const struct section_offsets *section_offsets,
+                   const section_offsets &section_offsets,
                    struct objfile *objfile, enum language language)
 {
                    struct objfile *objfile, enum language language)
 {
-  struct gdbarch *gdbarch = get_objfile_arch (objfile);
+  struct gdbarch *gdbarch = objfile->arch ();
   struct context_stack *newobj;
   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
   /* 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
@@ -2533,9 +2378,9 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
   if (get_last_source_file () == NULL && type != (unsigned char) N_SO)
     {
       /* Ignore any symbols which appear before an N_SO symbol.
   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 ().  */
+        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;
     }
 
       return;
     }
 
@@ -2550,11 +2395,11 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
             the current block.  */
          struct block *block;
 
             the current block.  */
          struct block *block;
 
-         if (context_stack_depth <= 0)
-           {
+         if (outermost_context_p ())
+           {
              lbrac_mismatch_complaint (symnum);
              lbrac_mismatch_complaint (symnum);
-             break;
-           }
+             break;
+           }
 
          /* The following check is added before recording line 0 at
             end of function so as to handle hand-generated stabs
 
          /* The following check is added before recording line 0 at
             end of function so as to handle hand-generated stabs
@@ -2564,21 +2409,21 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
            {
              CORE_ADDR addr = last_function_start + valu;
 
            {
              CORE_ADDR addr = last_function_start + valu;
 
-             record_line (current_subfile, 0,
+             record_line (get_current_subfile (), 0,
                           gdbarch_addr_bits_remove (gdbarch, addr));
            }
 
          within_function = 0;
                           gdbarch_addr_bits_remove (gdbarch, addr));
            }
 
          within_function = 0;
-         newobj = pop_context ();
+         cstk = pop_context ();
 
          /* Make a block for the local symbols within.  */
 
          /* Make a block for the local symbols within.  */
-         block = finish_block (newobj->name, &local_symbols,
-                               newobj->old_blocks, NULL,
-                               newobj->start_addr, newobj->start_addr + valu);
+         block = finish_block (cstk.name,
+                               cstk.old_blocks, NULL,
+                               cstk.start_addr, cstk.start_addr + valu);
 
          /* For C++, set the block's scope.  */
 
          /* For C++, set the block's scope.  */
-         if (SYMBOL_LANGUAGE (newobj->name) == language_cplus)
-           cp_set_block_scope (newobj->name, block, &objfile->objfile_obstack);
+         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.  */
 
          /* May be switching to an assembler file which may not be using
             block relative stabs, so reset the offset.  */
@@ -2590,7 +2435,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
       sline_found_in_function = 0;
 
       /* Relocate for dynamic loading.  */
       sline_found_in_function = 0;
 
       /* Relocate for dynamic loading.  */
-      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+      valu += section_offsets[SECT_OFF_TEXT (objfile)];
       valu = gdbarch_addr_bits_remove (gdbarch, valu);
       last_function_start = valu;
 
       valu = gdbarch_addr_bits_remove (gdbarch, valu);
       last_function_start = valu;
 
@@ -2598,7 +2443,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
 
     case N_LBRAC:
       /* This "symbol" just indicates the start of an inner lexical
 
     case N_LBRAC:
       /* This "symbol" just indicates the start of an inner lexical
-         context within a function.  */
+        context within a function.  */
 
       /* Ignore extra outermost context from SunPRO cc and acc.  */
       if (n_opt_found && desc == 1)
 
       /* Ignore extra outermost context from SunPRO cc and acc.  */
       if (n_opt_found && desc == 1)
@@ -2611,7 +2456,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
 
     case N_RBRAC:
       /* This "symbol" just indicates the end of an inner lexical
 
     case N_RBRAC:
       /* This "symbol" just indicates the end of an inner lexical
-         context that was started with N_LBRAC.  */
+        context that was started with N_LBRAC.  */
 
       /* Ignore extra outermost context from SunPRO cc and acc.  */
       if (n_opt_found && desc == 1)
 
       /* Ignore extra outermost context from SunPRO cc and acc.  */
       if (n_opt_found && desc == 1)
@@ -2619,29 +2464,28 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
 
       valu += function_start_offset;
 
 
       valu += function_start_offset;
 
-      if (context_stack_depth <= 0)
+      if (outermost_context_p ())
        {
          lbrac_mismatch_complaint (symnum);
          break;
        }
 
        {
          lbrac_mismatch_complaint (symnum);
          break;
        }
 
-      newobj = pop_context ();
-      if (desc != newobj->depth)
+      cstk = pop_context ();
+      if (desc != cstk.depth)
        lbrac_mismatch_complaint (symnum);
 
        lbrac_mismatch_complaint (symnum);
 
-      if (local_symbols != NULL)
+      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.  */
        {
          /* 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 (&symfile_complaints,
-                    _("misplaced N_LBRAC entry; discarding local "
+         complaint (_("misplaced N_LBRAC entry; discarding local "
                       "symbols which have no enclosing block"));
        }
                       "symbols which have no enclosing block"));
        }
-      local_symbols = newobj->locals;
+      *get_local_symbols () = cstk.locals;
 
 
-      if (context_stack_depth > 1)
+      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
        {
          /* This is not the outermost LBRAC...RBRAC pair in the
             function, its local symbols preceded it, and are the ones
@@ -2649,20 +2493,19 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
             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).  */
             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 (local_symbols != NULL)
+         if (*get_local_symbols () != NULL)
            {
              /* Muzzle a compiler bug that makes end < start.
 
                 ??? Which compilers?  Is this ever harmful?.  */
            {
              /* Muzzle a compiler bug that makes end < start.
 
                 ??? Which compilers?  Is this ever harmful?.  */
-             if (newobj->start_addr > valu)
+             if (cstk.start_addr > valu)
                {
                {
-                 complaint (&symfile_complaints,
-                            _("block start larger than block end"));
-                 newobj->start_addr = valu;
+                 complaint (_("block start larger than block end"));
+                 cstk.start_addr = valu;
                }
              /* Make a block for the local symbols within.  */
                }
              /* Make a block for the local symbols within.  */
-             finish_block (0, &local_symbols, newobj->old_blocks, NULL,
-                           newobj->start_addr, valu);
+             finish_block (0, cstk.old_blocks, NULL,
+                           cstk.start_addr, valu);
            }
        }
       else
            }
        }
       else
@@ -2679,16 +2522,16 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
     case N_FN:
     case N_FN_SEQ:
       /* This kind of symbol indicates the start of an object file.
     case N_FN:
     case N_FN_SEQ:
       /* This kind of symbol indicates the start of an object file.
-         Relocate for dynamic loading.  */
-      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+        Relocate for dynamic loading.  */
+      valu += section_offsets[SECT_OFF_TEXT (objfile)];
       break;
 
     case N_SO:
       /* This type of symbol indicates the start of data for one
       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.  */
-      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+        source file.  Finish the symbol table of the previous source
+        file (if any) and start accumulating a new symbol table.
+        Relocate for dynamic loading.  */
+      valu += section_offsets[SECT_OFF_TEXT (objfile)];
 
       n_opt_found = 0;
 
 
       n_opt_found = 0;
 
@@ -2700,7 +2543,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
             name.  Patch things up.  */
          if (previous_stab_code == (unsigned char) N_SO)
            {
             name.  Patch things up.  */
          if (previous_stab_code == (unsigned char) N_SO)
            {
-             patch_subfile_names (current_subfile, name);
+             patch_subfile_names (get_current_subfile (), name);
              break;            /* Ignore repeated SOs.  */
            }
          end_symtab (valu, SECT_OFF_TEXT (objfile));
              break;            /* Ignore repeated SOs.  */
            }
          end_symtab (valu, SECT_OFF_TEXT (objfile));
@@ -2708,7 +2551,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
        }
 
       /* Null name means this just marks the end of text for this .o
        }
 
       /* Null name means this just marks the end of text for this .o
-         file.  Don't start a new symtab in this case.  */
+        file.  Don't start a new symtab in this case.  */
       if (*name == '\000')
        break;
 
       if (*name == '\000')
        break;
 
@@ -2721,10 +2564,10 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
 
     case N_SOL:
       /* This type of symbol indicates the start of data for a
 
     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.  */
-      valu += ANOFFSET (section_offsets, SECT_OFF_TEXT (objfile));
+        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.  */
+      valu += section_offsets[SECT_OFF_TEXT (objfile)];
       start_subfile (name);
       break;
 
       start_subfile (name);
       break;
 
@@ -2744,14 +2587,14 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
 
     case N_SLINE:
       /* This type of "symbol" really just records one line-number --
 
     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.  */
+        core-address correspondence.  Enter it in the line list for
+        this symbol table.  */
 
       /* Relocate for dynamic loading and for ELF acc
 
       /* Relocate for dynamic loading and for ELF acc
-         function-relative symbols.  */
+        function-relative symbols.  */
       valu += function_start_offset;
 
       valu += function_start_offset;
 
-      /* GCC 2.95.3 emits the first N_SLINE stab somwehere in the
+      /* 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
         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
@@ -2770,12 +2613,12 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
          CORE_ADDR addr = processing_gcc_compilation == 2 ?
                           last_function_start : valu;
 
          CORE_ADDR addr = processing_gcc_compilation == 2 ?
                           last_function_start : valu;
 
-         record_line (current_subfile, desc,
+         record_line (get_current_subfile (), desc,
                       gdbarch_addr_bits_remove (gdbarch, addr));
          sline_found_in_function = 1;
        }
       else
                       gdbarch_addr_bits_remove (gdbarch, addr));
          sline_found_in_function = 1;
        }
       else
-       record_line (current_subfile, desc,
+       record_line (get_current_subfile (), desc,
                     gdbarch_addr_bits_remove (gdbarch, valu));
       break;
 
                     gdbarch_addr_bits_remove (gdbarch, valu));
       break;
 
@@ -2788,22 +2631,22 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
       break;
 
       /* The following symbol types need to have the appropriate
       break;
 
       /* The following symbol types need to have the appropriate
-         offset added to their value; then we process symbol
-         definitions in the name.  */
+        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.
 
     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).  */
+        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;
 
       {
        const char *p;
 
@@ -2824,12 +2667,12 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
                   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.  */
                   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.  */
-               valu += ANOFFSET (section_offsets, 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
                goto define_a_symbol;
              }
          }
        /* Since it's not the kludge case, re-dispatch to the right
-           handler.  */
+          handler.  */
        switch (type)
          {
          case N_STSYM:
        switch (type)
          {
          case N_STSYM:
@@ -2846,27 +2689,27 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
 
     case_N_STSYM:              /* Static symbol in data segment.  */
     case N_DSLINE:             /* Source line number, data segment.  */
 
     case_N_STSYM:              /* Static symbol in data segment.  */
     case N_DSLINE:             /* Source line number, data segment.  */
-      valu += ANOFFSET (section_offsets, 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.  */
       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.  */
-      valu += ANOFFSET (section_offsets, 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.  */
       goto define_a_symbol;
 
     case_N_ROSYM:              /* Static symbol in read-only data segment.  */
-      valu += ANOFFSET (section_offsets, 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.  */
       goto define_a_symbol;
 
     case N_ENTRY:              /* Alternate entry point.  */
       /* Relocate for dynamic loading.  */
-      valu += ANOFFSET (section_offsets, 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.
       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.  */
+        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.  */
     default:
     case N_CATCH:              /* Exception handler catcher.  */
     case N_EHDECL:             /* Exception handler name.  */
@@ -2883,9 +2726,9 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
       unknown_symtype_complaint (hex_string (type));
       /* FALLTHROUGH */
 
       unknown_symtype_complaint (hex_string (type));
       /* FALLTHROUGH */
 
-      /* The following symbol types don't need the address field
-         relocated, since it is either unused, or is absolute.  */
     define_a_symbol:
     define_a_symbol:
+      /* 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_GSYM:               /* Global variable.  */
     case N_NSYMS:              /* Number of symbols (Ultrix).  */
     case N_NOMAP:              /* No map?  (Ultrix).  */
@@ -2910,24 +2753,16 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
            case 'f':
            case 'F':
              /* Deal with the SunPRO 3.0 compiler which omits the
            case 'f':
            case 'F':
              /* Deal with the SunPRO 3.0 compiler which omits the
-                address from N_FUN symbols.  */
+                address from N_FUN symbols.  */
              if (type == N_FUN
              if (type == N_FUN
-                 && valu == ANOFFSET (section_offsets,
-                                      SECT_OFF_TEXT (objfile))
+                 && valu == section_offsets[SECT_OFF_TEXT (objfile)]
                  && gdbarch_sofun_address_maybe_missing (gdbarch))
                {
                  && gdbarch_sofun_address_maybe_missing (gdbarch))
                {
-                 CORE_ADDR minsym_valu = 
-                   find_stab_function_addr (name, get_last_source_file (),
-                                            objfile);
-
-                 /* The function find_stab_function_addr will return
-                    0 if the minimal symbol wasn't found.
-                    (Unfortunately, this might also be a valid
-                    address.)  Anyway, if it *does* return 0, it is
-                    likely that the value was set correctly to begin
-                    with...  */
-                 if (minsym_valu != 0)
-                   valu = minsym_valu;
+                 struct bound_minimal_symbol minsym
+                   = find_stab_function (name, get_last_source_file (),
+                                         objfile);
+                 if (minsym.minsym != NULL)
+                   valu = BMSYMBOL_VALUE_ADDRESS (minsym);
                }
 
              /* These addresses are absolute.  */
                }
 
              /* These addresses are absolute.  */
@@ -2935,27 +2770,26 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
 
              within_function = 1;
 
 
              within_function = 1;
 
-             if (context_stack_depth > 1)
+             if (get_context_stack_depth () > 1)
                {
                {
-                 complaint (&symfile_complaints,
-                            _("unmatched N_LBRAC before symtab pos %d"),
+                 complaint (_("unmatched N_LBRAC before symtab pos %d"),
                             symnum);
                  break;
                }
 
                             symnum);
                  break;
                }
 
-             if (context_stack_depth > 0)
+             if (!outermost_context_p ())
                {
                  struct block *block;
 
                {
                  struct block *block;
 
-                 newobj = pop_context ();
+                 cstk = pop_context ();
                  /* Make a block for the local symbols within.  */
                  /* Make a block for the local symbols within.  */
-                 block = finish_block (newobj->name, &local_symbols,
-                                       newobj->old_blocks, NULL,
-                                       newobj->start_addr, valu);
+                 block = finish_block (cstk.name,
+                                       cstk.old_blocks, NULL,
+                                       cstk.start_addr, valu);
 
                  /* For C++, set the block's scope.  */
 
                  /* For C++, set the block's scope.  */
-                 if (SYMBOL_LANGUAGE (newobj->name) == language_cplus)
-                   cp_set_block_scope (newobj->name, block,
+                 if (cstk.name->language () == language_cplus)
+                   cp_set_block_scope (cstk.name, block,
                                        &objfile->objfile_obstack);
                }
 
                                        &objfile->objfile_obstack);
                }
 
@@ -2971,8 +2805,8 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
       break;
 
       /* We use N_OPT to carry the gcc2_compiled flag.  Sun uses it
       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.  */
+        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)
        {
     case N_OPT:                        /* Solaris 2: Compiler options.  */
       if (name)
        {
@@ -3003,7 +2837,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *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
     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.  */
+        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;
     case N_ENDM:               /* Solaris 2: End of module.  */
     case N_ALIAS:              /* SunPro F77: alias name, ignore for now.  */
       break;
@@ -3018,17 +2852,17 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
   if (name[0] == '#')
     {
       /* Initialize symbol reference names and determine if this is a
   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.  */
+        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
 
       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.
+        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.  */
+        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))
       refnum = symbol_reference_defined (&s);
       if (refnum >= 0)
        if (!ref_search (refnum))
@@ -3065,14 +2899,17 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, const char *name,
 void
 coffstab_build_psymtabs (struct objfile *objfile,
                         CORE_ADDR textaddr, unsigned int textsize,
 void
 coffstab_build_psymtabs (struct objfile *objfile,
                         CORE_ADDR textaddr, unsigned int textsize,
-                        struct stab_section_list *stabsects,
+                        const std::vector<asection *> &stabsects,
                         file_ptr stabstroffset, unsigned int stabstrsize)
 {
   int val;
   bfd *sym_bfd = objfile->obfd;
                         file_ptr stabstroffset, unsigned int stabstrsize)
 {
   int val;
   bfd *sym_bfd = objfile->obfd;
-  char *name = bfd_get_filename (sym_bfd);
+  const char *name = bfd_get_filename (sym_bfd);
   unsigned int stabsize;
 
   unsigned int stabsize;
 
+  /* Allocate struct to keep track of stab reading.  */
+  dbx_objfile_data_key.emplace (objfile);
+
   DBX_TEXT_ADDR (objfile) = textaddr;
   DBX_TEXT_SIZE (objfile) = textsize;
 
   DBX_TEXT_ADDR (objfile) = textaddr;
   DBX_TEXT_SIZE (objfile) = textsize;
 
@@ -3096,7 +2933,6 @@ coffstab_build_psymtabs (struct objfile *objfile,
     perror_with_name (name);
 
   stabsread_new_init ();
     perror_with_name (name);
 
   stabsread_new_init ();
-  buildsym_new_init ();
   free_header_files ();
   init_header_files ();
 
   free_header_files ();
   init_header_files ();
 
@@ -3105,27 +2941,28 @@ coffstab_build_psymtabs (struct objfile *objfile,
   /* 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.  */
   /* 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.  */
-  if (stabsects->next == NULL)
+  scoped_restore save_symbuf_sections
+    = make_scoped_restore (&symbuf_sections);
+  if (stabsects.size () == 1)
     {
     {
-      stabsize = bfd_section_size (sym_bfd, stabsects->section);
+      stabsize = bfd_section_size (stabsects[0]);
       DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile);
       DBX_SYMCOUNT (objfile) = stabsize / DBX_SYMBOL_SIZE (objfile);
-      DBX_SYMTAB_OFFSET (objfile) = stabsects->section->filepos;
+      DBX_SYMTAB_OFFSET (objfile) = stabsects[0]->filepos;
     }
   else
     {
     }
   else
     {
-      struct stab_section_list *stabsect;
-
       DBX_SYMCOUNT (objfile) = 0;
       DBX_SYMCOUNT (objfile) = 0;
-      for (stabsect = stabsects; stabsect != NULL; stabsect = stabsect->next)
+      for (asection *section : stabsects)
        {
        {
-         stabsize = bfd_section_size (sym_bfd, stabsect->section);
+         stabsize = bfd_section_size (section);
          DBX_SYMCOUNT (objfile) += stabsize / DBX_SYMBOL_SIZE (objfile);
        }
 
          DBX_SYMCOUNT (objfile) += stabsize / DBX_SYMBOL_SIZE (objfile);
        }
 
-      DBX_SYMTAB_OFFSET (objfile) = stabsects->section->filepos;
+      DBX_SYMTAB_OFFSET (objfile) = stabsects[0]->filepos;
 
 
-      symbuf_sections = stabsects->next;
-      symbuf_left = bfd_section_size (sym_bfd, stabsects->section);
+      sect_idx = 1;
+      symbuf_sections = &stabsects;
+      symbuf_left = bfd_section_size (stabsects[0]);
       symbuf_read = 0;
     }
 
       symbuf_read = 0;
     }
 
@@ -3154,8 +2991,12 @@ elfstab_build_psymtabs (struct objfile *objfile, asection *stabsect,
 {
   int val;
   bfd *sym_bfd = objfile->obfd;
 {
   int val;
   bfd *sym_bfd = objfile->obfd;
-  char *name = bfd_get_filename (sym_bfd);
-  struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
+  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);
 
   /* Find the first and last text address.  dbx_symfile_read seems to
      want this.  */
 
   /* Find the first and last text address.  dbx_symfile_read seems to
      want this.  */
@@ -3164,7 +3005,7 @@ elfstab_build_psymtabs (struct objfile *objfile, asection *stabsect,
 #define        ELF_STABS_SYMBOL_SIZE   12      /* XXX FIXME XXX */
   DBX_SYMBOL_SIZE (objfile) = ELF_STABS_SYMBOL_SIZE;
   DBX_SYMCOUNT (objfile)
 #define        ELF_STABS_SYMBOL_SIZE   12      /* XXX FIXME XXX */
   DBX_SYMBOL_SIZE (objfile) = ELF_STABS_SYMBOL_SIZE;
   DBX_SYMCOUNT (objfile)
-    = bfd_section_size (objfile->obfd, stabsect) / DBX_SYMBOL_SIZE (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;
   DBX_STRINGTAB_SIZE (objfile) = stabstrsize;
   DBX_SYMTAB_OFFSET (objfile) = stabsect->filepos;
   DBX_STAB_SECTION (objfile) = stabsect;
@@ -3185,17 +3026,20 @@ elfstab_build_psymtabs (struct objfile *objfile, asection *stabsect,
     perror_with_name (name);
 
   stabsread_new_init ();
     perror_with_name (name);
 
   stabsread_new_init ();
-  buildsym_new_init ();
   free_header_files ();
   init_header_files ();
 
   processing_acc_compilation = 1;
 
   symbuf_read = 0;
   free_header_files ();
   init_header_files ();
 
   processing_acc_compilation = 1;
 
   symbuf_read = 0;
-  symbuf_left = bfd_section_size (objfile->obfd, stabsect);
+  symbuf_left = bfd_section_size (stabsect);
+
+  scoped_restore restore_stabs_data = make_scoped_restore (&stabs_data);
+  gdb::unique_xmalloc_ptr<gdb_byte> data_holder;
+
   stabs_data = symfile_relocate_debug_section (objfile, stabsect, NULL);
   if (stabs_data)
   stabs_data = symfile_relocate_debug_section (objfile, stabsect, NULL);
   if (stabs_data)
-    make_cleanup (free_current_contents, (void *) &stabs_data);
+    data_holder.reset (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
 
   /* 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
@@ -3204,8 +3048,6 @@ elfstab_build_psymtabs (struct objfile *objfile, asection *stabsect,
      table and normal symbol entries won't be in the ".stab" section; but in
      case it does, it will install them itself.  */
   dbx_symfile_read (objfile, 0);
      table and normal symbol entries won't be in the ".stab" section; but in
      case it does, it will install them itself.  */
   dbx_symfile_read (objfile, 0);
-
-  do_cleanups (back_to);
 }
 \f
 /* Scan and build partial symbols for a file with special sections for stabs
 }
 \f
 /* Scan and build partial symbols for a file with special sections for stabs
@@ -3230,11 +3072,10 @@ stabsect_build_psymtabs (struct objfile *objfile, char *stab_name,
 {
   int val;
   bfd *sym_bfd = objfile->obfd;
 {
   int val;
   bfd *sym_bfd = objfile->obfd;
-  char *name = bfd_get_filename (sym_bfd);
+  const char *name = bfd_get_filename (sym_bfd);
   asection *stabsect;
   asection *stabstrsect;
   asection *text_sect;
   asection *stabsect;
   asection *stabstrsect;
   asection *text_sect;
-  struct dbx_symfile_info *dbx;
 
   stabsect = bfd_get_section_by_name (sym_bfd, stab_name);
   stabstrsect = bfd_get_section_by_name (sym_bfd, stabstr_name);
 
   stabsect = bfd_get_section_by_name (sym_bfd, stab_name);
   stabstrsect = bfd_get_section_by_name (sym_bfd, stabstr_name);
@@ -3247,19 +3088,18 @@ stabsect_build_psymtabs (struct objfile *objfile, char *stab_name,
             "but not string section (%s)"),
           stab_name, stabstr_name);
 
             "but not string section (%s)"),
           stab_name, stabstr_name);
 
-  dbx = XCNEW (struct dbx_symfile_info);
-  set_objfile_data (objfile, dbx_objfile_data_key, dbx);
+  dbx_objfile_data_key.emplace (objfile);
 
   text_sect = bfd_get_section_by_name (sym_bfd, text_name);
   if (!text_sect)
     error (_("Can't find %s section in symbol file"), text_name);
 
   text_sect = bfd_get_section_by_name (sym_bfd, text_name);
   if (!text_sect)
     error (_("Can't find %s section in symbol file"), text_name);
-  DBX_TEXT_ADDR (objfile) = bfd_section_vma (sym_bfd, text_sect);
-  DBX_TEXT_SIZE (objfile) = bfd_section_size (sym_bfd, text_sect);
+  DBX_TEXT_ADDR (objfile) = bfd_section_vma (text_sect);
+  DBX_TEXT_SIZE (objfile) = bfd_section_size (text_sect);
 
   DBX_SYMBOL_SIZE (objfile) = sizeof (struct external_nlist);
 
   DBX_SYMBOL_SIZE (objfile) = sizeof (struct external_nlist);
-  DBX_SYMCOUNT (objfile) = bfd_section_size (sym_bfd, stabsect)
+  DBX_SYMCOUNT (objfile) = bfd_section_size (stabsect)
     / DBX_SYMBOL_SIZE (objfile);
     / DBX_SYMBOL_SIZE (objfile);
-  DBX_STRINGTAB_SIZE (objfile) = bfd_section_size (sym_bfd, stabstrsect);
+  DBX_STRINGTAB_SIZE (objfile) = bfd_section_size (stabstrsect);
   DBX_SYMTAB_OFFSET (objfile) = stabsect->filepos;     /* XXX - FIXME: POKING
                                                           INSIDE BFD DATA
                                                           STRUCTURES */
   DBX_SYMTAB_OFFSET (objfile) = stabsect->filepos;     /* XXX - FIXME: POKING
                                                           INSIDE BFD DATA
                                                           STRUCTURES */
@@ -3285,7 +3125,6 @@ stabsect_build_psymtabs (struct objfile *objfile, char *stab_name,
     perror_with_name (name);
 
   stabsread_new_init ();
     perror_with_name (name);
 
   stabsread_new_init ();
-  buildsym_new_init ();
   free_header_files ();
   init_header_files ();
 
   free_header_files ();
   init_header_files ();
 
@@ -3300,21 +3139,17 @@ 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_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 */
-  NULL,                                /* sym_read_psymbols */
   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 */
   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 */
-  &psym_functions
 };
 
 };
 
+void _initialize_dbxread ();
 void
 void
-_initialize_dbxread (void)
+_initialize_dbxread ()
 {
   add_symtab_fns (bfd_target_aout_flavour, &aout_sym_fns);
 {
   add_symtab_fns (bfd_target_aout_flavour, &aout_sym_fns);
-
-  dbx_objfile_data_key
-    = register_objfile_data_with_cleanup (NULL, dbx_free_symfile_info);
 }
 }