* 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.
This commit is contained in:
parent
e871fbb936
commit
95554aad6c
|
@ -1,3 +1,62 @@
|
|||
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.
|
||||
|
|
406
gdb/dwarf2read.c
406
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;
|
||||
|
|
Loading…
Reference in New Issue