CORE_ADDR *lowpc, CORE_ADDR *highpc,
int need_pc, struct dwarf2_cu *cu);
-static void dwarf2_psymtab_to_symtab (struct objfile *,
- struct partial_symtab *);
+static void dwarf2_read_symtab (struct partial_symtab *,
+ struct objfile *);
static void psymtab_to_symtab_1 (struct partial_symtab *);
gdb_assert (dwarf2_per_objfile);
}
-/* Reader function for dw2_build_type_unit_groups. */
-
-static void
-dw2_build_type_unit_groups_reader (const struct die_reader_specs *reader,
- gdb_byte *info_ptr,
- struct die_info *type_unit_die,
- int has_children,
- void *data)
-{
- struct dwarf2_cu *cu = reader->cu;
- struct attribute *attr;
- struct type_unit_group *tu_group;
-
- gdb_assert (data == NULL);
-
- if (! has_children)
- return;
-
- attr = dwarf2_attr_no_follow (type_unit_die, DW_AT_stmt_list);
- /* Call this for its side-effect of creating the associated
- struct type_unit_group if it doesn't already exist. */
- tu_group = get_type_unit_group (cu, attr);
-}
-
-/* Build dwarf2_per_objfile->type_unit_groups.
- This function may be called multiple times. */
-
-static void
-dw2_build_type_unit_groups (void)
-{
- if (dwarf2_per_objfile->type_unit_groups == NULL)
- build_type_unit_groups (dw2_build_type_unit_groups_reader, NULL);
-}
-
/* die_reader_func for dw2_get_file_names. */
static void
dw2_setup (objfile);
- dw2_build_type_unit_groups ();
+ /* The rule is CUs specify all the files, including those used by
+ any TU, so there's no need to scan TUs here. */
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_unit_groups); ++i)
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
{
int j;
struct dwarf2_per_cu_data *per_cu = dw2_get_primary_cu (i);
return 0;
}
-static struct symtab *
-dw2_lookup_symbol (struct objfile *objfile, int block_index,
- const char *name, domain_enum domain)
+/* Struct used to manage iterating over all CUs looking for a symbol. */
+
+struct dw2_symtab_iterator
{
- /* We do all the work in the pre_expand_symtabs_matching hook
- instead. */
- return NULL;
-}
+ /* The internalized form of .gdb_index. */
+ struct mapped_index *index;
+ /* If non-zero, only look for symbols that match BLOCK_INDEX. */
+ int want_specific_block;
+ /* One of GLOBAL_BLOCK or STATIC_BLOCK.
+ Unused if !WANT_SPECIFIC_BLOCK. */
+ int block_index;
+ /* The kind of symbol we're looking for. */
+ domain_enum domain;
+ /* The list of CUs from the index entry of the symbol,
+ or NULL if not found. */
+ offset_type *vec;
+ /* The next element in VEC to look at. */
+ int next;
+ /* The number of elements in VEC, or zero if there is no match. */
+ int length;
+};
-/* A helper function that expands all symtabs that hold an object
- named NAME. If WANT_SPECIFIC_BLOCK is non-zero, only look for
- symbols in block BLOCK_KIND. */
+/* Initialize the index symtab iterator ITER.
+ If WANT_SPECIFIC_BLOCK is non-zero, only look for symbols
+ in block BLOCK_INDEX. Otherwise BLOCK_INDEX is ignored. */
static void
-dw2_do_expand_symtabs_matching (struct objfile *objfile,
- int want_specific_block,
- enum block_enum block_kind,
- const char *name, domain_enum domain)
+dw2_symtab_iter_init (struct dw2_symtab_iterator *iter,
+ struct mapped_index *index,
+ int want_specific_block,
+ int block_index,
+ domain_enum domain,
+ const char *name)
+{
+ iter->index = index;
+ iter->want_specific_block = want_specific_block;
+ iter->block_index = block_index;
+ iter->domain = domain;
+ iter->next = 0;
+
+ if (find_slot_in_mapped_hash (index, name, &iter->vec))
+ iter->length = MAYBE_SWAP (*iter->vec);
+ else
+ {
+ iter->vec = NULL;
+ iter->length = 0;
+ }
+}
+
+/* Return the next matching CU or NULL if there are no more. */
+
+static struct dwarf2_per_cu_data *
+dw2_symtab_iter_next (struct dw2_symtab_iterator *iter)
+{
+ for ( ; iter->next < iter->length; ++iter->next)
+ {
+ offset_type cu_index_and_attrs =
+ MAYBE_SWAP (iter->vec[iter->next + 1]);
+ offset_type cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs);
+ struct dwarf2_per_cu_data *per_cu = dw2_get_cu (cu_index);
+ int want_static = iter->block_index != GLOBAL_BLOCK;
+ /* This value is only valid for index versions >= 7. */
+ int is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (cu_index_and_attrs);
+ gdb_index_symbol_kind symbol_kind =
+ GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs);
+ /* Only check the symbol attributes if they're present.
+ Indices prior to version 7 don't record them,
+ and indices >= 7 may elide them for certain symbols
+ (gold does this). */
+ int attrs_valid =
+ (iter->index->version >= 7
+ && symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE);
+
+ /* Skip if already read in. */
+ if (per_cu->v.quick->symtab)
+ continue;
+
+ if (attrs_valid
+ && iter->want_specific_block
+ && want_static != is_static)
+ continue;
+
+ /* Only check the symbol's kind if it has one. */
+ if (attrs_valid)
+ {
+ switch (iter->domain)
+ {
+ case VAR_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_VARIABLE
+ && symbol_kind != GDB_INDEX_SYMBOL_KIND_FUNCTION
+ /* Some types are also in VAR_DOMAIN. */
+ && symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
+ continue;
+ break;
+ case STRUCT_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
+ continue;
+ break;
+ case LABEL_DOMAIN:
+ if (symbol_kind != GDB_INDEX_SYMBOL_KIND_OTHER)
+ continue;
+ break;
+ default:
+ break;
+ }
+ }
+
+ ++iter->next;
+ return per_cu;
+ }
+
+ return NULL;
+}
+
+static struct symtab *
+dw2_lookup_symbol (struct objfile *objfile, int block_index,
+ const char *name, domain_enum domain)
{
+ struct symtab *stab_best = NULL;
struct mapped_index *index;
dw2_setup (objfile);
index = dwarf2_per_objfile->index_table;
- /* index_table is NULL if OBJF_READNOW. */
+ /* index is NULL if OBJF_READNOW. */
if (index)
{
- offset_type *vec;
+ struct dw2_symtab_iterator iter;
+ struct dwarf2_per_cu_data *per_cu;
- if (find_slot_in_mapped_hash (index, name, &vec))
+ dw2_symtab_iter_init (&iter, index, 1, block_index, domain, name);
+
+ while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
{
- offset_type i, len = MAYBE_SWAP (*vec);
- for (i = 0; i < len; ++i)
+ struct symbol *sym = NULL;
+ struct symtab *stab = dw2_instantiate_symtab (per_cu);
+
+ /* Some caution must be observed with overloaded functions
+ and methods, since the index will not contain any overload
+ information (but NAME might contain it). */
+ if (stab->primary)
{
- offset_type cu_index_and_attrs = MAYBE_SWAP (vec[i + 1]);
- offset_type cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs);
- struct dwarf2_per_cu_data *per_cu = dw2_get_cu (cu_index);
- int want_static = block_kind != GLOBAL_BLOCK;
- /* This value is only valid for index versions >= 7. */
- int is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (cu_index_and_attrs);
- gdb_index_symbol_kind symbol_kind =
- GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs);
- /* Only check the symbol attributes if they're present.
- Indices prior to version 7 don't record them,
- and indices >= 7 may elide them for certain symbols
- (gold does this). */
- int attrs_valid =
- (index->version >= 7
- && symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE);
-
- if (attrs_valid
- && want_specific_block
- && want_static != is_static)
- continue;
+ struct blockvector *bv = BLOCKVECTOR (stab);
+ struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
- /* Only check the symbol's kind if it has one. */
- if (attrs_valid)
- {
- switch (domain)
- {
- case VAR_DOMAIN:
- if (symbol_kind != GDB_INDEX_SYMBOL_KIND_VARIABLE
- && symbol_kind != GDB_INDEX_SYMBOL_KIND_FUNCTION
- /* Some types are also in VAR_DOMAIN. */
- && symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
- continue;
- break;
- case STRUCT_DOMAIN:
- if (symbol_kind != GDB_INDEX_SYMBOL_KIND_TYPE)
- continue;
- break;
- case LABEL_DOMAIN:
- if (symbol_kind != GDB_INDEX_SYMBOL_KIND_OTHER)
- continue;
- break;
- default:
- break;
- }
- }
+ sym = lookup_block_symbol (block, name, domain);
+ }
- dw2_instantiate_symtab (per_cu);
+ if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
+ {
+ if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
+ return stab;
+
+ stab_best = stab;
}
+
+ /* Keep looking through other CUs. */
}
}
-}
-static void
-dw2_pre_expand_symtabs_matching (struct objfile *objfile,
- enum block_enum block_kind, const char *name,
- domain_enum domain)
-{
- dw2_do_expand_symtabs_matching (objfile, 1, block_kind, name, domain);
+ return stab_best;
}
static void
dw2_expand_symtabs_for_function (struct objfile *objfile,
const char *func_name)
{
- /* Note: It doesn't matter what we pass for block_kind here. */
- dw2_do_expand_symtabs_matching (objfile, 0, GLOBAL_BLOCK, func_name,
- VAR_DOMAIN);
+ struct mapped_index *index;
+
+ dw2_setup (objfile);
+
+ index = dwarf2_per_objfile->index_table;
+
+ /* index is NULL if OBJF_READNOW. */
+ if (index)
+ {
+ struct dw2_symtab_iterator iter;
+ struct dwarf2_per_cu_data *per_cu;
+
+ /* Note: It doesn't matter what we pass for block_index here. */
+ dw2_symtab_iter_init (&iter, index, 0, GLOBAL_BLOCK, VAR_DOMAIN,
+ func_name);
+
+ while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
+ dw2_instantiate_symtab (per_cu);
+ }
}
static void
struct cleanup *cleanup;
htab_t visited_found, visited_not_found;
- dw2_build_type_unit_groups ();
-
visited_found = htab_create_alloc (10,
htab_hash_pointer, htab_eq_pointer,
NULL, xcalloc, xfree);
NULL, xcalloc, xfree);
make_cleanup_htab_delete (visited_not_found);
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_unit_groups); ++i)
+ /* The rule is CUs specify all the files, including those used by
+ any TU, so there's no need to scan TUs here. */
+
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
{
int j;
struct dwarf2_per_cu_data *per_cu = dw2_get_primary_cu (i);
cleanup = make_cleanup_htab_delete (visited);
dw2_setup (objfile);
- dw2_build_type_unit_groups ();
+ /* The rule is CUs specify all the files, including those used by
+ any TU, so there's no need to scan TUs here.
+ We can ignore file names coming from already-expanded CUs. */
- /* We can ignore file names coming from already-expanded CUs. */
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_units); ++i)
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
{
struct dwarf2_per_cu_data *per_cu = dw2_get_cu (i);
}
}
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_unit_groups); ++i)
+ for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
{
int j;
struct dwarf2_per_cu_data *per_cu = dw2_get_primary_cu (i);
dw2_forget_cached_source_info,
dw2_map_symtabs_matching_filename,
dw2_lookup_symbol,
- dw2_pre_expand_symtabs_matching,
dw2_print_stats,
dw2_dump,
dw2_relocate,
void
dwarf2_build_psymtabs (struct objfile *objfile)
{
+ volatile struct gdb_exception except;
+
if (objfile->global_psymbols.size == 0 && objfile->static_psymbols.size == 0)
{
init_psymbol_list (objfile, 1024);
}
- dwarf2_build_psymtabs_hard (objfile);
+ TRY_CATCH (except, RETURN_MASK_ERROR)
+ {
+ /* This isn't really ideal: all the data we allocate on the
+ objfile's obstack is still uselessly kept around. However,
+ freeing it seems unsafe. */
+ struct cleanup *cleanups = make_cleanup_discard_psymtabs (objfile);
+
+ dwarf2_build_psymtabs_hard (objfile);
+ discard_cleanups (cleanups);
+ }
+ if (except.reason < 0)
+ exception_print (gdb_stderr, except);
}
/* Return the total length of the CU described by HEADER. */
/* This is the glue that links PST into GDB's symbol API. */
pst->read_symtab_private = per_cu;
- pst->read_symtab = dwarf2_psymtab_to_symtab;
+ pst->read_symtab = dwarf2_read_symtab;
per_cu->v.psymtab = pst;
return pst;
return skip_children (reader, info_ptr);
}
-/* Expand this partial symbol table into a full symbol table. */
+/* Expand this partial symbol table into a full symbol table. SELF is
+ not NULL. */
static void
-dwarf2_psymtab_to_symtab (struct objfile *objfile, struct partial_symtab *pst)
+dwarf2_read_symtab (struct partial_symtab *self,
+ struct objfile *objfile)
{
- if (pst != NULL)
+ if (self->readin)
+ {
+ warning (_("bug: psymtab for %s is already read in."),
+ self->filename);
+ }
+ else
{
- if (pst->readin)
+ if (info_verbose)
{
- warning (_("bug: psymtab for %s is already read in."),
- pst->filename);
+ printf_filtered (_("Reading in symbols for %s..."),
+ self->filename);
+ gdb_flush (gdb_stdout);
}
- else
- {
- if (info_verbose)
- {
- printf_filtered (_("Reading in symbols for %s..."),
- pst->filename);
- gdb_flush (gdb_stdout);
- }
- /* Restore our global data. */
- dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
+ /* Restore our global data. */
+ dwarf2_per_objfile = objfile_data (objfile, dwarf2_objfile_data_key);
- /* If this psymtab is constructed from a debug-only objfile, the
- has_section_at_zero flag will not necessarily be correct. We
- can get the correct value for this flag by looking at the data
- associated with the (presumably stripped) associated objfile. */
- if (objfile->separate_debug_objfile_backlink)
- {
- struct dwarf2_per_objfile *dpo_backlink
- = objfile_data (objfile->separate_debug_objfile_backlink,
- dwarf2_objfile_data_key);
+ /* If this psymtab is constructed from a debug-only objfile, the
+ has_section_at_zero flag will not necessarily be correct. We
+ can get the correct value for this flag by looking at the data
+ associated with the (presumably stripped) associated objfile. */
+ if (objfile->separate_debug_objfile_backlink)
+ {
+ struct dwarf2_per_objfile *dpo_backlink
+ = objfile_data (objfile->separate_debug_objfile_backlink,
+ dwarf2_objfile_data_key);
- dwarf2_per_objfile->has_section_at_zero
- = dpo_backlink->has_section_at_zero;
- }
+ dwarf2_per_objfile->has_section_at_zero
+ = dpo_backlink->has_section_at_zero;
+ }
- dwarf2_per_objfile->reading_partial_symbols = 0;
+ dwarf2_per_objfile->reading_partial_symbols = 0;
- psymtab_to_symtab_1 (pst);
+ psymtab_to_symtab_1 (self);
- /* Finish up the debug error message. */
- if (info_verbose)
- printf_filtered (_("done.\n"));
- }
+ /* Finish up the debug error message. */
+ if (info_verbose)
+ printf_filtered (_("done.\n"));
}
process_cu_includes ();
return set_die_type (die, cv_type, cu);
}
+/* Handle DW_TAG_restrict_type. */
+
+static struct type *
+read_tag_restrict_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct type *base_type, *cv_type;
+
+ base_type = die_type (die, cu);
+
+ /* The die_type call above may have already set the type for this DIE. */
+ cv_type = get_die_type (die, cu);
+ if (cv_type)
+ return cv_type;
+
+ cv_type = make_restrict_type (base_type);
+ return set_die_type (die, cv_type, cu);
+}
+
/* Extract all information from a DW_TAG_string_type DIE and add to
the user defined type vector. It isn't really a user defined type,
but it behaves like one, with other DIE's using an AT_user_def_type
in line header LH of PST.
COMP_DIR is the compilation directory (DW_AT_comp_dir) or NULL if unknown.
If space for the result is malloc'd, it will be freed by a cleanup.
- Returns NULL if FILE_INDEX should be ignored, i.e., it is pst->filename. */
+ Returns NULL if FILE_INDEX should be ignored, i.e., it is pst->filename.
+
+ The function creates dangling cleanup registration. */
static char *
psymtab_include_file_name (const struct line_header *lh, int file_index,
case DW_TAG_volatile_type:
this_type = read_tag_volatile_type (die, cu);
break;
+ case DW_TAG_restrict_type:
+ this_type = read_tag_restrict_type (die, cu);
+ break;
case DW_TAG_string_type:
this_type = read_tag_string_type (die, cu);
break;