From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17611 invoked by alias); 23 Jul 2010 22:12:20 -0000 Received: (qmail 17589 invoked by uid 22791); 23 Jul 2010 22:12:16 -0000 X-SWARE-Spam-Status: No, hits=-6.0 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_BJ,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 23 Jul 2010 22:12:09 +0000 Received: from int-mx05.intmail.prod.int.phx2.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.18]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o6NMC5Wq032573 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 23 Jul 2010 18:12:06 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx05.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o6NMC4qS011772; Fri, 23 Jul 2010 18:12:05 -0400 Received: from opsy.redhat.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id o6NMC3qV004896; Fri, 23 Jul 2010 18:12:04 -0400 Received: by opsy.redhat.com (Postfix, from userid 500) id 87BDE3806CC; Fri, 23 Jul 2010 16:12:03 -0600 (MDT) From: Tom Tromey To: Paul Pluzhnikov Cc: gdb-patches@sourceware.org Subject: Re: [0/4] RFC: add DWARF index support References: Date: Fri, 23 Jul 2010 22:12:00 -0000 In-Reply-To: (Tom Tromey's message of "Thu, 22 Jul 2010 14:53:52 -0600") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-07/txt/msg00372.txt.bz2 >>>>> "Tom" == Tom Tromey writes: Tom> Here is what I am testing. Here is the variant I am checking it. It seems to work with all combinations of .debug_types, .gdb_index, and -readnow. Let me know if you hit any more problems. Tom 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. Index: dwarf2read.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2read.c,v retrieving revision 1.424 diff -u -r1.424 dwarf2read.c --- dwarf2read.c 23 Jul 2010 14:43:33 -0000 1.424 +++ dwarf2read.c 23 Jul 2010 22:07:16 -0000 @@ -180,6 +180,12 @@ /* 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; @@ -1190,6 +1196,8 @@ 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 *); @@ -1227,6 +1235,8 @@ static void init_cu_die_reader (struct die_reader_specs *reader, 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. */ @@ -1603,6 +1613,18 @@ 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. */ @@ -1629,11 +1651,10 @@ 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 @@ -1664,6 +1685,58 @@ 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 @@ -1695,7 +1768,7 @@ 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, @@ -1762,8 +1835,9 @@ 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) @@ -1772,26 +1846,58 @@ 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); @@ -1918,8 +2024,7 @@ 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 @@ -1928,9 +2033,10 @@ 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) { @@ -1952,10 +2058,11 @@ 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; @@ -2047,8 +2154,8 @@ 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); } } @@ -2070,9 +2177,10 @@ 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; @@ -2106,9 +2214,11 @@ 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); } @@ -2121,10 +2231,11 @@ 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; @@ -2165,7 +2276,7 @@ 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) @@ -2204,10 +2315,11 @@ 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) @@ -2252,8 +2364,9 @@ 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); } @@ -2323,10 +2436,11 @@ 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; @@ -2387,10 +2501,12 @@ 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); @@ -2604,6 +2720,34 @@ 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. */ @@ -2613,6 +2757,7 @@ { 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; @@ -2623,13 +2768,7 @@ 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"); @@ -2677,6 +2816,7 @@ 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); @@ -2691,6 +2831,16 @@ 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; } @@ -2959,7 +3109,6 @@ 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, @@ -12067,13 +12216,16 @@ 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)); @@ -13912,6 +14064,10 @@ 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); @@ -13957,13 +14113,53 @@ 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; @@ -13999,6 +14195,12 @@ 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]; @@ -14020,6 +14222,19 @@ 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); @@ -14028,11 +14243,11 @@ 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. */ @@ -14040,6 +14255,11 @@ 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)); @@ -14059,6 +14279,7 @@ 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); @@ -14083,18 +14304,33 @@ 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.