From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5322 invoked by alias); 22 Jul 2010 20:54:12 -0000 Received: (qmail 5306 invoked by uid 22791); 22 Jul 2010 20:54:09 -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; Thu, 22 Jul 2010 20:54:00 +0000 Received: from int-mx08.intmail.prod.int.phx2.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o6MKruEp029748 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 22 Jul 2010 16:53:57 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx08.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o6MKrtXm031626; Thu, 22 Jul 2010 16:53:56 -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 o6MKrrON010365; Thu, 22 Jul 2010 16:53:54 -0400 Received: by opsy.redhat.com (Postfix, from userid 500) id 6191A3797F3; Thu, 22 Jul 2010 14:53:52 -0600 (MDT) From: Tom Tromey To: Paul Pluzhnikov Cc: gdb-patches@sourceware.org Subject: Re: [0/4] RFC: add DWARF index support References: Date: Thu, 22 Jul 2010 20:54:00 -0000 In-Reply-To: (Tom Tromey's message of "Thu, 22 Jul 2010 09:53:26 -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/msg00356.txt.bz2 Tom> The bigger problem is that I completely forgot about .debug_types. Tom> I am not certain that a simple fix will work if we have both Tom> .debug_types and .gdb_index. I will try that out. Tom> I think this is going to need an index version bump. Tom> I am still looking into it. Here is what I am testing. This also fixes a bug in dwarf2_initialize_objfile that prevents -readnow from working when .debug_types exists. If necessary this can be fixed separately, though such a fix would have to be backed out when this patch goes in. I bumped the index version number because I believe we've built some version 1 indices in the Fedora buildroots already. Tom 2010-07-22 Tom Tromey * dwarf2read.c (dwarf2_per_cu_data_ptr): Remove. (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. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 8084f42..7ab18e4 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -155,9 +155,6 @@ struct mapped_index const char *constant_pool; }; -typedef struct dwarf2_per_cu_data *dwarf2_per_cu_data_ptr; -DEF_VEC_P (dwarf2_per_cu_data_ptr); - struct dwarf2_per_objfile { struct dwarf2_section_info info; @@ -182,6 +179,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; @@ -1192,6 +1195,8 @@ static struct type *set_die_type (struct die_info *, struct type *, 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 *); @@ -1229,6 +1234,8 @@ static gdb_byte *partial_read_comp_unit_head (struct comp_unit_head *header, 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. */ @@ -1605,6 +1612,18 @@ dw2_instantiate_symtab (struct objfile *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. */ @@ -1631,11 +1650,10 @@ extract_cu_value (const char *bytes, ULONGEST *result) 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 @@ -1666,6 +1684,58 @@ create_cus_from_index (struct objfile *objfile, struct mapped_index *index, 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 @@ -1697,7 +1767,7 @@ create_addrmap_from_index (struct objfile *objfile, struct mapped_index *index) 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, @@ -1767,8 +1837,9 @@ dwarf2_read_index (struct objfile *objfile) struct mapped_index *map; offset_type val, *metadata; char buf1[8], buf2[8]; - 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) @@ -1777,26 +1848,58 @@ dwarf2_read_index (struct objfile *objfile) 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 = st.st_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; + + map->constant_pool = addr + MAYBE_SWAP (metadata[i]); - if (!create_cus_from_index (objfile, map, cu_list, cu_list_elements)) + 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); @@ -1923,8 +2026,7 @@ dw2_find_last_source_symtab (struct objfile *objfile) 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 @@ -1933,9 +2035,10 @@ dw2_forget_cached_source_info (struct objfile *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); if (cu->v.quick->full_names) { @@ -1957,10 +2060,11 @@ dw2_lookup_symtab (struct objfile *objfile, const char *name, 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; @@ -2052,8 +2156,8 @@ dw2_do_expand_symtabs_matching (struct objfile *objfile, const char *name) 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); } } @@ -2075,9 +2179,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; @@ -2111,9 +2216,11 @@ dw2_expand_all_symtabs (struct objfile *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); } @@ -2126,10 +2233,11 @@ dw2_expand_symtabs_with_filename (struct objfile *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; @@ -2170,7 +2278,7 @@ dw2_find_symbol_file (struct objfile *objfile, const char *name) 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) @@ -2209,10 +2317,11 @@ dw2_expand_symtabs_matching (struct objfile *objfile, 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) @@ -2257,8 +2366,9 @@ dw2_expand_symtabs_matching (struct objfile *objfile, 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); } @@ -2328,10 +2438,11 @@ dw2_map_symbol_filenames (struct objfile *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; @@ -2392,10 +2503,12 @@ dwarf2_initialize_objfile (struct objfile *objfile) 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); @@ -2609,6 +2722,34 @@ eq_type_signature (const void *item_lhs, const void *item_rhs) 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. */ @@ -2618,6 +2759,7 @@ create_debug_types_hash_table (struct objfile *objfile) { 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; @@ -2628,13 +2770,7 @@ create_debug_types_hash_table (struct objfile *objfile) 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"); @@ -2695,6 +2831,16 @@ create_debug_types_hash_table (struct objfile *objfile) 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; } @@ -12051,13 +12197,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)); @@ -13881,6 +14030,10 @@ add_address_entry (struct objfile *objfile, 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); @@ -13926,13 +14079,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; @@ -13968,6 +14161,12 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) 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]; @@ -13989,6 +14188,19 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) 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); @@ -13997,11 +14209,11 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) 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. */ @@ -14009,6 +14221,11 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) 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)); @@ -14028,6 +14245,7 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) 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); @@ -14052,18 +14270,33 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir) 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 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.