[v2,06/12] Introduce class psymtab_storage

Message ID 20181125192043.8405-7-tom@tromey.com
State New, archived
Headers

Commit Message

Tom Tromey Nov. 25, 2018, 7:20 p.m. UTC
  This introduces a new psymtab_storage class, which holds all
psymbol-related objects that are independent of the objfile.  (This
latter contraint explains why psymbol_map was not moved; though this
could still be done with some work.)

This patch does not yet change where psymtab allocation is done --
that comes later.  This just wraps everything in a single object to
make further transformations simpler.

Note that a shared_ptr is used to link from the objfile to the
psymtab_storage object.  The end goal here is to allow a given symbol
reader to simply attach to the psymtab_storage object to the BFD, then
reuse it in later invocations; shared_ptr makes this simple to reason
about.

gdb/ChangeLog
2018-11-25  Tom Tromey  <tom@tromey.com>

	* symmisc.c (print_symbol_bcache_statistics): Update.
	(print_objfile_statistics): Update.
	* symfile.c (reread_symbols): Update.
	* psymtab.h (class psymtab_storage): New.
	* psymtab.c (psymtab_storage): New constructor.
	(~psymtab_storage): New destructor.
	(require_partial_symbols): Update.
	(ALL_OBJFILE_PSYMTABS_REQUIRED): Rewrite.
	(find_pc_sect_psymtab, find_pc_sect_psymbol)
	(match_partial_symbol, lookup_partial_symbol, dump_psymtab)
	(psym_dump, recursively_search_psymtabs, psym_has_symbols)
	(psym_find_compunit_symtab_by_address, sort_pst_symbols)
	(start_psymtab_common, end_psymtab_common)
	(add_psymbol_to_bcache, add_psymbol_to_list, init_psymbol_list)
	(allocate_psymtab): Update.
	(psymtab_storage::discard_psymtab): Rename from discard_psymtab.
	Update.
	(dump_psymtab_addrmap, maintenance_print_psymbols)
	(maintenance_check_psymtabs): Update.
	* psympriv.h (discard_psymtab): Now inline.
	(psymtab_discarder::psymtab_discarder): Update.
	(psymtab_discarder::~psymtab_discarder): Update.
	(ALL_OBJFILE_PSYMTABS): Rewrite.
	* objfiles.h (struct objfile) <psymtabs, psymtabs_addrmap,
	free_psymtabs, psymbol_cache, global_psymbols, static_psymbols>:
	Remove fields.
	<partial_symtabs>: New field.
	* objfiles.c (objfile::objfile): Initialize partial_symtabs, not
	psymbol_cache.
	(objfile::~objfile): Don't destroy psymbol_cache.
	* mdebugread.c (parse_partial_symbols): Update.
	* dwarf2read.c (create_addrmap_from_index)
	(create_addrmap_from_aranges, dw2_find_pc_sect_compunit_symtab)
	(process_psymtab_comp_unit_reader, dwarf2_build_psymtabs_hard)
	(add_partial_subprogram, dwarf2_ranges_read): Update.
	* dwarf-index-write.c (write_address_map)
	(write_one_signatured_type, recursively_write_psymbols)
	(class debug_names, class debug_names, write_psymtabs_to_index):
	Update.
---
 gdb/ChangeLog           |  42 +++++++++++
 gdb/dwarf-index-write.c |  27 +++++---
 gdb/dwarf2read.c        |  30 ++++----
 gdb/mdebugread.c        |  11 +--
 gdb/objfiles.c          |   5 +-
 gdb/objfiles.h          |  29 +-------
 gdb/psympriv.h          |  17 +++--
 gdb/psymtab.c           | 150 ++++++++++++++++++++++++----------------
 gdb/psymtab.h           |  63 +++++++++++++++++
 gdb/symfile.c           |  14 ++--
 gdb/symmisc.c           |  12 ++--
 11 files changed, 265 insertions(+), 135 deletions(-)
  

Patch

