[gdb/f14/master] - Use .gdb_index v3 to fix excessive resources rqmnts (BZ 640634, Tom Tromey).

Jan Kratochvil jkratoch at fedoraproject.org
Tue Oct 12 16:18:48 UTC 2010


commit df661e30f97bf961dcdd19c22207b6a5a783a0a3
Author: Jan Kratochvil <jan.kratochvil at redhat.com>
Date:   Tue Oct 12 18:18:54 2010 +0200

    - Use .gdb_index v3 to fix excessive resources rqmnts (BZ 640634, Tom Tromey).

 gdb-gdbindex-bigendian.patch |    6 +-
 gdb-gdbindex-v1-to-v2.patch  |  689 ++++++++++++++++++++++++++++++++++++++++++
 gdb-gdbindex-v2-to-v3.patch  |  278 +++++++++++++++++
 gdb.spec                     |    7 +
 4 files changed, 977 insertions(+), 3 deletions(-)
---
diff --git a/gdb-gdbindex-bigendian.patch b/gdb-gdbindex-bigendian.patch
index b03632f..edd4f4f 100644
--- a/gdb-gdbindex-bigendian.patch
+++ b/gdb-gdbindex-bigendian.patch
@@ -15,7 +15,7 @@ http://sourceware.org/ml/gdb-cvs/2010-09/msg00155.html
  	* valops.c (find_oload_champ_namespace_loop): replace incorrect
 --- src/gdb/dwarf2read.c	2010/09/22 19:22:44	1.460
 +++ src/gdb/dwarf2read.c	2010/09/24 16:11:46	1.461
