* dwarf2read.c (ABBREV_HASH_SIZE): Remove enclosing #ifndef/#endif.
authorDoug Evans <dje@google.com>
Fri, 29 Jun 2012 00:06:18 +0000 (00:06 +0000)
committerDoug Evans <dje@google.com>
Fri, 29 Jun 2012 00:06:18 +0000 (00:06 +0000)
(struct abbrev_table): Define.
(dwarf2_cu): Replace members dwarf2_abbrevs, abbrev_obstack with
abbrev_table.
(init_cutu_and_read_dies): Update.
(abbrev_table_alloc_abbrev): New function.  Replaces
dwarf_alloc_abbrev.  All callers updated.
(abbrev_table_add_abbrev): New function.
(abbrev_table_lookup_abbrev): New function.  Replaces
dwarf2_lookup_abbrev.  All callers updated.
(abbrev_table_read_table): New function.  Contents moved here from
dwarf2_read_abbrevs.
(dwarf2_read_abbrevs): Call it.
(abbrev_table_free): New function.
(dwarf2_free_abbrev_table): Call it.

gdb/ChangeLog
gdb/dwarf2read.c

index 0239a30..3a619ff 100644 (file)
@@ -1,3 +1,21 @@
+2012-06-28  Doug Evans  <dje@google.com>
+
+       * dwarf2read.c (ABBREV_HASH_SIZE): Remove enclosing #ifndef/#endif.
+       (struct abbrev_table): Define.
+       (dwarf2_cu): Replace members dwarf2_abbrevs, abbrev_obstack with
+       abbrev_table.
+       (init_cutu_and_read_dies): Update.
+       (abbrev_table_alloc_abbrev): New function.  Replaces
+       dwarf_alloc_abbrev.  All callers updated.
+       (abbrev_table_add_abbrev): New function.
+       (abbrev_table_lookup_abbrev): New function.  Replaces
+       dwarf2_lookup_abbrev.  All callers updated.
+       (abbrev_table_read_table): New function.  Contents moved here from
+       dwarf2_read_abbrevs.
+       (dwarf2_read_abbrevs): Call it.
+       (abbrev_table_free): New function.
+       (dwarf2_free_abbrev_table): Call it.
+
 2012-06-28  Stan Shebs  <stan@codesourcery.com>
 
        * osdata.c (info_osdata_command): Filter out "Title" columns
index 4744107..e3b3963 100644 (file)
@@ -310,11 +310,6 @@ dwo_section_names =
 
 /* local data types */
 
-/* We hold several abbreviation tables in memory at the same time.  */
-#ifndef ABBREV_HASH_SIZE
-#define ABBREV_HASH_SIZE 121
-#endif
-
 /* The data in a compilation unit header, after target2host
    translation, looks like this.  */
 struct comp_unit_head
@@ -395,11 +390,10 @@ struct dwarf2_cu
      distinguish these in buildsym.c.  */
   struct pending **list_in_scope;
 
-  /* DWARF abbreviation table associated with this compilation unit.  */
-  struct abbrev_info **dwarf2_abbrevs;
-
-  /* Storage for the abbrev table.  */
-  struct obstack abbrev_obstack;
+  /* The abbrev table for this CU.
+     Normally this points to the abbrev table in the objfile.
+     But if DWO_UNIT is non-NULL this is the abbrev table in the DWO file.  */
+  struct abbrev_table *abbrev_table;
 
   /* Hash table holding all the loaded partial DIEs
      with partial_die->offset.SECT_OFF as hash.  */
@@ -801,6 +795,27 @@ struct attr_abbrev
     ENUM_BITFIELD(dwarf_form) form : 16;
   };
 
