This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA 1 of 2] dwarf type unit scaling fix preparatory work


Hi.

I'm still finishing up patch 2 of 2, but while I'm doing that I'm hoping
people can start thinking about this patch.
It redoes the storage for global_psymbols and static_psymbols.
Currently they're each one big vector containing every psymtab for the entire
objfile, and it's hard to add to a psymtab after it's created.
This patch moves the storage of these objects to the psymtab itself.

IMO the patch is a clean up in and of itself, it could go in absent anything
that depends on it.

I've tested it with amd64-linux, --enable-targets=all,
and with -gstabs on amd64-linux,
but I haven't regression tested it with other affected file formats.
Can anyone do regression testing of mdebugread.c or xcoffread.c?


2012-06-03  Doug Evans  <dje@google.com>

	* dbxread.c (start_psymtab): Delete args global_syms, static_syms.
	All callers updated.
	* mdebugread.c (handle_psymbol_enumerators): Replace "objfile" arg
	with "pst".  All callers updated.
	* objfiles.c (free_objfile): Replace free'ing of global_psymbols.list
	and static_psymbols.list with call to free_objfile_psymtabs.
	* objfiles.h (struct objfile): Delete members global_psymbols,
	static_psymbols.  All uses updated to refer to corresponding members
	of struct partial_symtab.
	* psympriv.h (struct partial_symtab): New members global_psymbols,
	static_psymbols.  Delete members globals_offset, n_global_syms,
	statics_offset, n_static_syms.
	(N_GLOBAL_PSYMS, N_STATIC_PSYMS): Macro accessors to replace
	partial_symtab n_global_syms, n_static_syms.  All uses updated.
	(ALL_GLOBAL_PSYMBOLS, ALL_STATIC_PSYMBOLS): New macros.
	(add_psymbol_to_list): Update prototype.
	(init_psymbol_list): Delete.
	(start_psymtab_common): Update prototype.
	* psymtab.c (find_pc_sect_psymbol): Use ALL_GLOBAL_PSYMBOLS,
	ALL_STATIC_PSYMBOLS.
	(relocate_psymtabs): Rewrite loop to update psymtabs.
	(start_psymtab_common): Delete args global_syms, static_syms.
	All callers updated.
	(extend_psymbol_list): Delete arg objfile.  All callers updated.
	(add_psymbol_to_list): New arg psymtab, global.  Delete args list,
	objfile.  All callers updated.
	(init_psymbol_list): Delete.  All calls removed.
	(free_psymtab_resources, free_objfile_psymtabs): New functions.
	(discard_psymtab): Call free_psymtab_resources.
	* psymtab.h (free_objfile_psymtabs): Declare.
	* symfile.c (reread_symbols): Replace free'ing of global_psymbols.list
	and static_psymbols.list with call to free_objfile_psymtabs.
	* xcoffread.c (xcoff_start_psymtab): Delete args global_syms,
	static_syms.  All callers updated.

diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index 2d47407..ee6832b 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -294,9 +294,7 @@ static void add_old_header_file (char *, int);
 static void add_this_object_header_file (int);
 
 static struct partial_symtab *start_psymtab (struct objfile *, char *,
-					     CORE_ADDR, int,
-					     struct partial_symbol **,
-					     struct partial_symbol **);
+					     CORE_ADDR, int);
 
 /* Free up old header file tables.  */
 
@@ -559,10 +557,6 @@ dbx_symfile_read (struct objfile *objfile, int symfile_flags)
   if (val < 0)
     perror_with_name (objfile->name);
 
-  /* Size the symbol table.  */
-  if (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0)
-    init_psymbol_list (objfile, DBX_SYMCOUNT (objfile));
-
   symbol_size = DBX_SYMBOL_SIZE (objfile);
   symbol_table_offset = DBX_SYMTAB_OFFSET (objfile);
 
@@ -1542,9 +1536,7 @@ read_dbx_symtab (struct objfile *objfile)
 	      {
 		pst = start_psymtab (objfile,
 				     namestring, valu,
-				     first_so_symnum * symbol_size,
-				     objfile->global_psymbols.next,
-				     objfile->static_psymbols.next);
+				     first_so_symnum * symbol_size);
 		pst->dirname = dirname_nso;
 		dirname_nso = NULL;
 	      }
@@ -1725,11 +1717,11 @@ read_dbx_symtab (struct objfile *objfile)
 	      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,
-				   0, nlist.n_value,
-				   psymtab_language, objfile);
+	      if (pst)
+		add_psymbol_to_list (pst, sym_name, sym_len, 1,
+				     VAR_DOMAIN, LOC_STATIC,
+				     0, nlist.n_value,
+				     psymtab_language, 0);
 	      continue;
 
 	    case 'G':
@@ -1737,11 +1729,11 @@ read_dbx_symtab (struct objfile *objfile)
 					 data_sect_index);
 	      /* 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,
-				   0, nlist.n_value,
-				   psymtab_language, objfile);
+	      if (pst)
+		add_psymbol_to_list (pst, sym_name, sym_len, 1,
+				     VAR_DOMAIN, LOC_STATIC,
+				     0, nlist.n_value,
+				     psymtab_language, 1);
 	      continue;
 
 	    case 'T':
@@ -1755,19 +1747,19 @@ read_dbx_symtab (struct objfile *objfile)
 		  || (p == namestring + 1
 		      && namestring[0] != ' '))
 		{
-		  add_psymbol_to_list (sym_name, sym_len, 1,
-				       STRUCT_DOMAIN, LOC_TYPEDEF,
-				       &objfile->static_psymbols,
-				       nlist.n_value, 0,
-				       psymtab_language, objfile);
+		  if (pst)
+		    add_psymbol_to_list (pst, sym_name, sym_len, 1,
+					 STRUCT_DOMAIN, LOC_TYPEDEF,
+					 nlist.n_value, 0,
+					 psymtab_language, 0);
 		  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,
-					   nlist.n_value, 0,
-					   psymtab_language, objfile);
+		      if (pst)
+			add_psymbol_to_list (pst, sym_name, sym_len, 1,
+					     VAR_DOMAIN, LOC_TYPEDEF,
+					     nlist.n_value, 0,
+					     psymtab_language, 0);
 		      p += 1;
 		    }
 		}
@@ -1776,11 +1768,11 @@ read_dbx_symtab (struct objfile *objfile)
 	    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,
-				       nlist.n_value, 0,
-				       psymtab_language, objfile);
+		  if (pst)
+		    add_psymbol_to_list (pst, sym_name, sym_len, 1,
+					 VAR_DOMAIN, LOC_TYPEDEF,
+					 nlist.n_value, 0,
+					 psymtab_language, 0);
 		}
 	    check_enum:
 	      /* If this is an enumerated type, we need to
@@ -1838,10 +1830,10 @@ read_dbx_symtab (struct objfile *objfile)
 			;
 		      /* 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,
-					   0, psymtab_language, objfile);
+		      if (pst)
+			add_psymbol_to_list (pst, p, q - p, 1,
+					     VAR_DOMAIN, LOC_CONST,
+					     0, 0, psymtab_language, 0);
 		      /* Point past the name.  */
 		      p = q;
 		      /* Skip over the value.  */
@@ -1856,10 +1848,10 @@ read_dbx_symtab (struct objfile *objfile)
 
 	    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, nlist.n_value,
-				   0, psymtab_language, objfile);
+	      if (pst)
+		add_psymbol_to_list (pst, sym_name, sym_len, 1,
+				     VAR_DOMAIN, LOC_CONST,
+				     nlist.n_value, 0, psymtab_language, 0);
 	      continue;
 
 	    case 'f':
@@ -1922,11 +1914,11 @@ read_dbx_symtab (struct objfile *objfile)
 		  pst->textlow = nlist.n_value;
 		  textlow_not_set = 0;
 		}
