aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDoug Evans <dje@google.com>2013-05-20 17:24:21 +0000
committerDoug Evans <dje@google.com>2013-05-20 17:24:21 +0000
commita2ce51a0ef22447c5a38208f0e4af682edc1778a (patch)
treeab72a8e152244ba893048817eb5fc90505e45a92
parent593f8f293850551eaf010c0af54015db4da140e8 (diff)
downloadgdb-a2ce51a0ef22447c5a38208f0e4af682edc1778a.zip
gdb-a2ce51a0ef22447c5a38208f0e4af682edc1778a.tar.gz
gdb-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/ChangeLog28
-rw-r--r--gdb/dwarf2read.c382
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);