diff --git a/gdb/dwarf-index-write.c b/gdb/dwarf-index-write.c
index 8a4c1c7ea4..56ef355b03 100644
--- a/gdb/dwarf-index-write.c
+++ b/gdb/dwarf-index-write.c
@@ -474,8 +474,8 @@  write_address_map (struct objfile *objfile, data_buf &addr_vec,
   addrmap_index_data.objfile = objfile;
   addrmap_index_data.previous_valid = 0;
 
-  addrmap_foreach (objfile->psymtabs_addrmap, add_address_entry_worker,
-		   &addrmap_index_data);
+  addrmap_foreach (objfile->partial_symtabs->psymtabs_addrmap,
+		   add_address_entry_worker, &addrmap_index_data);
 
   /* It's highly unlikely the last entry (end address = 0xff...ff)
      is valid, but we should still handle it.
@@ -582,13 +582,13 @@  write_one_signatured_type (void **slot, void *d)
 
   write_psymbols (info->symtab,
 		  info->psyms_seen,
-		  (info->objfile->global_psymbols.data ()
+		  (info->objfile->partial_symtabs->global_psymbols.data ()
 		   + psymtab->globals_offset),
 		  psymtab->n_global_syms, info->cu_index,
 		  0);
   write_psymbols (info->symtab,
 		  info->psyms_seen,
-		  (info->objfile->static_psymbols.data ()
+		  (info->objfile->partial_symtabs->static_psymbols.data ()
 		   + psymtab->statics_offset),
 		  psymtab->n_static_syms, info->cu_index,
 		  1);
@@ -639,12 +639,14 @@  recursively_write_psymbols (struct objfile *objfile,
 
   write_psymbols (symtab,
 		  psyms_seen,
-		  objfile->global_psymbols.data () + psymtab->globals_offset,
+		  (objfile->partial_symtabs->global_psymbols.data ()
+		   + psymtab->globals_offset),
 		  psymtab->n_global_syms, cu_index,
 		  0);
   write_psymbols (symtab,
 		  psyms_seen,
-		  objfile->static_psymbols.data () + psymtab->statics_offset,
+		  (objfile->partial_symtabs->static_psymbols.data ()
+		   + psymtab->statics_offset),
 		  psymtab->n_static_syms, cu_index,
 		  1);
 }
@@ -835,10 +837,12 @@  public:
 				    psyms_seen, cu_index);
 
     write_psymbols (psyms_seen,
-		    objfile->global_psymbols.data () + psymtab->globals_offset,
+		    (objfile->partial_symtabs->global_psymbols.data ()
+		     + psymtab->globals_offset),
 		    psymtab->n_global_syms, cu_index, false, unit_kind::cu);
     write_psymbols (psyms_seen,
-		    objfile->static_psymbols.data () + psymtab->statics_offset,
+		    (objfile->partial_symtabs->static_psymbols.data ()
+		     + psymtab->statics_offset),
 		    psymtab->n_static_syms, cu_index, true, unit_kind::cu);
   }
 
@@ -1195,12 +1199,12 @@  private:
     struct partial_symtab *psymtab = entry->per_cu.v.psymtab;
 
     write_psymbols (info->psyms_seen,
-		    (info->objfile->global_psymbols.data ()
+		    (info->objfile->partial_symtabs->global_psymbols.data ()
 		     + psymtab->globals_offset),
 		    psymtab->n_global_syms, info->cu_index, false,
 		    unit_kind::tu);
     write_psymbols (info->psyms_seen,
-		    (info->objfile->static_psymbols.data ()
+		    (info->objfile->partial_symtabs->static_psymbols.data ()
 		     + psymtab->statics_offset),
 		    psymtab->n_static_syms, info->cu_index, true,
 		    unit_kind::tu);
@@ -1554,7 +1558,8 @@  write_psymtabs_to_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
   if (VEC_length (dwarf2_section_info_def, dwarf2_per_objfile->types) > 1)
     error (_("Cannot make an index when the file has multiple .debug_types sections"));
 
-  if (!objfile->psymtabs || !objfile->psymtabs_addrmap)
+  if (!objfile->partial_symtabs->psymtabs
+      || !objfile->partial_symtabs->psymtabs_addrmap)
     return;
 
   struct stat st;
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 9fceb9e7cc..26fc47b669 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -3190,8 +3190,8 @@  create_addrmap_from_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
 			 dwarf2_per_objfile->get_cu (cu_index));
     }
 
-  objfile->psymtabs_addrmap = addrmap_create_fixed (mutable_map,
-						    &objfile->objfile_obstack);
+  objfile->partial_symtabs->psymtabs_addrmap
+    = addrmap_create_fixed (mutable_map, &objfile->objfile_obstack);
 }
 
 /* Read the address map data from DWARF-5 .debug_aranges, and use it to
@@ -3351,8 +3351,8 @@  create_addrmap_from_aranges (struct dwarf2_per_objfile *dwarf2_per_objfile,
 	}
     }
 
-  objfile->psymtabs_addrmap = addrmap_create_fixed (mutable_map,
-						    &objfile->objfile_obstack);
+  objfile->partial_symtabs->psymtabs_addrmap
+    = addrmap_create_fixed (mutable_map, &objfile->objfile_obstack);
 }
 
 /* Find a slot in the mapped index INDEX for the object named NAME.
@@ -5245,13 +5245,13 @@  dw2_find_pc_sect_compunit_symtab (struct objfile *objfile,
   struct dwarf2_per_cu_data *data;
   struct compunit_symtab *result;
 
-  if (!objfile->psymtabs_addrmap)
+  if (!objfile->partial_symtabs->psymtabs_addrmap)
     return NULL;
 
   CORE_ADDR baseaddr = ANOFFSET (objfile->section_offsets,
 				 SECT_OFF_TEXT (objfile));
-  data = (struct dwarf2_per_cu_data *) addrmap_find (objfile->psymtabs_addrmap,
-						     pc - baseaddr);
+  data = (struct dwarf2_per_cu_data *) addrmap_find
+    (objfile->partial_symtabs->psymtabs_addrmap, pc - baseaddr);
   if (!data)
     return NULL;
 
@@ -8004,7 +8004,8 @@  process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
 	   - baseaddr - 1);
       /* Store the contiguous range if it is not empty; it can be
 	 empty for CUs with no code.  */
-      addrmap_set_empty (objfile->psymtabs_addrmap, low, high, pst);
+      addrmap_set_empty (objfile->partial_symtabs->psymtabs_addrmap,
+			 low, high, pst);
     }
 
   /* Check if comp unit has_children.
@@ -8461,7 +8462,7 @@  dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile)
   auto_obstack temp_obstack;
 
   scoped_restore save_psymtabs_addrmap
-    = make_scoped_restore (&objfile->psymtabs_addrmap,
+    = make_scoped_restore (&objfile->partial_symtabs->psymtabs_addrmap,
 			   addrmap_create_mutable (&temp_obstack));
 
   for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
@@ -8482,8 +8483,9 @@  dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile)
 
   set_partial_user (dwarf2_per_objfile);
 
-  objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap,
-						    &objfile->objfile_obstack);
+  objfile->partial_symtabs->psymtabs_addrmap
+    = addrmap_create_fixed (objfile->partial_symtabs->psymtabs_addrmap,
+			    &objfile->objfile_obstack);
   /* At this point we want to keep the address map.  */
   save_psymtabs_addrmap.release ();
 