-	      add_psymbol_to_list (sym_name, sym_len, 1,
-				   VAR_DOMAIN, LOC_BLOCK,
-				   &objfile->static_psymbols,
-				   0, nlist.n_value,
-				   psymtab_language, objfile);
+	      if (pst)
+		add_psymbol_to_list (pst, sym_name, sym_len, 1,
+				     VAR_DOMAIN, LOC_BLOCK,
+				     0, nlist.n_value,
+				     psymtab_language, 0);
 	      continue;
 
 	      /* Global functions were ignored here, but now they
@@ -1992,11 +1984,10 @@ read_dbx_symtab (struct objfile *objfile)
 		  pst->textlow = nlist.n_value;
 		  textlow_not_set = 0;
 		}
-	      add_psymbol_to_list (sym_name, sym_len, 1,
-				   VAR_DOMAIN, LOC_BLOCK,
-				   &objfile->global_psymbols,
-				   0, nlist.n_value,
-				   psymtab_language, objfile);
+	      if (pst)
+		add_psymbol_to_list (pst, sym_name, sym_len, 1,
+				     VAR_DOMAIN, LOC_BLOCK,
+				     0, nlist.n_value, psymtab_language, 1);
 	      continue;
 
 	      /* Two things show up here (hopefully); static symbols of
@@ -2190,12 +2181,11 @@ read_dbx_symtab (struct objfile *objfile)
 
 static struct partial_symtab *
 start_psymtab (struct objfile *objfile, char *filename, CORE_ADDR textlow,
-	       int ldsymoff, struct partial_symbol **global_syms,
-	       struct partial_symbol **static_syms)
+	       int ldsymoff)
 {
   struct partial_symtab *result =
     start_psymtab_common (objfile, objfile->section_offsets,
-			  filename, textlow, global_syms, static_syms);
+			  filename, textlow);
 
   result->read_symtab_private = obstack_alloc (&objfile->objfile_obstack,
 					       sizeof (struct symloc));
@@ -2317,13 +2307,6 @@ end_psymtab (struct partial_symtab *pst,
 
   /* End of kludge for patching Solaris textlow and texthigh.  */
 
-  pst->n_global_syms =
-    objfile->global_psymbols.next - (objfile->global_psymbols.list
-				     + pst->globals_offset);
-  pst->n_static_syms =
-    objfile->static_psymbols.next - (objfile->static_psymbols.list
-				     + pst->statics_offset);
-
   pst->number_of_dependencies = number_dependencies;
   if (number_dependencies)
     {
@@ -2358,11 +2341,6 @@ end_psymtab (struct partial_symtab *pst,
       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->symtab = 0;
       subpst->read_symtab = pst->read_symtab;
@@ -2372,8 +2350,8 @@ end_psymtab (struct partial_symtab *pst,
 
   if (num_includes == 0
       && number_dependencies == 0
-      && pst->n_global_syms == 0
-      && pst->n_static_syms == 0
+      && N_GLOBAL_PSYMS (pst) == 0
+      && N_STATIC_PSYMS (pst) == 0
       && has_line_numbers == 0)
     {
       /* Throw away this psymtab, it's empty.  We can't deallocate it, since
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 8dbc53e..71d2a47 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -3191,11 +3191,6 @@ dwarf2_initialize_objfile (struct objfile *objfile)
 void
 dwarf2_build_psymtabs (struct objfile *objfile)
 {
-  if (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0)
-    {
-      init_psymbol_list (objfile, 1024);
-    }
-
   dwarf2_build_psymtabs_hard (objfile);
 }
 
@@ -3359,10 +3354,6 @@ dwarf2_create_include_psymtab (char *name, struct partial_symtab *pst,
   subpst->dependencies[0] = pst;
   subpst->number_of_dependencies = 1;
 
-  subpst->globals_offset = 0;
-  subpst->n_global_syms = 0;
-  subpst->statics_offset = 0;
-  subpst->n_static_syms = 0;
   subpst->symtab = NULL;
   subpst->read_symtab = pst->read_symtab;
   subpst->readin = 0;
@@ -4102,9 +4093,7 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
   pst = start_psymtab_common (objfile, objfile->section_offsets,
 			      filename,
 			      /* TEXTLOW and TEXTHIGH are set below.  */
-			      0,
-			      objfile->global_psymbols.next,
-			      objfile->static_psymbols.next);
+			      0);
   pst->psymtabs_addrmap_supported = 1;
 
   attr = dwarf2_attr (comp_unit_die, DW_AT_comp_dir, cu);
@@ -4165,10 +4154,6 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
   pst->textlow = best_lowpc + baseaddr;
   pst->texthigh = best_highpc + baseaddr;
 
-  pst->n_global_syms = objfile->global_psymbols.next -
-    (objfile->global_psymbols.list + pst->globals_offset);
-  pst->n_static_syms = objfile->static_psymbols.next -
-    (objfile->static_psymbols.list + pst->statics_offset);
   sort_pst_symbols (pst);
 
   if (!VEC_empty (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs))
@@ -4672,6 +4657,7 @@ static void
 add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 {
   struct objfile *objfile = cu->objfile;
+  struct partial_symtab *pst = cu->per_cu->v.psymtab;
   CORE_ADDR addr = 0;
   char *actual_name = NULL;
   CORE_ADDR baseaddr;
@@ -4697,36 +4683,30 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
              in the global scope.  */
 	  /* prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
 	     mst_text, objfile); */
-	  add_psymbol_to_list (actual_name, strlen (actual_name),
+	  add_psymbol_to_list (pst, actual_name, strlen (actual_name),
 			       built_actual_name,
 			       VAR_DOMAIN, LOC_BLOCK,
-			       &objfile->global_psymbols,
 			       0, pdi->lowpc + baseaddr,
-			       cu->language, objfile);
+			       cu->language, 1);
 	}
       else
 	{
 	  /* prim_record_minimal_symbol (actual_name, pdi->lowpc + baseaddr,
 	     mst_file_text, objfile); */
-	  add_psymbol_to_list (actual_name, strlen (actual_name),
+	  add_psymbol_to_list (pst, actual_name, strlen (actual_name),
 			       built_actual_name,
 			       VAR_DOMAIN, LOC_BLOCK,
-			       &objfile->static_psymbols,
 			       0, pdi->lowpc + baseaddr,
-			       cu->language, objfile);
+			       cu->language, 0);
 	}
       break;
     case DW_TAG_constant:
       {
-        struct psymbol_allocation_list *list;
+        int global = pdi->is_external;
 
-	if (pdi->is_external)
-	  list = &objfile->global_psymbols;
-	else
-	  list = &objfile->static_psymbols;
-	add_psymbol_to_list (actual_name, strlen (actual_name),
+	add_psymbol_to_list (pst, actual_name, strlen (actual_name),
 			     built_actual_name, VAR_DOMAIN, LOC_STATIC,
-			     list, 0, 0, cu->language, objfile);
+			     0, 0, cu->language, global);
       }
       break;
     case DW_TAG_variable:
@@ -4758,12 +4738,11 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 	     table building.  */
 
 	  if (pdi->d.locdesc || pdi->has_type)
-	    add_psymbol_to_list (actual_name, strlen (actual_name),
+	    add_psymbol_to_list (pst, actual_name, strlen (actual_name),
 				 built_actual_name,
 				 VAR_DOMAIN, LOC_STATIC,
-				 &objfile->global_psymbols,
 				 0, addr + baseaddr,
-				 cu->language, objfile);
+				 cu->language, 1);
 	}
       else
 	{
@@ -4776,29 +4755,26 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 	    }
 	  /* prim_record_minimal_symbol (actual_name, addr + baseaddr,
 	     mst_file_data, objfile); */
-	  add_psymbol_to_list (actual_name, strlen (actual_name),
+	  add_psymbol_to_list (pst, actual_name, strlen (actual_name),
 			       built_actual_name,
 			       VAR_DOMAIN, LOC_STATIC,
-			       &objfile->static_psymbols,
 			       0, addr + baseaddr,
-			       cu->language, objfile);
+			       cu->language, 0);
 	}
       break;
     case DW_TAG_typedef:
     case DW_TAG_base_type:
     case DW_TAG_subrange_type:
-      add_psymbol_to_list (actual_name, strlen (actual_name),
+      add_psymbol_to_list (pst, actual_name, strlen (actual_name),
 			   built_actual_name,
 			   VAR_DOMAIN, LOC_TYPEDEF,
-			   &objfile->static_psymbols,
-			   0, (CORE_ADDR) 0, cu->language, objfile);
+			   0, (CORE_ADDR) 0, cu->language, 0);
       break;
     case DW_TAG_namespace:
-      add_psymbol_to_list (actual_name, strlen (actual_name),
+      add_psymbol_to_list (pst, actual_name, strlen (actual_name),
 			   built_actual_name,
 			   VAR_DOMAIN, LOC_TYPEDEF,
-			   &objfile->global_psymbols,
-			   0, (CORE_ADDR) 0, cu->language, objfile);
+			   0, (CORE_ADDR) 0, cu->language, 1);
       break;
     case DW_TAG_class_type:
     case DW_TAG_interface_type:
@@ -4819,25 +4795,20 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
 
       /* NOTE: carlton/2003-10-07: See comment in new_symbol about
 	 static vs. global.  */