+/* Size of abbrev_table.abbrev_hash_table.  */
+#define ABBREV_HASH_SIZE 121
+
+/* Top level data structure to contain an abbreviation table.  */
+
+struct abbrev_table
+{
+  /* Where the abbrev table came from.  */
+  struct dwarf2_section_info *section;
+  sect_offset offset;
+
+  /* Storage for the abbrev table.  */
+  struct obstack abbrev_obstack;
+
+  /* Hash table of abbrevs.
+     This is an array of size ABBREV_HASH_SIZE allocated in abbrev_obstack.
+     It could be statically allocated, but the previous code didn't so we
+     don't either.  */
+  struct abbrev_info **abbrevs;
+};
+
 /* Attributes have a name and a value.  */
 struct attribute
   {
@@ -1080,6 +1095,14 @@ static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
 
 static void psymtab_to_symtab_1 (struct partial_symtab *);
 
+static struct abbrev_info *abbrev_table_lookup_abbrev
+  (const struct abbrev_table *, unsigned int);
+
+static struct abbrev_table *abbrev_table_read_table
+  (struct dwarf2_section_info *, sect_offset);
+
+static void abbrev_table_free (struct abbrev_table *);
+
 static void dwarf2_read_abbrevs (struct dwarf2_cu *,
                                 struct dwarf2_section_info *);
 
@@ -1087,12 +1110,6 @@ static void dwarf2_free_abbrev_table (void *);
 
 static unsigned int peek_abbrev_code (bfd *, gdb_byte *);
 
-static struct abbrev_info *peek_die_abbrev (gdb_byte *, unsigned int *,
-                                           struct dwarf2_cu *);
-
-static struct abbrev_info *dwarf2_lookup_abbrev (unsigned int,
-                                                struct dwarf2_cu *);
-
 static struct partial_die_info *load_partial_dies
   (const struct die_reader_specs *, gdb_byte *, int);
 
@@ -1373,8 +1390,6 @@ static void read_signatured_type (struct signatured_type *);
 
 static struct dwarf_block *dwarf_alloc_block (struct dwarf2_cu *);
 
-static struct abbrev_info *dwarf_alloc_abbrev (struct dwarf2_cu *);
-
 static struct die_info *dwarf_alloc_die (struct dwarf2_cu *, int);
 
 static void dwarf_decode_macros (struct dwarf2_cu *, unsigned int,
@@ -3951,8 +3966,10 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
       return;
     }
 
-  /* Read the abbrevs for this compilation unit into a table.  */
-  if (cu->dwarf2_abbrevs == NULL)
+  /* If we don't have them yet, read the abbrevs for this compilation unit.
+     And if we need to read them now, make sure they're freed when we're
+     done.  */
+  if (cu->abbrev_table == NULL)
     {
       dwarf2_read_abbrevs (cu, abbrev_section);
       make_cleanup (dwarf2_free_abbrev_table, cu);
@@ -5168,7 +5185,7 @@ peek_die_abbrev (gdb_byte *info_ptr, unsigned int *bytes_read,
   if (abbrev_number == 0)
     return NULL;
 
-  abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
+  abbrev = abbrev_table_lookup_abbrev (cu->abbrev_table, abbrev_number);
   if (!abbrev)
     {
       error (_("Dwarf Error: Could not find abbrev number %d [in module %s]"),
@@ -10923,7 +10940,7 @@ read_full_die_1 (const struct die_reader_specs *reader,
       return info_ptr;
     }
 
-  abbrev = dwarf2_lookup_abbrev (abbrev_number, cu);
+  abbrev = abbrev_table_lookup_abbrev (cu->abbrev_table, abbrev_number);
   if (!abbrev)
     error (_("Dwarf Error: could not find abbrev number %d [in module %s]"),
           abbrev_number,
@@ -10960,37 +10977,89 @@ read_full_die (const struct die_reader_specs *reader,
 {
   return read_full_die_1 (reader, diep, info_ptr, has_children, 0);
 }
+\f
+/* Abbreviation tables.
 
-/* In DWARF version 2, the description of the debugging information is
+   In DWARF version 2, the description of the debugging information is
    stored in a separate .debug_abbrev section.  Before we read any
    dies from a section we read in all abbreviations and install them
-   in a hash table.  This function also sets flags in CU describing
-   the data found in the abbrev table.  */
+   in a hash table.  */
+
+/* Allocate space for a struct abbrev_info object in ABBREV_TABLE.  */
+
+static struct abbrev_info *
+abbrev_table_alloc_abbrev (struct abbrev_table *abbrev_table)
+{
+  struct abbrev_info *abbrev;
+
+  abbrev = (struct abbrev_info *)
+    obstack_alloc (&abbrev_table->abbrev_obstack, sizeof (struct abbrev_info));
+  memset (abbrev, 0, sizeof (struct abbrev_info));
+  return abbrev;
+}
+
+/* Add an abbreviation to the table.  */
 
 static void
-dwarf2_read_abbrevs (struct dwarf2_cu *cu,
-                    struct dwarf2_section_info *abbrev_section)
+abbrev_table_add_abbrev (struct abbrev_table *abbrev_table,
+                        unsigned int abbrev_number,
+                        struct abbrev_info *abbrev)
+{
+  unsigned int hash_number;
+
+  hash_number = abbrev_number % ABBREV_HASH_SIZE;
+  abbrev->next = abbrev_table->abbrevs[hash_number];
+  abbrev_table->abbrevs[hash_number] = abbrev;
+}
 
+/* Look up an abbrev in the table.
+   Returns NULL if the abbrev is not found.  */
+
+static struct abbrev_info *
+abbrev_table_lookup_abbrev (const struct abbrev_table *abbrev_table,
+                           unsigned int abbrev_number)
 {
-  bfd *abfd = abbrev_section->asection->owner;
-  struct comp_unit_head *cu_header = &cu->header;
+  unsigned int hash_number;
+  struct abbrev_info *abbrev;
+
+  hash_number = abbrev_number % ABBREV_HASH_SIZE;
+  abbrev = abbrev_table->abbrevs[hash_number];
+
+  while (abbrev)
+    {
+      if (abbrev->number == abbrev_number)
+       return abbrev;
+      abbrev = abbrev->next;
+    }
+  return NULL;
+}
+
+/* Read in an abbrev table.  */
+
+static struct abbrev_table *
+abbrev_table_read_table (struct dwarf2_section_info *section,
+                        sect_offset offset)
+{
+  struct objfile *objfile = dwarf2_per_objfile->objfile;
+  bfd *abfd = section->asection->owner;
+  struct abbrev_table *abbrev_table;
   gdb_byte *abbrev_ptr;
   struct abbrev_info *cur_abbrev;
   unsigned int abbrev_number, bytes_read, abbrev_name;
-  unsigned int abbrev_form, hash_number;
+  unsigned int abbrev_form;
   struct attr_abbrev *cur_attrs;
   unsigned int allocated_attrs;
 
-  /* Initialize dwarf2 abbrevs.  */
-  obstack_init (&cu->abbrev_obstack);
-  cu->dwarf2_abbrevs = obstack_alloc (&cu->abbrev_obstack,
-                                     (ABBREV_HASH_SIZE
-                                      * sizeof (struct abbrev_info *)));
-  memset (cu->dwarf2_abbrevs, 0,
-          ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
+  abbrev_table = XMALLOC (struct abbrev_table);
+  obstack_init (&abbrev_table->abbrev_obstack);
+  abbrev_table->abbrevs = obstack_alloc (&abbrev_table->abbrev_obstack,
+                                        (ABBREV_HASH_SIZE
+                                         * sizeof (struct abbrev_info *)));
+  memset (abbrev_table->abbrevs, 0,
+         ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
 
-  dwarf2_read_section (cu->objfile, abbrev_section);
-  abbrev_ptr = abbrev_section->buffer + cu_header->abbrev_offset.sect_off;
+  dwarf2_read_section (objfile, section);
+  abbrev_ptr = section->buffer + offset.sect_off;
   abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
   abbrev_ptr += bytes_read;
 
@@ -11000,7 +11069,7 @@ dwarf2_read_abbrevs (struct dwarf2_cu *cu,
   /* Loop until we reach an abbrev number of 0.  */
   while (abbrev_number)
     {
-      cur_abbrev = dwarf_alloc_abbrev (cu);
+      cur_abbrev = abbrev_table_alloc_abbrev (abbrev_table);
 
       /* read in abbrev header */
       cur_abbrev->number = abbrev_number;
@@ -11032,15 +11101,13 @@ dwarf2_read_abbrevs (struct dwarf2_cu *cu,
          abbrev_ptr += bytes_read;
        }
 
-      cur_abbrev->attrs = obstack_alloc (&cu->abbrev_obstack,
+      cur_abbrev->attrs = obstack_alloc (&abbrev_table->abbrev_obstack,
                                         (cur_abbrev->num_attrs
                                          * sizeof (struct attr_abbrev)));
       memcpy (cur_abbrev->attrs, cur_attrs,
              cur_abbrev->num_attrs * sizeof (struct attr_abbrev));
 
-      hash_number = abbrev_number % ABBREV_HASH_SIZE;
-      cur_abbrev->next = cu->dwarf2_abbrevs[hash_number];
-      cu->dwarf2_abbrevs[hash_number] = cur_abbrev;
+      abbrev_table_add_abbrev (abbrev_table, abbrev_number, cur_abbrev);
 
       /* Get next abbreviation.
          Under Irix6 the abbreviations for a compilation unit are not
@@ -11049,50 +11116,51 @@ dwarf2_read_abbrevs (struct dwarf2_cu *cu,
          already read (which means we are about to read the abbreviations
          for the next compile unit) or if the end of the abbreviation
          table is reached.  */
-      if ((unsigned int) (abbrev_ptr - abbrev_section->buffer)
-         >= abbrev_section->size)
+      if ((unsigned int) (abbrev_ptr - section->buffer) >= section->size)
        break;
       abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
       abbrev_ptr += bytes_read;
-      if (dwarf2_lookup_abbrev (abbrev_number, cu) != NULL)
+      if (abbrev_table_lookup_abbrev (abbrev_table, abbrev_number) != NULL)
        break;
     }
 
   xfree (cur_attrs);
+  return abbrev_table;
 }
 
-/* Release the memory used by the abbrev table for a compilation unit.  */
+/* Free the resources held by ABBREV_TABLE.  */
 
 static void
-dwarf2_free_abbrev_table (void *ptr_to_cu)
+abbrev_table_free (struct abbrev_table *abbrev_table)
 {
-  struct dwarf2_cu *cu = ptr_to_cu;
-
-  obstack_free (&cu->abbrev_obstack, NULL);
-  cu->dwarf2_abbrevs = NULL;
+  obstack_free (&abbrev_table->abbrev_obstack, NULL);
+  xfree (abbrev_table);
 }
 
-/* Lookup an abbrev_info structure in the abbrev hash table.  */
+/* Read the abbrev table for CU from ABBREV_SECTION.  */
+
+static void
+dwarf2_read_abbrevs (struct dwarf2_cu *cu,
+                    struct dwarf2_section_info *abbrev_section)
 
-static struct abbrev_info *
-dwarf2_lookup_abbrev (unsigned int number, struct dwarf2_cu *cu)
 {
-  unsigned int hash_number;
-  struct abbrev_info *abbrev;
+  cu->abbrev_table =
+    abbrev_table_read_table (abbrev_section, cu->header.abbrev_offset);
+}
 
-  hash_number = number % ABBREV_HASH_SIZE;
-  abbrev = cu->dwarf2_abbrevs[hash_number];
+/* Release the memory used by the abbrev table for a compilation unit.  */
 
-  while (abbrev)
-    {
-      if (abbrev->number == number)
-       return abbrev;
-      else
-       abbrev = abbrev->next;
-    }
-  return NULL;
-}
+static void
+dwarf2_free_abbrev_table (void *ptr_to_cu)
+{
+  struct dwarf2_cu *cu = ptr_to_cu;
 
+  abbrev_table_free (cu->abbrev_table);
+  /* Set this to NULL so that we SEGV if we try to read it later,
+     and also because free_comp_unit verifies this is NULL.  */
+  cu->abbrev_table = NULL;
+}
+\f
 /* Returns nonzero if TAG represents a type that we might generate a partial
    symbol for.  */
 
@@ -15736,17 +15804,6 @@ dwarf_alloc_block (struct dwarf2_cu *cu)
   return (blk);
 }
 
-static struct abbrev_info *
-dwarf_alloc_abbrev (struct dwarf2_cu *cu)
-{
-  struct abbrev_info *abbrev;
-
-  abbrev = (struct abbrev_info *)
-    obstack_alloc (&cu->abbrev_obstack, sizeof (struct abbrev_info));
-  memset (abbrev, 0, sizeof (struct abbrev_info));
-  return (abbrev);
-}
-
 static struct die_info *
 dwarf_alloc_die (struct dwarf2_cu *cu, int num_attrs)
 {