@@ -9107,7 +9109,7 @@  add_partial_subprogram (struct partial_die_info *pdi,
 		= (gdbarch_adjust_dwarf2_addr (gdbarch,
 					       pdi->highpc + baseaddr)
 		   - baseaddr);
-	      addrmap_set_empty (objfile->psymtabs_addrmap,
+	      addrmap_set_empty (objfile->partial_symtabs->psymtabs_addrmap,
 				 this_lowpc, this_highpc - 1,
 				 cu->per_cu->v.psymtab);
 	    }
@@ -14597,8 +14599,8 @@  dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
 	  highpc = (gdbarch_adjust_dwarf2_addr (gdbarch,
 						range_end + baseaddr)
 		    - baseaddr);
-	  addrmap_set_empty (objfile->psymtabs_addrmap, lowpc, highpc - 1,
-			     ranges_pst);
+	  addrmap_set_empty (objfile->partial_symtabs->psymtabs_addrmap,
+			     lowpc, highpc - 1, ranges_pst);
 	}
 
       /* FIXME: This is recording everything as a low-high
diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c
index e93f1edc08..5cc944fefe 100644
--- a/gdb/mdebugread.c
+++ b/gdb/mdebugread.c
@@ -3739,11 +3739,12 @@  parse_partial_symbols (minimal_symbol_reader &reader,
 
   /* Remove the dummy psymtab created for -O3 images above, if it is
      still empty, to enable the detection of stripped executables.  */
-  if (objfile->psymtabs->next == NULL
-      && objfile->psymtabs->number_of_dependencies == 0
-      && objfile->psymtabs->n_global_syms == 0
-      && objfile->psymtabs->n_static_syms == 0)
-    objfile->psymtabs = NULL;
+  pst = objfile->partial_symtabs->psymtabs;
+  if (pst->next == NULL
+      && pst->number_of_dependencies == 0
+      && pst->n_global_syms == 0
+      && pst->n_static_syms == 0)
+    objfile->partial_symtabs->psymtabs = NULL;
 }
 
 /* If the current psymbol has an enumerated type, we need to add
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index a9b8fa7c58..b1fa36609b 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -369,8 +369,8 @@  build_objfile_section_table (struct objfile *objfile)
 objfile::objfile (bfd *abfd, const char *name, objfile_flags flags_)
   : flags (flags_),
     pspace (current_program_space),
-    obfd (abfd),
-    psymbol_cache (psymbol_bcache_init ())
+    partial_symtabs (new psymtab_storage (this)),
+    obfd (abfd)
 {
   const char *expanded_name;
 
@@ -713,7 +713,6 @@  objfile::~objfile ()
   }
 
   /* Free the obstacks for non-reusable objfiles.  */
-  psymbol_bcache_free (psymbol_cache);
   obstack_free (&objfile_obstack, 0);
 
   /* Rebuild section map next time we need it.  */
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index 7a9087b015..a3ec3884cf 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -27,6 +27,7 @@ 
 #include "progspace.h"
 #include "registry.h"
 #include "gdb_bfd.h"
+#include "psymtab.h"
 #include <vector>
 
 struct bcache;
@@ -319,22 +320,9 @@  struct objfile
 
   struct compunit_symtab *compunit_symtabs = nullptr;
 
-  /* Each objfile points to a linked list of partial symtabs derived from
-     this file, one partial symtab structure for each compilation unit
-     (source file).  */
+  /* The partial symbol tables.  */
 
-  struct partial_symtab *psymtabs = nullptr;
-
-  /* Map addresses to the entries of PSYMTABS.  It would be more efficient to
-     have a map per the whole process but ADDRMAP cannot selectively remove
-     its items during FREE_OBJFILE.  This mapping is already present even for
-     PARTIAL_SYMTABs which still have no corresponding full SYMTABs read.  */
-
-  struct addrmap *psymtabs_addrmap = nullptr;
-
-  /* List of freed partial symtabs, available for re-use.  */
-
-  struct partial_symtab *free_psymtabs = nullptr;
+  std::shared_ptr<psymtab_storage> partial_symtabs;
 
   /* The object file's BFD.  Can be null if the objfile contains only
      minimal symbols, e.g. the run time common symbols for SunOS4.  */
@@ -356,22 +344,11 @@  struct objfile
 
   struct obstack objfile_obstack {};
 
-  /* A byte cache where we can stash arbitrary "chunks" of bytes that
-     will not change.  */
-
-  struct psymbol_bcache *psymbol_cache;
-
   /* Map symbol addresses to the partial symtab that defines the
      object at that address.  */
 
   std::vector<std::pair<CORE_ADDR, partial_symtab *>> psymbol_map;
 