-      add_psymbol_to_list (actual_name, strlen (actual_name),
+      add_psymbol_to_list (pst, actual_name, strlen (actual_name),
 			   built_actual_name,
 			   STRUCT_DOMAIN, LOC_TYPEDEF,
+			   0, (CORE_ADDR) 0, cu->language,
 			   (cu->language == language_cplus
-			    || cu->language == language_java)
-			   ? &objfile->global_psymbols
-			   : &objfile->static_psymbols,
-			   0, (CORE_ADDR) 0, cu->language, objfile);
-
+			    || cu->language == language_java));
       break;
     case DW_TAG_enumerator:
-      add_psymbol_to_list (actual_name, strlen (actual_name),
+      add_psymbol_to_list (pst, actual_name, strlen (actual_name),
 			   built_actual_name,
 			   VAR_DOMAIN, LOC_CONST,
+			   0, (CORE_ADDR) 0, cu->language,
 			   (cu->language == language_cplus
-			    || cu->language == language_java)
-			   ? &objfile->global_psymbols
-			   : &objfile->static_psymbols,
-			   0, (CORE_ADDR) 0, cu->language, objfile);
+			    || cu->language == language_java));
       break;
     default:
       break;
@@ -10903,6 +10874,7 @@ load_partial_dies (const struct die_reader_specs *reader,
 {
   struct dwarf2_cu *cu = reader->cu;
   struct objfile *objfile = cu->objfile;
+  struct partial_symtab *pst = cu->per_cu->v.psymtab;
   struct partial_die_info *part_die;
   struct partial_die_info *parent_die, *last_die, *first_die = NULL;
   struct abbrev_info *abbrev;
@@ -11028,10 +11000,9 @@ load_partial_dies (const struct die_reader_specs *reader,
 	      || part_die->tag == DW_TAG_subrange_type))
 	{
 	  if (building_psymtab && part_die->name != NULL)
-	    add_psymbol_to_list (part_die->name, strlen (part_die->name), 0,
-				 VAR_DOMAIN, LOC_TYPEDEF,
-				 &objfile->static_psymbols,
-				 0, (CORE_ADDR) 0, cu->language, objfile);
+	    add_psymbol_to_list (pst, part_die->name, strlen (part_die->name),
+				 0, VAR_DOMAIN, LOC_TYPEDEF,
+				 0, (CORE_ADDR) 0, cu->language, 0);
 	  info_ptr = locate_pdi_sibling (reader, part_die, info_ptr);
 	  continue;
 	}
@@ -11064,13 +11035,11 @@ load_partial_dies (const struct die_reader_specs *reader,
 	    complaint (&symfile_complaints,
 		       _("malformed enumerator DIE ignored"));
 	  else if (building_psymtab)
-	    add_psymbol_to_list (part_die->name, strlen (part_die->name), 0,
-				 VAR_DOMAIN, LOC_CONST,
+	    add_psymbol_to_list (pst, part_die->name, strlen (part_die->name),
+				 0, VAR_DOMAIN, LOC_CONST,
+				 0, (CORE_ADDR) 0, cu->language,
 				 (cu->language == language_cplus
-				  || cu->language == language_java)
-				 ? &objfile->global_psymbols
-				 : &objfile->static_psymbols,
-				 0, (CORE_ADDR) 0, cu->language, objfile);
+				  || cu->language == language_java));
 
 	  info_ptr = locate_pdi_sibling (reader, part_die, info_ptr);
 	  continue;
@@ -17681,15 +17650,13 @@ write_one_signatured_type (void **slot, void *d)
 
   write_psymbols (info->symtab,
 		  info->psyms_seen,
-		  info->objfile->global_psymbols.list
-		  + psymtab->globals_offset,
-		  psymtab->n_global_syms, info->cu_index,
+		  psymtab->global_psymbols.list,
+		  N_GLOBAL_PSYMS (psymtab), info->cu_index,
 		  0);
   write_psymbols (info->symtab,
 		  info->psyms_seen,
-		  info->objfile->static_psymbols.list
-		  + psymtab->statics_offset,
-		  psymtab->n_static_syms, info->cu_index,
+		  psymtab->static_psymbols.list,
+		  N_STATIC_PSYMS (psymtab), info->cu_index,
 		  1);
 
   store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE,
@@ -17725,13 +17692,13 @@ recursively_write_psymbols (struct objfile *objfile,
 
   write_psymbols (symtab,
 		  psyms_seen,
-		  objfile->global_psymbols.list + psymtab->globals_offset,
-		  psymtab->n_global_syms, cu_index,
+		  psymtab->global_psymbols.list,
+		  N_GLOBAL_PSYMS (psymtab), cu_index,
 		  0);
   write_psymbols (symtab,
 		  psyms_seen,
-		  objfile->static_psymbols.list + psymtab->statics_offset,
-		  psymtab->n_static_syms, cu_index,
+		  psymtab->static_psymbols.list,
+		  N_STATIC_PSYMS (psymtab), cu_index,
 		  1);
 }
 
diff --git a/gdb/mdebugread.c b/gdb/mdebugread.c
index d1b9177..5bfac62 100644
--- a/gdb/mdebugread.c
+++ b/gdb/mdebugread.c
@@ -265,7 +265,7 @@ static int add_line (struct linetable *, int, CORE_ADDR, int);
 
 static struct linetable *shrink_linetable (struct linetable *);
 
-static void handle_psymbol_enumerators (struct objfile *, FDR *, int,
+static void handle_psymbol_enumerators (struct partial_symtab *, FDR *, int,
 					CORE_ADDR);
 
 static char *mdebug_next_symbol_text (struct objfile *);
@@ -2686,9 +2686,7 @@ parse_partial_symbols (struct objfile *objfile)
 	textlow = 0;
       pst = start_psymtab_common (objfile, objfile->section_offsets,
 				  fdr_name (fh),
-				  textlow,
-				  objfile->global_psymbols.next,
-				  objfile->static_psymbols.next);
+				  textlow);
       pst->read_symtab_private = obstack_alloc (&objfile->objfile_obstack,
 						sizeof (struct symloc));
       memset (pst->read_symtab_private, 0, sizeof (struct symloc));
@@ -3145,11 +3143,12 @@ parse_partial_symbols (struct objfile *objfile)
 			  namestring = gdbarch_static_transform_name
 					 (gdbarch, namestring);
 
-			add_psymbol_to_list (namestring, p - namestring, 1,
-					     VAR_DOMAIN, LOC_STATIC,
-					     &objfile->static_psymbols,
-					     0, sh.value,
-					     psymtab_language, objfile);
+			if (pst)
+			  add_psymbol_to_list (pst,
+					       namestring, p - namestring, 1,
+					       VAR_DOMAIN, LOC_STATIC,
+					       0, sh.value,
+					       psymtab_language, 0);
 			continue;
 		      case 'G':
 			sh.value += ANOFFSET (objfile->section_offsets,
@@ -3157,11 +3156,12 @@ parse_partial_symbols (struct objfile *objfile)
 			/* The addresses in these entries are reported
 			   to be wrong.  See the code that reads 'G's
 			   for symtabs.  */
-			add_psymbol_to_list (namestring, p - namestring, 1,
-					     VAR_DOMAIN, LOC_STATIC,
-					     &objfile->global_psymbols,
-					     0, sh.value,
-					     psymtab_language, objfile);
+			if (pst)
+			  add_psymbol_to_list (pst,
+					       namestring, p - namestring, 1,
+					       VAR_DOMAIN, LOC_STATIC,
+					       0, sh.value,
+					       psymtab_language, 1);
 			continue;
 
 		      case 'T':
@@ -3175,21 +3175,24 @@ parse_partial_symbols (struct objfile *objfile)
 			    || (p == namestring + 1
 				&& namestring[0] != ' '))
 			  {
-			    add_psymbol_to_list (namestring, p - namestring, 1,
-						 STRUCT_DOMAIN, LOC_TYPEDEF,
-						 &objfile->static_psymbols,
-						 sh.value, 0,
-						 psymtab_language, objfile);
+			    if (pst)
+			      add_psymbol_to_list (pst,
+						   namestring,
+						   p - namestring, 1,
+						   STRUCT_DOMAIN, LOC_TYPEDEF,
+						   sh.value, 0,
+						   psymtab_language, 0);
 			    if (p[2] == 't')
 			      {
 				/* Also a typedef with the same name.  */
-				add_psymbol_to_list (namestring,
-						     p - namestring, 1,
-						     VAR_DOMAIN, LOC_TYPEDEF,
-						     &objfile->static_psymbols,
-						     sh.value, 0,
-						     psymtab_language,
-						     objfile);
+				if (pst)
+				  add_psymbol_to_list (pst,
+						       namestring,
+						       p - namestring, 1,
+						       VAR_DOMAIN, LOC_TYPEDEF,
+						       sh.value, 0,
+						       psymtab_language,
+						       1);
 				p += 1;
 			      }
 			  }
@@ -3198,11 +3201,13 @@ parse_partial_symbols (struct objfile *objfile)
 			if (p != namestring)	/* a name is there, not
 						   just :T...  */
 			  {
-			    add_psymbol_to_list (namestring, p - namestring, 1,
-						 VAR_DOMAIN, LOC_TYPEDEF,
-						 &objfile->static_psymbols,
-						 sh.value, 0,
-						 psymtab_language, objfile);
+			    if (pst)
+			      add_psymbol_to_list (pst,
+						   namestring,
+						   p - namestring, 1,
+						   VAR_DOMAIN, LOC_TYPEDEF,
+						   sh.value, 0,
+						   psymtab_language, 0);
 			  }
 		      check_enum:
 			/* If this is an enumerated type, we need to add
@@ -3263,11 +3268,12 @@ parse_partial_symbols (struct objfile *objfile)
 				/* 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, 0, psymtab_language,
-						     objfile);
+				if (pst)
+				  add_psymbol_to_list (pst,
+						       p, q - p, 1,
+						       VAR_DOMAIN, LOC_CONST,
+						       0, 0, psymtab_language,
+						       0);
 				/* Point past the name.  */
 				p = q;
 				/* Skip over the value.  */
@@ -3281,11 +3287,12 @@ parse_partial_symbols (struct objfile *objfile)
 			continue;
 		      case 'c':
 			/* Constant, e.g. from "const" in Pascal.  */
-			add_psymbol_to_list (namestring, p - namestring, 1,
-					     VAR_DOMAIN, LOC_CONST,
-					     &objfile->static_psymbols,
-					     sh.value, 0, psymtab_language,
-					     objfile);
+			if (pst)
+			  add_psymbol_to_list (pst,
+					       namestring, p - namestring, 1,
+					       VAR_DOMAIN, LOC_CONST,
+					       sh.value, 0, psymtab_language,
+					       0);
 			continue;
 
 		      case 'f':
@@ -3301,11 +3308,12 @@ parse_partial_symbols (struct objfile *objfile)
 			  }
 			sh.value += ANOFFSET (objfile->section_offsets,
 					      SECT_OFF_TEXT (objfile));
