aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2012-05-10 20:17:51 +0000
committerTom Tromey <tromey@redhat.com>2012-05-10 20:17:51 +0000
commit95554aad6c78f459750b8edda9e1832063083132 (patch)
treed9f044d34cf13aa5839eb2447d30663b4235baa1
parente871fbb936d39edd8558e25169114820f1042ef1 (diff)
downloadgdb-95554aad6c78f459750b8edda9e1832063083132.zip
gdb-95554aad6c78f459750b8edda9e1832063083132.tar.gz
gdb-95554aad6c78f459750b8edda9e1832063083132.tar.bz2
* dwarf2read.c (recursively_write_psymbols): New function.
(write_psymtabs_to_index): Use it. * dwarf2read.c (struct dwarf2_queue_item) <pretend_language>: New field. (load_cu, dw2_do_instantiate_symtab, process_psymtab_comp_unit) (load_partial_comp_unit): Update. (queue_comp_unit): Add argument 'pretend_language'. (process_queue): Update. (psymtab_to_symtab_1): Skip dependencies that have a user. (load_partial_comp_unit_reader): Give meaning to the 'data' argument. (load_full_comp_unit): Add 'pretend_language' argument. (process_full_comp_unit): Add 'pretend_language' argument. Set language on CU. (process_imported_unit_die, read_file_scope, read_type_unit_scope): Update. (maybe_queue_comp_unit): Add 'pretend_language' argument. (follow_die_offset, follow_die_sig, read_signatured_type_reader): Update. (prepare_one_comp_unit): Add 'pretend_language' argument. * dwarf2read.c: (dwarf2_per_cu_ptr): New typedef. (struct dwarf2_per_objfile) <just_read_cus>: New field. (struct dwarf2_per_cu_data) <imported_symtabs>: New field. (dw2_do_instantiate_symtab): Check whether symtab was read in before queueing. (dw2_instantiate_symtab): Add assertion. Call process_cu_includes. (process_psymtab_comp_unit): Compute 'dependencies' for psymtab. (partial_symtab_p): New typedef. (set_partial_user): New function. (dwarf2_build_psymtabs_hard): Use set_partial_user. (scan_partial_symbols): Add imported CU to imported_symtabs. (dwarf2_psymtab_to_symtab): Call process_cu_includes. (psymtab_to_symtab_1): Do nothing if psymtab is readin. (get_symtab, recursively_compute_inclusions) (compute_symtab_includes, process_cu_includes) (process_imported_unit_die): New functions. (process_die) <DW_TAG_imported_unit>: New case. (dwarf2_per_objfile_free): Free 'imported_symtabs'. * dwarf2read.c (struct dwarf2_per_cu_data) <psymtab>: Update comment. (struct partial_die_info) <locdesc>: Remove. <d>: New field. (process_psymtab_comp_unit): Add 'read_partial' argument. Update. (process_type_comp_unit, dwarf2_build_psymtabs_hard): Update. (scan_partial_symbols): Handle DW_TAG_imported_unit. (add_partial_symbol): Update. (process_die): Handle DW_TAG_partial_unit. (read_file_scope): Update comment. (load_partial_dies): Handle DW_TAG_imported_unit. (read_partial_die): Handle DW_TAG_partial_unit, DW_AT_import. (determine_prefix, dwarf2_name): Handle DW_TAG_partial_unit.
-rw-r--r--gdb/ChangeLog59
-rw-r--r--gdb/dwarf2read.c406
2 files changed, 408 insertions, 57 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 31cf97b..f79f1ef 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,64 @@
2012-05-10 Tom Tromey <tromey@redhat.com>
+ * dwarf2read.c (recursively_write_psymbols): New function.
+ (write_psymtabs_to_index): Use it.
+
+ * dwarf2read.c (struct dwarf2_queue_item) <pretend_language>: New
+ field.
+ (load_cu, dw2_do_instantiate_symtab, process_psymtab_comp_unit)
+ (load_partial_comp_unit): Update.
+ (queue_comp_unit): Add argument 'pretend_language'.
+ (process_queue): Update.
+ (psymtab_to_symtab_1): Skip dependencies that have a user.
+ (load_partial_comp_unit_reader): Give meaning to the 'data'
+ argument.
+ (load_full_comp_unit): Add 'pretend_language' argument.
+ (process_full_comp_unit): Add 'pretend_language' argument. Set
+ language on CU.
+ (process_imported_unit_die, read_file_scope, read_type_unit_scope):
+ Update.
+ (maybe_queue_comp_unit): Add 'pretend_language' argument.
+ (follow_die_offset, follow_die_sig, read_signatured_type_reader):
+ Update.
+ (prepare_one_comp_unit): Add 'pretend_language' argument.
+
+ * dwarf2read.c: (dwarf2_per_cu_ptr): New typedef.
+ (struct dwarf2_per_objfile) <just_read_cus>: New field.
+ (struct dwarf2_per_cu_data) <imported_symtabs>: New field.
+ (dw2_do_instantiate_symtab): Check whether symtab was read in
+ before queueing.
+ (dw2_instantiate_symtab): Add assertion. Call
+ process_cu_includes.
+ (process_psymtab_comp_unit): Compute 'dependencies' for psymtab.
+ (partial_symtab_p): New typedef.
+ (set_partial_user): New function.
+ (dwarf2_build_psymtabs_hard): Use set_partial_user.
+ (scan_partial_symbols): Add imported CU to imported_symtabs.
+ (dwarf2_psymtab_to_symtab): Call process_cu_includes.
+ (psymtab_to_symtab_1): Do nothing if psymtab is readin.
+ (get_symtab, recursively_compute_inclusions)
+ (compute_symtab_includes, process_cu_includes)
+ (process_imported_unit_die): New functions.
+ (process_die) <DW_TAG_imported_unit>: New case.
+ (dwarf2_per_objfile_free): Free 'imported_symtabs'.
+
+ * dwarf2read.c (struct dwarf2_per_cu_data) <psymtab>: Update
+ comment.
+ (struct partial_die_info) <locdesc>: Remove.
+ <d>: New field.
+ (process_psymtab_comp_unit): Add 'read_partial' argument.
+ Update.
+ (process_type_comp_unit, dwarf2_build_psymtabs_hard): Update.
+ (scan_partial_symbols): Handle DW_TAG_imported_unit.
+ (add_partial_symbol): Update.
+ (process_die): Handle DW_TAG_partial_unit.
+ (read_file_scope): Update comment.
+ (load_partial_dies): Handle DW_TAG_imported_unit.
+ (read_partial_die): Handle DW_TAG_partial_unit, DW_AT_import.
+ (determine_prefix, dwarf2_name): Handle DW_TAG_partial_unit.
+
+2012-05-10 Tom Tromey <tromey@redhat.com>
+
* cc-with-dwz.sh: New file.
2012-05-10 Tom Tromey <tromey@redhat.com>
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 8964b00..f06dea6 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -148,6 +148,9 @@ struct mapped_index
const char *constant_pool;
};
+typedef struct dwarf2_per_cu_data *dwarf2_per_cu_ptr;
+DEF_VEC_P (dwarf2_per_cu_ptr);
+
/* Collection of data recorded per objfile.
This hangs off of dwarf2_objfile_data_key. */
@@ -221,6 +224,9 @@ struct dwarf2_per_objfile
This is NULL if not allocated yet.
The mapping is done via (CU/TU signature + DIE offset) -> type. */
htab_t die_type_hash;
+
+ /* The CUs we recently read. */
+ VEC (dwarf2_per_cu_ptr) *just_read_cus;
};
static struct dwarf2_per_objfile *dwarf2_per_objfile;
@@ -483,13 +489,18 @@ struct dwarf2_per_cu_data
union
{
/* The partial symbol table associated with this compilation unit,
- or NULL for partial units (which do not have an associated
- symtab). */
+ or NULL for unread partial units. */
struct partial_symtab *psymtab;
/* Data needed by the "quick" functions. */
struct dwarf2_per_cu_quick_data *quick;
} v;
+
+ /* The CUs we import using DW_TAG_imported_unit. This is filled in
+ while reading psymtabs, used to compute the psymtab dependencies,
+ and then cleared. Then it is filled in again while reading full
+ symbols, and only deleted when the objfile is destroyed. */
+ VEC (dwarf2_per_cu_ptr) *imported_symtabs;
};
/* Entry in the signatured_types hash table. */
@@ -695,8 +706,15 @@ struct partial_die_info
when this compilation unit leaves the cache. */
char *scope;
- /* The location description associated with this DIE, if any. */
- struct dwarf_block *locdesc;
+ /* Some data associated with the partial DIE. The tag determines
+ which field is live. */
+ union
+ {
+ /* The location description associated with this DIE, if any. */
+ struct dwarf_block *locdesc;
+ /* The offset of an import, for DW_TAG_imported_unit. */
+ sect_offset offset;
+ } d;
/* If HAS_PC_INFO, the PC range associated with this DIE. */
CORE_ADDR lowpc;
@@ -887,6 +905,7 @@ struct field_info
struct dwarf2_queue_item
{
struct dwarf2_per_cu_data *per_cu;
+ enum language pretend_language;
struct dwarf2_queue_item *next;
};
@@ -1346,7 +1365,8 @@ static void init_one_comp_unit (struct dwarf2_cu *cu,
struct dwarf2_per_cu_data *per_cu);
static void prepare_one_comp_unit (struct dwarf2_cu *cu,
- struct die_info *comp_unit_die);
+ struct die_info *comp_unit_die,
+ enum language pretend_language);
static void free_heap_comp_unit (void *);
@@ -1363,9 +1383,11 @@ static void create_all_comp_units (struct objfile *);
static int create_all_type_units (struct objfile *);
-static void load_full_comp_unit (struct dwarf2_per_cu_data *);
+static void load_full_comp_unit (struct dwarf2_per_cu_data *,
+ enum language);
-static void process_full_comp_unit (struct dwarf2_per_cu_data *);
+static void process_full_comp_unit (struct dwarf2_per_cu_data *,
+ enum language);
static void dwarf2_add_dependence (struct dwarf2_cu *,
struct dwarf2_per_cu_data *);
@@ -1381,7 +1403,12 @@ static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
static void dwarf2_release_queue (void *dummy);
-static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu);
+static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
+ enum language pretend_language);
+
+static int maybe_queue_comp_unit (struct dwarf2_cu *this_cu,
+ struct dwarf2_per_cu_data *per_cu,
+ enum language pretend_language);
static void process_queue (void);
@@ -1407,7 +1434,7 @@ static void init_cutu_and_read_dies_simple
static htab_t allocate_signatured_type_table (struct objfile *objfile);
-static void process_psymtab_comp_unit (struct dwarf2_per_cu_data *);
+static void process_psymtab_comp_unit (struct dwarf2_per_cu_data *, int);
static htab_t allocate_dwo_unit_table (struct objfile *objfile);
@@ -1421,6 +1448,8 @@ static void free_dwo_file_cleanup (void *);
static void munmap_section_buffer (struct dwarf2_section_info *);
+static void process_cu_includes (void);
+
#if WORDS_BIGENDIAN
/* Convert VALUE between big- and little-endian. */
@@ -1926,7 +1955,7 @@ load_cu (struct dwarf2_per_cu_data *per_cu)
if (per_cu->is_debug_types)
load_full_type_unit (per_cu);
else
- load_full_comp_unit (per_cu);
+ load_full_comp_unit (per_cu, language_minimal);
gdb_assert (per_cu->cu != NULL);
@@ -1942,9 +1971,13 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
back_to = make_cleanup (dwarf2_release_queue, NULL);
- queue_comp_unit (per_cu);
-
- load_cu (per_cu);
+ if (dwarf2_per_objfile->using_index
+ ? per_cu->v.quick->symtab == NULL
+ : (per_cu->v.psymtab == NULL || !per_cu->v.psymtab->readin))
+ {
+ queue_comp_unit (per_cu, language_minimal);
+ load_cu (per_cu);
+ }
process_queue ();
@@ -1962,11 +1995,13 @@ dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
static struct symtab *
dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
{
+ gdb_assert (dwarf2_per_objfile->using_index);
if (!per_cu->v.quick->symtab)
{
struct cleanup *back_to = make_cleanup (free_cached_comp_units, NULL);
increment_reading_symtab ();
dw2_do_instantiate_symtab (per_cu);
+ process_cu_includes ();
do_cleanups (back_to);
}
return per_cu->v.quick->symtab;
@@ -4014,11 +4049,14 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
struct partial_symtab *pst;
int has_pc_info;
const char *filename;
+ int *want_partial_unit_ptr = data;
- if (comp_unit_die->tag == DW_TAG_partial_unit)
+ if (comp_unit_die->tag == DW_TAG_partial_unit
+ && (want_partial_unit_ptr == NULL
+ || !*want_partial_unit_ptr))
return;
- prepare_one_comp_unit (cu, comp_unit_die);
+ prepare_one_comp_unit (cu, comp_unit_die, language_minimal);
cu->list_in_scope = &file_symbols;
@@ -4100,6 +4138,26 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
(objfile->static_psymbols.list + pst->statics_offset);
sort_pst_symbols (pst);
+ if (!VEC_empty (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs))
+ {
+ int i;
+ int len = VEC_length (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs);
+ struct dwarf2_per_cu_data *iter;
+
+ /* Fill in 'dependencies' here; we fill in 'users' in a
+ post-pass. */
+ pst->number_of_dependencies = len;
+ pst->dependencies = obstack_alloc (&objfile->objfile_obstack,
+ len * sizeof (struct symtab *));
+ for (i = 0;
+ VEC_iterate (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
+ i, iter);
+ ++i)
+ pst->dependencies[i] = iter->v.psymtab;
+
+ VEC_free (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs);
+ }
+
if (per_cu->is_debug_types)
{
/* It's not clear we want to do anything with stmt lists here.
@@ -4117,7 +4175,8 @@ process_psymtab_comp_unit_reader (const struct die_reader_specs *reader,
Process compilation unit THIS_CU for a psymtab. */
static void
-process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu)
+process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
+ int want_partial_unit)
{
/* If this compilation unit was already read in, free the
cached copy in order to read it in again. This is
@@ -4129,7 +4188,7 @@ process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu)
gdb_assert (! this_cu->is_debug_types);
init_cutu_and_read_dies (this_cu, 0, 0, process_psymtab_comp_unit_reader,
- NULL);
+ &want_partial_unit);
/* Age out any secondary CUs. */
age_cached_comp_units ();
@@ -4187,6 +4246,28 @@ psymtabs_addrmap_cleanup (void *o)
objfile->psymtabs_addrmap = NULL;
}
+/* Compute the 'user' field for each psymtab in OBJFILE. */
+
+static void
+set_partial_user (struct objfile *objfile)
+{
+ int i;
+
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+ {
+ struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
+ struct partial_symtab *pst = per_cu->v.psymtab;
+ int j;
+
+ for (j = 0; j < pst->number_of_dependencies; ++j)
+ {
+ /* Set the 'user' field only if it is not already set. */
+ if (pst->dependencies[j]->user == NULL)
+ pst->dependencies[j]->user = pst;
+ }
+ }
+}
+
/* Build the partial symbol table by doing a quick pass through the
.debug_info and .debug_abbrev sections. */
@@ -4220,9 +4301,11 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile)
{
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
- process_psymtab_comp_unit (per_cu);
+ process_psymtab_comp_unit (per_cu, 0);
}
+ set_partial_user (objfile);
+
objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap,
&objfile->objfile_obstack);
discard_cleanups (addrmap_cleanup);
@@ -4241,7 +4324,7 @@ load_partial_comp_unit_reader (const struct die_reader_specs *reader,
{
struct dwarf2_cu *cu = reader->cu;
- prepare_one_comp_unit (cu, comp_unit_die);
+ prepare_one_comp_unit (cu, comp_unit_die, language_minimal);
/* Check if comp unit has_children.
If so, read the rest of the partial symbols from this comp unit.
@@ -4350,7 +4433,8 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
enums. */
if (pdi->name != NULL || pdi->tag == DW_TAG_namespace
- || pdi->tag == DW_TAG_module || pdi->tag == DW_TAG_enumeration_type)
+ || pdi->tag == DW_TAG_module || pdi->tag == DW_TAG_enumeration_type
+ || pdi->tag == DW_TAG_imported_unit)
{
switch (pdi->tag)
{
@@ -4390,6 +4474,21 @@ scan_partial_symbols (struct partial_die_info *first_die, CORE_ADDR *lowpc,
case DW_TAG_module:
add_partial_module (pdi, lowpc, highpc, need_pc, cu);
break;
+ case DW_TAG_imported_unit:
+ {
+ struct dwarf2_per_cu_data *per_cu;
+
+ per_cu = dwarf2_find_containing_comp_unit (pdi->d.offset,
+ cu->objfile);
+
+ /* Go read the partial unit, if needed. */
+ if (per_cu->v.psymtab == NULL)
+ process_psymtab_comp_unit (per_cu, 1);
+
+ VEC_safe_push (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
+ per_cu);
+ }
+ break;
default:
break;
}
@@ -4598,10 +4697,10 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
}
break;
case DW_TAG_variable:
- if (pdi->locdesc)
- addr = decode_locdesc (pdi->locdesc, cu);
+ if (pdi->d.locdesc)
+ addr = decode_locdesc (pdi->d.locdesc, cu);
- if (pdi->locdesc
+ if (pdi->d.locdesc
&& addr == 0
&& !dwarf2_per_objfile->has_section_at_zero)
{
@@ -4625,7 +4724,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
used by GDB, but it comes in handy for debugging partial symbol
table building. */
- if (pdi->locdesc || pdi->has_type)
+ if (pdi->d.locdesc || pdi->has_type)
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name,
VAR_DOMAIN, LOC_STATIC,
@@ -4636,7 +4735,7 @@ add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
else
{
/* Static Variable. Skip symbols without location descriptors. */
- if (pdi->locdesc == NULL)
+ if (pdi->d.locdesc == NULL)
{
if (built_actual_name)
xfree (actual_name);
@@ -5079,6 +5178,8 @@ dwarf2_psymtab_to_symtab (struct partial_symtab *pst)
printf_filtered (_("done.\n"));
}
}
+
+ process_cu_includes ();
}
/* Reading in full CUs. */
@@ -5086,13 +5187,15 @@ dwarf2_psymtab_to_symtab (struct partial_symtab *pst)
/* Add PER_CU to the queue. */
static void
-queue_comp_unit (struct dwarf2_per_cu_data *per_cu)
+queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
+ enum language pretend_language)
{
struct dwarf2_queue_item *item;
per_cu->queued = 1;
item = xmalloc (sizeof (*item));
item->per_cu = per_cu;
+ item->pretend_language = pretend_language;
item->next = NULL;
if (dwarf2_queue == NULL)
@@ -5117,7 +5220,7 @@ process_queue (void)
if (dwarf2_per_objfile->using_index
? !item->per_cu->v.quick->symtab
: (item->per_cu->v.psymtab && !item->per_cu->v.psymtab->readin))
- process_full_comp_unit (item->per_cu);
+ process_full_comp_unit (item->per_cu, item->pretend_language);
item->per_cu->queued = 0;
next_item = item->next;
@@ -5165,8 +5268,12 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
struct cleanup *back_to;
int i;
+ if (pst->readin)
+ return;
+
for (i = 0; i < pst->number_of_dependencies; i++)
- if (!pst->dependencies[i]->readin)
+ if (!pst->dependencies[i]->readin
+ && pst->dependencies[i]->user == NULL)
{
/* Inform about additional files that need to be read in. */
if (info_verbose)
@@ -5232,6 +5339,7 @@ load_full_comp_unit_reader (const struct die_reader_specs *reader,
{
struct dwarf2_cu *cu = reader->cu;
struct attribute *attr;
+ enum language *language_ptr = data;
gdb_assert (cu->die_hash == NULL);
cu->die_hash =
@@ -5255,17 +5363,19 @@ load_full_comp_unit_reader (const struct die_reader_specs *reader,
or we won't be able to build types correctly.
Similarly, if we do not read the producer, we can not apply
producer-specific interpretation. */
- prepare_one_comp_unit (cu, cu->dies);
+ prepare_one_comp_unit (cu, cu->dies, *language_ptr);
}
/* Load the DIEs associated with PER_CU into memory. */
static void
-load_full_comp_unit (struct dwarf2_per_cu_data *this_cu)
+load_full_comp_unit (struct dwarf2_per_cu_data *this_cu,
+ enum language pretend_language)
{
gdb_assert (! this_cu->is_debug_types);
- init_cutu_and_read_dies (this_cu, 1, 1, load_full_comp_unit_reader, NULL);
+ init_cutu_and_read_dies (this_cu, 1, 1, load_full_comp_unit_reader,
+ &pretend_language);
}
/* Add a DIE to the delayed physname list. */
@@ -5390,11 +5500,117 @@ fixup_go_packaging (struct dwarf2_cu *cu)
}
}
+static void compute_symtab_includes (struct dwarf2_per_cu_data *per_cu);
+
+/* Return the symtab for PER_CU. This works properly regardless of
+ whether we're using the index or psymtabs. */
+
+static struct symtab *
+get_symtab (struct dwarf2_per_cu_data *per_cu)
+{
+ return (dwarf2_per_objfile->using_index
+ ? per_cu->v.quick->symtab
+ : per_cu->v.psymtab->symtab);
+}
+
+/* A helper function for computing the list of all symbol tables
+ included by PER_CU. */
+
+static void
+recursively_compute_inclusions (VEC (dwarf2_per_cu_ptr) **result,
+ htab_t all_children,
+ struct dwarf2_per_cu_data *per_cu)
+{
+ void **slot;
+ int ix;
+ struct dwarf2_per_cu_data *iter;
+
+ slot = htab_find_slot (all_children, per_cu, INSERT);
+ if (*slot != NULL)
+ {
+ /* This inclusion and its children have been processed. */
+ return;
+ }
+
+ *slot = per_cu;
+ /* Only add a CU if it has a symbol table. */
+ if (get_symtab (per_cu) != NULL)
+ VEC_safe_push (dwarf2_per_cu_ptr, *result, per_cu);
+
+ for (ix = 0;
+ VEC_iterate (dwarf2_per_cu_ptr, per_cu->imported_symtabs, ix, iter);
+ ++ix)
+ recursively_compute_inclusions (result, all_children, iter);
+}
+
+/* Compute the symtab 'includes' fields for the symtab related to
+ PER_CU. */
+
+static void
+compute_symtab_includes (struct dwarf2_per_cu_data *per_cu)
+{
+ if (!VEC_empty (dwarf2_per_cu_ptr, per_cu->imported_symtabs))
+ {
+ int ix, len;
+ struct dwarf2_per_cu_data *iter;
+ VEC (dwarf2_per_cu_ptr) *result_children = NULL;
+ htab_t all_children;
+ struct symtab *symtab = get_symtab (per_cu);
+
+ /* If we don't have a symtab, we can just skip this case. */
+ if (symtab == NULL)
+ return;
+
+ all_children = htab_create_alloc (1, htab_hash_pointer, htab_eq_pointer,
+ NULL, xcalloc, xfree);
+
+ for (ix = 0;
+ VEC_iterate (dwarf2_per_cu_ptr, per_cu->imported_symtabs,
+ ix, iter);
+ ++ix)
+ recursively_compute_inclusions (&result_children, all_children, iter);
+
+ /* Now we have a transitive closure of all the included CUs, so
+ we can convert it to a list of symtabs. */
+ len = VEC_length (dwarf2_per_cu_ptr, result_children);
+ symtab->includes
+ = obstack_alloc (&dwarf2_per_objfile->objfile->objfile_obstack,
+ (len + 1) * sizeof (struct symtab *));
+ for (ix = 0;
+ VEC_iterate (dwarf2_per_cu_ptr, result_children, ix, iter);
+ ++ix)
+ symtab->includes[ix] = get_symtab (iter);
+ symtab->includes[len] = NULL;
+
+ VEC_free (dwarf2_per_cu_ptr, result_children);
+ htab_delete (all_children);
+ }
+}
+
+/* Compute the 'includes' field for the symtabs of all the CUs we just
+ read. */
+
+static void
+process_cu_includes (void)
+{
+ int ix;
+ struct dwarf2_per_cu_data *iter;
+
+ for (ix = 0;
+ VEC_iterate (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus,
+ ix, iter);
+ ++ix)
+ compute_symtab_includes (iter);
+
+ VEC_free (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus);
+}
+
/* Generate full symbol information for PER_CU, whose DIEs have
already been loaded into memory. */
static void
-process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
+process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
+ enum language pretend_language)
{
struct dwarf2_cu *cu = per_cu->cu;
struct objfile *objfile = per_cu->objfile;
@@ -5411,6 +5627,9 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
cu->list_in_scope = &file_symbols;
+ cu->language = pretend_language;
+ cu->language_defn = language_def (cu->language);
+
/* Do line number decoding in read_file_scope () */
process_die (cu->dies, cu);
@@ -5471,9 +5690,38 @@ process_full_comp_unit (struct dwarf2_per_cu_data *per_cu)
pst->readin = 1;
}
+ /* Push it for inclusion processing later. */
+ VEC_safe_push (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus, per_cu);
+
do_cleanups (back_to);
}
+/* Process an imported unit DIE. */
+
+static void
+process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct attribute *attr;
+
+ attr = dwarf2_attr (die, DW_AT_import, cu);
+ if (attr != NULL)
+ {
+ struct dwarf2_per_cu_data *per_cu;
+ struct symtab *imported_symtab;
+ sect_offset offset;
+
+ offset = dwarf2_get_ref_die_offset (attr);
+ per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
+
+ /* Queue the unit, if needed. */
+ if (maybe_queue_comp_unit (cu, per_cu, cu->language))
+ load_full_comp_unit (per_cu, cu->language);
+
+ VEC_safe_push (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
+ per_cu);
+ }
+}
+
/* Process a die and its children. */
static void
@@ -5484,6 +5732,7 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
case DW_TAG_padding:
break;
case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
read_file_scope (die, cu);
break;
case DW_TAG_type_unit:
@@ -5552,6 +5801,11 @@ process_die (struct die_info *die, struct dwarf2_cu *cu)
dwarf_tag_name (die->tag));
read_import_statement (die, cu);
break;
+
+ case DW_TAG_imported_unit:
+ process_imported_unit_die (die, cu);
+ break;
+
default:
new_symbol (die, NULL, cu);
break;
@@ -6226,7 +6480,7 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
}
}
-/* Process DW_TAG_compile_unit. */
+/* Process DW_TAG_compile_unit or DW_TAG_partial_unit. */
static void
read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
@@ -6255,7 +6509,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
find_file_and_directory (die, cu, &name, &comp_dir);
- prepare_one_comp_unit (cu, die);
+ prepare_one_comp_unit (cu, die, cu->language);
/* The XLCL doesn't generate DW_LANG_OpenCL because this attribute is not
standardised yet. As a workaround for the language detection we fall
@@ -6365,7 +6619,7 @@ read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu)
if (name == NULL)
name = "<unknown>";
- prepare_one_comp_unit (cu, die);
+ prepare_one_comp_unit (cu, die, language_minimal);
/* We assume that we're processing GCC output. */
processing_gcc_compilation = 2;
@@ -10688,7 +10942,8 @@ load_partial_dies (const struct die_reader_specs *reader,
&& abbrev->tag != DW_TAG_variable
&& abbrev->tag != DW_TAG_namespace
&& abbrev->tag != DW_TAG_module
- && abbrev->tag != DW_TAG_member)
+ && abbrev->tag != DW_TAG_member
+ && abbrev->tag != DW_TAG_imported_unit)
{
/* Otherwise we skip to the next sibling, if any. */
info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev);
@@ -10906,6 +11161,7 @@ read_partial_die (const struct die_reader_specs *reader,
switch (part_die->tag)
{
case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
case DW_TAG_type_unit:
/* Compilation units have a DW_AT_name that is a filename, not
a source language identifier. */
@@ -10950,7 +11206,7 @@ read_partial_die (const struct die_reader_specs *reader,
/* Support the .debug_loc offsets. */
if (attr_form_is_block (&attr))
{
- part_die->locdesc = DW_BLOCK (&attr);
+ part_die->d.locdesc = DW_BLOCK (&attr);
}
else if (attr_form_is_section_offset (&attr))
{
@@ -11019,6 +11275,12 @@ read_partial_die (const struct die_reader_specs *reader,
|| DW_UNSND (&attr) == DW_INL_declared_inlined)
part_die->may_be_inlined = 1;
break;
+
+ case DW_AT_import:
+ if (part_die->tag == DW_TAG_imported_unit)
+ part_die->d.offset = dwarf2_get_ref_die_offset (&attr);
+ break;
+
default:
break;
}
@@ -14021,6 +14283,7 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
So it does not need a prefix. */
return "";
case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
/* gcc-4.5 -gdwarf-4 can drop the enclosing namespace. Cope. */
if (cu->language == language_cplus
&& !VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types)
@@ -14141,6 +14404,7 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
switch (die->tag)
{
case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
/* Compilation units have a DW_AT_name that is a filename, not
a source language identifier. */
case DW_TAG_enumeration_type:
@@ -14174,7 +14438,8 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
if (die->tag == DW_TAG_class_type)
return dwarf2_name (die, cu);
}
- while (die->tag != DW_TAG_compile_unit);
+ while (die->tag != DW_TAG_compile_unit
+ && die->tag != DW_TAG_partial_unit);
}
break;
@@ -14571,7 +14836,8 @@ dwarf2_get_attr_constant_value (struct attribute *attr, int default_value)
static int
maybe_queue_comp_unit (struct dwarf2_cu *this_cu,
- struct dwarf2_per_cu_data *per_cu)
+ struct dwarf2_per_cu_data *per_cu,
+ enum language pretend_language)
{
/* We may arrive here during partial symbol reading, if we need full
DIEs to process an unusual case (e.g. template arguments). Do
@@ -14600,7 +14866,7 @@ maybe_queue_comp_unit (struct dwarf2_cu *this_cu,
}
/* Add it to the queue. */
- queue_comp_unit (per_cu);
+ queue_comp_unit (per_cu, pretend_language);
return 1;
}
@@ -14659,8 +14925,8 @@ follow_die_offset (sect_offset offset, struct dwarf2_cu **ref_cu)
per_cu = dwarf2_find_containing_comp_unit (offset, cu->objfile);
/* If necessary, add it to the queue and load its DIEs. */
- if (maybe_queue_comp_unit (cu, per_cu))
- load_full_comp_unit (per_cu);
+ if (maybe_queue_comp_unit (cu, per_cu, cu->language))
+ load_full_comp_unit (per_cu, cu->language);
target_cu = per_cu->cu;
}
@@ -14668,7 +14934,7 @@ follow_die_offset (sect_offset offset, struct dwarf2_cu **ref_cu)
{
/* We're loading full DIEs during partial symbol reading. */
gdb_assert (dwarf2_per_objfile->reading_partial_symbols);
- load_full_comp_unit (cu->per_cu);
+ load_full_comp_unit (cu->per_cu, language_minimal);
}
*ref_cu = target_cu;
@@ -14800,7 +15066,7 @@ follow_die_sig (struct die_info *src_die, struct attribute *attr,
/* If necessary, add it to the queue and load its DIEs. */
- if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu))
+ if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu, language_minimal))
read_signatured_type (sig_type);
gdb_assert (sig_type->per_cu.cu != NULL);
@@ -14913,7 +15179,7 @@ read_signatured_type_reader (const struct die_reader_specs *reader,
or we won't be able to build types correctly.
Similarly, if we do not read the producer, we can not apply
producer-specific interpretation. */
- prepare_one_comp_unit (cu, cu->dies);
+ prepare_one_comp_unit (cu, cu->dies, language_minimal);
}
/* Read in a signatured type and build its CU and DIEs.
@@ -16379,7 +16645,8 @@ init_one_comp_unit (struct dwarf2_cu *cu, struct dwarf2_per_cu_data *per_cu)
/* Initialize basic fields of dwarf_cu CU according to DIE COMP_UNIT_DIE. */
static void
-prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die)
+prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die,
+ enum language pretend_language)
{
struct attribute *attr;
@@ -16389,7 +16656,7 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die)
set_cu_language (DW_UNSND (attr), cu);
else
{
- cu->language = language_minimal;
+ cu->language = pretend_language;
cu->language_defn = language_def (cu->language);
}
@@ -16833,6 +17100,10 @@ dwarf2_per_objfile_free (struct objfile *objfile, void *d)
++ix)
munmap_section_buffer (section);
+ for (ix = 0; ix < dwarf2_per_objfile->n_comp_units; ++ix)
+ VEC_free (dwarf2_per_cu_ptr,
+ dwarf2_per_objfile->all_comp_units[ix]->imported_symtabs);
+
VEC_free (dwarf2_section_info_def, data->types);
if (data->dwo_files)
@@ -17393,6 +17664,35 @@ write_one_signatured_type (void **slot, void *d)
return 1;
}
+/* Recurse into all "included" dependencies and write their symbols as
+ if they appeared in this psymtab. */
+
+static void
+recursively_write_psymbols (struct objfile *objfile,
+ struct partial_symtab *psymtab,
+ struct mapped_symtab *symtab,
+ htab_t psyms_seen,
+ offset_type cu_index)
+{
+ int i;
+
+ for (i = 0; i < psymtab->number_of_dependencies; ++i)
+ if (psymtab->dependencies[i]->user != NULL)
+ recursively_write_psymbols (objfile, psymtab->dependencies[i],
+ symtab, psyms_seen, cu_index);
+
+ write_psymbols (symtab,
+ psyms_seen,
+ objfile->global_psymbols.list + psymtab->globals_offset,
+ psymtab->n_global_syms, cu_index,
+ 0);
+ write_psymbols (symtab,
+ psyms_seen,
+ objfile->static_psymbols.list + psymtab->statics_offset,
+ psymtab->n_static_syms, cu_index,
+ 1);
+}
+
/* Create an index file for OBJFILE in the directory DIR. */
static void
@@ -17477,16 +17777,8 @@ write_psymtabs_to_index (struct objfile *objfile, const char *dir)
struct psymtab_cu_index_map *map;
void **slot;
- write_psymbols (symtab,
- psyms_seen,
- objfile->global_psymbols.list + psymtab->globals_offset,
- psymtab->n_global_syms, i,
- 0);
- write_psymbols (symtab,
- psyms_seen,
- objfile->static_psymbols.list + psymtab->statics_offset,
- psymtab->n_static_syms, i,
- 1);
+ if (psymtab->user == NULL)
+ recursively_write_psymbols (objfile, psymtab, symtab, psyms_seen, i);
map = &psymtab_cu_index_map[i];
map->psymtab = psymtab;