-  /* Vectors of all partial symbols read in from file.  The actual data
-     is stored in the objfile_obstack.  */
-
-  std::vector<partial_symbol *> global_psymbols;
-  std::vector<partial_symbol *> static_psymbols;
-
   /* Structure which keeps track of functions that manipulate objfile's
      of the same type as this objfile.  I.e. the function to read partial
      symbols for example.  Note that this structure is in statically
diff --git a/gdb/psympriv.h b/gdb/psympriv.h
index b28c946a87..f7a5de6093 100644
--- a/gdb/psympriv.h
+++ b/gdb/psympriv.h
@@ -311,7 +311,11 @@  extern struct partial_symtab *allocate_psymtab (const char *filename,
 						struct objfile *objfile)
   ATTRIBUTE_NONNULL (1);
 
-extern void discard_psymtab (struct objfile *, struct partial_symtab *);
+static inline void
+discard_psymtab (struct objfile *objfile, struct partial_symtab *pst)
+{
+  objfile->partial_symtabs->discard_psymtab (pst);
+}
 
 /* Used when recording partial symbol tables.  On destruction,
    discards any partial symbol tables that have been built.  However,
@@ -322,15 +326,14 @@  class psymtab_discarder
 
   psymtab_discarder (struct objfile *objfile)
     : m_objfile (objfile),
-      m_psymtab (objfile->psymtabs)
+      m_psymtab (objfile->partial_symtabs->psymtabs)
   {
   }
 
   ~psymtab_discarder ()
   {
     if (m_objfile != NULL)
-      while (m_objfile->psymtabs != m_psymtab)
-	discard_psymtab (m_objfile, m_objfile->psymtabs);
+      m_objfile->partial_symtabs->discard_psymtabs_to (m_psymtab);
   }
 
   /* Keep any partial symbol tables that were built.  */
@@ -350,7 +353,9 @@  class psymtab_discarder
 
 /* Traverse all psymtabs in one objfile.  */
 