-			add_psymbol_to_list (namestring, p - namestring, 1,
-					     VAR_DOMAIN, LOC_BLOCK,
-					     &objfile->static_psymbols,
-					     0, sh.value,
-					     psymtab_language, objfile);
+			if (pst)
+			  add_psymbol_to_list (pst,
+					       namestring, p - namestring, 1,
+					       VAR_DOMAIN, LOC_BLOCK,
+					       0, sh.value,
+					       psymtab_language, 0);
 			continue;
 
 			/* Global functions were ignored here, but now they
@@ -3325,11 +3333,12 @@ parse_partial_symbols (struct objfile *objfile)
 			  }
 			sh.value += ANOFFSET (objfile->section_offsets,
 					      SECT_OFF_TEXT (objfile));
-			add_psymbol_to_list (namestring, p - namestring, 1,
-					     VAR_DOMAIN, LOC_BLOCK,
-					     &objfile->global_psymbols,
-					     0, sh.value,
-					     psymtab_language, objfile);
+			if (pst)
+			  add_psymbol_to_list (pst,
+					       namestring, p - namestring, 1,
+					       VAR_DOMAIN, LOC_BLOCK,
+					       0, sh.value,
+					       psymtab_language, 1);
 			continue;
 
 			/* Two things show up here (hopefully); static
@@ -3449,7 +3458,7 @@ parse_partial_symbols (struct objfile *objfile)
 	      /* end - Handle continuation */
 	    }
 	}
-      else
+      else /* ! processing_gcc_compilation */
 	{
 	  for (cur_sdx = 0; cur_sdx < fh->csym;)
 	    {
@@ -3565,15 +3574,13 @@ parse_partial_symbols (struct objfile *objfile)
 		     symbol table, and the MAIN__ symbol via the minimal
 		     symbol table.  */
 		  if (sh.st == stProc)
-		    add_psymbol_to_list (name, strlen (name), 1,
+		    add_psymbol_to_list (pst, name, strlen (name), 1,
 					 VAR_DOMAIN, LOC_BLOCK,
-					 &objfile->global_psymbols,
-				    0, sh.value, psymtab_language, objfile);
+					 0, sh.value, psymtab_language, 1);
 		  else
-		    add_psymbol_to_list (name, strlen (name), 1,
+		    add_psymbol_to_list (pst, name, strlen (name), 1,
 					 VAR_DOMAIN, LOC_BLOCK,
-					 &objfile->static_psymbols,
-				    0, sh.value, psymtab_language, objfile);
+					 0, sh.value, psymtab_language, 0);
 
 		  procaddr = sh.value;
 
@@ -3639,13 +3646,12 @@ parse_partial_symbols (struct objfile *objfile)
 		      && sh.iss != 0
 		      && sh.index != cur_sdx + 2)
 		    {
-		      add_psymbol_to_list (name, strlen (name), 1,
+		      add_psymbol_to_list (pst, name, strlen (name), 1,
 					   STRUCT_DOMAIN, LOC_TYPEDEF,
-					   &objfile->static_psymbols,
 					   0, (CORE_ADDR) 0,
-					   psymtab_language, objfile);
+					   psymtab_language, 0);
 		    }
-		  handle_psymbol_enumerators (objfile, fh, sh.st, sh.value);
+		  handle_psymbol_enumerators (pst, fh, sh.st, sh.value);
 
 		  /* Skip over the block.  */
 		  new_sdx = sh.index;
@@ -3680,10 +3686,9 @@ parse_partial_symbols (struct objfile *objfile)
 		  continue;
 		}
 	      /* Use this gdb symbol.  */
-	      add_psymbol_to_list (name, strlen (name), 1,
+	      add_psymbol_to_list (pst, name, strlen (name), 1,
 				   VAR_DOMAIN, class,
-				   &objfile->static_psymbols,
-				   0, sh.value, psymtab_language, objfile);
+				   0, sh.value, psymtab_language, 0);
 	    skip:
 	      cur_sdx++;	/* Go to next file symbol.  */
 	    }
@@ -3760,11 +3765,10 @@ parse_partial_symbols (struct objfile *objfile)
 		  break;
 		}
 	      name = debug_info->ssext + psh->iss;
-	      add_psymbol_to_list (name, strlen (name), 1,
+	      add_psymbol_to_list (pst, name, strlen (name), 1,
 				   VAR_DOMAIN, class,
-				   &objfile->global_psymbols,
 				   0, svalue,
-				   psymtab_language, objfile);
+				   psymtab_language, 1);
 	    }
 	}
 
@@ -3858,8 +3862,8 @@ parse_partial_symbols (struct objfile *objfile)
      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)
+      && N_GLOBAL_PSYMS (objfile->psymtabs) == 0
+      && N_STATIC_PSYMS (objfile->psymtabs) == 0)
     objfile->psymtabs = NULL;
   do_cleanups (old_chain);
 }
@@ -3868,7 +3872,7 @@ parse_partial_symbols (struct objfile *objfile)
    all the enum constants to the partial symbol table.  */
 
 static void
-handle_psymbol_enumerators (struct objfile *objfile, FDR *fh, int stype,
+handle_psymbol_enumerators (struct partial_symtab *pst, FDR *fh, int stype,
 			    CORE_ADDR svalue)
 {
   const bfd_size_type external_sym_size = debug_swap->external_sym_size;
@@ -3924,10 +3928,9 @@ handle_psymbol_enumerators (struct objfile *objfile, FDR *fh, int stype,
 
       /* Note that the value doesn't matter for enum constants
          in psymtabs, just in symtabs.  */
-      add_psymbol_to_list (name, strlen (name), 1,
+      add_psymbol_to_list (pst, name, strlen (name), 1,
 			   VAR_DOMAIN, LOC_CONST,
-			   &objfile->static_psymbols, 0,
-			   (CORE_ADDR) 0, psymtab_language, objfile);
+			   0, (CORE_ADDR) 0, psymtab_language, 0);
       ext_sym += external_sym_size;
     }
 }
@@ -4002,7 +4005,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst, const char *filename)
 
   /* Do nothing if this is a dummy psymtab.  */
 
