move minimal symbols to per-bfd
authorTom Tromey <tromey@redhat.com>
Tue, 15 Oct 2013 17:37:19 +0000 (11:37 -0600)
committerTom Tromey <tromey@redhat.com>
Wed, 26 Feb 2014 19:11:17 +0000 (12:11 -0700)
Now that minimal symbols are independent of the program space, we can
move them to the per-BFD object.  This lets us save memory in the
multi-inferior case; and, once the symbol readers are updated, time.

The other prerequisite for this move is that all the objects referred
to by the minimal symbols have a lifetime at least as long as the
per-BFD object.  I think this is satisfied partially by this patch
(moving the copied names there) and partially by earlier patches
moving the demangled name hash.

This patch contains a bit of logic to avoid creating new minimal
symbols if they have already been read for a given BFD.  This allows
us to avoid trying to update all the symbol readers for this
condition.  At first glance this may seem like a hack, but some symbol
readers mix psym and minsym reading, and would require logic just like
this regardless -- and it is simpler and less error-prone to just do
the work in a central spot.

2014-02-26  Tom Tromey  <tromey@redhat.com>

* minsyms.c (lookup_minimal_symbol, iterate_over_minimal_symbols)
(lookup_minimal_symbol_text, lookup_minimal_symbol_by_pc_name)
(lookup_minimal_symbol_solib_trampoline)
(lookup_minimal_symbol_by_pc_section_1)
(lookup_minimal_symbol_and_objfile): Update.
(prim_record_minimal_symbol_full): Use the per-BFD obstack.
Don't allocate a minimal symbol if minsyms have already been read.
(build_minimal_symbol_hash_tables): Update.
(install_minimal_symbols): Do nothing if minsyms already read.
Use the per-BFD obstack.
(terminate_minimal_symbol_table): Use the per-BFD obstack.
* objfiles.c (allocate_objfile): Call
terminate_minimal_symbol_table later.
(have_minimal_symbols): Update.
* objfiles.h (struct objfile_per_bfd_storage) <msymbols,
minimal_symbol_count, msymbol_hash, msymbol_demangled_hash>:
Move from struct objfile.
<minsyms_read>: New field.
(struct objfile) <msymbols, minimal_symbol_count,
msymbol_hash, msymbol_demangled_hash>: Move.
(ALL_OBJFILE_MSYMBOLS): Update.
* symfile.c (read_symbols): Set minsyms_read.
(reread_symbols): Update.
* symmisc.c (dump_objfile, dump_msymbols): Update.

gdb/ChangeLog
gdb/minsyms.c
gdb/objfiles.c
gdb/objfiles.h
gdb/symfile.c
gdb/symmisc.c

index 76389ccf48094e0d8c12b8ab2f6b4e24ee9dd7e6..859a01c2dff4db7b4a692162991245a9aee32eb1 100644 (file)
@@ -1,3 +1,30 @@
+2014-02-26  Tom Tromey  <tromey@redhat.com>
+
+       * minsyms.c (lookup_minimal_symbol, iterate_over_minimal_symbols)
+       (lookup_minimal_symbol_text, lookup_minimal_symbol_by_pc_name)
+       (lookup_minimal_symbol_solib_trampoline)
+       (lookup_minimal_symbol_by_pc_section_1)
+       (lookup_minimal_symbol_and_objfile): Update.
+       (prim_record_minimal_symbol_full): Use the per-BFD obstack.
+       Don't allocate a minimal symbol if minsyms have already been read.
+       (build_minimal_symbol_hash_tables): Update.
+       (install_minimal_symbols): Do nothing if minsyms already read.
+       Use the per-BFD obstack.
+       (terminate_minimal_symbol_table): Use the per-BFD obstack.
+       * objfiles.c (allocate_objfile): Call
+       terminate_minimal_symbol_table later.
+       (have_minimal_symbols): Update.
+       * objfiles.h (struct objfile_per_bfd_storage) <msymbols,
+       minimal_symbol_count, msymbol_hash, msymbol_demangled_hash>:
+       Move from struct objfile.
+       <minsyms_read>: New field.
+       (struct objfile) <msymbols, minimal_symbol_count,
+       msymbol_hash, msymbol_demangled_hash>: Move.
+       (ALL_OBJFILE_MSYMBOLS): Update.
+       * symfile.c (read_symbols): Set minsyms_read.
+       (reread_symbols): Update.
+       * symmisc.c (dump_objfile, dump_msymbols): Update.
+
 2014-02-26  Tom Tromey  <tromey@redhat.com>
 
        * minsyms.c (msymbols_sort): Remove.