-@@ -2248,10 +2248,12 @@ dw2_expand_symtabs_matching (struct objf
+@@ -2382,10 +2382,12 @@
  {
    int i;
    offset_type iter;
@@ -26,8 +26,8 @@ http://sourceware.org/ml/gdb-cvs/2010-09/msg00155.html
      return;
 +  index = dwarf2_per_objfile->index_table;
  
-   for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
-     {
+   for (i = 0; i < (dwarf2_per_objfile->n_comp_units
+ 		   + dwarf2_per_objfile->n_type_comp_units); ++i)
 @@ -2411,28 +2413,24 @@
  	}
      }
diff --git a/gdb-gdbindex-v1-to-v2.patch b/gdb-gdbindex-v1-to-v2.patch
new file mode 100644
index 0000000..2a7b9b7
--- /dev/null
+++ b/gdb-gdbindex-v1-to-v2.patch
@@ -0,0 +1,689 @@
+http://sourceware.org/ml/gdb-cvs/2010-07/msg00139.html
+
+### src/gdb/ChangeLog	2010/07/23 21:10:54	1.12013
+### src/gdb/ChangeLog	2010/07/23 22:15:13	1.12014
+## -1,3 +1,31 @@
++2010-07-23  Tom Tromey  <tromey at redhat.com>
++
++	* dwarf2read.c (struct dwarf2_per_objfile) <n_type_comp_units,
++	type_comp_units>: New fields.
++	(dw2_get_cu): New function.
++	(create_cus_from_index): Remove unused argument.
++	(create_signatured_type_hash_from_index): New function.
++	(create_addrmap_from_index): Update.
++	(dwarf2_read_index): Handle version 2.
++	(dw2_find_last_source_symtab, dw2_forget_cached_source_info)
++	(dw2_lookup_symtab, dw2_do_expand_symtabs_matching)
++	(dw2_print_stats, dw2_expand_all_symtabs)
++	(dw2_expand_symtabs_with_filename, dw2_find_symbol_file)
++	(dw2_expand_symtabs_matching, dw2_map_symbol_filenames): Update.
++	(dwarf2_initialize_objfile): Call create_debug_types_hash_table.
++	(allocate_signatured_type_hash_table): New function.
++	(add_signatured_type_cu_to_list): Likewise.
++	(create_debug_types_hash_table): Use them.  Set type_comp_units.
++	(read_signatured_type): Ensure section data is available.
++	(add_address_entry): Don't record empty ranges.
++	(struct signatured_type_index_data): New.
++	(write_one_signatured_type): New function.
++	(write_psymtabs_to_index): Write type CUs.
++	(save_gdb_index_command): Update comment.
++	(process_type_comp_unit): Move inititalization of
++	from_debug_types...
++	(create_debug_types_hash_table): ... here.
++
+ 2010-07-23  Jan Kratochvil  <jan.kratochvil at redhat.com>
+ 
+ 	* gdb_gcore.sh (tmpfile): Remove the variable, its initialization,
+Index: gdb-7.2/gdb/dwarf2read.c
+===================================================================
+--- gdb-7.2.orig/gdb/dwarf2read.c	2010-10-12 18:10:47.000000000 +0200
++++ gdb-7.2/gdb/dwarf2read.c	2010-10-12 18:11:16.000000000 +0200
+@@ -184,6 +184,12 @@ struct dwarf2_per_objfile
+   /* The number of compilation units in ALL_COMP_UNITS.  */
+   int n_comp_units;
+ 
++  /* The number of .debug_types-related CUs.  */
++  int n_type_comp_units;
++
++  /* The .debug_types-related CUs.  */
++  struct dwarf2_per_cu_data **type_comp_units;
++
+   /* A chain of compilation units that are currently read in, so that
+      they can be freed later.  */
+   struct dwarf2_per_cu_data *read_in_chain;
+@@ -1226,6 +1232,8 @@ static struct type *set_die_type (struct
+ 
+ static void create_all_comp_units (struct objfile *);
+ 
++static int create_debug_types_hash_table (struct objfile *objfile);
++
+ static void load_full_comp_unit (struct dwarf2_per_cu_data *,
+ 				 struct objfile *);
+ 
+@@ -1269,6 +1277,8 @@ static void init_cu_die_reader (struct d
+ static const char *dwarf2_physname (char *name, struct die_info *die,
+ 				    struct dwarf2_cu *cu);
+ 
++static htab_t allocate_signatured_type_hash_table (struct objfile *objfile);
++
+ #if WORDS_BIGENDIAN
+ 
+ /* Convert VALUE between big- and little-endian.  */
+@@ -1646,6 +1656,18 @@ dw2_instantiate_symtab (struct objfile *
+   return per_cu->v.quick->symtab;
+ }
+ 
++/* Return the CU given its index.  */
++static struct dwarf2_per_cu_data *
++dw2_get_cu (int index)
++{
++  if (index >= dwarf2_per_objfile->n_comp_units)
++    {
++      index -= dwarf2_per_objfile->n_comp_units;
++      return dwarf2_per_objfile->type_comp_units[index];
++    }
++  return dwarf2_per_objfile->all_comp_units[index];
++}
++
+ /* A helper function that knows how to read a 64-bit value in a way
+    that doesn't make gdb die.  Returns 1 if the conversion went ok, 0
+    otherwise.  */
+@@ -1672,11 +1694,10 @@ extract_cu_value (const char *bytes, ULO
+    the CU objects for this objfile.  Return 0 if something went wrong,
+    1 if everything went ok.  */
+ static int
+-create_cus_from_index (struct objfile *objfile, struct mapped_index *index,
+-		       const gdb_byte *cu_list, offset_type cu_list_elements)
++create_cus_from_index (struct objfile *objfile, const gdb_byte *cu_list,
++		       offset_type cu_list_elements)
+ {
+   offset_type i;
+-  const char *entry;
+ 
+   dwarf2_per_objfile->n_comp_units = cu_list_elements / 2;
+   dwarf2_per_objfile->all_comp_units
+@@ -1707,6 +1728,58 @@ create_cus_from_index (struct objfile *o
+   return 1;
+ }
+ 
++/* Create the signatured type hash table from the index.  */
++static int
++create_signatured_type_hash_from_index (struct objfile *objfile,
++					const gdb_byte *bytes,
++					offset_type elements)
++{
++  offset_type i;
++  htab_t type_hash;
++
++  dwarf2_per_objfile->n_type_comp_units = elements / 3;
++  dwarf2_per_objfile->type_comp_units
++    = obstack_alloc (&objfile->objfile_obstack,
++		     dwarf2_per_objfile->n_type_comp_units
++		     * sizeof (struct dwarf2_per_cu_data *));
++
++  type_hash = allocate_signatured_type_hash_table (objfile);
++
++  for (i = 0; i < elements; i += 3)
++    {
++      struct signatured_type *type_sig;
++      ULONGEST offset, type_offset, signature;
++      void **slot;
++
++      if (!extract_cu_value (bytes, &offset)
++	  || !extract_cu_value (bytes + 8, &type_offset))
++	return 0;
++      signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
++      bytes += 3 * 8;
++
++      type_sig = OBSTACK_ZALLOC (&objfile->objfile_obstack,
++				 struct signatured_type);
++      type_sig->signature = signature;
++      type_sig->offset = offset;
++      type_sig->type_offset = type_offset;
++      type_sig->per_cu.from_debug_types = 1;
++      type_sig->per_cu.offset = offset;
++      type_sig->per_cu.objfile = objfile;
++      type_sig->per_cu.v.quick
++	= OBSTACK_ZALLOC (&objfile->objfile_obstack,
++			  struct dwarf2_per_cu_quick_data);
++
++      slot = htab_find_slot (type_hash, type_sig, INSERT);
++      *slot = type_sig;
++
++      dwarf2_per_objfile->type_comp_units[i / 3] = &type_sig->per_cu;
++    }
++
++  dwarf2_per_objfile->signatured_types = type_hash;
++
++  return 1;
++}
++
+ /* Read the address map data from the mapped index, and use it to
+    populate the objfile's psymtabs_addrmap.  */
+ static void
+@@ -1738,7 +1811,7 @@ create_addrmap_from_index (struct objfil
+       iter += 4;
+       
+       addrmap_set_empty (mutable_map, lo + baseaddr, hi + baseaddr - 1,
+-			 dwarf2_per_objfile->all_comp_units[cu_index]);
++			 dw2_get_cu (cu_index));
+     }
+ 
+   objfile->psymtabs_addrmap = addrmap_create_fixed (mutable_map,
+@@ -1805,8 +1878,9 @@ dwarf2_read_index (struct objfile *objfi
+   char *addr;
+   struct mapped_index *map;
+   offset_type *metadata;
+-  const gdb_byte *cu_list;
+-  offset_type cu_list_elements;
++  const gdb_byte *cu_list, *types_list;
++  offset_type version, cu_list_elements, types_list_elements;
++  int i;
+ 
+   if (dwarf2_per_objfile->gdb_index.asection == NULL
+       || dwarf2_per_objfile->gdb_index.size == 0)
+@@ -1822,26 +1896,58 @@ dwarf2_read_index (struct objfile *objfi
+ 
+   addr = dwarf2_per_objfile->gdb_index.buffer;
+   /* Version check.  */
+-  if (MAYBE_SWAP (*(offset_type *) addr) != 1)
++  version = MAYBE_SWAP (*(offset_type *) addr);
++  if (version == 1)
++    {
++      /* Index version 1 neglected to account for .debug_types.  So,
++	 if we see .debug_types, we cannot use this index.  */
++      if (dwarf2_per_objfile->types.asection != NULL
++	  && dwarf2_per_objfile->types.size != 0)
++	return 0;
++    }
++  else if (version != 2)
+     return 0;
+ 
+   map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index);
+   map->total_size = dwarf2_per_objfile->gdb_index.size;
+ 
+   metadata = (offset_type *) (addr + sizeof (offset_type));
+-  cu_list = addr + MAYBE_SWAP (metadata[0]);
+-  cu_list_elements = ((MAYBE_SWAP (metadata[1]) - MAYBE_SWAP (metadata[0]))
++
++  i = 0;
++  cu_list = addr + MAYBE_SWAP (metadata[i]);
++  cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i]))
+ 		      / 8);
+-  map->address_table = addr + MAYBE_SWAP (metadata[1]);
+-  map->address_table_size = (MAYBE_SWAP (metadata[2])
+-			     - MAYBE_SWAP (metadata[1]));
+-  map->index_table = (offset_type *) (addr + MAYBE_SWAP (metadata[2]));
+-  map->index_table_slots = ((MAYBE_SWAP (metadata[3])
+-			     - MAYBE_SWAP (metadata[2]))
++  ++i;
++
++  if (version == 2)
++    {
++      types_list = addr + MAYBE_SWAP (metadata[i]);
++      types_list_elements = ((MAYBE_SWAP (metadata[i + 1])
++			      - MAYBE_SWAP (metadata[i]))
++			     / 8);
++      ++i;
++    }
++
++  map->address_table = addr + MAYBE_SWAP (metadata[i]);
++  map->address_table_size = (MAYBE_SWAP (metadata[i + 1])
++			     - MAYBE_SWAP (metadata[i]));
++  ++i;
++
++  map->index_table = (offset_type *) (addr + MAYBE_SWAP (metadata[i]));
++  map->index_table_slots = ((MAYBE_SWAP (metadata[i + 1])
++			     - MAYBE_SWAP (metadata[i]))
+ 			    / (2 * sizeof (offset_type)));
+-  map->constant_pool = addr + MAYBE_SWAP (metadata[3]);
++  ++i;
+ 
+-  if (!create_cus_from_index (objfile, map, cu_list, cu_list_elements))
++  map->constant_pool = addr + MAYBE_SWAP (metadata[i]);
++
++  if (!create_cus_from_index (objfile, cu_list, cu_list_elements))
++    return 0;
++
++  if (version == 2
++      && types_list_elements
++      && !create_signatured_type_hash_from_index (objfile, types_list,
++						  types_list_elements))
+     return 0;
+ 
+   create_addrmap_from_index (objfile, map);
+@@ -1968,8 +2074,7 @@ dw2_find_last_source_symtab (struct objf
+   int index;
+   dw2_setup (objfile);
+   index = dwarf2_per_objfile->n_comp_units - 1;
+-  return dw2_instantiate_symtab (objfile,
+-				 dwarf2_per_objfile->all_comp_units[index]);
++  return dw2_instantiate_symtab (objfile, dw2_get_cu (index));
+ }
+ 
+ static void
+@@ -1978,9 +2083,10 @@ dw2_forget_cached_source_info (struct ob
+   int i;
+ 
+   dw2_setup (objfile);
+-  for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
++  for (i = 0; i < (dwarf2_per_objfile->n_comp_units
++		   + dwarf2_per_objfile->n_type_comp_units); ++i)
+     {
+-      struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
++      struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
+ 
+       if (cu->v.quick->full_names)
+ 	{
+@@ -2002,10 +2108,11 @@ dw2_lookup_symtab (struct objfile *objfi
+   struct dwarf2_per_cu_data *base_cu = NULL;
+ 
+   dw2_setup (objfile);
+-  for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
++  for (i = 0; i < (dwarf2_per_objfile->n_comp_units
++		   + dwarf2_per_objfile->n_type_comp_units); ++i)
+     {
+       int j;
+-      struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
++      struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
+ 
+       if (cu->v.quick->symtab)
+ 	continue;
+@@ -2097,8 +2204,8 @@ dw2_do_expand_symtabs_matching (struct o
+ 	  for (i = 0; i < len; ++i)
+ 	    {
+ 	      offset_type cu_index = MAYBE_SWAP (vec[i + 1]);
+-	      struct dwarf2_per_cu_data *cu;
+-	      cu = dwarf2_per_objfile->all_comp_units[cu_index];
++	      struct dwarf2_per_cu_data *cu = dw2_get_cu (cu_index);
++
+ 	      dw2_instantiate_symtab (objfile, cu);
+ 	    }
+ 	}
+@@ -2120,9 +2227,10 @@ dw2_print_stats (struct objfile *objfile
+ 
+   dw2_setup (objfile);
+   count = 0;
+-  for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
++  for (i = 0; i < (dwarf2_per_objfile->n_comp_units
++		   + dwarf2_per_objfile->n_type_comp_units); ++i)
+     {
+-      struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
++      struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
+ 
+       if (!cu->v.quick->symtab)
+ 	++count;
+@@ -2156,9 +2264,11 @@ dw2_expand_all_symtabs (struct objfile *
+   int i;
+ 
+   dw2_setup (objfile);
+-  for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
++
++  for (i = 0; i < (dwarf2_per_objfile->n_comp_units
++		   + dwarf2_per_objfile->n_type_comp_units); ++i)
+     {
+-      struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
++      struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
+ 
+       dw2_instantiate_symtab (objfile, cu);
+     }
+@@ -2171,10 +2281,11 @@ dw2_expand_symtabs_with_filename (struct
+   int i;
+ 
+   dw2_setup (objfile);
+-  for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
++  for (i = 0; i < (dwarf2_per_objfile->n_comp_units
++		   + dwarf2_per_objfile->n_type_comp_units); ++i)
+     {
+       int j;
+-      struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
++      struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
+ 
+       if (cu->v.quick->symtab)
+ 	continue;
+@@ -2215,7 +2326,7 @@ dw2_find_symbol_file (struct objfile *ob
+      should be rewritten so that it doesn't require a custom hook.  It
+      could just use the ordinary symbol tables.  */
+   /* vec[0] is the length, which must always be >0.  */
+-  cu = dwarf2_per_objfile->all_comp_units[MAYBE_SWAP (vec[1])];
++  cu = dw2_get_cu (MAYBE_SWAP (vec[1]));
+ 
+   dw2_require_line_header (objfile, cu);
+   if (!cu->v.quick->lines)
+@@ -2253,10 +2364,11 @@ dw2_expand_symtabs_matching (struct objf
+   if (!dwarf2_per_objfile->index_table)
+     return;
+ 
+-  for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
++  for (i = 0; i < (dwarf2_per_objfile->n_comp_units
++		   + dwarf2_per_objfile->n_type_comp_units); ++i)
+     {
+       int j;
+-      struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
++      struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
+ 
+       cu->v.quick->mark = 0;
+       if (cu->v.quick->symtab)
+@@ -2301,8 +2413,9 @@ dw2_expand_symtabs_matching (struct objf
+       vec_len = MAYBE_SWAP (vec[0]);
+       for (vec_idx = 0; vec_idx < vec_len; ++vec_idx)
+ 	{
+-	  struct dwarf2_per_cu_data *cu
+-	    = dwarf2_per_objfile->all_comp_units[MAYBE_SWAP (vec[vec_idx + 1])];
++	  struct dwarf2_per_cu_data *cu;
++
++	  cu = dw2_get_cu (MAYBE_SWAP (vec[vec_idx + 1]));
+ 	  if (cu->v.quick->mark)
+ 	    dw2_instantiate_symtab (objfile, cu);
+ 	}
+@@ -2372,10 +2485,11 @@ dw2_map_symbol_filenames (struct objfile
+   int i;
+ 
+   dw2_setup (objfile);
+-  for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
++  for (i = 0; i < (dwarf2_per_objfile->n_comp_units
++		   + dwarf2_per_objfile->n_type_comp_units); ++i)
+     {
+       int j;
+-      struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
++      struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
+ 
+       if (cu->v.quick->symtab)
+ 	continue;
+@@ -2436,10 +2550,12 @@ dwarf2_initialize_objfile (struct objfil
+ 
+       dwarf2_per_objfile->using_index = 1;
+       create_all_comp_units (objfile);
++      create_debug_types_hash_table (objfile);
+ 
+-      for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
++      for (i = 0; i < (dwarf2_per_objfile->n_comp_units
++		       + dwarf2_per_objfile->n_type_comp_units); ++i)
+ 	{
+-	  struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
++	  struct dwarf2_per_cu_data *cu = dw2_get_cu (i);
+ 
+ 	  cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ 					struct dwarf2_per_cu_quick_data);
+@@ -2653,6 +2769,34 @@ eq_type_signature (const void *item_lhs,
+   return lhs->signature == rhs->signature;
+ }
+ 
++/* Allocate a hash table for signatured types.  */
++
++static htab_t
++allocate_signatured_type_hash_table (struct objfile *objfile)
++{
++  return htab_create_alloc_ex (41,
++			       hash_type_signature,
++			       eq_type_signature,
++			       NULL,
++			       &objfile->objfile_obstack,
++			       hashtab_obstack_allocate,
++			       dummy_obstack_deallocate);
++}
++
++/* A helper function to add a signatured type CU to a list.  */
++
++static int
++add_signatured_type_cu_to_list (void **slot, void *datum)
++{
++  struct signatured_type *sigt = *slot;
++  struct dwarf2_per_cu_data ***datap = datum;
++
++  **datap = &sigt->per_cu;
++  ++*datap;
++
++  return 1;
++}
++
+ /* Create the hash table of all entries in the .debug_types section.
+    The result is zero if there is an error (e.g. missing .debug_types section),
+    otherwise non-zero.	*/
+@@ -2662,6 +2806,7 @@ create_debug_types_hash_table (struct ob
+ {
+   gdb_byte *info_ptr;
+   htab_t types_htab;
++  struct dwarf2_per_cu_data **iter;
+ 
+   dwarf2_read_section (objfile, &dwarf2_per_objfile->types);
+   info_ptr = dwarf2_per_objfile->types.buffer;
+@@ -2672,13 +2817,7 @@ create_debug_types_hash_table (struct ob
+       return 0;
+     }
+ 
+-  types_htab = htab_create_alloc_ex (41,
+-				     hash_type_signature,
+-				     eq_type_signature,
+-				     NULL,
+-				     &objfile->objfile_obstack,
+-				     hashtab_obstack_allocate,
+-				     dummy_obstack_deallocate);
++  types_htab = allocate_signatured_type_hash_table (objfile);
+ 
+   if (dwarf2_die_debug)
+     fprintf_unfiltered (gdb_stdlog, "Signatured types:\n");
+@@ -2726,6 +2865,7 @@ create_debug_types_hash_table (struct ob
+       type_sig->offset = offset;
+       type_sig->type_offset = type_offset;
+       type_sig->per_cu.objfile = objfile;
++      type_sig->per_cu.from_debug_types = 1;
+ 
+       slot = htab_find_slot (types_htab, type_sig, INSERT);
+       gdb_assert (slot != NULL);
+@@ -2740,6 +2880,16 @@ create_debug_types_hash_table (struct ob
+ 
+   dwarf2_per_objfile->signatured_types = types_htab;
+ 
++  dwarf2_per_objfile->n_type_comp_units = htab_elements (types_htab);
++  dwarf2_per_objfile->type_comp_units
++    = obstack_alloc (&objfile->objfile_obstack,
++		     dwarf2_per_objfile->n_type_comp_units
++		     * sizeof (struct dwarf2_per_cu_data *));
++  iter = &dwarf2_per_objfile->type_comp_units[0];
++  htab_traverse_noresize (types_htab, add_signatured_type_cu_to_list, &iter);
++  gdb_assert (iter - &dwarf2_per_objfile->type_comp_units[0]
++	      == dwarf2_per_objfile->n_type_comp_units);
++
+   return 1;
+ }
+ 
+@@ -3008,7 +3158,6 @@ process_type_comp_unit (void **slot, voi
+   struct dwarf2_per_cu_data *this_cu;
+ 
+   this_cu = &entry->per_cu;
+-  this_cu->from_debug_types = 1;
+ 
+   gdb_assert (dwarf2_per_objfile->types.readin);
+   process_psymtab_comp_unit (objfile, this_cu,
+@@ -12483,13 +12632,16 @@ static void
+ read_signatured_type (struct objfile *objfile,
+ 		      struct signatured_type *type_sig)
+ {
+-  gdb_byte *types_ptr = dwarf2_per_objfile->types.buffer + type_sig->offset;
++  gdb_byte *types_ptr;
+   struct die_reader_specs reader_specs;
+   struct dwarf2_cu *cu;
+   ULONGEST signature;
+   struct cleanup *back_to, *free_cu_cleanup;
+   struct attribute *attr;
+ 
++  dwarf2_read_section (objfile, &dwarf2_per_objfile->types);
++  types_ptr = dwarf2_per_objfile->types.buffer + type_sig->offset;
++
+   gdb_assert (type_sig->per_cu.cu == NULL);
+ 
+   cu = xmalloc (sizeof (struct dwarf2_cu));
+@@ -14402,6 +14554,10 @@ add_address_entry (struct objfile *objfi
+   char addr[8];
+   CORE_ADDR baseaddr;
+ 
++  /* Don't bother recording empty ranges.  */
++  if (pst->textlow == pst->texthigh)
++    return;
++
+   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ 
+   store_unsigned_integer (addr, 8, BFD_ENDIAN_LITTLE, pst->textlow - baseaddr);
+@@ -14447,13 +14603,53 @@ unlink_if_set (void *p)
+     unlink (*filename);
+ }
+ 
++/* A helper struct used when iterating over debug_types.  */
++struct signatured_type_index_data
++{
++  struct objfile *objfile;
++  struct mapped_symtab *symtab;
++  struct obstack *types_list;
++  int cu_index;
++};
++
++/* A helper function that writes a single signatured_type to an
++   obstack.  */
++static int
++write_one_signatured_type (void **slot, void *d)
++{
++  struct signatured_type_index_data *info = d;
++  struct signatured_type *entry = (struct signatured_type *) *slot;
++  struct dwarf2_per_cu_data *cu = &entry->per_cu;
++  struct partial_symtab *psymtab = cu->v.psymtab;
++  gdb_byte val[8];
++
++  write_psymbols (info->symtab,
++		  info->objfile->global_psymbols.list + psymtab->globals_offset,
++		  psymtab->n_global_syms, info->cu_index);
++  write_psymbols (info->symtab,
++		  info->objfile->static_psymbols.list + psymtab->statics_offset,
++		  psymtab->n_static_syms, info->cu_index);
++
++  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->offset);
++  obstack_grow (info->types_list, val, 8);
++  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->type_offset);
++  obstack_grow (info->types_list, val, 8);
++  store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->signature);
++  obstack_grow (info->types_list, val, 8);
++
++  ++info->cu_index;
++
++  return 1;
++}
++
+ /* Create an index file for OBJFILE in the directory DIR.  */
+ static void
+ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
+ {
+   struct cleanup *cleanup;
+   char *filename, *cleanup_filename;
+-  struct obstack contents, addr_obstack, constant_pool, symtab_obstack, cu_list;
++  struct obstack contents, addr_obstack, constant_pool, symtab_obstack;
++  struct obstack cu_list, types_cu_list;
+   int i;
+   FILE *out_file;
+   struct mapped_symtab *symtab;
+@@ -14489,6 +14685,12 @@ write_psymtabs_to_index (struct objfile 
+   obstack_init (&cu_list);
+   make_cleanup_obstack_free (&cu_list);
+ 
++  obstack_init (&types_cu_list);
++  make_cleanup_obstack_free (&types_cu_list);
++
++  /* The list is already sorted, so we don't need to do additional
++     work here.  Also, the debug_types entries do not appear in
++     all_comp_units, but only in their own hash table.  */
+   for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+     {
+       struct dwarf2_per_cu_data *cu = dwarf2_per_objfile->all_comp_units[i];
+@@ -14510,6 +14712,19 @@ write_psymtabs_to_index (struct objfile 
+       obstack_grow (&cu_list, val, 8);
+     }
+ 
++  /* Write out the .debug_type entries, if any.  */
++  if (dwarf2_per_objfile->signatured_types)
++    {
++      struct signatured_type_index_data sig_data;
++
++      sig_data.objfile = objfile;
++      sig_data.symtab = symtab;
++      sig_data.types_list = &types_cu_list;
++      sig_data.cu_index = dwarf2_per_objfile->n_comp_units;
++      htab_traverse_noresize (dwarf2_per_objfile->signatured_types,
++			      write_one_signatured_type, &sig_data);
++    }
++
+   obstack_init (&constant_pool);
+   make_cleanup_obstack_free (&constant_pool);
+   obstack_init (&symtab_obstack);
+@@ -14518,11 +14733,11 @@ write_psymtabs_to_index (struct objfile 
+ 
+   obstack_init (&contents);
+   make_cleanup_obstack_free (&contents);
+-  size_of_contents = 5 * sizeof (offset_type);
++  size_of_contents = 6 * sizeof (offset_type);
+   total_len = size_of_contents;
+ 
+   /* The version number.  */
+-  val = MAYBE_SWAP (1);
++  val = MAYBE_SWAP (2);
+   obstack_grow (&contents, &val, sizeof (val));
+ 
+   /* The offset of the CU list from the start of the file.  */
+@@ -14530,6 +14745,11 @@ write_psymtabs_to_index (struct objfile 
+   obstack_grow (&contents, &val, sizeof (val));
+   total_len += obstack_object_size (&cu_list);
+ 
++  /* The offset of the types CU list from the start of the file.  */
++  val = MAYBE_SWAP (total_len);
++  obstack_grow (&contents, &val, sizeof (val));
++  total_len += obstack_object_size (&types_cu_list);
++
+   /* The offset of the address table from the start of the file.  */
+   val = MAYBE_SWAP (total_len);
+   obstack_grow (&contents, &val, sizeof (val));
+@@ -14549,6 +14769,7 @@ write_psymtabs_to_index (struct objfile 
+ 
+   write_obstack (out_file, &contents);
+   write_obstack (out_file, &cu_list);
++  write_obstack (out_file, &types_cu_list);
+   write_obstack (out_file, &addr_obstack);
+   write_obstack (out_file, &symtab_obstack);
+   write_obstack (out_file, &constant_pool);
+@@ -14573,18 +14794,33 @@ write_psymtabs_to_index (struct objfile 
+ 
+    1. The file header.  This is a sequence of values, of offset_type
+    unless otherwise noted:
+-   [0] The version number.  Currently 1.
++   [0] The version number.  Currently 1 or 2.  The differences are
++   noted below.  Version 1 did not account for .debug_types sections;
++   the presence of a .debug_types section invalidates any version 1
++   index that may exist.
+    [1] The offset, from the start of the file, of the CU list.
++   [1.5] In version 2, the offset, from the start of the file, of the
++   types CU list.  This offset does not appear in version 1.  Note
++   that this can be empty, in which case this offset will be equal to
++   the next offset.
+    [2] The offset, from the start of the file, of the address section.
+    [3] The offset, from the start of the file, of the symbol table.
+    [4] The offset, from the start of the file, of the constant pool.
+ 
+    2. The CU list.  This is a sequence of pairs of 64-bit
+-   little-endian values.  The first element in each pair is the offset
+-   of a CU in the .debug_info section.  The second element in each
+-   pair is the length of that CU.  References to a CU elsewhere in the
+-   map are done using a CU index, which is just the 0-based index into
+-   this table.
++   little-endian values, sorted by the CU offset.  The first element
++   in each pair is the offset of a CU in the .debug_info section.  The
++   second element in each pair is the length of that CU.  References
++   to a CU elsewhere in the map are done using a CU index, which is
++   just the 0-based index into this table.  Note that if there are
++   type CUs, then conceptually CUs and type CUs form a single list for
++   the purposes of CU indices.
++
++   2.5 The types CU list.  This does not appear in a version 1 index.
++   This is a sequence of triplets of 64-bit little-endian values.  In
++   a triplet, the first value is the CU offset, the second value is
++   the type offset in the CU, and the third value is the type
++   signature.  The types CU list is not sorted.
+ 
+    3. The address section.  The address section consists of a sequence
+    of address entries.  Each address entry has three elements.
diff --git a/gdb-gdbindex-v2-to-v3.patch b/gdb-gdbindex-v2-to-v3.patch
new file mode 100644
index 0000000..bbd7045
--- /dev/null
+++ b/gdb-gdbindex-v2-to-v3.patch
@@ -0,0 +1,278 @@
+FYI: index pre-expansion fix
+http://sourceware.org/ml/gdb-patches/2010-09/msg00452.html
+http://sourceware.org/ml/gdb-cvs/2010-09/msg00165.html
+
+### src/gdb/ChangeLog	2010/09/27 17:41:35	1.12206
+### src/gdb/ChangeLog	2010/09/27 18:42:35	1.12207
+## -1,5 +1,17 @@
+ 2010-09-27  Tom Tromey  <tromey at redhat.com>
+ 
++	* dwarf2read.c (dwarf2_read_index): Only allow version 3.
++	(write_psymbols): Add 'psyms_seen' and 'is_static' arguments.
++	Only emit a given psymbol once.
++	(struct signatured_type_index_data) <psyms_seen>: New field.
++	(write_one_signatured_type): Update.
++	(cleanup_htab): New function.
++	(write_psymtabs_to_index): Update.  Create psyms_seen hash.  Bump
++	version to 3.
++	(save_gdb_index_command): Update index documentation.
++
++2010-09-27  Tom Tromey  <tromey at redhat.com>
++
+ 	* bcache.c (expand_hash_table): Use hash_function, not hash.
+ 
+ 2010-09-27  Tom Tromey  <tromey at redhat.com>
+Index: gdb-7.2/gdb/dwarf2read.c
+===================================================================
+--- gdb-7.2.orig/gdb/dwarf2read.c	2010-10-12 18:11:27.000000000 +0200
++++ gdb-7.2/gdb/dwarf2read.c	2010-10-12 18:12:03.000000000 +0200
+@@ -1897,15 +1897,10 @@ dwarf2_read_index (struct objfile *objfi
+   addr = dwarf2_per_objfile->gdb_index.buffer;
+   /* Version check.  */
+   version = MAYBE_SWAP (*(offset_type *) addr);
+-  if (version == 1)
+-    {
+-      /* Index version 1 neglected to account for .debug_types.  So,
+-	 if we see .debug_types, we cannot use this index.  */
+-      if (dwarf2_per_objfile->types.asection != NULL
+-	  && dwarf2_per_objfile->types.size != 0)
+-	return 0;
+-    }
+-  else if (version != 2)
++  /* Versions earlier than 3 emitted every copy of a psymbol.  This
++     causes the index to behave very poorly for certain requests.  So,
++     it seems better to just ignore such indices.  */
++  if (version < 3)
+     return 0;
+ 
+   map = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct mapped_index);
+@@ -1919,14 +1914,11 @@ dwarf2_read_index (struct objfile *objfi
+ 		      / 8);
+   ++i;
+ 
+-  if (version == 2)
+-    {
+-      types_list = addr + MAYBE_SWAP (metadata[i]);
+-      types_list_elements = ((MAYBE_SWAP (metadata[i + 1])
+-			      - MAYBE_SWAP (metadata[i]))
+-			     / 8);
+-      ++i;
+-    }
++  types_list = addr + MAYBE_SWAP (metadata[i]);
++  types_list_elements = ((MAYBE_SWAP (metadata[i + 1])
++			  - MAYBE_SWAP (metadata[i]))
++			 / 8);
++  ++i;
+ 
+   map->address_table = addr + MAYBE_SWAP (metadata[i]);
+   map->address_table_size = (MAYBE_SWAP (metadata[i + 1])
+@@ -1944,8 +1936,7 @@ dwarf2_read_index (struct objfile *objfi
+   if (!create_cus_from_index (objfile, cu_list, cu_list_elements))
+     return 0;
+ 
+-  if (version == 2
+-      && types_list_elements
++  if (types_list_elements
+       && !create_signatured_type_hash_from_index (objfile, types_list,
+ 						  types_list_elements))
+     return 0;
+@@ -14568,15 +14559,38 @@ add_address_entry (struct objfile *objfi
+ /* Add a list of partial symbols to SYMTAB.  */
+ static void
+ write_psymbols (struct mapped_symtab *symtab,
++		htab_t psyms_seen,
+ 		struct partial_symbol **psymp,
+ 		int count,
+-		offset_type cu_index)
++		offset_type cu_index,
++		int is_static)
+ {
+   for (; count-- > 0; ++psymp)
+     {
++      void **slot, *lookup;
++
+       if (SYMBOL_LANGUAGE (*psymp) == language_ada)
+ 	error (_("Ada is not currently supported by the index"));
+-      add_index_entry (symtab, SYMBOL_NATURAL_NAME (*psymp), cu_index);
++
++      /* We only want to add a given psymbol once.  However, we also
++	 want to account for whether it is global or static.  So, we
++	 may add it twice, using slightly different values.  */
++      if (is_static)
++	{
++	  uintptr_t val = 1 | (uintptr_t) *psymp;
++
++	  lookup = (void *) val;
++	}
++      else
++	lookup = *psymp;
++
++      /* Only add a given psymbol once.  */
++      slot = htab_find_slot (psyms_seen, lookup, INSERT);
++      if (!*slot)
++	{
++	  *slot = lookup;
++	  add_index_entry (symtab, SYMBOL_NATURAL_NAME (*psymp), cu_index);
++	}
+     }
+ }
+ 
+@@ -14606,6 +14620,7 @@ struct signatured_type_index_data
+   struct objfile *objfile;
+   struct mapped_symtab *symtab;
+   struct obstack *types_list;
++  htab_t psyms_seen;
+   int cu_index;
+ };
+ 
+@@ -14621,11 +14636,15 @@ write_one_signatured_type (void **slot, 
+   gdb_byte val[8];
+ 
+   write_psymbols (info->symtab,
++		  info->psyms_seen,
+ 		  info->objfile->global_psymbols.list + psymtab->globals_offset,
+-		  psymtab->n_global_syms, info->cu_index);
++		  psymtab->n_global_syms, 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->n_static_syms, info->cu_index,
++		  1);
+ 
+   store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->offset);
+   obstack_grow (info->types_list, val, 8);
+@@ -14639,6 +14658,14 @@ write_one_signatured_type (void **slot, 
+   return 1;
+ }
+ 
++/* A cleanup function for an htab_t.  */
++
++static void
++cleanup_htab (void *arg)
++{
++  htab_delete (arg);
++}
++
+ /* Create an index file for OBJFILE in the directory DIR.  */
+ static void
+ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
+@@ -14653,6 +14680,7 @@ write_psymtabs_to_index (struct objfile 
+   offset_type val, size_of_contents, total_len;
+   struct stat st;
+   char buf[8];
++  htab_t psyms_seen;
+ 
+   if (!objfile->psymtabs)
+     return;
+@@ -14685,6 +14713,10 @@ write_psymtabs_to_index (struct objfile 
+   obstack_init (&types_cu_list);
+   make_cleanup_obstack_free (&types_cu_list);
+ 
++  psyms_seen = htab_create_alloc (100, htab_hash_pointer, htab_eq_pointer,
++				  NULL, xcalloc, xfree);
++  make_cleanup (cleanup_htab, psyms_seen);
++
+   /* The list is already sorted, so we don't need to do additional
+      work here.  Also, the debug_types entries do not appear in
+      all_comp_units, but only in their own hash table.  */
+@@ -14695,11 +14727,15 @@ write_psymtabs_to_index (struct objfile 
+       gdb_byte val[8];
+ 
+       write_psymbols (symtab,
++		      psyms_seen,
+ 		      objfile->global_psymbols.list + psymtab->globals_offset,
+-		      psymtab->n_global_syms, i);
++		      psymtab->n_global_syms, i,
++		      0);
+       write_psymbols (symtab,
++		      psyms_seen,
+ 		      objfile->static_psymbols.list + psymtab->statics_offset,
+-		      psymtab->n_static_syms, i);
++		      psymtab->n_static_syms, i,
++		      1);
+ 
+       add_address_entry (objfile, &addr_obstack, psymtab, i);
+ 
+@@ -14717,6 +14753,7 @@ write_psymtabs_to_index (struct objfile 
+       sig_data.objfile = objfile;
+       sig_data.symtab = symtab;
+       sig_data.types_list = &types_cu_list;
++      sig_data.psyms_seen = psyms_seen;
+       sig_data.cu_index = dwarf2_per_objfile->n_comp_units;
+       htab_traverse_noresize (dwarf2_per_objfile->signatured_types,
+ 			      write_one_signatured_type, &sig_data);
+@@ -14734,7 +14771,7 @@ write_psymtabs_to_index (struct objfile 
+   total_len = size_of_contents;
+ 
+   /* The version number.  */
+-  val = MAYBE_SWAP (2);
++  val = MAYBE_SWAP (3);
+   obstack_grow (&contents, &val, sizeof (val));
+ 
+   /* The offset of the CU list from the start of the file.  */
+@@ -14791,18 +14828,16 @@ write_psymtabs_to_index (struct objfile 
+ 
+    1. The file header.  This is a sequence of values, of offset_type
+    unless otherwise noted:
+-   [0] The version number.  Currently 1 or 2.  The differences are
+-   noted below.  Version 1 did not account for .debug_types sections;
+-   the presence of a .debug_types section invalidates any version 1
+-   index that may exist.
++
++   [0] The version number, currently 3.  Versions 1 and 2 are
++   obsolete.
+    [1] The offset, from the start of the file, of the CU list.
+-   [1.5] In version 2, the offset, from the start of the file, of the
+-   types CU list.  This offset does not appear in version 1.  Note
+-   that this can be empty, in which case this offset will be equal to
+-   the next offset.
+-   [2] The offset, from the start of the file, of the address section.
+-   [3] The offset, from the start of the file, of the symbol table.
+-   [4] The offset, from the start of the file, of the constant pool.
++   [2] The offset, from the start of the file, of the types CU list.
++   Note that this section can be empty, in which case this offset will
++   be equal to the next offset.
++   [3] The offset, from the start of the file, of the address section.
++   [4] The offset, from the start of the file, of the symbol table.
++   [5] The offset, from the start of the file, of the constant pool.
+ 
+    2. The CU list.  This is a sequence of pairs of 64-bit
+    little-endian values, sorted by the CU offset.  The first element
+@@ -14813,19 +14848,19 @@ write_psymtabs_to_index (struct objfile 
+    type CUs, then conceptually CUs and type CUs form a single list for
+    the purposes of CU indices.
+ 
+-   2.5 The types CU list.  This does not appear in a version 1 index.
+-   This is a sequence of triplets of 64-bit little-endian values.  In
+-   a triplet, the first value is the CU offset, the second value is
+-   the type offset in the CU, and the third value is the type
+-   signature.  The types CU list is not sorted.
++   3. The types CU list.  This is a sequence of triplets of 64-bit
++   little-endian values.  In a triplet, the first value is the CU
++   offset, the second value is the type offset in the CU, and the
++   third value is the type signature.  The types CU list is not
++   sorted.
+ 
+-   3. The address section.  The address section consists of a sequence
++   4. The address section.  The address section consists of a sequence
+    of address entries.  Each address entry has three elements.
+    [0] The low address.  This is a 64-bit little-endian value.
+    [1] The high address.  This is a 64-bit little-endian value.
+    [2] The CU index.  This is an offset_type value.
+ 
+-   4. The symbol table.  This is a hash table.  The size of the hash
++   5. The symbol table.  This is a hash table.  The size of the hash
+    table is always a power of 2.  The initial hash and the step are
+    currently defined by the `find_slot' function.
+ 
+@@ -14847,7 +14882,7 @@ write_psymtabs_to_index (struct objfile 
+    element in the hash table is used to indicate which CUs define the
+    symbol.
+ 
+-   5. The constant pool.  This is simply a bunch of bytes.  It is
++   6. The constant pool.  This is simply a bunch of bytes.  It is
+    organized so that alignment is correct: CU vectors are stored
+    first, followed by strings.  */
+ static void
diff --git a/gdb.spec b/gdb.spec
index ab47d56..0aa090d 100644
--- a/gdb.spec
+++ b/gdb.spec
@@ -452,7 +452,9 @@ Patch510: gdb-bz592031-siginfo-lost-4of5.patch
 Patch511: gdb-bz592031-siginfo-lost-5of5.patch
 
 # Fix .gdb_index for big-endian hosts (Tom Tromey).
+Patch514: gdb-gdbindex-v1-to-v2.patch
 Patch512: gdb-gdbindex-bigendian.patch
+Patch515: gdb-gdbindex-v2-to-v3.patch
 
 # [ifunc] Fix crash on deleting watchpoint of an autovariable (BZ 637770).
 Patch513: gdb-bz637770-ifunc-watchpoint-delete.patch
@@ -721,7 +723,9 @@ rm -f gdb/jv-exp.c gdb/m2-exp.c gdb/objc-exp.c gdb/p-exp.c
 %patch509 -p1
 %patch510 -p1
 %patch511 -p1
+%patch514 -p1
 %patch512 -p1
+%patch515 -p1
 %patch513 -p1
 
 %patch393 -p1
@@ -1093,6 +1097,9 @@ fi
 %endif
 
 %changelog
+* Tue Oct 12 2010 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.2-19.fc14
+- Use .gdb_index v3 to fix excessive resources rqmnts (BZ 640634, Tom Tromey).
+
 * Wed Oct  6 2010 Jan Kratochvil <jan.kratochvil at redhat.com> - 7.2-18.fc14
 - Fix false warning: non-absolute filename: <the main exec. file> (BZ 640648).
 


More information about the scm-commits mailing list