-  if (pst->n_global_syms == 0 && pst->n_static_syms == 0
+  if (N_GLOBAL_PSYMS (pst) == 0 && N_STATIC_PSYMS (pst) == 0
       && pst->textlow == 0 && pst->texthigh == 0)
     return;
 
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 8d9f8a5..80e389b 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -597,10 +597,7 @@ free_objfile (struct objfile *objfile)
   /* The last thing we do is free the objfile struct itself.  */
 
   xfree (objfile->name);
-  if (objfile->global_psymbols.list)
-    xfree (objfile->global_psymbols.list);
-  if (objfile->static_psymbols.list)
-    xfree (objfile->static_psymbols.list);
+  free_objfile_psymtabs (objfile);
   /* Free the obstacks for non-reusable objfiles.  */
   psymbol_bcache_free (objfile->psymbol_cache);
   bcache_xfree (objfile->macro_cache);
diff --git a/gdb/objfiles.h b/gdb/objfiles.h
index d5c807f..6d4fe42 100644
--- a/gdb/objfiles.h
+++ b/gdb/objfiles.h
@@ -21,7 +21,7 @@
 #define OBJFILES_H
 
 #include "gdb_obstack.h"	/* For obstack internals.  */
-#include "symfile.h"		/* For struct psymbol_allocation_list.  */
+#include "symfile.h"
 #include "progspace.h"
 
 struct bcache;
@@ -257,12 +257,6 @@ struct objfile
        if the name doesn't demangle.  */
     struct htab *demangled_names_hash;
 
-    /* Vectors of all partial symbols read in from file.  The actual data
-       is stored in the objfile_obstack.  */
-
-    struct psymbol_allocation_list global_psymbols;
-    struct psymbol_allocation_list static_psymbols;
-
     /* Each file contains a pointer to an array of minimal symbols for all
        global symbols that are defined within the file.  The array is
        terminated by a "null symbol", one that has a NULL pointer for the
diff --git a/gdb/psympriv.h b/gdb/psympriv.h
index 370ce86..3cd1f4b 100644
--- a/gdb/psympriv.h
+++ b/gdb/psympriv.h
@@ -153,22 +153,20 @@ struct partial_symtab
 
   /* Global symbol list.  This list will be sorted after readin to
      improve access.  Binary search will be the usual method of
-     finding a symbol within it.  globals_offset is an integer offset
-     within global_psymbols[].  */
+     finding a symbol within it.
+     The actual data is stored in the objfile_obstack.  */
 
-  int globals_offset;
-  int n_global_syms;
+  struct psymbol_allocation_list global_psymbols;
 
   /* Static symbol list.  This list will *not* be sorted after readin;
      to find a symbol in it, exhaustive search must be used.  This is
      reasonable because searches through this list will eventually
      lead to either the read in of a files symbols for real (assumed
      to take a *lot* of time; check) or an error (and we don't care
-     how long errors take).  This is an offset and size within
-     static_psymbols[].  */
+     how long errors take).
+     The actual data is stored in the objfile_obstack.  */
 
-  int statics_offset;
-  int n_static_syms;
+  struct psymbol_allocation_list static_psymbols;
 
   /* Non-zero if the symtab corresponding to this psymtab has been
      readin.  This is located here so that this structure packs better
@@ -204,24 +202,42 @@ struct partial_symtab
   void *read_symtab_private;
 };
 
+/* Convenience macros.  */
+#define N_GLOBAL_PSYMS(psymtab) \
+  ((psymtab)->global_psymbols.next - (psymtab)->global_psymbols.list)
+#define N_STATIC_PSYMS(psymtab) \
+  ((psymtab)->static_psymbols.next - (psymtab)->static_psymbols.list)
+
+/* Iterate over all global psymbols.  */
+#define ALL_GLOBAL_PSYMBOLS(psymtab, iter, psym) \
+  for (i = 0, psym = ((psymtab)->global_psymbols.list \
+		      ? (psymtab)->global_psymbols.list[0] \
+		      : NULL); \
+       i < N_GLOBAL_PSYMS (psymtab); \
+       ++i, psym = (psymtab)->global_psymbols.list[i])
+
+/* Iterate over all static psymbols.  */
+#define ALL_STATIC_PSYMBOLS(psymtab, iter, psym) \
+  for (i = 0, psym = ((psymtab)->static_psymbols.list \
+		      ? (psymtab)->static_psymbols.list[0] \
+		      : NULL); \
+       i < N_STATIC_PSYMS (psymtab); \
+       ++i, psym = (psymtab)->static_psymbols.list[i])
+
 extern void sort_pst_symbols (struct partial_symtab *);
 
 /* Add any kind of symbol to a psymbol_allocation_list.  */
 
-extern void add_psymbol_to_list (const char *, int,
+extern void add_psymbol_to_list (struct partial_symtab *,
+				 const char *, int,
 				 int, domain_enum,
 				 enum address_class,
-				 struct psymbol_allocation_list *,
 				 long, CORE_ADDR,
-				 enum language, struct objfile *);
-
-extern void init_psymbol_list (struct objfile *, int);
+				 enum language, int);
 
 extern struct partial_symtab *start_psymtab_common (struct objfile *,
 						    struct section_offsets *,
-						    const char *, CORE_ADDR,
-						    struct partial_symbol **,
-						    struct partial_symbol **);
+						    const char *, CORE_ADDR);
 
 extern struct partial_symtab *allocate_psymtab (const char *,
 						struct objfile *);