index df499a4b4ad9131a7ebf372402a0694b5e74fef9..1dc86eb70036187ca49fab6b57fd1a98988a57bd 100644 (file)
@@ -54,7 +54,7 @@
 
 /* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE.
    At the end, copy them all into one newly allocated location on an objfile's
-   symbol obstack.  */
+   per-BFD storage obstack.  */
 
 #define BUNCH_SIZE 127
 
@@ -207,9 +207,9 @@ lookup_minimal_symbol (const char *name, const char *sfile,
            {
             /* Select hash list according to pass.  */
             if (pass == 1)
-              msymbol = objfile->msymbol_hash[hash];
+              msymbol = objfile->per_bfd->msymbol_hash[hash];
             else
-              msymbol = objfile->msymbol_demangled_hash[dem_hash];
+              msymbol = objfile->per_bfd->msymbol_demangled_hash[dem_hash];
 
             while (msymbol != NULL && found_symbol.minsym == NULL)
                {
@@ -314,7 +314,7 @@ iterate_over_minimal_symbols (struct objfile *objf, const char *name,
 
   /* The first pass is over the ordinary hash table.  */
   hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
-  iter = objf->msymbol_hash[hash];
+  iter = objf->per_bfd->msymbol_hash[hash];
   cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp);
   while (iter)
     {
@@ -325,7 +325,7 @@ iterate_over_minimal_symbols (struct objfile *objf, const char *name,
 
   /* The second pass is over the demangled table.  */
   hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE;
-  iter = objf->msymbol_demangled_hash[hash];
+  iter = objf->per_bfd->msymbol_demangled_hash[hash];
   while (iter)
     {
       if (MSYMBOL_MATCHES_SEARCH_NAME (iter, name))
@@ -353,7 +353,7 @@ lookup_minimal_symbol_text (const char *name, struct objfile *objf)
       if (objf == NULL || objf == objfile
          || objf == objfile->separate_debug_objfile_backlink)
        {
-         for (msymbol = objfile->msymbol_hash[hash];
+         for (msymbol = objfile->per_bfd->msymbol_hash[hash];
               msymbol != NULL && found_symbol.minsym == NULL;
               msymbol = msymbol->hash_next)
            {
@@ -403,7 +403,7 @@ lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name,
       if (objf == NULL || objf == objfile
          || objf == objfile->separate_debug_objfile_backlink)
        {
-         for (msymbol = objfile->msymbol_hash[hash];
+         for (msymbol = objfile->per_bfd->msymbol_hash[hash];
               msymbol != NULL;
               msymbol = msymbol->hash_next)
            {
@@ -436,7 +436,7 @@ lookup_minimal_symbol_solib_trampoline (const char *name,
       if (objf == NULL || objf == objfile
          || objf == objfile->separate_debug_objfile_backlink)
        {
-         for (msymbol = objfile->msymbol_hash[hash];
+         for (msymbol = objfile->per_bfd->msymbol_hash[hash];
               msymbol != NULL;
               msymbol = msymbol->hash_next)
            {
@@ -532,13 +532,13 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc_in,
          "null symbol".  If there are no real symbols, then there is no
          minimal symbol table at all.  */
 
-      if (objfile->minimal_symbol_count > 0)
+      if (objfile->per_bfd->minimal_symbol_count > 0)
        {
          int best_zero_sized = -1;
 
-          msymbol = objfile->msymbols;
+          msymbol = objfile->per_bfd->msymbols;
          lo = 0;
-         hi = objfile->minimal_symbol_count - 1;
+         hi = objfile->per_bfd->minimal_symbol_count - 1;
 
          /* This code assumes that the minimal symbols are sorted by
             ascending address values.  If the pc value is greater than or
@@ -580,7 +580,7 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc_in,
              /* If we have multiple symbols at the same address, we want
                 hi to point to the last one.  That way we can find the
                 right symbol if it has an index greater than hi.  */
-             while (hi < objfile->minimal_symbol_count - 1
+             while (hi < objfile->per_bfd->minimal_symbol_count - 1
                     && (MSYMBOL_VALUE_RAW_ADDRESS (&msymbol[hi])
                         == MSYMBOL_VALUE_RAW_ADDRESS (&msymbol[hi + 1])))
                hi++;
@@ -836,7 +836,7 @@ lookup_minimal_symbol_and_objfile (const char *name)
     {
       struct minimal_symbol *msym;
 
-      for (msym = objfile->msymbol_hash[hash];
+      for (msym = objfile->per_bfd->msymbol_hash[hash];
           msym != NULL;
           msym = msym->hash_next)
        {
@@ -955,7 +955,8 @@ prim_record_minimal_symbol_full (const char *name, int name_len, int copy_name,
       msym_bunch = new;
     }
   msymbol = &msym_bunch->contents[msym_bunch_index];
-  MSYMBOL_SET_LANGUAGE (msymbol, language_auto, &objfile->objfile_obstack);
+  MSYMBOL_SET_LANGUAGE (msymbol, language_auto,
+                       &objfile->per_bfd->storage_obstack);
   MSYMBOL_SET_NAMES (msymbol, name, name_len, copy_name, objfile);
 
   SET_MSYMBOL_VALUE_ADDRESS (msymbol, address);
@@ -973,7 +974,10 @@ prim_record_minimal_symbol_full (const char *name, int name_len, int copy_name,
   msymbol->hash_next = NULL;
   msymbol->demangled_hash_next = NULL;
 
-  msym_bunch_index++;
+  /* If we already read minimal symbols for this objfile, then don't
+     ever allocate a new one.  */
+  if (!objfile->per_bfd->minsyms_read)
+    msym_bunch_index++;
   msym_count++;
   OBJSTAT (objfile, n_minsyms++);
   return msymbol;
@@ -1084,7 +1088,7 @@ make_cleanup_discard_minimal_symbols (void)
 
    Note that we are not concerned here about recovering the space that
    is potentially freed up, because the strings themselves are allocated
-   on the objfile_obstack, and will get automatically freed when the symbol
+   on the storage_obstack, and will get automatically freed when the symbol
    table is freed.  The caller can free up the unused minimal symbols at
    the end of the compacted region if their allocation strategy allows it.
 
@@ -1143,22 +1147,23 @@ build_minimal_symbol_hash_tables (struct objfile *objfile)
   /* Clear the hash tables.  */
   for (i = 0; i < MINIMAL_SYMBOL_HASH_SIZE; i++)
     {
-      objfile->msymbol_hash[i] = 0;
-      objfile->msymbol_demangled_hash[i] = 0;
+      objfile->per_bfd->msymbol_hash[i] = 0;
+      objfile->per_bfd->msymbol_demangled_hash[i] = 0;
     }
 
   /* Now, (re)insert the actual entries.  */
-  for (i = objfile->minimal_symbol_count, msym = objfile->msymbols;
+  for ((i = objfile->per_bfd->minimal_symbol_count,
+       msym = objfile->per_bfd->msymbols);
        i > 0;
        i--, msym++)
     {
       msym->hash_next = 0;
-      add_minsym_to_hash_table (msym, objfile->msymbol_hash);
+      add_minsym_to_hash_table (msym, objfile->per_bfd->msymbol_hash);
 
       msym->demangled_hash_next = 0;
       if (MSYMBOL_SEARCH_NAME (msym) != MSYMBOL_LINKAGE_NAME (msym))
        add_minsym_to_demangled_hash_table (msym,
-                                            objfile->msymbol_demangled_hash);
+                                            objfile->per_bfd->msymbol_demangled_hash);
     }
 }
 
@@ -1194,6 +1199,9 @@ install_minimal_symbols (struct objfile *objfile)
   struct minimal_symbol *msymbols;
   int alloc_count;
 
+  if (objfile->per_bfd->minsyms_read)
+    return;
+
   if (msym_count > 0)
     {
       if (symtab_create_debug)
@@ -1208,17 +1216,17 @@ install_minimal_symbols (struct objfile *objfile)
          compact out the duplicate entries.  Once we have a final table,
          we will give back the excess space.  */
 
-      alloc_count = msym_count + objfile->minimal_symbol_count + 1;
-      obstack_blank (&objfile->objfile_obstack,
+      alloc_count = msym_count + objfile->per_bfd->minimal_symbol_count + 1;
+      obstack_blank (&objfile->per_bfd->storage_obstack,
                     alloc_count * sizeof (struct minimal_symbol));
       msymbols = (struct minimal_symbol *)
-       obstack_base (&objfile->objfile_obstack);
+       obstack_base (&objfile->per_bfd->storage_obstack);
 
       /* Copy in the existing minimal symbols, if there are any.  */
 
-      if (objfile->minimal_symbol_count)
-       memcpy ((char *) msymbols, (char *) objfile->msymbols,
-           objfile->minimal_symbol_count * sizeof (struct minimal_symbol));
+      if (objfile->per_bfd->minimal_symbol_count)
+       memcpy ((char *) msymbols, (char *) objfile->per_bfd->msymbols,
+           objfile->per_bfd->minimal_symbol_count * sizeof (struct minimal_symbol));
 
       /* Walk through the list of minimal symbol bunches, adding each symbol
          to the new contiguous array of symbols.  Note that we start with the
@@ -1226,7 +1234,7 @@ install_minimal_symbols (struct objfile *objfile)
          msym_bunch_index for the first bunch we copy over), and thereafter
          each bunch is full.  */
 
-      mcount = objfile->minimal_symbol_count;
+      mcount = objfile->per_bfd->minimal_symbol_count;
 
       for (bunch = msym_bunch; bunch != NULL; bunch = bunch->next)
        {
@@ -1245,10 +1253,10 @@ install_minimal_symbols (struct objfile *objfile)
 
       mcount = compact_minimal_symbols (msymbols, mcount, objfile);
 
-      obstack_blank (&objfile->objfile_obstack,
+      obstack_blank (&objfile->per_bfd->storage_obstack,
               (mcount + 1 - alloc_count) * sizeof (struct minimal_symbol));
       msymbols = (struct minimal_symbol *)
-       obstack_finish (&objfile->objfile_obstack);
+       obstack_finish (&objfile->per_bfd->storage_obstack);
 
       /* We also terminate the minimal symbol table with a "null symbol",
          which is *not* included in the size of the table.  This makes it
@@ -1261,11 +1269,11 @@ install_minimal_symbols (struct objfile *objfile)
       memset (&msymbols[mcount], 0, sizeof (struct minimal_symbol));
 
       /* Attach the minimal symbol table to the specified objfile.
-         The strings themselves are also located in the objfile_obstack
+         The strings themselves are also located in the storage_obstack
          of this objfile.  */
 
-      objfile->minimal_symbol_count = mcount;
-      objfile->msymbols = msymbols;
+      objfile->per_bfd->minimal_symbol_count = mcount;
+      objfile->per_bfd->msymbols = msymbols;
 
       /* Now build the hash tables; we can't do this incrementally
          at an earlier point since we weren't finished with the obstack
@@ -1280,19 +1288,21 @@ install_minimal_symbols (struct objfile *objfile)
 void
 terminate_minimal_symbol_table (struct objfile *objfile)
 {
-  if (! objfile->msymbols)
-    objfile->msymbols = ((struct minimal_symbol *)
-                         obstack_alloc (&objfile->objfile_obstack,
-                                        sizeof (objfile->msymbols[0])));
+  if (! objfile->per_bfd->msymbols)
+    objfile->per_bfd->msymbols
+      = ((struct minimal_symbol *)
+        obstack_alloc (&objfile->per_bfd->storage_obstack,
+                       sizeof (struct minimal_symbol)));
 
   {
     struct minimal_symbol *m
-      = &objfile->msymbols[objfile->minimal_symbol_count];
+      = &objfile->per_bfd->msymbols[objfile->per_bfd->minimal_symbol_count];
 
     memset (m, 0, sizeof (*m));
     /* Don't rely on these enumeration values being 0's.  */
     MSYMBOL_TYPE (m) = mst_unknown;
-    MSYMBOL_SET_LANGUAGE (m, language_unknown, &objfile->objfile_obstack);
+    MSYMBOL_SET_LANGUAGE (m, language_unknown,
+                         &objfile->per_bfd->storage_obstack);
   }
 }
 
index f45656987ff9fcdbf2a3d131ddc56a5d3548e76c..83b896103892772690a1d9ade88a4c6219a2a55e 100644 (file)
@@ -294,7 +294,6 @@ allocate_objfile (bfd *abfd, const char *name, int flags)
   /* We could use obstack_specify_allocation here instead, but
      gdb_obstack.h specifies the alloc/dealloc functions.  */
   obstack_init (&objfile->objfile_obstack);
-  terminate_minimal_symbol_table (objfile);
 
   objfile_alloc_data (objfile);
 
@@ -334,6 +333,8 @@ allocate_objfile (bfd *abfd, const char *name, int flags)
   objfile->per_bfd = get_objfile_bfd_data (objfile, abfd);
   objfile->pspace = current_program_space;
 
+  terminate_minimal_symbol_table (objfile);
+
   /* Initialize the section indexes for this objfile, so that we can
      later detect if they are used w/o being properly assigned to.  */
 
@@ -1029,7 +1030,7 @@ have_minimal_symbols (void)
 
   ALL_OBJFILES (ofp)
   {
-    if (ofp->minimal_symbol_count > 0)
+    if (ofp->per_bfd->minimal_symbol_count > 0)
       {
        return 1;
       }
index 64a371d247e9fa4743a8bfe057623716ad97b9da..d585bc47794a9e504d11a90e5cb24db0387212e1 100644 (file)
@@ -210,6 +210,38 @@ struct objfile_per_bfd_storage
 
   const char *name_of_main;
   enum language language_of_main;
+
+  /* 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
+     name and a zero value for the address.  This makes it easy to walk
+     through the array when passed a pointer to somewhere in the middle
+     of it.  There is also a count of the number of symbols, which does
+     not include the terminating null symbol.  The array itself, as well
+     as all the data that it points to, should be allocated on the
+     objfile_obstack for this file.  */
+
+  struct minimal_symbol *msymbols;
+  int minimal_symbol_count;
+
+  /* This is true if minimal symbols have already been read.  Symbol
+     readers can use this to bypass minimal symbol reading.  Also, the
+     minimal symbol table management code in minsyms.c uses this to
+     suppress new minimal symbols.  You might think that MSYMBOLS or
+     MINIMAL_SYMBOL_COUNT could be used for this, but it is possible
+     for multiple readers to install minimal symbols into a given
+     per-BFD.  */
+
+  unsigned int minsyms_read : 1;
+
+  /* This is a hash table used to index the minimal symbols by name.  */
+
+  struct minimal_symbol *msymbol_hash[MINIMAL_SYMBOL_HASH_SIZE];
+
+  /* This hash table is used to index the minimal symbols by their
+     demangled names.  */
+
+  struct minimal_symbol *msymbol_demangled_hash[MINIMAL_SYMBOL_HASH_SIZE];
 };
 
 /* Master structure for keeping track of each file from which
@@ -303,28 +335,6 @@ struct objfile
     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
-       name and a zero value for the address.  This makes it easy to walk
-       through the array when passed a pointer to somewhere in the middle
-       of it.  There is also a count of the number of symbols, which does
-       not include the terminating null symbol.  The array itself, as well
-       as all the data that it points to, should be allocated on the
-       objfile_obstack for this file.  */
-
-    struct minimal_symbol *msymbols;
-    int minimal_symbol_count;
-
-    /* This is a hash table used to index the minimal symbols by name.  */
-
-    struct minimal_symbol *msymbol_hash[MINIMAL_SYMBOL_HASH_SIZE];
-
-    /* This hash table is used to index the minimal symbols by their
-       demangled names.  */
-
-    struct minimal_symbol *msymbol_demangled_hash[MINIMAL_SYMBOL_HASH_SIZE];
-
     /* 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
@@ -588,8 +598,10 @@ extern void default_iterate_over_objfiles_in_search_order
 
 /* Traverse all minimal symbols in one objfile.  */
 
-#define        ALL_OBJFILE_MSYMBOLS(objfile, m) \
-    for ((m) = (objfile) -> msymbols; MSYMBOL_LINKAGE_NAME(m) != NULL; (m)++)
+#define        ALL_OBJFILE_MSYMBOLS(objfile, m)        \
+    for ((m) = (objfile)->per_bfd->msymbols;   \
+        MSYMBOL_LINKAGE_NAME (m) != NULL;      \
+        (m)++)
 
 /* Traverse all symtabs in all objfiles in the current symbol
    space.  */
index d5cb7cb227d3513bb5659196037de92ba69d273f..aee7ef53595a17dd345bc364225d7b2e6044f3cf 100644 (file)
@@ -836,6 +836,7 @@ static void
 read_symbols (struct objfile *objfile, int add_flags)
 {
   (*objfile->sf->sym_read) (objfile, add_flags);
+  objfile->per_bfd->minsyms_read = 1;
 
   /* find_separate_debug_file_in_section should be called only if there is
      single binary with no existing separate debug info file.  */
@@ -2608,12 +2609,6 @@ reread_symbols (void)
          objfile->psymtabs_addrmap = NULL;
          objfile->free_psymtabs = NULL;
          objfile->template_symbols = NULL;
-         objfile->msymbols = NULL;
-         objfile->minimal_symbol_count = 0;
-         memset (&objfile->msymbol_hash, 0,
-                 sizeof (objfile->msymbol_hash));
-         memset (&objfile->msymbol_demangled_hash, 0,
-                 sizeof (objfile->msymbol_demangled_hash));
 
          /* obstack_init also initializes the obstack so it is
             empty.  We could use obstack_specify_allocation but
index 0fc78d540dcc887493e2166466ac45d620acbaef..eb15ecc1bbd60de15d3dcd600e9e8d1c5d60cd23 100644 (file)
@@ -168,7 +168,7 @@ dump_objfile (struct objfile *objfile)
   printf_filtered (", bfd at ");
   gdb_print_host_address (objfile->obfd, gdb_stdout);
   printf_filtered (", %d minsyms\n\n",
-                  objfile->minimal_symbol_count);
+                  objfile->per_bfd->minimal_symbol_count);
 
   if (objfile->sf)
     objfile->sf->qf->dump (objfile);
@@ -204,7 +204,7 @@ dump_msymbols (struct objfile *objfile, struct ui_file *outfile)
   char ms_type;
 
   fprintf_filtered (outfile, "\nObject file %s:\n\n", objfile_name (objfile));
-  if (objfile->minimal_symbol_count == 0)
+  if (objfile->per_bfd->minimal_symbol_count == 0)
     {
       fprintf_filtered (outfile, "No minimal symbols found.\n");
       return;
@@ -274,10 +274,10 @@ dump_msymbols (struct objfile *objfile, struct ui_file *outfile)
       fputs_filtered ("\n", outfile);
       index++;
     }
-  if (objfile->minimal_symbol_count != index)
+  if (objfile->per_bfd->minimal_symbol_count != index)
     {
       warning (_("internal error:  minimal symbol count %d != %d"),
-              objfile->minimal_symbol_count, index);
+              objfile->per_bfd->minimal_symbol_count, index);
     }
   fprintf_filtered (outfile, "\n");
 }