From df661e30f97bf961dcdd19c22207b6a5a783a0a3 Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Oct 12 2010 16:18:54 +0000 Subject: - Use .gdb_index v3 to fix excessive resources rqmnts (BZ 640634, Tom Tromey). --- 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 ++ ++ * dwarf2read.c (struct dwarf2_per_objfile) : 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 + + * 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 + ++ * 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) : 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 ++ + * bcache.c (expand_hash_table): Use hash_function, not hash. + + 2010-09-27 Tom Tromey +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 - 7.2-19.fc14 +- Use .gdb_index v3 to fix excessive resources rqmnts (BZ 640634, Tom Tromey). + * Wed Oct 6 2010 Jan Kratochvil - 7.2-18.fc14 - Fix false warning: non-absolute filename: (BZ 640648).