@@ -229,6 +245,7 @@ extern struct partial_symtab *allocate_psymtab (const char *,
 extern void discard_psymtab (struct partial_symtab *);
 
 /* Traverse all psymtabs in one objfile.  */
+/* FIXME: This should be in objfile.h.  */
 
 #define	ALL_OBJFILE_PSYMTABS(objfile, p) \
     for ((p) = (objfile) -> psymtabs; (p) != NULL; (p) = (p) -> next)
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 647368c..aab3421 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -410,7 +410,8 @@ static struct partial_symbol *
 find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc,
 		      struct obj_section *section)
 {
-  struct partial_symbol *best = NULL, *p, **pp;
+  int i;
+  struct partial_symbol *best = NULL, *p;
   CORE_ADDR best_pc;
 
   gdb_assert (psymtab != NULL);
@@ -421,12 +422,8 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc,
   /* Search the global symbols as well as the static symbols, so that
      find_pc_partial_function doesn't use a minimal symbol and thus
      cache a bad endaddr.  */
-  for (pp = psymtab->objfile->global_psymbols.list + psymtab->globals_offset;
-    (pp - (psymtab->objfile->global_psymbols.list + psymtab->globals_offset)
-     < psymtab->n_global_syms);
-       pp++)
+  ALL_GLOBAL_PSYMBOLS (psymtab, i, p)
     {
-      p = *pp;
       if (SYMBOL_DOMAIN (p) == VAR_DOMAIN
 	  && SYMBOL_CLASS (p) == LOC_BLOCK
 	  && pc >= SYMBOL_VALUE_ADDRESS (p)
@@ -445,12 +442,8 @@ find_pc_sect_psymbol (struct partial_symtab *psymtab, CORE_ADDR pc,
 	}
     }
 
-  for (pp = psymtab->objfile->static_psymbols.list + psymtab->statics_offset;
-    (pp - (psymtab->objfile->static_psymbols.list + psymtab->statics_offset)
-     < psymtab->n_static_syms);
-       pp++)
+  ALL_STATIC_PSYMBOLS (psymtab, i, p)
     {
-      p = *pp;
       if (SYMBOL_DOMAIN (p) == VAR_DOMAIN
 	  && SYMBOL_CLASS (p) == LOC_BLOCK
 	  && pc >= SYMBOL_VALUE_ADDRESS (p)
@@ -561,14 +554,12 @@ match_partial_symbol (struct partial_symtab *pst, int global,
 {
   struct partial_symbol **start, **psym;
   struct partial_symbol **top, **real_top, **bottom, **center;
-  int length = (global ? pst->n_global_syms : pst->n_static_syms);
+  int length = (global ? N_GLOBAL_PSYMS (pst) : N_STATIC_PSYMS (pst));
   int do_linear_search = 1;
 
   if (length == 0)
       return NULL;
-  start = (global ?
-	   pst->objfile->global_psymbols.list + pst->globals_offset :
-	   pst->objfile->static_psymbols.list + pst->statics_offset);
+  start = global ? pst->global_psymbols.list : pst->static_psymbols.list;
 
   if (global && ordered_compare)  /* Can use a binary search.  */
     {
@@ -675,7 +666,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
 {
   struct partial_symbol **start, **psym;
   struct partial_symbol **top, **real_top, **bottom, **center;
-  int length = (global ? pst->n_global_syms : pst->n_static_syms);
+  int length = (global ? N_GLOBAL_PSYMS (pst) : N_STATIC_PSYMS (pst));
   int do_linear_search = 1;
   char *search_name;
   struct cleanup *cleanup;
@@ -687,9 +678,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
 
   search_name = psymtab_search_name (name);
   cleanup = make_cleanup (xfree, search_name);
-  start = (global ?
-	   pst->objfile->global_psymbols.list + pst->globals_offset :
-	   pst->objfile->static_psymbols.list + pst->statics_offset);
+  start = global ? pst->global_psymbols.list : pst->static_psymbols.list;
 
   if (global)			/* This means we can use a binary search.  */
     {
@@ -802,7 +791,6 @@ relocate_psymtabs (struct objfile *objfile,
 		   struct section_offsets *new_offsets,
 		   struct section_offsets *delta)
 {
-  struct partial_symbol **psym;
   struct partial_symtab *p;
 
   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
@@ -811,23 +799,26 @@ relocate_psymtabs (struct objfile *objfile,
       p->texthigh += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
     }
 
-  for (psym = objfile->global_psymbols.list;
-       psym < objfile->global_psymbols.next;
-       psym++)
-    {
-      fixup_psymbol_section (*psym, objfile);
-      if (SYMBOL_SECTION (*psym) >= 0)
-	SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
-						  SYMBOL_SECTION (*psym));
-    }
-  for (psym = objfile->static_psymbols.list;
-       psym < objfile->static_psymbols.next;
-       psym++)
+  /* Blech.  IWBN to use ALL_OBJFILE_PSYMTABS here.  */
+  for (p = objfile->psymtabs; p != NULL; p = p->next)
     {
-      fixup_psymbol_section (*psym, objfile);
-      if (SYMBOL_SECTION (*psym) >= 0)
-	SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
-						  SYMBOL_SECTION (*psym));
+      int i;
+      struct partial_symbol *psym;
+
+      ALL_GLOBAL_PSYMBOLS (p, i, psym)
+	{
+	  fixup_psymbol_section (psym, objfile);
+	  if (SYMBOL_SECTION (psym) >= 0)
+	    SYMBOL_VALUE_ADDRESS (psym) += ANOFFSET (delta,
+						     SYMBOL_SECTION (psym));
+	}
+      ALL_STATIC_PSYMBOLS (p, i, psym)
+	{
+	  fixup_psymbol_section (psym, objfile);
+	  if (SYMBOL_SECTION (psym) >= 0)
+	    SYMBOL_VALUE_ADDRESS (psym) += ANOFFSET (delta,
+						     SYMBOL_SECTION (psym));
+	}
     }
 }
 
@@ -1027,19 +1018,17 @@ dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
       gdb_print_host_address (psymtab->user, outfile);
       fprintf_filtered (outfile, "\n");
     }
-  if (psymtab->n_global_syms > 0)
+  if (N_GLOBAL_PSYMS (psymtab) > 0)
     {
       print_partial_symbols (gdbarch,
-			     objfile->global_psymbols.list
-			     + psymtab->globals_offset,
-			     psymtab->n_global_syms, "Global", outfile);
+			     psymtab->global_psymbols.list,
+			     N_GLOBAL_PSYMS (psymtab), "Global", outfile);
     }
-  if (psymtab->n_static_syms > 0)
+  if (N_STATIC_PSYMS (psymtab) > 0)
     {
       print_partial_symbols (gdbarch,
-			     objfile->static_psymbols.list
-			     + psymtab->statics_offset,
-			     psymtab->n_static_syms, "Static", outfile);
+			     psymtab->static_psymbols.list,
+			     N_STATIC_PSYMS (psymtab), "Static", outfile);
     }
   fprintf_filtered (outfile, "\n");
 }
@@ -1303,22 +1292,20 @@ recursively_search_psymtabs (struct partial_symtab *ps,
 	}
     }
 
-  gbound = (objfile->global_psymbols.list
-	    + ps->globals_offset + ps->n_global_syms);
-  sbound = (objfile->static_psymbols.list
-	    + ps->statics_offset + ps->n_static_syms);
+  gbound = ps->global_psymbols.list + N_GLOBAL_PSYMS (ps);
+  sbound = ps->static_psymbols.list + N_STATIC_PSYMS (ps);
   bound = gbound;
 
   /* Go through all of the symbols stored in a partial
      symtab in one loop.  */
-  psym = objfile->global_psymbols.list + ps->globals_offset;
+  psym = ps->global_psymbols.list;
   while (keep_going)
     {
       if (psym >= bound)
 	{
-	  if (bound == gbound && ps->n_static_syms != 0)
+	  if (bound == gbound && N_STATIC_PSYMS (ps) != 0)
 	    {
-	      psym = objfile->static_psymbols.list + ps->statics_offset;
+	      psym = ps->static_psymbols.list;
 	      bound = sbound;
 	    }
 	  else
@@ -1432,9 +1419,8 @@ sort_pst_symbols (struct partial_symtab *pst)
 {
   /* Sort the global list; don't sort the static list.  */
 
-  qsort (pst->objfile->global_psymbols.list + pst->globals_offset,
-	 pst->n_global_syms, sizeof (struct partial_symbol *),
-	 compare_psymbols);
+  qsort (pst->global_psymbols.list, N_GLOBAL_PSYMS (pst),
+	 sizeof (struct partial_symbol *), compare_psymbols);
 }
 
 /* Allocate and partially fill a partial symtab.  It will be
@@ -1446,8 +1432,7 @@ struct partial_symtab *
 start_psymtab_common (struct objfile *objfile,
 		      struct section_offsets *section_offsets,
 		      const char *filename,
-		      CORE_ADDR textlow, struct partial_symbol **global_syms,
-		      struct partial_symbol **static_syms)
+		      CORE_ADDR textlow)
 {
   struct partial_symtab *psymtab;
 
@@ -1455,9 +1440,7 @@ start_psymtab_common (struct objfile *objfile,
   psymtab->section_offsets = section_offsets;
   psymtab->textlow = textlow;
   psymtab->texthigh = psymtab->textlow;		/* default */
-  psymtab->globals_offset = global_syms - objfile->global_psymbols.list;
-  psymtab->statics_offset = static_syms - objfile->static_psymbols.list;
-  return (psymtab);
+  return psymtab;
 }
 
 /* Calculate a hash code for the given partial symbol.  The hash is
@@ -1596,14 +1579,15 @@ add_psymbol_to_bcache (const char *name, int namelength, int copy_name,
    be freed in free_objfile().  */
 
 static void
-extend_psymbol_list (struct psymbol_allocation_list *listp,
-		     struct objfile *objfile)
+extend_psymbol_list (struct psymbol_allocation_list *listp)
 {
   int new_size;
 
   if (listp->size == 0)
     {
-      new_size = 255;
+      /* There's no measurable cost to starting this small, and there is a
+	 sufficient space savings for selected testcases.  */
+      new_size = 1;
       listp->list = (struct partial_symbol **)
 	xmalloc (new_size * sizeof (struct partial_symbol *));
     }
@@ -1629,26 +1613,30 @@ append_psymbol_to_list (struct psymbol_allocation_list *list,
 			struct objfile *objfile)
 {
   if (list->next >= list->list + list->size)
-    extend_psymbol_list (list, objfile);
+    extend_psymbol_list (list);
   *list->next++ = (struct partial_symbol *) psym;
   OBJSTAT (objfile, n_psyms++);
 }
 
-/* Add a symbol with a long value to a psymtab.
-   Since one arg is a struct, we pass in a ptr and deref it (sigh).
-   Return the partial symbol that has been added.  */
+/* Add symbol NAME to PSYMTAB.
+   If GLOBAL is non-zero add it to the global list,
+   otherwise add it to the static list.
+   VAL and COREADDR are mutually exclusive, one of them must be zero.  */
 
 void
-add_psymbol_to_list (const char *name, int namelength, int copy_name,
+add_psymbol_to_list (struct partial_symtab *psymtab,
+		     const char *name, int namelength, int copy_name,
 		     domain_enum domain,
 		     enum address_class class,
-		     struct psymbol_allocation_list *list, 
-		     long val,	/* Value as a long */
-		     CORE_ADDR coreaddr,	/* Value as a CORE_ADDR */
-		     enum language language, struct objfile *objfile)
+		     long val,  /* Value as a long */
+		     CORE_ADDR coreaddr,  /* Value as a CORE_ADDR */
+		     enum language language,
+		     int global)
 {
+  struct objfile *objfile = psymtab->objfile;
+  struct psymbol_allocation_list *list =
+    global ? &psymtab->global_psymbols : &psymtab->static_psymbols;
   const struct partial_symbol *psym;
-
   int added;
 
   /* Stash the partial symbol away in the cache.  */
@@ -1656,53 +1644,13 @@ add_psymbol_to_list (const char *name, int namelength, int copy_name,
 				val, coreaddr, language, objfile, &added);
 
   /* Do not duplicate global partial symbols.  */
-  if (list == &objfile->global_psymbols
-      && !added)
+  if (global && !added)
     return;
 
   /* Save pointer to partial symbol in psymtab, growing symtab if needed.  */
   append_psymbol_to_list (list, psym, objfile);
 }
 
-/* Initialize storage for partial symbols.  */
-
-void
-init_psymbol_list (struct objfile *objfile, int total_symbols)
-{
-  /* Free any previously allocated psymbol lists.  */
-
-  if (objfile->global_psymbols.list)
-    {
-      xfree (objfile->global_psymbols.list);
-    }
-  if (objfile->static_psymbols.list)
-    {
-      xfree (objfile->static_psymbols.list);
-    }
-
-  /* Current best guess is that approximately a twentieth
-     of the total symbols (in a debugging file) are global or static
-     oriented symbols.  */
-
-  objfile->global_psymbols.size = total_symbols / 10;
-  objfile->static_psymbols.size = total_symbols / 10;
-
-  if (objfile->global_psymbols.size > 0)
-    {
-      objfile->global_psymbols.next =
-	objfile->global_psymbols.list = (struct partial_symbol **)
-	xmalloc ((objfile->global_psymbols.size
-		  * sizeof (struct partial_symbol *)));
-    }
-  if (objfile->static_psymbols.size > 0)
-    {
-      objfile->static_psymbols.next =
-	objfile->static_psymbols.list = (struct partial_symbol **)
-	xmalloc ((objfile->static_psymbols.size
-		  * sizeof (struct partial_symbol *)));
-    }
-}
-
 struct partial_symtab *
 allocate_psymtab (const char *filename, struct objfile *objfile)
 {
@@ -1734,6 +1682,27 @@ allocate_psymtab (const char *filename, struct objfile *objfile)
   return (psymtab);
 }
 
+/* Free resources held by partial symtab P.  */
+
+static void
+free_psymtab_resources (struct partial_symtab *p)
+{
+  xfree (p->global_psymbols.list);
+  xfree (p->static_psymbols.list);
+}
+
+/* Free resources held by all partial symtabs of OBJFILE.  */
+
+void
+free_objfile_psymtabs (struct objfile *objfile)
+{
+  struct partial_symtab *p;
+
+  /* Blech.  IWBN to use ALL_OBJFILE_PSYMTABS here.  */
+  for (p = objfile->psymtabs; p != NULL; p = p->next)
+    free_psymtab_resources (p);
+}
+
 void
 discard_psymtab (struct partial_symtab *pst)
 {
@@ -1746,14 +1715,18 @@ discard_psymtab (struct partial_symtab *pst)
      nothing else is not empty, but we don't realize that.  Fixing
      that without slowing things down might be tricky.  */
 
-  /* First, snip it out of the psymtab chain.  */
+  /* Free resources held by this psymtab.  */
+
+  free_psymtab_resources (pst);
+
+  /* Snip it out of the psymtab chain.  */
 
   prev_pst = &(pst->objfile->psymtabs);
   while ((*prev_pst) != pst)
     prev_pst = &((*prev_pst)->next);
   (*prev_pst) = pst->next;
 
-  /* Next, put it on a free list for recycling.  */
+  /* Put it on a free list for recycling.  */
 
   pst->next = pst->objfile->free_psymtabs;
   pst->objfile->free_psymtabs = pst;
@@ -1865,22 +1838,20 @@ maintenance_info_psymtabs (char *regexp, int from_tty)
 			       (psymtab->psymtabs_addrmap_supported
 				? "yes" : "no"));
 	      printf_filtered ("    globals ");
-	      if (psymtab->n_global_syms)
+	      if (N_GLOBAL_PSYMS (psymtab))
 		{
-		  printf_filtered ("(* (struct partial_symbol **) %s @ %d)\n",
-				   host_address_to_string (psymtab->objfile->global_psymbols.list
-				    + psymtab->globals_offset),
-				   psymtab->n_global_syms);
+		  printf_filtered ("(* (struct partial_symbol **) %s @ %ld)\n",
+				   host_address_to_string (psymtab->global_psymbols.list),
+				   (long) N_GLOBAL_PSYMS (psymtab));
 		}
 	      else
 		printf_filtered ("(none)\n");
 	      printf_filtered ("    statics ");
-	      if (psymtab->n_static_syms)
+	      if (N_STATIC_PSYMS (psymtab))
 		{
-		  printf_filtered ("(* (struct partial_symbol **) %s @ %d)\n",
-				   host_address_to_string (psymtab->objfile->static_psymbols.list
-				    + psymtab->statics_offset),
-				   psymtab->n_static_syms);
+		  printf_filtered ("(* (struct partial_symbol **) %s @ %ld)\n",
+				   host_address_to_string (psymtab->static_psymbols.list),
+				   (long) N_STATIC_PSYMS (psymtab));
 		}
 	      else
 		printf_filtered ("(none)\n");
@@ -1936,8 +1907,8 @@ maintenance_check_symtabs (char *ignore, int from_tty)
       continue;
     bv = BLOCKVECTOR (s);
     b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-    psym = ps->objfile->static_psymbols.list + ps->statics_offset;
-    length = ps->n_static_syms;
+    psym = ps->static_psymbols.list;
+    length = N_STATIC_PSYMS (ps);
     while (length--)
       {
 	sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym),
@@ -1953,8 +1924,8 @@ maintenance_check_symtabs (char *ignore, int from_tty)
 	psym++;
       }
     b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-    psym = ps->objfile->global_psymbols.list + ps->globals_offset;
-    length = ps->n_global_syms;
+    psym = ps->global_psymbols.list;
+    length = N_GLOBAL_PSYMS (ps);
     while (length--)
       {
 	sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym),
diff --git a/gdb/psymtab.h b/gdb/psymtab.h
index 4089d46..5e83653 100644
--- a/gdb/psymtab.h
+++ b/gdb/psymtab.h
@@ -48,4 +48,6 @@ extern const struct quick_symbol_functions dwarf2_gdb_index_functions;
 extern struct objfile *require_partial_symbols (struct objfile *objfile,
 						int verbose);
 
+extern void free_objfile_psymtabs (struct objfile *);
+
 #endif /* PSYMTAB_H */
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 31da4e4..411fdde 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -2539,16 +2539,7 @@ reread_symbols (void)
 	  memcpy (offsets, objfile->section_offsets,
 		  SIZEOF_N_SECTION_OFFSETS (num_offsets));
 
-	  /* FIXME: Do we have to free a whole linked list, or is this
-	     enough?  */
-	  if (objfile->global_psymbols.list)
-	    xfree (objfile->global_psymbols.list);
-	  memset (&objfile->global_psymbols, 0,
-		  sizeof (objfile->global_psymbols));
-	  if (objfile->static_psymbols.list)
-	    xfree (objfile->static_psymbols.list);
-	  memset (&objfile->static_psymbols, 0,
-		  sizeof (objfile->static_psymbols));
+	  free_objfile_psymtabs (objfile);
 
 	  /* Free the obstacks for non-reusable objfiles.  */
 	  psymbol_bcache_free (objfile->psymbol_cache);
diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c
index af93a43..27da3e6 100644
--- a/gdb/xcoffread.c
+++ b/gdb/xcoffread.c
@@ -2019,16 +2019,13 @@ static unsigned int first_fun_line_offset;
 
 static struct partial_symtab *
 xcoff_start_psymtab (struct objfile *objfile,
-		     const char *filename, int first_symnum,
-		     struct partial_symbol **global_syms,
-		     struct partial_symbol **static_syms)
+		     const char *filename, int first_symnum)
 {
   struct partial_symtab *result =
     start_psymtab_common (objfile, objfile->section_offsets,
 			  filename,
 			  /* We fill in textlow later.  */
-			  0,
-			  global_syms, static_syms);
+			  0);
 
   result->read_symtab_private = obstack_alloc (&objfile->objfile_obstack,
 					       sizeof (struct symloc));
@@ -2065,10 +2062,6 @@ xcoff_end_psymtab (struct partial_symtab *pst, const char **include_list,
   ((struct symloc *) pst->read_symtab_private)->lineno_off =
     first_fun_line_offset;
   first_fun_line_offset = 0;
-  pst->n_global_syms = objfile->global_psymbols.next
-    - (objfile->global_psymbols.list + pst->globals_offset);
-  pst->n_static_syms = objfile->static_psymbols.next
-    - (objfile->static_psymbols.list + pst->statics_offset);
 
   pst->number_of_dependencies = number_dependencies;
   if (number_dependencies)
@@ -2103,11 +2096,6 @@ xcoff_end_psymtab (struct partial_symtab *pst, const char **include_list,
       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->symtab = 0;
       subpst->read_symtab = pst->read_symtab;
@@ -2117,8 +2105,8 @@ xcoff_end_psymtab (struct partial_symtab *pst, const char **include_list,
 
   if (num_includes == 0
       && number_dependencies == 0
-      && pst->n_global_syms == 0
-      && pst->n_static_syms == 0)
+      && N_GLOBAL_PSYMS (pst) == 0
+      && N_STATIC_PSYMS (pst) == 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.  */
@@ -2329,9 +2317,7 @@ scan_xcoff_symtab (struct objfile *objfile)
 			    pst = xcoff_start_psymtab
 			      (objfile,
 			       filestring,
-			       symnum_before,
-			       objfile->global_psymbols.next,
-			       objfile->static_psymbols.next);
+			       symnum_before);
 			  }
 		      }
 		    /* Activate the misc_func_recorded mechanism for
@@ -2518,9 +2504,7 @@ scan_xcoff_symtab (struct objfile *objfile)
 
 	    pst = xcoff_start_psymtab (objfile,
 				       filestring,
-				       symnum_before,
-				       objfile->global_psymbols.next,
-				       objfile->static_psymbols.next);
+				       symnum_before);
 	    last_csect_name = NULL;
 	  }
 	  break;
@@ -2679,11 +2663,12 @@ scan_xcoff_symtab (struct objfile *objfile)
 		  namestring = gdbarch_static_transform_name
 				 (gdbarch, namestring);
 
-		add_psymbol_to_list (namestring, p - namestring, 1,
-				     VAR_DOMAIN, LOC_STATIC,
-				     &objfile->static_psymbols,
-				     0, symbol.n_value,
-				     psymtab_language, objfile);
+		if (pst)
+		  add_psymbol_to_list (pst,
+				       namestring, p - namestring, 1,
+				       VAR_DOMAIN, LOC_STATIC,
+				       0, symbol.n_value,
+				       psymtab_language, 0);
 		continue;
 
 	      case 'G':
@@ -2691,11 +2676,12 @@ scan_xcoff_symtab (struct objfile *objfile)
 					    SECT_OFF_DATA (objfile));
 		/* The addresses in these entries are reported to be
 		   wrong.  See the code that reads 'G's for symtabs.  */
-		add_psymbol_to_list (namestring, p - namestring, 1,
-				     VAR_DOMAIN, LOC_STATIC,
-				     &objfile->global_psymbols,
-				     0, symbol.n_value,
-				     psymtab_language, objfile);
+		if (pst)
+		  add_psymbol_to_list (pst,
+				       namestring, p - namestring, 1,
+				       VAR_DOMAIN, LOC_STATIC,
+				       0, symbol.n_value,
+				       psymtab_language, 1);
 		continue;
 
 	      case 'T':
@@ -2709,19 +2695,21 @@ scan_xcoff_symtab (struct objfile *objfile)
 		    || (p == namestring + 1
 			&& namestring[0] != ' '))
 		  {
-		    add_psymbol_to_list (namestring, p - namestring, 1,
-					 STRUCT_DOMAIN, LOC_TYPEDEF,
-					 &objfile->static_psymbols,
-					 symbol.n_value, 0,
-					 psymtab_language, objfile);
+		    if (pst)
+		      add_psymbol_to_list (pst,
+					   namestring, p - namestring, 1,
+					   STRUCT_DOMAIN, LOC_TYPEDEF,
+					   symbol.n_value, 0,
+					   psymtab_language, 0);
 		    if (p[2] == 't')
 		      {
 			/* Also a typedef with the same name.  */
-			add_psymbol_to_list (namestring, p - namestring, 1,
-					     VAR_DOMAIN, LOC_TYPEDEF,
-					     &objfile->static_psymbols,
-					     symbol.n_value, 0,
-					     psymtab_language, objfile);
+			if (pst)
+			  add_psymbol_to_list (pst,
+					       namestring, p - namestring, 1,
+					       VAR_DOMAIN, LOC_TYPEDEF,
+					       symbol.n_value, 0,
+					       psymtab_language, 0);
 			p += 1;
 		      }
 		  }
@@ -2730,11 +2718,12 @@ scan_xcoff_symtab (struct objfile *objfile)
 	      case 't':
 		if (p != namestring)	/* a name is there, not just :T...  */
 		  {
-		    add_psymbol_to_list (namestring, p - namestring, 1,
-					 VAR_DOMAIN, LOC_TYPEDEF,
-					 &objfile->static_psymbols,
-					 symbol.n_value, 0,
-					 psymtab_language, objfile);
+		    if (pst)
+		      add_psymbol_to_list (pst,
+					   namestring, p - namestring, 1,
+					   VAR_DOMAIN, LOC_TYPEDEF,
+					   symbol.n_value, 0,
+					   psymtab_language, 0);
 		  }
 	      check_enum:
 		/* If this is an enumerated type, we need to
@@ -2793,10 +2782,11 @@ scan_xcoff_symtab (struct objfile *objfile)
 			  ;
 			/* 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,
-					     0, psymtab_language, objfile);
+			if (pst)
+			  add_psymbol_to_list (pst,
+					       p, q - p, 1,
+					       VAR_DOMAIN, LOC_CONST,
+					       0, 0, psymtab_language, 0);
 			/* Point past the name.  */
 			p = q;
 			/* Skip over the value.  */
@@ -2811,10 +2801,11 @@ scan_xcoff_symtab (struct objfile *objfile)
 
 	      case 'c':
 		/* Constant, e.g. from "const" in Pascal.  */
-		add_psymbol_to_list (namestring, p - namestring, 1,
-				     VAR_DOMAIN, LOC_CONST,
-				     &objfile->static_psymbols, symbol.n_value,
-				     0, psymtab_language, objfile);
+		if (pst)
+		  add_psymbol_to_list (pst,
+				       namestring, p - namestring, 1,
+				       VAR_DOMAIN, LOC_CONST,
+				       symbol.n_value, 0, psymtab_language, 0);
 		continue;
 
 	      case 'f':
@@ -2830,11 +2821,12 @@ scan_xcoff_symtab (struct objfile *objfile)
 		  }
 		symbol.n_value += ANOFFSET (objfile->section_offsets,
 					    SECT_OFF_TEXT (objfile));