-#define	ALL_OBJFILE_PSYMTABS(objfile, p) \
-    for ((p) = (objfile) -> psymtabs; (p) != NULL; (p) = (p) -> next)
+#define	ALL_OBJFILE_PSYMTABS(objfile, p)		\
+    for ((p) = (objfile) -> partial_symtabs->psymtabs;	\
+	 (p) != NULL;					\
+	 (p) = (p) -> next)
 
 #endif /* PSYMPRIV_H */
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index ffe99004d4..c06ff0c70e 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -65,6 +65,21 @@  static struct partial_symbol *find_pc_sect_psymbol (struct objfile *,
 static struct compunit_symtab *psymtab_to_symtab (struct objfile *objfile,
 						  struct partial_symtab *pst);
 
+
+
+psymtab_storage::psymtab_storage (struct objfile *objfile)
+  : obstack (&objfile->objfile_obstack),
+    psymbol_cache (psymbol_bcache_init ())
+{
+}
+
+psymtab_storage::~psymtab_storage ()
+{
+  psymbol_bcache_free (psymbol_cache);
+}
+
+
+
 /* Ensure that the partial symbols for OBJFILE have been loaded.  This
    function always returns its argument, as a convenience.  */
 
@@ -84,8 +99,8 @@  require_partial_symbols (struct objfile *objfile, int verbose)
 
 	  /* Partial symbols list are not expected to changed after this
 	     point.  */
-	  objfile->global_psymbols.shrink_to_fit ();
-	  objfile->static_psymbols.shrink_to_fit ();
+	  objfile->partial_symtabs->global_psymbols.shrink_to_fit ();
+	  objfile->partial_symtabs->static_psymbols.shrink_to_fit ();
 
 	  if (verbose && !objfile_has_symbols (objfile))
 	    printf_filtered (_("(No debugging symbols found in %s)\n"),
@@ -99,9 +114,10 @@  require_partial_symbols (struct objfile *objfile, int verbose)
 /* Traverse all psymtabs in one objfile, requiring that the psymtabs
    be read in.  */
 
-#define ALL_OBJFILE_PSYMTABS_REQUIRED(objfile, p)		\
-    for ((p) = require_partial_symbols (objfile, 1)->psymtabs;	\
-	 (p) != NULL;						\
+#define ALL_OBJFILE_PSYMTABS_REQUIRED(objfile, p)			\
+    for ((p) = require_partial_symbols (objfile,			\
+					1)->partial_symtabs->psymtabs;	\
+	 (p) != NULL;							\
 	 (p) = (p)->next)
 
 /* We want to make sure this file always requires psymtabs.  */
@@ -302,10 +318,11 @@  find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc,
   /* Try just the PSYMTABS_ADDRMAP mapping first as it has better granularity
      than the later used TEXTLOW/TEXTHIGH one.  */
 
-  if (objfile->psymtabs_addrmap != NULL)
+  if (objfile->partial_symtabs->psymtabs_addrmap != NULL)
     {
       pst = ((struct partial_symtab *)
-	     addrmap_find (objfile->psymtabs_addrmap, pc - baseaddr));
+	     addrmap_find (objfile->partial_symtabs->psymtabs_addrmap,
+			   pc - baseaddr));
       if (pst != NULL)
 	{
 	  /* FIXME: addrmaps currently do not handle overlayed sections,
@@ -411,7 +428,9 @@  find_pc_sect_psymbol (struct objfile *objfile,
      cache a bad endaddr.  */
   for (int i = 0; i < psymtab->n_global_syms; i++)
     {
-      partial_symbol *p = objfile->global_psymbols[psymtab->globals_offset + i];
+      partial_symbol *p
+	= objfile->partial_symtabs->global_psymbols[psymtab->globals_offset
+						    + i];
 
       if (p->domain == VAR_DOMAIN
 	  && p->aclass == LOC_BLOCK
@@ -433,7 +452,9 @@  find_pc_sect_psymbol (struct objfile *objfile,
 
   for (int i = 0; i < psymtab->n_static_syms; i++)
     {
-      partial_symbol *p = objfile->static_psymbols[psymtab->statics_offset + i];
+      partial_symbol *p
+	= objfile->partial_symtabs->static_psymbols[psymtab->statics_offset
+						    + i];
 
       if (p->domain == VAR_DOMAIN
 	  && p->aclass == LOC_BLOCK
@@ -543,8 +564,8 @@  match_partial_symbol (struct objfile *objfile,
   lookup_name_info lookup_name (name, match_type);
 
   start = (global ?
-	   &objfile->global_psymbols[pst->globals_offset] :
-	   &objfile->static_psymbols[pst->statics_offset]);
+	   &objfile->partial_symtabs->global_psymbols[pst->globals_offset] :
+	   &objfile->partial_symtabs->static_psymbols[pst->statics_offset]);
 
   if (global && ordered_compare)  /* Can use a binary search.  */
     {
@@ -653,8 +674,8 @@  lookup_partial_symbol (struct objfile *objfile,
   lookup_name_info lookup_name (search_name.get (), symbol_name_match_type::FULL);
 
   start = (global ?
-	   &objfile->global_psymbols[pst->globals_offset] :
-	   &objfile->static_psymbols[pst->statics_offset]);
+	   &objfile->partial_symtabs->global_psymbols[pst->globals_offset] :
+	   &objfile->partial_symtabs->static_psymbols[pst->statics_offset]);
 
   if (global)			/* This means we can use a binary search.  */
     {
@@ -959,15 +980,17 @@  dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
     }
   if (psymtab->n_global_syms > 0)
     {
-      print_partial_symbols (gdbarch, objfile,
-			     &objfile->global_psymbols[psymtab->globals_offset],
-			     psymtab->n_global_syms, "Global", outfile);
+      print_partial_symbols
+	(gdbarch, objfile,
+	 &objfile->partial_symtabs->global_psymbols[psymtab->globals_offset],
+	 psymtab->n_global_syms, "Global", outfile);
     }
   if (psymtab->n_static_syms > 0)
     {
-      print_partial_symbols (gdbarch, objfile,
-			     &objfile->static_psymbols[psymtab->statics_offset],
-			     psymtab->n_static_syms, "Static", outfile);
+      print_partial_symbols
+	(gdbarch, objfile,
+	 &objfile->partial_symtabs->static_psymbols[psymtab->statics_offset],
+	 psymtab->n_static_syms, "Static", outfile);
     }
   fprintf_filtered (outfile, "\n");
 }
@@ -998,10 +1021,10 @@  psym_dump (struct objfile *objfile)
 {
   struct partial_symtab *psymtab;
 
-  if (objfile->psymtabs)
+  if (objfile->partial_symtabs->psymtabs)
     {
       printf_filtered ("Psymtabs:\n");
-      for (psymtab = objfile->psymtabs;
+      for (psymtab = objfile->partial_symtabs->psymtabs;
 	   psymtab != NULL;
 	   psymtab = psymtab->next)
 	{
@@ -1263,21 +1286,25 @@  recursively_search_psymtabs
     }
 
   partial_symbol **gbound
-    = objfile->global_psymbols.data () + ps->globals_offset + ps->n_global_syms;
+    = (objfile->partial_symtabs->global_psymbols.data ()
+       + ps->globals_offset + ps->n_global_syms);
   partial_symbol **sbound
-    = objfile->static_psymbols.data () + ps->statics_offset + ps->n_static_syms;
+    = (objfile->partial_symtabs->static_psymbols.data ()
+       + ps->statics_offset + ps->n_static_syms);
   partial_symbol **bound = gbound;
 
   /* Go through all of the symbols stored in a partial
      symtab in one loop.  */
-  partial_symbol **psym = objfile->global_psymbols.data () + ps->globals_offset;
+  partial_symbol **psym = (objfile->partial_symtabs->global_psymbols.data ()
+			   + ps->globals_offset);
   while (keep_going)
     {
       if (psym >= bound)
 	{
 	  if (bound == gbound && ps->n_static_syms != 0)
 	    {
-	      psym = objfile->static_psymbols.data () + ps->statics_offset;
+	      psym = (objfile->partial_symtabs->static_psymbols.data ()
+		      + ps->statics_offset);
 	      bound = sbound;
 	    }
 	  else
@@ -1383,7 +1410,7 @@  psym_expand_symtabs_matching
 static int
 psym_has_symbols (struct objfile *objfile)
 {
-  return objfile->psymtabs != NULL;
+  return objfile->partial_symtabs->psymtabs != NULL;
 }
 
 /* Helper function for psym_find_compunit_symtab_by_address that fills
@@ -1430,12 +1457,12 @@  psym_find_compunit_symtab_by_address (struct objfile *objfile,
       {
 	psym_fill_psymbol_map (objfile, pst,
 			       &seen_addrs,
-			       objfile->global_psymbols,
+			       objfile->partial_symtabs->global_psymbols,
 			       pst->globals_offset,
 			       pst->n_global_syms);
 	psym_fill_psymbol_map (objfile, pst,
 			       &seen_addrs,
-			       objfile->static_psymbols,
+			       objfile->partial_symtabs->static_psymbols,
 			       pst->statics_offset,
 			       pst->n_static_syms);
       }
@@ -1489,12 +1516,12 @@  static void
 sort_pst_symbols (struct objfile *objfile, struct partial_symtab *pst)
 {
   /* Sort the global list; don't sort the static list.  */
-  auto begin = objfile->global_psymbols.begin ();
+  auto begin = objfile->partial_symtabs->global_psymbols.begin ();
   std::advance (begin, pst->globals_offset);
 
   /* The psymbols for this partial_symtab are currently at the end of the
      vector.  */
-  auto end = objfile->global_psymbols.end ();
+  auto end = objfile->partial_symtabs->global_psymbols.end ();
 
   std::sort (begin, end, [] (partial_symbol *s1, partial_symbol *s2)
     {
@@ -1518,8 +1545,8 @@  start_psymtab_common (struct objfile *objfile,
   psymtab = allocate_psymtab (filename, objfile);
   psymtab->set_text_low (textlow);
   psymtab->set_text_high (psymtab->raw_text_low ()); /* default */
-  psymtab->globals_offset = objfile->global_psymbols.size ();
-  psymtab->statics_offset = objfile->static_psymbols.size ();
+  psymtab->globals_offset = objfile->partial_symtabs->global_psymbols.size ();
+  psymtab->statics_offset = objfile->partial_symtabs->static_psymbols.size ();
   return psymtab;
 }
 
@@ -1528,8 +1555,10 @@  start_psymtab_common (struct objfile *objfile,
 void
 end_psymtab_common (struct objfile *objfile, struct partial_symtab *pst)
 {
-  pst->n_global_syms = objfile->global_psymbols.size () - pst->globals_offset;
-  pst->n_static_syms = objfile->static_psymbols.size () - pst->statics_offset;
+  pst->n_global_syms = (objfile->partial_symtabs->global_psymbols.size ()
+			- pst->globals_offset);
+  pst->n_static_syms = (objfile->partial_symtabs->static_psymbols.size ()
+			- pst->statics_offset);
 
   sort_pst_symbols (objfile, pst);
 }
@@ -1655,7 +1684,9 @@  add_psymbol_to_bcache (const char *name, int namelength, int copy_name,
   symbol_set_names (&psymbol, name, namelength, copy_name, objfile->per_bfd);
 
   /* Stash the partial symbol away in the cache.  */
-  return psymbol_bcache_full (&psymbol, objfile->psymbol_cache, added);
+  return psymbol_bcache_full (&psymbol,
+			      objfile->partial_symtabs->psymbol_cache,
+			      added);
 }
 
 /* Helper function, adds partial symbol to the given partial symbol list.  */
@@ -1699,8 +1730,8 @@  add_psymbol_to_list (const char *name, int namelength, int copy_name,
   /* Save pointer to partial symbol in psymtab, growing symtab if needed.  */
   std::vector<partial_symbol *> *list
     = (where == psymbol_placement::STATIC
-       ? &objfile->static_psymbols
-       : &objfile->global_psymbols);
+       ? &objfile->partial_symtabs->static_psymbols
+       : &objfile->partial_symtabs->global_psymbols);
   append_psymbol_to_list (list, psym, objfile);
 }
 
@@ -1709,15 +1740,15 @@  add_psymbol_to_list (const char *name, int namelength, int copy_name,
 void
 init_psymbol_list (struct objfile *objfile, int total_symbols)
 {
-  if (objfile->global_psymbols.capacity () == 0
-      && objfile->static_psymbols.capacity () == 0)
+  if (objfile->partial_symtabs->global_psymbols.capacity () == 0
+      && objfile->partial_symtabs->static_psymbols.capacity () == 0)
     {
       /* Current best guess is that approximately a twentieth of the
 	 total symbols (in a debugging file) are global or static
 	 oriented symbols, then multiply that by slop factor of
 	 two.  */
-      objfile->global_psymbols.reserve (total_symbols / 10);
-      objfile->static_psymbols.reserve (total_symbols / 10);
+      objfile->partial_symtabs->global_psymbols.reserve (total_symbols / 10);
+      objfile->partial_symtabs->static_psymbols.reserve (total_symbols / 10);
     }
 }
 
@@ -1728,10 +1759,10 @@  allocate_psymtab (const char *filename, struct objfile *objfile)
 {
   struct partial_symtab *psymtab;
 
-  if (objfile->free_psymtabs)
+  if (objfile->partial_symtabs->free_psymtabs)
     {
-      psymtab = objfile->free_psymtabs;
-      objfile->free_psymtabs = psymtab->next;
+      psymtab = objfile->partial_symtabs->free_psymtabs;
+      objfile->partial_symtabs->free_psymtabs = psymtab->next;
     }
   else
     psymtab = XOBNEW (&objfile->objfile_obstack, partial_symtab);
@@ -1746,8 +1777,8 @@  allocate_psymtab (const char *filename, struct objfile *objfile)
      Psymtabs are searched in most recent inserted -> least recent
      inserted order.  */
 
-  psymtab->next = objfile->psymtabs;
-  objfile->psymtabs = psymtab;
+  psymtab->next = objfile->partial_symtabs->psymtabs;
+  objfile->partial_symtabs->psymtabs = psymtab;
 
   if (symtab_create_debug)
     {
@@ -1773,7 +1804,7 @@  allocate_psymtab (const char *filename, struct objfile *objfile)
 }
 
 void
-discard_psymtab (struct objfile *objfile, struct partial_symtab *pst)
+psymtab_storage::discard_psymtab (struct partial_symtab *pst)
 {
   struct partial_symtab **prev_pst;
 
@@ -1786,15 +1817,15 @@  discard_psymtab (struct objfile *objfile, struct partial_symtab *pst)
 
   /* First, snip it out of the psymtab chain.  */
 
-  prev_pst = &(objfile->psymtabs);
+  prev_pst = &psymtabs;
   while ((*prev_pst) != pst)
     prev_pst = &((*prev_pst)->next);
   (*prev_pst) = pst->next;
 
   /* Next, put it on a free list for recycling.  */
 
-  pst->next = objfile->free_psymtabs;
-  objfile->free_psymtabs = pst;
+  pst->next = free_psymtabs;
+  free_psymtabs = pst;
 }
 
 
@@ -1860,7 +1891,7 @@  dump_psymtab_addrmap (struct objfile *objfile, struct partial_symtab *psymtab,
 
   if ((psymtab == NULL
        || psymtab->psymtabs_addrmap_supported)
-      && objfile->psymtabs_addrmap != NULL)
+      && objfile->partial_symtabs->psymtabs_addrmap != NULL)
     {
       addrmap_dump_data.objfile = objfile;
       addrmap_dump_data.psymtab = psymtab;
@@ -1868,8 +1899,8 @@  dump_psymtab_addrmap (struct objfile *objfile, struct partial_symtab *psymtab,
       addrmap_dump_data.previous_matched = 0;
       fprintf_filtered (outfile, "%sddress map:\n",
 			psymtab == NULL ? "Entire a" : "  A");
-      addrmap_foreach (objfile->psymtabs_addrmap, dump_psymtab_addrmap_1,
-		       &addrmap_dump_data);
+      addrmap_foreach (objfile->partial_symtabs->psymtabs_addrmap,
+		       dump_psymtab_addrmap_1, &addrmap_dump_data);
     }
 }
 
@@ -2013,7 +2044,7 @@  maintenance_print_psymbols (const char *args, int from_tty)
 
       if (address_arg == NULL
 	  && source_arg == NULL
-	  && objfile->psymtabs_addrmap != NULL)
+	  && objfile->partial_symtabs->psymtabs_addrmap != NULL)
 	{
 	  outfile->puts ("\n");
 	  dump_psymtab_addrmap (objfile, NULL, outfile);
@@ -2089,7 +2120,8 @@  maintenance_info_psymtabs (const char *regexp, int from_tty)
 	      printf_filtered ("    globals ");
 	      if (psymtab->n_global_syms)
 		{
-		  auto p = &objfile->global_psymbols[psymtab->globals_offset];
+		  int off = psymtab->globals_offset;
+		  auto p = &objfile->partial_symtabs->global_psymbols[off];
 
 		  printf_filtered ("(* (struct partial_symbol **) %s @ %d)\n",
 				   host_address_to_string (p),
@@ -2100,7 +2132,8 @@  maintenance_info_psymtabs (const char *regexp, int from_tty)
 	      printf_filtered ("    statics ");
 	      if (psymtab->n_static_syms)
 		{
-		  auto p = &objfile->static_psymbols[psymtab->statics_offset];
+		  int off = psymtab->statics_offset;
+		  auto p = &objfile->partial_symtabs->static_psymbols[off];
 
 		  printf_filtered ("(* (struct partial_symbol **) %s @ %d)\n",
 				   host_address_to_string (p),
@@ -2179,7 +2212,8 @@  maintenance_check_psymtabs (const char *ignore, int from_tty)
       continue;
     bv = COMPUNIT_BLOCKVECTOR (cust);
     b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-    partial_symbol **psym = &objfile->static_psymbols[ps->statics_offset];
+    partial_symbol **psym
+      = &objfile->partial_symtabs->static_psymbols[ps->statics_offset];
     length = ps->n_static_syms;
     while (length--)
       {
@@ -2197,7 +2231,7 @@  maintenance_check_psymtabs (const char *ignore, int from_tty)
 	psym++;
       }
     b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-    psym = &objfile->global_psymbols[ps->globals_offset];
+    psym = &objfile->partial_symtabs->global_psymbols[ps->globals_offset];
     length = ps->n_global_syms;
     while (length--)
       {
diff --git a/gdb/psymtab.h b/gdb/psymtab.h
index 6d9f257f31..7bdb9d185f 100644
--- a/gdb/psymtab.h
+++ b/gdb/psymtab.h
@@ -22,10 +22,73 @@ 
 
 #include "symfile.h"
 
+struct partial_symbol;
+
 /* A bcache for partial symbols.  */
 
 struct psymbol_bcache;
 
+/* An instance of this class manages the partial symbol tables and
+   partial symbols for a given objfile.  */
+
+class psymtab_storage
+{
+public:
+
+  explicit psymtab_storage (struct objfile *objfile);
+
+  ~psymtab_storage ();
+
+  DISABLE_COPY_AND_ASSIGN (psymtab_storage);
+
+  /* Discard all partial symbol tables starting with "psymtabs" and
+     proceeding until "to" has been discarded.  */
+
+  void discard_psymtabs_to (struct partial_symtab *to)
+  {
+    while (psymtabs != to)
+      discard_psymtab (psymtabs);
+  }
+
+  /* Discard the partial symbol table.  */
+
+  void discard_psymtab (struct partial_symtab *pst);
+
+
+  /* Each objfile points to a linked list of partial symtabs derived from
+     this file, one partial symtab structure for each compilation unit
+     (source file).  */
+
+  struct partial_symtab *psymtabs = nullptr;
+
+  /* Map addresses to the entries of PSYMTABS.  It would be more efficient to
+     have a map per the whole process but ADDRMAP cannot selectively remove
+     its items during FREE_OBJFILE.  This mapping is already present even for
+     PARTIAL_SYMTABs which still have no corresponding full SYMTABs read.  */
+
+  struct addrmap *psymtabs_addrmap = nullptr;
+
+  /* List of freed partial symtabs, available for re-use.  */
+
+  struct partial_symtab *free_psymtabs = nullptr;
+
+  /* The obstack where allocations are made.  */
+
+  struct obstack *obstack;
+
+  /* A byte cache where we can stash arbitrary "chunks" of bytes that
+     will not change.  */
+
+  struct psymbol_bcache *psymbol_cache;
+
+  /* Vectors of all partial symbols read in from file.  The actual data
+     is stored in the objfile_obstack.  */
+
+  std::vector<partial_symbol *> global_psymbols;
+  std::vector<partial_symbol *> static_psymbols;
+};
+
+
 extern struct psymbol_bcache *psymbol_bcache_init (void);
 extern void psymbol_bcache_free (struct psymbol_bcache *);
 extern struct bcache *psymbol_bcache_get_bcache (struct psymbol_bcache *);
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 8ab6a25de7..64fbfb43db 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -2481,21 +2481,21 @@  reread_symbols (void)
 
 	  /* FIXME: Do we have to free a whole linked list, or is this
 	     enough?  */
-	  objfile->global_psymbols.clear ();
-	  objfile->static_psymbols.clear ();
+	  objfile->partial_symtabs->global_psymbols.clear ();
+	  objfile->partial_symtabs->static_psymbols.clear ();
 
 	  /* Free the obstacks for non-reusable objfiles.  */
-	  psymbol_bcache_free (objfile->psymbol_cache);
-	  objfile->psymbol_cache = psymbol_bcache_init ();
+	  psymbol_bcache_free (objfile->partial_symtabs->psymbol_cache);
+	  objfile->partial_symtabs->psymbol_cache = psymbol_bcache_init ();
 
 	  /* NB: after this call to obstack_free, objfiles_changed
 	     will need to be called (see discussion below).  */
 	  obstack_free (&objfile->objfile_obstack, 0);
 	  objfile->sections = NULL;
 	  objfile->compunit_symtabs = NULL;
-	  objfile->psymtabs = NULL;
-	  objfile->psymtabs_addrmap = NULL;
-	  objfile->free_psymtabs = NULL;
+	  objfile->partial_symtabs->psymtabs = NULL;
+	  objfile->partial_symtabs->psymtabs_addrmap = NULL;
+	  objfile->partial_symtabs->free_psymtabs = NULL;
 	  objfile->template_symbols = NULL;
 	  objfile->static_links = NULL;
 
diff --git a/gdb/symmisc.c b/gdb/symmisc.c
index d30a35481e..d5087ebe5f 100644
--- a/gdb/symmisc.c
+++ b/gdb/symmisc.c
@@ -70,8 +70,9 @@  print_symbol_bcache_statistics (void)
     QUIT;
     printf_filtered (_("Byte cache statistics for '%s':\n"),
 		     objfile_name (objfile));
-    print_bcache_statistics (psymbol_bcache_get_bcache (objfile->psymbol_cache),
-                             "partial symbol cache");
+    print_bcache_statistics
+      (psymbol_bcache_get_bcache (objfile->partial_symtabs->psymbol_cache),
+       "partial symbol cache");
     print_bcache_statistics (objfile->per_bfd->macro_cache,
 			     "preprocessor macro cache");
     print_bcache_statistics (objfile->per_bfd->filename_cache,
@@ -134,9 +135,10 @@  print_objfile_statistics (void)
     printf_filtered (_("  Total memory used for BFD obstack: %s\n"),
 		     pulongest (obstack_memory_used (&objfile->per_bfd
 						     ->storage_obstack)));
-    printf_filtered (_("  Total memory used for psymbol cache: %d\n"),
-		     bcache_memory_used (psymbol_bcache_get_bcache
-		                          (objfile->psymbol_cache)));
+    printf_filtered
+      (_("  Total memory used for psymbol cache: %d\n"),
+       bcache_memory_used (psymbol_bcache_get_bcache
+			   (objfile->partial_symtabs->psymbol_cache)));
     printf_filtered (_("  Total memory used for macro cache: %d\n"),
 		     bcache_memory_used (objfile->per_bfd->macro_cache));
     printf_filtered (_("  Total memory used for file name cache: %d\n"),