[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