-		add_psymbol_to_list (namestring, p - namestring, 1,
-				     VAR_DOMAIN, LOC_BLOCK,
-				     &objfile->static_psymbols,
-				     0, symbol.n_value,
-				     psymtab_language, objfile);
+		if (pst)
+		  add_psymbol_to_list (pst,
+				       namestring, p - namestring, 1,
+				       VAR_DOMAIN, LOC_BLOCK,
+				       0, symbol.n_value,
+				       psymtab_language, 0);
 		continue;
 
 		/* Global functions were ignored here, but now they
@@ -2861,11 +2853,12 @@ scan_xcoff_symtab (struct objfile *objfile)
 
 		symbol.n_value += ANOFFSET (objfile->section_offsets,
 					    SECT_OFF_TEXT (objfile));
-		add_psymbol_to_list (namestring, p - namestring, 1,
-				     VAR_DOMAIN, LOC_BLOCK,
-				     &objfile->global_psymbols,
-				     0, symbol.n_value,
-				     psymtab_language, objfile);
+		if (pst)
+		  add_psymbol_to_list (pst,
+				       namestring, p - namestring, 1,
+				       VAR_DOMAIN, LOC_BLOCK,
+				       0, symbol.n_value,
+				       psymtab_language, 1);
 		continue;
 
 		/* Two things show up here (hopefully); static symbols of
@@ -3033,14 +3026,6 @@ xcoff_initial_scan (struct objfile *objfile, int symfile_flags)
   if (val != size)
     perror_with_name (_("reading symbol table"));
 
-  /* If we are reinitializing, or if we have never loaded syms yet, init.  */
-  if (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0)
-    /* I'm not sure how how good num_symbols is; the rule of thumb in
-       init_psymbol_list was developed for a.out.  On the one hand,
-       num_symbols includes auxents.  On the other hand, it doesn't
-       include N_SLINE.  */
-    init_psymbol_list (objfile, num_symbols);
-
   free_pending_blocks ();
   back_to = make_cleanup (really_free_pendings, 0);
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]