diff options
author | Doug Evans <dje@google.com> | 2013-05-20 17:24:21 +0000 |
---|---|---|
committer | Doug Evans <dje@google.com> | 2013-05-20 17:24:21 +0000 |
commit | a2ce51a0ef22447c5a38208f0e4af682edc1778a (patch) | |
tree | ab72a8e152244ba893048817eb5fc90505e45a92 | |
parent | 593f8f293850551eaf010c0af54015db4da140e8 (diff) | |
download | binutils-a2ce51a0ef22447c5a38208f0e4af682edc1778a.zip binutils-a2ce51a0ef22447c5a38208f0e4af682edc1778a.tar.gz binutils-a2ce51a0ef22447c5a38208f0e4af682edc1778a.tar.bz2 |
When reading CU, stay in DWO. Be more tolerent of bad debug info.
For Fission.
* dwarf2read.c (struct dwarf2_per_cu_data): New member
reading_dwo_directly.
(struct signatured_type): New member dwo_unit.
(struct die_reader_specs): New member comp_dir.
(create_signatured_type_table_from_index): Use malloc for
all_type_units instead of objfile's obstack.
(create_all_type_units): Ditto.
(fill_in_sig_entry_from_dwo_entry): New function.
(add_type_unit): New function.
(lookup_dwo_signatured_type): New function.
(lookup_dwp_signatured_type): New function.
(lookup_signatured_type): New arg cu. All callers updated.
(init_cu_die_reader): Initialize comp_dir.
(read_cutu_die_from_dwo): New arg stub_comp_dir. All callers updated.
Change assert of matching type signatures to call error on mismatch.
(lookup_dwo_unit): Add assert.
(init_tu_and_read_dwo_dies): New function.
(init_cutu_and_read_dies): Call it.
(build_type_unit_groups): Handle case of no type unit groups created.
(hash_dwo_file, eq_dwo_file): Handle missing comp_dir.
(lookup_dwo_cutu): Tweak complaint.
(dwarf2_free_abbrev_table): Check for NULL abbrev_table.
(dwarf2_per_objfile_free): Free all_type_units.
-rw-r--r-- | gdb/ChangeLog | 28 | ||||
-rw-r--r-- | gdb/dwarf2read.c | 382 |
2 files changed, 385 insertions, 25 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 20bd955..59995a2 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,31 @@ +2013-05-20 Doug Evans <dje@google.com> + + When reading CU, stay in DWO. Be more tolerent of bad debug info. + For Fission. + * dwarf2read.c (struct dwarf2_per_cu_data): New member + reading_dwo_directly. + (struct signatured_type): New member dwo_unit. + (struct die_reader_specs): New member comp_dir. + (create_signatured_type_table_from_index): Use malloc for + all_type_units instead of objfile's obstack. + (create_all_type_units): Ditto. + (fill_in_sig_entry_from_dwo_entry): New function. + (add_type_unit): New function. + (lookup_dwo_signatured_type): New function. + (lookup_dwp_signatured_type): New function. + (lookup_signatured_type): New arg cu. All callers updated. + (init_cu_die_reader): Initialize comp_dir. + (read_cutu_die_from_dwo): New arg stub_comp_dir. All callers updated. + Change assert of matching type signatures to call error on mismatch. + (lookup_dwo_unit): Add assert. + (init_tu_and_read_dwo_dies): New function. + (init_cutu_and_read_dies): Call it. + (build_type_unit_groups): Handle case of no type unit groups created. + (hash_dwo_file, eq_dwo_file): Handle missing comp_dir. + (lookup_dwo_cutu): Tweak complaint. + (dwarf2_free_abbrev_table): Check for NULL abbrev_table. + (dwarf2_per_objfile_free): Free all_type_units. + 2013-05-20 Joel Brobecker <brobecker@adacore.com> * windows-nat.c (handle_unload_dll): Add missing empty line. diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c index 036ccfe..b819d3c 100644 --- a/gdb/dwarf2read.c +++ b/gdb/dwarf2read.c @@ -202,7 +202,8 @@ struct dwarf2_per_objfile /* The number of .debug_types-related CUs. */ int n_type_units; - /* The .debug_types-related CUs (TUs). */ + /* The .debug_types-related CUs (TUs). + This is stored in malloc space because we may realloc it. */ struct signatured_type **all_type_units; /* The number of entries in all_type_unit_groups. */ @@ -551,6 +552,12 @@ struct dwarf2_per_cu_data /* Non-zero if this CU is from the .dwz file. */ unsigned int is_dwz : 1; + /* Non-zero if reading a TU directly from a DWO file, bypassing the stub. + This flag is only valid if is_debug_types is true. + We can't read a CU directly from a DWO file: There are required + attributes in the stub. */ + unsigned int reading_dwo_directly : 1; + /* The section this CU/TU lives in. If the DIE refers to a DWO file, this is always the original die, not the DWO file. */ @@ -630,6 +637,10 @@ struct signatured_type The first time we encounter this type we fully read it in and install it in the symbol tables. Subsequent times we only need the type. */ struct type *type; + + /* Containing DWO unit. + This field is valid iff per_cu.reading_dwo_directly. */ + struct dwo_unit *dwo_unit; }; typedef struct signatured_type *sig_type_ptr; @@ -863,6 +874,9 @@ struct die_reader_specs /* The end of the buffer. */ const gdb_byte *buffer_end; + + /* The value of the DW_AT_comp_dir attribute. */ + const char *comp_dir; }; /* Type of function passed to init_cutu_and_read_dies, et.al. */ @@ -1745,6 +1759,12 @@ static htab_t allocate_signatured_type_table (struct objfile *objfile); static htab_t allocate_dwo_unit_table (struct objfile *objfile); +static struct dwo_unit *lookup_dwo_in_dwp + (struct dwp_file *dwp_file, const struct dwp_hash_table *htab, + const char *comp_dir, ULONGEST signature, int is_debug_types); + +static struct dwp_file *get_dwp_file (void); + static struct dwo_unit *lookup_dwo_comp_unit (struct dwarf2_per_cu_data *, const char *, const char *, ULONGEST); @@ -2466,9 +2486,8 @@ create_signatured_type_table_from_index (struct objfile *objfile, dwarf2_per_objfile->n_type_units = elements / 3; dwarf2_per_objfile->all_type_units - = obstack_alloc (&objfile->objfile_obstack, - dwarf2_per_objfile->n_type_units - * sizeof (struct signatured_type *)); + = xmalloc (dwarf2_per_objfile->n_type_units + * sizeof (struct signatured_type *)); sig_types_hash = allocate_signatured_type_table (objfile); @@ -4378,9 +4397,8 @@ create_all_type_units (struct objfile *objfile) dwarf2_per_objfile->n_type_units = htab_elements (types_htab); dwarf2_per_objfile->all_type_units - = obstack_alloc (&objfile->objfile_obstack, - dwarf2_per_objfile->n_type_units - * sizeof (struct signatured_type *)); + = xmalloc (dwarf2_per_objfile->n_type_units + * sizeof (struct signatured_type *)); iter = &dwarf2_per_objfile->all_type_units[0]; htab_traverse_noresize (types_htab, add_signatured_type_cu_to_table, &iter); gdb_assert (iter - &dwarf2_per_objfile->all_type_units[0] @@ -4389,20 +4407,196 @@ create_all_type_units (struct objfile *objfile) return 1; } +/* Subroutine of lookup_dwo_signatured_type and lookup_dwp_signatured_type. + Fill in SIG_ENTRY with DWO_ENTRY. */ + +static void +fill_in_sig_entry_from_dwo_entry (struct objfile *objfile, + struct signatured_type *sig_entry, + struct dwo_unit *dwo_entry) +{ + sig_entry->per_cu.section = dwo_entry->section; + sig_entry->per_cu.offset = dwo_entry->offset; + sig_entry->per_cu.length = dwo_entry->length; + sig_entry->per_cu.reading_dwo_directly = 1; + sig_entry->per_cu.objfile = objfile; + gdb_assert (! sig_entry->per_cu.queued); + gdb_assert (sig_entry->per_cu.cu == NULL); + gdb_assert (sig_entry->per_cu.v.quick != NULL); + gdb_assert (sig_entry->per_cu.v.quick->symtab == NULL); + gdb_assert (sig_entry->signature == dwo_entry->signature); + gdb_assert (sig_entry->type_offset_in_section.sect_off == 0); + gdb_assert (sig_entry->type_unit_group == NULL); + sig_entry->type_offset_in_tu = dwo_entry->type_offset_in_tu; + sig_entry->dwo_unit = dwo_entry; +} + +/* Subroutine of lookup_signatured_type. + Create the signatured_type data structure for a TU to be read in + directly from a DWO file, bypassing the stub. + We do this for the case where there is no DWP file and we're using + .gdb_index: When reading a CU we want to stay in the DWO file containing + that CU. Otherwise we could end up reading several other DWO files (due + to comdat folding) to process the transitive closure of all the mentioned + TUs, and that can be slow. The current DWO file will have every type + signature that it needs. + We only do this for .gdb_index because in the psymtab case we already have + to read all the DWOs to build the type unit groups. */ + +static struct signatured_type * +lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct dwo_file *dwo_file; + struct dwo_unit find_dwo_entry, *dwo_entry; + struct signatured_type find_sig_entry, *sig_entry; + + gdb_assert (cu->dwo_unit && dwarf2_per_objfile->using_index); + + /* Note: cu->dwo_unit is the dwo_unit that references this TU, not the + dwo_unit of the TU itself. */ + dwo_file = cu->dwo_unit->dwo_file; + + /* We only ever need to read in one copy of a signatured type. + Just use the global signatured_types array. If this is the first time + we're reading this type, replace the recorded data from .gdb_index with + this TU. */ + + if (dwarf2_per_objfile->signatured_types == NULL) + return NULL; + find_sig_entry.signature = sig; + sig_entry = htab_find (dwarf2_per_objfile->signatured_types, &find_sig_entry); + if (sig_entry == NULL) + return NULL; + /* Have we already tried to read this TU? */ + if (sig_entry->dwo_unit != NULL) + return sig_entry; + + /* Ok, this is the first time we're reading this TU. */ + if (dwo_file->tus == NULL) + return NULL; + find_dwo_entry.signature = sig; + dwo_entry = htab_find (dwo_file->tus, &find_dwo_entry); + if (dwo_entry == NULL) + return NULL; + + fill_in_sig_entry_from_dwo_entry (objfile, sig_entry, dwo_entry); + return sig_entry; +} + +/* Subroutine of lookup_dwp_signatured_type. + Add an entry for signature SIG to dwarf2_per_objfile->signatured_types. */ + +static struct signatured_type * +add_type_unit (ULONGEST sig) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + int n_type_units = dwarf2_per_objfile->n_type_units; + struct signatured_type *sig_type; + void **slot; + + ++n_type_units; + dwarf2_per_objfile->all_type_units = + xrealloc (dwarf2_per_objfile->all_type_units, + n_type_units * sizeof (struct signatured_type *)); + dwarf2_per_objfile->n_type_units = n_type_units; + sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack, + struct signatured_type); + dwarf2_per_objfile->all_type_units[n_type_units - 1] = sig_type; + sig_type->signature = sig; + sig_type->per_cu.is_debug_types = 1; + sig_type->per_cu.v.quick = + OBSTACK_ZALLOC (&objfile->objfile_obstack, + struct dwarf2_per_cu_quick_data); + slot = htab_find_slot (dwarf2_per_objfile->signatured_types, + sig_type, INSERT); + gdb_assert (*slot == NULL); + *slot = sig_type; + /* The rest of sig_type must be filled in by the caller. */ + return sig_type; +} + +/* Subroutine of lookup_signatured_type. + Look up the type for signature SIG, and if we can't find SIG in .gdb_index + then try the DWP file. + Normally this "can't happen", but if there's a bug in signature + generation and/or the DWP file is built incorrectly, it can happen. + Using the type directly from the DWP file means we don't have the stub + which has some useful attributes (e.g., DW_AT_comp_dir), but they're + not critical. [Eventually the stub may go away for type units anyway.] */ + +static struct signatured_type * +lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig) +{ + struct objfile *objfile = dwarf2_per_objfile->objfile; + struct dwp_file *dwp_file = get_dwp_file (); + struct dwo_unit *dwo_entry; + struct signatured_type find_sig_entry, *sig_entry; + + gdb_assert (cu->dwo_unit && dwarf2_per_objfile->using_index); + gdb_assert (dwp_file != NULL); + + if (dwarf2_per_objfile->signatured_types != NULL) + { + find_sig_entry.signature = sig; + sig_entry = htab_find (dwarf2_per_objfile->signatured_types, + &find_sig_entry); + if (sig_entry != NULL) + return sig_entry; + } + + /* This is the "shouldn't happen" case. + Try the DWP file and hope for the best. */ + if (dwp_file->tus == NULL) + return NULL; + dwo_entry = lookup_dwo_in_dwp (dwp_file, dwp_file->tus, NULL, + sig, 1 /* is_debug_types */); + if (dwo_entry == NULL) + return NULL; + + sig_entry = add_type_unit (sig); + fill_in_sig_entry_from_dwo_entry (objfile, sig_entry, dwo_entry); + + /* The caller will signal a complaint if we return NULL. + Here we don't return NULL but we still want to complain. */ + complaint (&symfile_complaints, + _("Bad type signature %s referenced by %s at 0x%x," + " coping by using copy in DWP [in module %s]"), + hex_string (sig), + cu->per_cu->is_debug_types ? "TU" : "CU", + cu->per_cu->offset.sect_off, + objfile->name); + + return sig_entry; +} + /* Lookup a signature based type for DW_FORM_ref_sig8. Returns NULL if signature SIG is not present in the table. It is up to the caller to complain about this. */ static struct signatured_type * -lookup_signatured_type (ULONGEST sig) +lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig) { - struct signatured_type find_entry, *entry; + if (cu->dwo_unit + && dwarf2_per_objfile->using_index) + { + /* We're in a DWO/DWP file, and we're using .gdb_index. + These cases require special processing. */ + if (get_dwp_file () == NULL) + return lookup_dwo_signatured_type (cu, sig); + else + return lookup_dwp_signatured_type (cu, sig); + } + else + { + struct signatured_type find_entry, *entry; - if (dwarf2_per_objfile->signatured_types == NULL) - return NULL; - find_entry.signature = sig; - entry = htab_find (dwarf2_per_objfile->signatured_types, &find_entry); - return entry; + if (dwarf2_per_objfile->signatured_types == NULL) + return NULL; + find_entry.signature = sig; + entry = htab_find (dwarf2_per_objfile->signatured_types, &find_entry); + return entry; + } } /* Low level DIE reading support. */ @@ -4422,6 +4616,7 @@ init_cu_die_reader (struct die_reader_specs *reader, reader->die_section = section; reader->buffer = section->buffer; reader->buffer_end = section->buffer + section->size; + reader->comp_dir = NULL; } /* Subroutine of init_cutu_and_read_dies to simplify it. @@ -4431,6 +4626,10 @@ init_cu_die_reader (struct die_reader_specs *reader, STUB_COMP_UNIT_DIE is for the stub DIE, we copy over certain attributes from it to the DIE in the DWO. If NULL we are skipping the stub. + STUB_COMP_DIR is similar to STUB_COMP_UNIT_DIE: When reading a TU directly + from the DWO file, bypassing the stub, it contains the DW_AT_comp_dir + attribute of the referencing CU. Exactly one of STUB_COMP_UNIT_DIE and + COMP_DIR must be non-NULL. *RESULT_READER,*RESULT_INFO_PTR,*RESULT_COMP_UNIT_DIE,*RESULT_HAS_CHILDREN are filled in with the info of the DIE from the DWO file. ABBREV_TABLE_PROVIDED is non-zero if the caller of init_cutu_and_read_dies @@ -4442,6 +4641,7 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu, struct dwo_unit *dwo_unit, int abbrev_table_provided, struct die_info *stub_comp_unit_die, + const char *stub_comp_dir, struct die_reader_specs *result_reader, const gdb_byte **result_info_ptr, struct die_info **result_comp_unit_die, @@ -4458,8 +4658,12 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu, int i,num_extra_attrs; struct dwarf2_section_info *dwo_abbrev_section; struct attribute *attr; + struct attribute comp_dir_attr; struct die_info *comp_unit_die; + /* Both can't be provided. */ + gdb_assert (! (stub_comp_unit_die && stub_comp_dir)); + /* These attributes aren't processed until later: DW_AT_stmt_list, DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges. However, the attribute is found in the stub which we won't have later. @@ -4497,6 +4701,16 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu, if (attr) cu->ranges_base = DW_UNSND (attr); } + else if (stub_comp_dir != NULL) + { + /* Reconstruct the comp_dir attribute to simplify the code below. */ + comp_dir = (struct attribute *) + obstack_alloc (&cu->comp_unit_obstack, sizeof (*comp_dir)); + comp_dir->name = DW_AT_comp_dir; + comp_dir->form = DW_FORM_string; + DW_STRING_IS_CANONICAL (comp_dir) = 0; + DW_STRING (comp_dir) = stub_comp_dir; + } /* Set up for reading the DWO CU/TU. */ cu->dwo_unit = dwo_unit; @@ -4518,7 +4732,16 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu, info_ptr, &header_signature, &type_offset_in_tu); - gdb_assert (sig_type->signature == header_signature); + /* This is not an assert because it can be caused by bad debug info. */ + if (sig_type->signature != header_signature) + { + error (_("Dwarf Error: signature mismatch %s vs %s while reading" + " TU at offset 0x%x [in module %s]"), + hex_string (sig_type->signature), + hex_string (header_signature), + dwo_unit->offset.sect_off, + bfd_get_filename (abfd)); + } gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off); /* For DWOs coming from DWP files, we don't know the CU length nor the type's offset in the TU until now. */ @@ -4595,6 +4818,13 @@ read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu, dump_die (comp_unit_die, dwarf2_die_debug); } + /* Save the comp_dir attribute. If there is no DWP file then we'll read + TUs by skipping the stub and going directly to the entry in the DWO file. + However, skipping the stub means we won't get DW_AT_comp_dir, so we have + to get it via circuitous means. Blech. */ + if (comp_dir != NULL) + result_reader->comp_dir = DW_STRING (comp_dir); + /* Skip dummy compilation units. */ if (info_ptr >= begin_info_ptr + dwo_unit->length || peek_abbrev_code (abfd, info_ptr) == 0) @@ -4618,6 +4848,8 @@ lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu, struct dwo_unit *dwo_unit; const char *comp_dir, *dwo_name; + gdb_assert (cu != NULL); + /* Yeah, we look dwo_name up again, but it simplifies the code. */ attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_name, cu); gdb_assert (attr != NULL); @@ -4654,6 +4886,75 @@ lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu, return dwo_unit; } +/* Subroutine of init_cutu_and_read_dies to simplify it. + Read a TU directly from a DWO file, bypassing the stub. */ + +static void +init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu, int keep, + die_reader_func_ftype *die_reader_func, + void *data) +{ + struct dwarf2_cu *cu; + struct signatured_type *sig_type; + struct cleanup *cleanups, *free_cu_cleanup; + struct die_reader_specs reader; + const gdb_byte *info_ptr; + struct die_info *comp_unit_die; + int has_children; + + /* Verify we can do the following downcast, and that we have the + data we need. */ + gdb_assert (this_cu->is_debug_types && this_cu->reading_dwo_directly); + sig_type = (struct signatured_type *) this_cu; + gdb_assert (sig_type->dwo_unit != NULL); + + cleanups = make_cleanup (null_cleanup, NULL); + + gdb_assert (this_cu->cu == NULL); + cu = xmalloc (sizeof (*cu)); + init_one_comp_unit (cu, this_cu); + /* If an error occurs while loading, release our storage. */ + free_cu_cleanup = make_cleanup (free_heap_comp_unit, cu); + + if (read_cutu_die_from_dwo (this_cu, sig_type->dwo_unit, + 0 /* abbrev_table_provided */, + NULL /* stub_comp_unit_die */, + sig_type->dwo_unit->dwo_file->comp_dir, + &reader, &info_ptr, + &comp_unit_die, &has_children) == 0) + { + /* Dummy die. */ + do_cleanups (cleanups); + return; + } + + /* All the "real" work is done here. */ + die_reader_func (&reader, info_ptr, comp_unit_die, has_children, data); + + /* This duplicates some code in init_cutu_and_read_dies, + but the alternative is making the latter more complex. + This function is only for the special case of using DWO files directly: + no point in overly complicating the general case just to handle this. */ + if (keep) + { + /* We've successfully allocated this compilation unit. Let our + caller clean it up when finished with it. */ + discard_cleanups (free_cu_cleanup); + + /* We can only discard free_cu_cleanup and all subsequent cleanups. + So we have to manually free the abbrev table. */ + dwarf2_free_abbrev_table (cu); + + /* Link this CU into read_in_chain. */ + this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain; + dwarf2_per_objfile->read_in_chain = this_cu; + } + else + do_cleanups (free_cu_cleanup); + + do_cleanups (cleanups); +} + /* Initialize a CU (or TU) and read its DIEs. If the CU defers to a DWO file, read the DWO file as well. @@ -4691,7 +4992,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, struct dwarf2_section_info *abbrev_section; /* Non-zero if CU currently points to a DWO file and we need to reread it. When this happens we need to reread the skeleton die - before we can reread the DWO file. */ + before we can reread the DWO file (this only applies to CUs, not TUs). */ int rereading_dwo_cu = 0; if (dwarf2_die_debug) @@ -4702,6 +5003,18 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, if (use_existing_cu) gdb_assert (keep); + /* If we're reading a TU directly from a DWO file, including a virtual DWO + file (instead of going through the stub), short-circuit all of this. */ + if (this_cu->reading_dwo_directly) + { + /* Narrow down the scope of possibilities to have to understand. */ + gdb_assert (this_cu->is_debug_types); + gdb_assert (abbrev_table == NULL); + gdb_assert (!use_existing_cu); + init_tu_and_read_dwo_dies (this_cu, keep, die_reader_func, data); + return; + } + cleanups = make_cleanup (null_cleanup, NULL); /* This is cheap if the section is already read in. */ @@ -4838,7 +5151,7 @@ init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu, { if (read_cutu_die_from_dwo (this_cu, dwo_unit, abbrev_table != NULL, - comp_unit_die, + comp_unit_die, NULL, &reader, &info_ptr, &dwo_comp_unit_die, &has_children) == 0) { @@ -5272,6 +5585,16 @@ build_type_unit_groups (die_reader_func_ftype *func, void *data) func, data); } + /* type_unit_groups can be NULL if there is an error in the debug info. + Just create an empty table so the rest of gdb doesn't have to watch + for this error case. */ + if (dwarf2_per_objfile->type_unit_groups == NULL) + { + dwarf2_per_objfile->type_unit_groups = + allocate_type_unit_groups_table (); + dwarf2_per_objfile->n_type_unit_groups = 0; + } + /* Create a vector of pointers to primary type units to make it easy to iterate over them and CUs. See dw2_get_primary_cu. */ dwarf2_per_objfile->n_type_unit_groups = @@ -8323,9 +8646,12 @@ static hashval_t hash_dwo_file (const void *item) { const struct dwo_file *dwo_file = item; + hashval_t hash; - return (htab_hash_string (dwo_file->dwo_name) - + htab_hash_string (dwo_file->comp_dir)); + hash = htab_hash_string (dwo_file->dwo_name); + if (dwo_file->comp_dir != NULL) + hash += htab_hash_string (dwo_file->comp_dir); + return hash; } static int @@ -8334,8 +8660,11 @@ eq_dwo_file (const void *item_lhs, const void *item_rhs) const struct dwo_file *lhs = item_lhs; const struct dwo_file *rhs = item_rhs; - return (strcmp (lhs->dwo_name, rhs->dwo_name) == 0 - && strcmp (lhs->comp_dir, rhs->comp_dir) == 0); + if (strcmp (lhs->dwo_name, rhs->dwo_name) != 0) + return 0; + if (lhs->comp_dir == NULL || rhs->comp_dir == NULL) + return lhs->comp_dir == rhs->comp_dir; + return strcmp (lhs->comp_dir, rhs->comp_dir) == 0; } /* Allocate a hash table for DWO files. */ @@ -9386,9 +9715,10 @@ lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit, } complaint (&symfile_complaints, - _("Could not find DWO %s %s(%s) referenced by CU at offset 0x%x" + _("Could not find DWO %s %s(%s) referenced by %s at offset 0x%x" " [in module %s]"), kind, dwo_name, hex_string (signature), + this_unit->is_debug_types ? "TU" : "CU", this_unit->offset.sect_off, objfile->name); return NULL; } @@ -13475,7 +13805,8 @@ dwarf2_free_abbrev_table (void *ptr_to_cu) { struct dwarf2_cu *cu = ptr_to_cu; - abbrev_table_free (cu->abbrev_table); + if (cu->abbrev_table != NULL) + abbrev_table_free (cu->abbrev_table); /* Set this to NULL so that we SEGV if we try to read it later, and also because free_comp_unit verifies this is NULL. */ cu->abbrev_table = NULL; @@ -18012,7 +18343,7 @@ follow_die_sig (struct die_info *src_die, struct attribute *attr, gdb_assert (attr->form == DW_FORM_ref_sig8); - sig_type = lookup_signatured_type (signature); + sig_type = lookup_signatured_type (*ref_cu, signature); /* sig_type will be NULL if the signatured type is missing from the debug info. */ if (sig_type == NULL) @@ -18048,7 +18379,7 @@ get_signatured_type (struct die_info *die, ULONGEST signature, struct die_info *type_die; struct type *type; - sig_type = lookup_signatured_type (signature); + sig_type = lookup_signatured_type (cu, signature); /* sig_type will be NULL if the signatured type is missing from the debug info. */ if (sig_type == NULL) @@ -20153,6 +20484,7 @@ dwarf2_per_objfile_free (struct objfile *objfile, void *d) for (ix = 0; ix < dwarf2_per_objfile->n_type_units; ++ix) VEC_free (dwarf2_per_cu_ptr, dwarf2_per_objfile->all_type_units[ix]->per_cu.imported_symtabs); + xfree (dwarf2_per_objfile->all_type_units); VEC_free (dwarf2_section_info_def, data->types); |