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]

Re: [RFA, doc RFA] Work around binutils/15021


Tom Tromey writes:
 > >>>>> "Doug" == Doug Evans <dje@google.com> writes:
 > 
 > Doug> Regression tested with gdb-generated .gdb_index version 7 (by hacking the
 > Doug> gdb-under-test to generate version 7), version 8, with dwz, and with gold.
 > 
 > I think index version bumps require a documentation update and also a
 > binutils patch.
 > 
 > Doug> 	Work around binutils/15021
 > 
 > IIUC, the version bump is part of the workaround for the gold bug,
 > right?  The idea being that gold will generate version 7 indices,
 > causing gdb to take the "inclusion" path.  (I'm just trying to make sure
 > I understand what is going on.)
 > 
 > Doug> +     This is also used to work around a difference between the way gold
 > Doug> +     generates .gdb_index version <=7 and the way gdb does.  Arguably this
 > Doug> +     is a gold bug.
 > 
 > To me it doesn't seem arguable, but I'm curious to know what the case is
 > for it not being a gold bug.
 > 
 > Doug> @@ -19634,7 +19660,7 @@ dwarf2_per_objfile_free (struct objfile 
 >  
 > Doug>    for (ix = 0; ix < dwarf2_per_objfile->n_comp_units; ++ix)
 > Doug>      VEC_free (dwarf2_per_cu_ptr,
 > Doug> -	      dwarf2_per_objfile->all_comp_units[ix]->s.imported_symtabs);
 > Doug> +	      dwarf2_per_objfile->all_comp_units[ix]->imported_symtabs);
 > 
 > If follow_die_sig can be called when one TU refers to another TU, then
 > it seems like the TU could have a non-empty 'imported_symtabs', meaning
 > that the loop here should also iterate over TUs.

How's this?

Eli, this has a doc change.

2013-01-17  Doug Evans  <dje@google.com>

	Work around binutils/15021
	* dwarf2read.c (dwarf2_per_cu_data): Split imported_symtabs and
	type_unit_group out of union s.  All uses updated.
	(read_index_from_section): Watch for index version 8.
	(follow_die_sig): If using .gdb_index version <= 7, record the TU as
	an imported symtab.
	(write_psymtabs_to_index): Increment version number to 8.

	doc/
	* gdb.texinfo (Index Section Format): Document .gdb_index version 8.

Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.731
diff -u -p -r1.731 dwarf2read.c
--- dwarf2read.c	15 Jan 2013 21:32:36 -0000	1.731
+++ dwarf2read.c	17 Jan 2013 20:57:32 -0000
@@ -566,19 +566,29 @@ struct dwarf2_per_cu_data
     struct dwarf2_per_cu_quick_data *quick;
   } v;
 
-  union
-  {
-    /* The CUs we import using DW_TAG_imported_unit.  This is filled in
-       while reading psymtabs, used to compute the psymtab dependencies,
-       and then cleared.  Then it is filled in again while reading full
-       symbols, and only deleted when the objfile is destroyed.  */
-    VEC (dwarf2_per_cu_ptr) *imported_symtabs;
-
-    /* Type units are grouped by their DW_AT_stmt_list entry so that they
-       can share them.  If this is a TU, this points to the containing
-       symtab.  */
-    struct type_unit_group *type_unit_group;
-  } s;
+  /* The CUs we import using DW_TAG_imported_unit.  This is filled in
+     while reading psymtabs, used to compute the psymtab dependencies,
+     and then cleared.  Then it is filled in again while reading full
+     symbols, and only deleted when the objfile is destroyed.
+
+     This is also used to work around a difference between the way gold
+     generates .gdb_index version <=7 and the way gdb does.  Arguably this
+     is a gold bug.  For symbols coming from TUs, gold records in the index
+     the CU that includes the TU instead of the TU itself.  This breaks
+     dw2_lookup_symbol: It assumes that if the index says symbol X lives
+     in CU/TU Y, then one need only expand Y and a subsequent lookup in Y
+     will find X.  Alas TUs live in their own symtab, so after expanding CU Y
+     we need to look in TU Z to find X.  Fortunately, this is akin to
+     DW_TAG_imported_unit, so we just use the same mechanism: For
+     .gdb_index version <=7 this also records the TUs that the CU referred
+     to.  Concurrently with this change gdb was modified to emit version 8
+     indices so we only pay a price for gold generated indices.  */
+  VEC (dwarf2_per_cu_ptr) *imported_symtabs;
+
+  /* Type units are grouped by their DW_AT_stmt_list entry so that they
+     can share them.  If this is a TU, this points to the containing
+     symtab.  */
+  struct type_unit_group *type_unit_group;
 };
 
 /* Entry in the signatured_types hash table.  */
@@ -2690,9 +2700,14 @@ to use the section anyway."),
 	}
       return 0;
     }
+  /* Version 7 indices generated by gold refer to the CU for a symbol instead
+     of the TU (for symbols coming from TUs).  It's just a performance bug, and
+     we can't distinguish gdb-generated indices from gold-generated ones, so
+     nothing to do here.  */
+
   /* Indexes with higher version than the one supported by GDB may be no
      longer backward compatible.  */
-  if (version > 7)
+  if (version > 8)
     return 0;
 
   map->version = version;
@@ -2963,7 +2978,7 @@ dw2_get_file_names (struct objfile *objf
      DWO file.  */
   if (this_cu->is_debug_types)
     {
-      struct type_unit_group *tu_group = this_cu->s.type_unit_group;
+      struct type_unit_group *tu_group = this_cu->type_unit_group;
 
       init_cutu_and_read_dies (tu_group->t.first_tu, NULL, 0, 0,
 			       dw2_get_file_names_reader, tu_group);
@@ -4994,10 +5009,10 @@ process_psymtab_comp_unit_reader (const 
     (objfile->static_psymbols.list + pst->statics_offset);
   sort_pst_symbols (objfile, pst);
 
-  if (!VEC_empty (dwarf2_per_cu_ptr, cu->per_cu->s.imported_symtabs))
+  if (!VEC_empty (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs))
     {
       int i;
-      int len = VEC_length (dwarf2_per_cu_ptr, cu->per_cu->s.imported_symtabs);
+      int len = VEC_length (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs);
       struct dwarf2_per_cu_data *iter;
 
       /* Fill in 'dependencies' here; we fill in 'users' in a
@@ -5006,12 +5021,12 @@ process_psymtab_comp_unit_reader (const 
       pst->dependencies = obstack_alloc (&objfile->objfile_obstack,
 					 len * sizeof (struct symtab *));
       for (i = 0;
-	   VEC_iterate (dwarf2_per_cu_ptr, cu->per_cu->s.imported_symtabs,
+	   VEC_iterate (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
 			i, iter);
 	   ++i)
 	pst->dependencies[i] = iter->v.psymtab;
 
-      VEC_free (dwarf2_per_cu_ptr, cu->per_cu->s.imported_symtabs);
+      VEC_free (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs);
     }
 
   /* Get the list of files included in the current compilation unit,
@@ -5109,7 +5124,7 @@ create_type_unit_group (struct dwarf2_cu
   per_cu = &tu_group->per_cu;
   per_cu->objfile = objfile;
   per_cu->is_debug_types = 1;
-  per_cu->s.type_unit_group = tu_group;
+  per_cu->type_unit_group = tu_group;
 
   if (dwarf2_per_objfile->using_index)
     {
@@ -5446,7 +5461,7 @@ build_type_psymtab_dependencies (void **
        ++i)
     {
       pst->dependencies[i] = iter->v.psymtab;
-      iter->s.type_unit_group = tu_group;
+      iter->type_unit_group = tu_group;
     }
 
   VEC_free (dwarf2_per_cu_ptr, tu_group->t.tus);
@@ -5767,7 +5782,7 @@ scan_partial_symbols (struct partial_die
 		  process_psymtab_comp_unit (per_cu, 1);
 
 		VEC_safe_push (dwarf2_per_cu_ptr,
-			       cu->per_cu->s.imported_symtabs, per_cu);
+			       cu->per_cu->imported_symtabs, per_cu);
 	      }
 	      break;
 	    default:
@@ -6899,7 +6914,7 @@ recursively_compute_inclusions (VEC (dwa
     VEC_safe_push (dwarf2_per_cu_ptr, *result, per_cu);
 
   for (ix = 0;
-       VEC_iterate (dwarf2_per_cu_ptr, per_cu->s.imported_symtabs, ix, iter);
+       VEC_iterate (dwarf2_per_cu_ptr, per_cu->imported_symtabs, ix, iter);
        ++ix)
     recursively_compute_inclusions (result, all_children, iter);
 }
@@ -6912,7 +6927,7 @@ compute_symtab_includes (struct dwarf2_p
 {
   gdb_assert (! per_cu->is_debug_types);
 
-  if (!VEC_empty (dwarf2_per_cu_ptr, per_cu->s.imported_symtabs))
+  if (!VEC_empty (dwarf2_per_cu_ptr, per_cu->imported_symtabs))
     {
       int ix, len;
       struct dwarf2_per_cu_data *iter;
@@ -6928,13 +6943,14 @@ compute_symtab_includes (struct dwarf2_p
 					NULL, xcalloc, xfree);
 
       for (ix = 0;
-	   VEC_iterate (dwarf2_per_cu_ptr, per_cu->s.imported_symtabs,
+	   VEC_iterate (dwarf2_per_cu_ptr, per_cu->imported_symtabs,
 			ix, iter);
 	   ++ix)
 	recursively_compute_inclusions (&result_children, all_children, iter);
 
-      /* Now we have a transitive closure of all the included CUs, so
-	 we can convert it to a list of symtabs.  */
+      /* Now we have a transitive closure of all the included CUs, and
+	 for .gdb_index version 7 the included TUs, so we can convert it
+	 to a list of symtabs.  */
       len = VEC_length (dwarf2_per_cu_ptr, result_children);
       symtab->includes
 	= obstack_alloc (&dwarf2_per_objfile->objfile->objfile_obstack,
@@ -7017,7 +7033,7 @@ process_full_comp_unit (struct dwarf2_pe
 
   static_block
     = end_symtab_get_static_block (highpc + baseaddr, objfile, 0,
-				   per_cu->s.imported_symtabs != NULL);
+				   per_cu->imported_symtabs != NULL);
 
   /* If the comp unit has DW_AT_ranges, it may have discontiguous ranges.
      Also, DW_AT_ranges may record ranges not belonging to any child DIEs
@@ -7113,10 +7129,10 @@ process_full_type_unit (struct dwarf2_pe
      If this is the first TU to use this symtab, complete the construction
      of it with end_expandable_symtab.  Otherwise, complete the addition of
      this TU's symbols to the existing symtab.  */
-  if (per_cu->s.type_unit_group->primary_symtab == NULL)
+  if (per_cu->type_unit_group->primary_symtab == NULL)
     {
       symtab = end_expandable_symtab (0, objfile, SECT_OFF_TEXT (objfile));
-      per_cu->s.type_unit_group->primary_symtab = symtab;
+      per_cu->type_unit_group->primary_symtab = symtab;
 
       if (symtab != NULL)
 	{
@@ -7131,8 +7147,8 @@ process_full_type_unit (struct dwarf2_pe
   else
     {
       augment_type_symtab (objfile,
-			   per_cu->s.type_unit_group->primary_symtab);
-      symtab = per_cu->s.type_unit_group->primary_symtab;
+			   per_cu->type_unit_group->primary_symtab);
+      symtab = per_cu->type_unit_group->primary_symtab;
     }
 
   if (dwarf2_per_objfile->using_index)
@@ -7178,7 +7194,7 @@ process_imported_unit_die (struct die_in
       if (maybe_queue_comp_unit (cu, per_cu, cu->language))
 	load_full_comp_unit (per_cu, cu->language);
 
-      VEC_safe_push (dwarf2_per_cu_ptr, cu->per_cu->s.imported_symtabs,
+      VEC_safe_push (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
 		     per_cu);
     }
 }
@@ -8067,9 +8083,9 @@ setup_type_unit_groups (struct die_info 
 
   /* If we're using .gdb_index (includes -readnow) then
      per_cu->s.type_unit_group may not have been set up yet.  */
-  if (per_cu->s.type_unit_group == NULL)
-    per_cu->s.type_unit_group = get_type_unit_group (cu, attr);
-  tu_group = per_cu->s.type_unit_group;
+  if (per_cu->type_unit_group == NULL)
+    per_cu->type_unit_group = get_type_unit_group (cu, attr);
+  tu_group = per_cu->type_unit_group;
 
   /* If we've already processed this stmt_list there's no real need to
      do it again, we could fake it and just recreate the part we need
@@ -17620,6 +17636,16 @@ follow_die_sig (struct die_info *src_die
 			     temp_die.offset.sect_off);
   if (die)
     {
+      /* For .gdb_index version 7 keep track of included TUs.
+	 http://sourceware.org/bugzilla/show_bug.cgi?id=15021.  */
+      if (dwarf2_per_objfile->index_table != NULL
+	  && dwarf2_per_objfile->index_table->version <= 7)
+	{
+	  VEC_safe_push (dwarf2_per_cu_ptr,
+			 (*ref_cu)->per_cu->imported_symtabs,
+			 sig_cu->per_cu);
+	}
+
       *ref_cu = sig_cu;
       return die;
     }
@@ -19670,7 +19696,11 @@ dwarf2_per_objfile_free (struct objfile 
 
   for (ix = 0; ix < dwarf2_per_objfile->n_comp_units; ++ix)
     VEC_free (dwarf2_per_cu_ptr,
-	      dwarf2_per_objfile->all_comp_units[ix]->s.imported_symtabs);
+	      dwarf2_per_objfile->all_comp_units[ix]->imported_symtabs);
+
+  for (ix = 0; ix < dwarf2_per_objfile->n_type_units; ++ix)
+    VEC_free (dwarf2_per_cu_ptr,
+	      dwarf2_per_objfile->all_type_units[ix]->per_cu.imported_symtabs);
 
   VEC_free (dwarf2_section_info_def, data->types);
 
@@ -20492,7 +20522,7 @@ write_psymtabs_to_index (struct objfile 
   total_len = size_of_contents;
 
   /* The version number.  */
-  val = MAYBE_SWAP (7);
+  val = MAYBE_SWAP (8);
   obstack_grow (&contents, &val, sizeof (val));
 
   /* The offset of the CU list from the start of the file.  */
Index: doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.1042
diff -u -p -r1.1042 gdb.texinfo
--- doc/gdb.texinfo	16 Jan 2013 17:31:39 -0000	1.1042
+++ doc/gdb.texinfo	17 Jan 2013 20:57:33 -0000
@@ -41031,12 +41031,18 @@ unless otherwise noted:
 
 @enumerate
 @item
-The version number, currently 7.  Versions 1, 2 and 3 are obsolete.
+The version number, currently 8.  Versions 1, 2 and 3 are obsolete.
 Version 4 uses a different hashing function from versions 5 and 6.
 Version 6 includes symbols for inlined functions, whereas versions 4
 and 5 do not.  Version 7 adds attributes to the CU indices in the
-symbol table.  @value{GDBN} will only read version 4, 5, or 6 indices
+symbol table.  Version 8 specifies that symbols from DWARF type units
+(@samp{DW_TAG_type_unit}) refer to the type unit's symbol table and not the
+compilation unit (@samp{DW_TAG_comp_unit}) using the type.
+
+@value{GDBN} will only read version 4, 5, or 6 indices
 by specifying @code{set use-deprecated-index-sections on}.
+GDB has a workaround for potentially broken version 7 indices so it is
+currently not flagged as deprecated.
 
 @item
 The offset, from the start of the file, of the CU list.


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