{
dwarf2_per_bfd *per_bfd;
- /* We can share a "dwarf2_per_bfd" with other objfiles if the BFD
- doesn't require relocations and if there aren't partial symbols
- from some other reader. */
- if (!objfile->has_partial_symbols ()
- && !gdb_bfd_requires_relocations (objfile->obfd))
+ /* We can share a "dwarf2_per_bfd" with other objfiles if the
+ BFD doesn't require relocations.
+
+ We don't share with objfiles for which -readnow was requested,
+ because it would complicate things when loading the same BFD with
+ -readnow and then without -readnow. */
+ if (!gdb_bfd_requires_relocations (objfile->obfd)
+ && (objfile->flags & OBJF_READNOW) == 0)
{
/* See if one has been created for this BFD yet. */
per_bfd = dwarf2_per_bfd_bfd_data_key.get (objfile->obfd);
unsigned int no_file_data : 1;
};
+/* A subclass of psymbol_functions that arranges to read the DWARF
+ partial symbols when needed. */
+struct lazy_dwarf_reader : public psymbol_functions
+{
+ using psymbol_functions::psymbol_functions;
+
+ bool can_lazily_read_symbols () override
+ {
+ return true;
+ }
+
+ void read_partial_symbols (struct objfile *objfile) override
+ {
+ if (dwarf2_has_info (objfile, nullptr))
+ dwarf2_build_psymtabs (objfile, this);
+ }
+};
+
+static quick_symbol_functions_up
+make_lazy_dwarf_reader ()
+{
+ return quick_symbol_functions_up (new lazy_dwarf_reader);
+}
+
struct dwarf2_base_index_functions : public quick_symbol_functions
{
bool has_symbols (struct objfile *objfile) override;
return language_unknown;
}
- void print_stats (struct objfile *objfile) override;
+ void print_stats (struct objfile *objfile, bool print_bcache) override;
void expand_all_symtabs (struct objfile *objfile) override;
}
void map_symbol_filenames (struct objfile *objfile,
- symbol_filename_ftype *fun, void *data,
- int need_fullname) override;
+ gdb::function_view<symbol_filename_ftype> fun,
+ bool need_fullname) override;
};
struct dwarf2_gdb_index : public dwarf2_base_index_functions
gdb::function_view<symbol_found_callback_ftype> callback,
symbol_compare_ftype *ordered_compare) override;
- void expand_symtabs_matching
+ bool expand_symtabs_matching
(struct objfile *objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
const lookup_name_info *lookup_name,
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+ block_search_flags search_flags,
enum search_domain kind) override;
};
gdb::function_view<symbol_found_callback_ftype> callback,
symbol_compare_ftype *ordered_compare) override;
- void expand_symtabs_matching
+ bool expand_symtabs_matching
(struct objfile *objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
const lookup_name_info *lookup_name,
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+ block_search_flags search_flags,
enum search_domain kind) override;
};
-quick_symbol_functions_up
+static quick_symbol_functions_up
make_dwarf_gdb_index ()
{
return quick_symbol_functions_up (new dwarf2_gdb_index);
}
-quick_symbol_functions_up
+static quick_symbol_functions_up
make_dwarf_debug_names ()
{
return quick_symbol_functions_up (new dwarf2_debug_names_index);
}
/* Read the address map data from the mapped index, and use it to
- populate the objfile's psymtabs_addrmap. */
+ populate the psymtabs_addrmap. */
static void
create_addrmap_from_index (dwarf2_per_objfile *per_objfile,
struct mapped_index *index)
{
struct objfile *objfile = per_objfile->objfile;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
struct gdbarch *gdbarch = objfile->arch ();
const gdb_byte *iter, *end;
struct addrmap *mutable_map;
continue;
}
- if (cu_index >= per_objfile->per_bfd->all_comp_units.size ())
+ if (cu_index >= per_bfd->all_comp_units.size ())
{
complaint (_(".gdb_index address table has invalid CU number %u"),
(unsigned) cu_index);
lo = gdbarch_adjust_dwarf2_addr (gdbarch, lo + baseaddr) - baseaddr;
hi = gdbarch_adjust_dwarf2_addr (gdbarch, hi + baseaddr) - baseaddr;
addrmap_set_empty (mutable_map, lo, hi - 1,
- per_objfile->per_bfd->get_cu (cu_index));
+ per_bfd->get_cu (cu_index));
}
- objfile->partial_symtabs->psymtabs_addrmap
- = addrmap_create_fixed (mutable_map, objfile->partial_symtabs->obstack ());
+ per_bfd->index_addrmap = addrmap_create_fixed (mutable_map,
+ &per_bfd->obstack);
}
/* Read the address map data from DWARF-5 .debug_aranges, and use it to
- populate the objfile's psymtabs_addrmap. */
+ populate the psymtabs_addrmap. */
static void
create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile,
bfd *abfd = objfile->obfd;
struct gdbarch *gdbarch = objfile->arch ();
const CORE_ADDR baseaddr = objfile->text_section_offset ();
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
auto_obstack temp_obstack;
addrmap *mutable_map = addrmap_create_mutable (&temp_obstack);
dwarf2_per_cu_data *,
gdb::hash_enum<sect_offset>>
debug_info_offset_to_per_cu;
- for (dwarf2_per_cu_data *per_cu : per_objfile->per_bfd->all_comp_units)
+ for (dwarf2_per_cu_data *per_cu : per_bfd->all_comp_units)
{
const auto insertpair
= debug_info_offset_to_per_cu.emplace (per_cu->sect_off, per_cu);
addr += address_size;
if (start == 0 && length == 0)
break;
- if (start == 0 && !per_objfile->per_bfd->has_section_at_zero)
+ if (start == 0 && !per_bfd->has_section_at_zero)
{
/* Symbol was eliminated due to a COMDAT group. */
continue;
}
}
- objfile->partial_symtabs->psymtabs_addrmap
- = addrmap_create_fixed (mutable_map, objfile->partial_symtabs->obstack ());
+ per_bfd->index_addrmap = addrmap_create_fixed (mutable_map,
+ &per_bfd->obstack);
}
/* Find a slot in the mapped index INDEX for the object named NAME.
per_bfd->quick_file_names_table =
create_quick_file_names_table (per_bfd->all_comp_units.size ());
- /* Save partial symtabs in the per_bfd object, for the benefit of subsequent
- objfiles using the same BFD. */
- gdb_assert (per_bfd->partial_symtabs == nullptr);
- per_bfd->partial_symtabs = objfile->partial_symtabs;
-
return 1;
}
}
void
-dwarf2_base_index_functions::print_stats (struct objfile *objfile)
+dwarf2_base_index_functions::print_stats (struct objfile *objfile,
+ bool print_bcache)
{
+ if (print_bcache)
+ return;
+
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
int total = (per_objfile->per_bfd->all_comp_units.size ()
+ per_objfile->per_bfd->all_type_units.size ());
}
}
-static void
+static bool
dw2_expand_symtabs_matching_symbol
(mapped_index_base &index,
const lookup_name_info &lookup_name_in,
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
- enum search_domain kind,
gdb::function_view<bool (offset_type)> match_callback,
dwarf2_per_objfile *per_objfile);
-static void
+static bool
dw2_expand_symtabs_matching_one
(dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify);
-static void
-dw2_map_matching_symbols
+void
+dwarf2_gdb_index::map_matching_symbols
(struct objfile *objfile,
const lookup_name_info &name, domain_enum domain,
int global,
return ordered_compare (symname, match_name) == 0;
};
- dw2_expand_symtabs_matching_symbol (index, name, matcher, ALL_DOMAIN,
+ dw2_expand_symtabs_matching_symbol (index, name, matcher,
[&] (offset_type namei)
{
struct dw2_symtab_iterator iter;
}
}
-void
-dwarf2_gdb_index::map_matching_symbols
- (struct objfile *objfile,
- const lookup_name_info &name, domain_enum domain,
- int global,
- gdb::function_view<symbol_found_callback_ftype> callback,
- symbol_compare_ftype *ordered_compare)
-{
- dw2_map_matching_symbols (objfile, name, domain, global, callback,
- ordered_compare);
-}
-
/* Starting from a search name, return the string that finds the upper
bound of all strings that start with SEARCH_NAME in a sorted name
list. Returns the empty string to indicate that the upper bound is
symbol name that matches, calls MATCH_CALLBACK, passing it the
symbol's index in the mapped_index_base symbol table. */
-static void
+static bool
dw2_expand_symtabs_matching_symbol
(mapped_index_base &index,
const lookup_name_info &lookup_name_in,
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
- enum search_domain kind,
gdb::function_view<bool (offset_type)> match_callback,
dwarf2_per_objfile *per_objfile)
{
/* Finally call the callback, once per match. */
ULONGEST prev = -1;
+ bool result = true;
for (offset_type idx : matches)
{
if (prev != idx)
{
if (!match_callback (idx))
- break;
+ {
+ result = false;
+ break;
+ }
prev = idx;
}
}
/* Above we use a type wider than idx's for 'prev', since 0 and
(offset_type)-1 are both possible values. */
static_assert (sizeof (prev) > sizeof (offset_type), "");
+
+ return result;
}
#if GDB_SELF_TEST
auto expected_end = expected_list.end ();
dw2_expand_symtabs_matching_symbol (mock_index, lookup_name,
- NULL, ALL_DOMAIN,
+ nullptr,
[&] (offset_type idx)
{
const char *matched_name = mock_index.symbol_name_at (idx, per_objfile);
dw_expand_symtabs_matching_file_matcher), expand the CU and call
EXPANSION_NOTIFY on it. */
-static void
+static bool
dw2_expand_symtabs_matching_one
(dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile,
gdb_assert (symtab != nullptr);
if (expansion_notify != NULL && symtab_was_null)
- expansion_notify (symtab);
+ return expansion_notify (symtab);
}
+ return true;
}
/* Helper for dw2_expand_matching symtabs. Called on each symbol
matched, to expand corresponding CUs that were marked. IDX is the
index of the symbol name that matched. */
-static void
+static bool
dw2_expand_marked_cus
(dwarf2_per_objfile *per_objfile, offset_type idx,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+ block_search_flags search_flags,
search_domain kind)
{
offset_type *vec, vec_len, vec_idx;
/* Only check the symbol's kind if it has one. */
if (attrs_valid)
{
+ if (is_static)
+ {
+ if ((search_flags & SEARCH_STATIC_BLOCK) == 0)
+ continue;
+ }
+ else
+ {
+ if ((search_flags & SEARCH_GLOBAL_BLOCK) == 0)
+ continue;
+ }
+
switch (kind)
{
case VARIABLES_DOMAIN:
}
dwarf2_per_cu_data *per_cu = per_objfile->per_bfd->get_cutu (cu_index);
- dw2_expand_symtabs_matching_one (per_cu, per_objfile, file_matcher,
- expansion_notify);
+ if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile, file_matcher,
+ expansion_notify))
+ return false;
}
+
+ return true;
}
/* If FILE_MATCHER is non-NULL, set all the
}
}
-static void
-dw2_expand_symtabs_matching
- (struct objfile *objfile,
- gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
- const lookup_name_info *lookup_name,
- gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
- gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
- enum search_domain kind)
+bool
+dwarf2_gdb_index::expand_symtabs_matching
+ (struct objfile *objfile,
+ gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+ const lookup_name_info *lookup_name,
+ gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
+ gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+ block_search_flags search_flags,
+ enum search_domain kind)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
/* index_table is NULL if OBJF_READNOW. */
if (!per_objfile->per_bfd->index_table)
- return;
+ return true;
dw_expand_symtabs_matching_file_matcher (per_objfile, file_matcher);
{
QUIT;
- dw2_expand_symtabs_matching_one (per_cu, per_objfile,
- file_matcher, expansion_notify);
+ if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
+ file_matcher,
+ expansion_notify))
+ return false;
}
- return;
+ return true;
}
mapped_index &index = *per_objfile->per_bfd->index_table;
- dw2_expand_symtabs_matching_symbol (index, *lookup_name,
- symbol_matcher,
- kind, [&] (offset_type idx)
+ bool result
+ = dw2_expand_symtabs_matching_symbol (index, *lookup_name,
+ symbol_matcher,
+ [&] (offset_type idx)
{
- dw2_expand_marked_cus (per_objfile, idx, file_matcher, expansion_notify,
- kind);
+ if (!dw2_expand_marked_cus (per_objfile, idx, file_matcher,
+ expansion_notify, search_flags, kind))
+ return false;
return true;
}, per_objfile);
-}
-void
-dwarf2_gdb_index::expand_symtabs_matching
- (struct objfile *objfile,
- gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
- const lookup_name_info *lookup_name,
- gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
- gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
- enum search_domain kind)
-{
- dw2_expand_symtabs_matching (objfile, file_matcher, lookup_name,
- symbol_matcher, expansion_notify, kind);
+ return result;
}
/* A helper for dw2_find_pc_sect_compunit_symtab which finds the most specific
struct dwarf2_per_cu_data *data;
struct compunit_symtab *result;
- if (!objfile->partial_symtabs->psymtabs_addrmap)
+ dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+ if (per_objfile->per_bfd->index_addrmap == nullptr)
return NULL;
CORE_ADDR baseaddr = objfile->text_section_offset ();
- data = (struct dwarf2_per_cu_data *) addrmap_find
- (objfile->partial_symtabs->psymtabs_addrmap, pc - baseaddr);
+ data = ((struct dwarf2_per_cu_data *)
+ addrmap_find (per_objfile->per_bfd->index_addrmap,
+ pc - baseaddr));
if (!data)
return NULL;
- dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
if (warn_if_readin && per_objfile->symtab_set_p (data))
warning (_("(Internal error: pc %s in read in CU, but not in symtab.)"),
paddress (objfile->arch (), pc));
}
void
-dwarf2_base_index_functions::map_symbol_filenames (struct objfile *objfile,
- symbol_filename_ftype *fun,
- void *data,
- int need_fullname)
+dwarf2_base_index_functions::map_symbol_filenames
+ (struct objfile *objfile,
+ gdb::function_view<symbol_filename_ftype> fun,
+ bool need_fullname)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
if (need_fullname)
this_real_name = gdb_realpath (filename);
- (*fun) (filename, this_real_name.get (), data);
+ fun (filename, this_real_name.get ());
});
}
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
if (!read_debug_names_from_section (objfile, objfile_name (objfile),
- &per_objfile->per_bfd->debug_names, *map))
+ &per_bfd->debug_names, *map))
return false;
/* Don't use the index if it's empty. */
per_bfd->debug_names_table = std::move (map);
per_bfd->using_index = 1;
per_bfd->quick_file_names_table =
- create_quick_file_names_table (per_objfile->per_bfd->all_comp_units.size ());
-
- /* Save partial symtabs in the per_bfd object, for the benefit of subsequent
- objfiles using the same BFD. */
- gdb_assert (per_bfd->partial_symtabs == nullptr);
- per_bfd->partial_symtabs = objfile->partial_symtabs;
+ create_quick_file_names_table (per_bfd->all_comp_units.size ());
return true;
}
{
public:
dw2_debug_names_iterator (const mapped_debug_names &map,
- gdb::optional<block_enum> block_index,
+ block_search_flags block_index,
domain_enum domain,
const char *name, dwarf2_per_objfile *per_objfile)
: m_map (map), m_block_index (block_index), m_domain (domain),
{}
dw2_debug_names_iterator (const mapped_debug_names &map,
- search_domain search, uint32_t namei, dwarf2_per_objfile *per_objfile)
+ search_domain search, uint32_t namei,
+ dwarf2_per_objfile *per_objfile)
: m_map (map),
m_search (search),
m_addr (find_vec_in_debug_names (map, namei, per_objfile)),
{}
dw2_debug_names_iterator (const mapped_debug_names &map,
- block_enum block_index, domain_enum domain,
+ block_search_flags block_index, domain_enum domain,
uint32_t namei, dwarf2_per_objfile *per_objfile)
: m_map (map), m_block_index (block_index), m_domain (domain),
m_addr (find_vec_in_debug_names (map, namei, per_objfile)),
/* The internalized form of .debug_names. */
const mapped_debug_names &m_map;
- /* If set, only look for symbols that match that block. Valid values are
- GLOBAL_BLOCK and STATIC_BLOCK. */
- const gdb::optional<block_enum> m_block_index;
+ /* Restrict the search to these blocks. */
+ block_search_flags m_block_index = (SEARCH_GLOBAL_BLOCK
+ | SEARCH_STATIC_BLOCK);
/* The kind of symbol we're looking for. */
const domain_enum m_domain = UNDEF_DOMAIN;
{
case DW_IDX_compile_unit:
/* Don't crash on bad data. */
- if (ull >= m_per_objfile->per_bfd->all_comp_units.size ())
+ if (ull >= per_bfd->all_comp_units.size ())
{
complaint (_(".debug_names entry has bad CU index %s"
" [in module %s]"),
goto again;
/* Check static vs global. */
- if (symbol_linkage_ != symbol_linkage::unknown && m_block_index.has_value ())
+ if (symbol_linkage_ != symbol_linkage::unknown)
{
- const bool want_static = *m_block_index == STATIC_BLOCK;
- const bool symbol_is_static =
- symbol_linkage_ == symbol_linkage::static_;
- if (want_static != symbol_is_static)
- goto again;
+ if (symbol_linkage_ == symbol_linkage::static_)
+ {
+ if ((m_block_index & SEARCH_STATIC_BLOCK) == 0)
+ goto again;
+ }
+ else
+ {
+ if ((m_block_index & SEARCH_GLOBAL_BLOCK) == 0)
+ goto again;
+ }
}
/* Match dw2_symtab_iter_next, symbol_kind
}
const auto &map = *mapp;
- dw2_debug_names_iterator iter (map, block_index, domain, name, per_objfile);
+ dw2_debug_names_iterator iter (map,
+ block_index == GLOBAL_BLOCK
+ ? SEARCH_GLOBAL_BLOCK
+ : SEARCH_STATIC_BLOCK,
+ domain, name, per_objfile);
struct compunit_symtab *stab_best = NULL;
struct dwarf2_per_cu_data *per_cu;
{
const mapped_debug_names &map = *per_objfile->per_bfd->debug_names_table;
- dw2_debug_names_iterator iter (map, {}, VAR_DOMAIN, func_name,
+ dw2_debug_names_iterator iter (map,
+ (SEARCH_GLOBAL_BLOCK
+ | SEARCH_STATIC_BLOCK),
+ VAR_DOMAIN, func_name,
per_objfile);
struct dwarf2_per_cu_data *per_cu;
mapped_debug_names &map = *per_objfile->per_bfd->debug_names_table;
const block_enum block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
+ const block_search_flags block_flags
+ = global ? SEARCH_GLOBAL_BLOCK : SEARCH_STATIC_BLOCK;
const char *match_name = name.ada ().lookup_name ().c_str ();
auto matcher = [&] (const char *symname)
return ordered_compare (symname, match_name) == 0;
};
- dw2_expand_symtabs_matching_symbol (map, name, matcher, ALL_DOMAIN,
+ dw2_expand_symtabs_matching_symbol (map, name, matcher,
[&] (offset_type namei)
{
/* The name was matched, now expand corresponding CUs that were
marked. */
- dw2_debug_names_iterator iter (map, block_kind, domain, namei,
+ dw2_debug_names_iterator iter (map, block_flags, domain, namei,
per_objfile);
struct dwarf2_per_cu_data *per_cu;
}
}
-void
+bool
dwarf2_debug_names_index::expand_symtabs_matching
(struct objfile *objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
const lookup_name_info *lookup_name,
gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+ block_search_flags search_flags,
enum search_domain kind)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
/* debug_names_table is NULL if OBJF_READNOW. */
if (!per_objfile->per_bfd->debug_names_table)
- return;
+ return true;
dw_expand_symtabs_matching_file_matcher (per_objfile, file_matcher);
{
QUIT;
- dw2_expand_symtabs_matching_one (per_cu, per_objfile, file_matcher,
- expansion_notify);
+ if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
+ file_matcher,
+ expansion_notify))
+ return false;
}
- return;
+ return true;
}
mapped_debug_names &map = *per_objfile->per_bfd->debug_names_table;
- dw2_expand_symtabs_matching_symbol (map, *lookup_name,
- symbol_matcher,
- kind, [&] (offset_type namei)
+ bool result
+ = dw2_expand_symtabs_matching_symbol (map, *lookup_name,
+ symbol_matcher,
+ [&] (offset_type namei)
{
/* The name was matched, now expand corresponding CUs that were
marked. */
struct dwarf2_per_cu_data *per_cu;
while ((per_cu = iter.next ()) != NULL)
- dw2_expand_symtabs_matching_one (per_cu, per_objfile, file_matcher,
- expansion_notify);
+ if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
+ file_matcher,
+ expansion_notify))
+ return false;
return true;
}, per_objfile);
+
+ return result;
}
/* Get the content of the .gdb_index section of OBJ. SECTION_OWNER should point
return global_index_cache.lookup_gdb_index (build_id, &dwz->index_cache_res);
}
-/* See symfile.h. */
+/* See dwarf2/public.h. */
-bool
-dwarf2_initialize_objfile (struct objfile *objfile, dw_index_kind *index_kind)
+void
+dwarf2_initialize_objfile (struct objfile *objfile)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
if (per_bfd->using_index)
{
dwarf_read_debug_printf ("using_index already set");
- *index_kind = dw_index_kind::GDB_INDEX;
per_objfile->resize_symtabs ();
- return true;
+ objfile->qf.push_front (make_dwarf_gdb_index ());
+ return;
}
per_bfd->using_index = 1;
struct dwarf2_per_cu_quick_data);
}
- /* Return 1 so that gdb sees the "quick" functions. However,
- these functions will be no-ops because we will have expanded
- all symtabs. */
- *index_kind = dw_index_kind::GDB_INDEX;
- return true;
+ /* Arrange for gdb to see the "quick" functions. However, these
+ functions will be no-ops because we will have expanded all
+ symtabs. */
+ objfile->qf.push_front (make_dwarf_gdb_index ());
+ return;
}
/* Was a debug names index already read when we processed an objfile sharing
if (per_bfd->debug_names_table != nullptr)
{
dwarf_read_debug_printf ("re-using shared debug names table");
- *index_kind = dw_index_kind::DEBUG_NAMES;
- per_objfile->objfile->partial_symtabs = per_bfd->partial_symtabs;
per_objfile->resize_symtabs ();
- return true;
+ objfile->qf.push_front (make_dwarf_debug_names ());
+ return;
}
/* Was a GDB index already read when we processed an objfile sharing
if (per_bfd->index_table != nullptr)
{
dwarf_read_debug_printf ("re-using shared index table");
- *index_kind = dw_index_kind::GDB_INDEX;
- per_objfile->objfile->partial_symtabs = per_bfd->partial_symtabs;
per_objfile->resize_symtabs ();
- return true;
+ objfile->qf.push_front (make_dwarf_gdb_index ());
+ return;
}
/* There might already be partial symtabs built for this BFD. This happens
if (per_bfd->partial_symtabs != nullptr)
{
dwarf_read_debug_printf ("re-using shared partial symtabs");
- return false;
+ objfile->qf.push_front (make_lazy_dwarf_reader ());
+ return;
}
if (dwarf2_read_debug_names (per_objfile))
{
dwarf_read_debug_printf ("found debug names");
- *index_kind = dw_index_kind::DEBUG_NAMES;
per_objfile->resize_symtabs ();
- return true;
+ objfile->qf.push_front (make_dwarf_debug_names ());
+ return;
}
if (dwarf2_read_gdb_index (per_objfile,
get_gdb_index_contents_from_section<dwz_file>))
{
dwarf_read_debug_printf ("found gdb index from file");
- *index_kind = dw_index_kind::GDB_INDEX;
per_objfile->resize_symtabs ();
- return true;
+ objfile->qf.push_front (make_dwarf_gdb_index ());
+ return;
}
/* ... otherwise, try to find the index in the index cache. */
{
dwarf_read_debug_printf ("found gdb index from cache");
global_index_cache.hit ();
- *index_kind = dw_index_kind::GDB_INDEX;
per_objfile->resize_symtabs ();
- return true;
+ objfile->qf.push_front (make_dwarf_gdb_index ());
+ return;
}
global_index_cache.miss ();
- return false;
+ objfile->qf.push_front (make_lazy_dwarf_reader ());
}
\f
/* Build a partial symbol table. */
void
-dwarf2_build_psymtabs (struct objfile *objfile)
+dwarf2_build_psymtabs (struct objfile *objfile, psymbol_functions *psf)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
{
/* Partial symbols were already read, so now we can simply
attach them. */
- objfile->partial_symtabs = per_bfd->partial_symtabs;
+ if (psf == nullptr)
+ {
+ psf = new psymbol_functions (per_bfd->partial_symtabs);
+ objfile->qf.emplace_front (psf);
+ }
+ else
+ psf->set_partial_symtabs (per_bfd->partial_symtabs);
per_objfile->resize_symtabs ();
return;
}
+ if (psf == nullptr)
+ {
+ psf = new psymbol_functions;
+ objfile->qf.emplace_front (psf);
+ }
+ const std::shared_ptr<psymtab_storage> &partial_symtabs
+ = psf->get_partial_symtabs ();
+
/* Set the local reference to partial symtabs, so that we don't try
to read them again if reading another objfile with the same BFD.
If we can't in fact share, this won't make a difference anyway as
the dwarf2_per_bfd object won't be shared. */
- per_bfd->partial_symtabs = objfile->partial_symtabs;
+ per_bfd->partial_symtabs = partial_symtabs;
try
{
/* 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. */
- psymtab_discarder psymtabs (objfile->partial_symtabs.get ());
+ psymtab_discarder psymtabs (partial_symtabs.get ());
dwarf2_build_psymtabs_hard (per_objfile);
psymtabs.keep ();
/* A partial symtab that is used only for include files. */
struct dwarf2_include_psymtab : public partial_symtab
{
- dwarf2_include_psymtab (const char *filename, struct objfile *objfile)
- : partial_symtab (filename, objfile)
+ dwarf2_include_psymtab (const char *filename,
+ psymtab_storage *partial_symtabs,
+ objfile_per_bfd_storage *objfile_per_bfd)
+ : partial_symtab (filename, partial_symtabs, objfile_per_bfd)
{
}
partial symtab as being an include of PST. */
static void
-dwarf2_create_include_psymtab (const char *name, dwarf2_psymtab *pst,
- struct objfile *objfile)
+dwarf2_create_include_psymtab (dwarf2_per_bfd *per_bfd,
+ const char *name,
+ dwarf2_psymtab *pst,
+ psymtab_storage *partial_symtabs,
+ objfile_per_bfd_storage *objfile_per_bfd)
{
- dwarf2_include_psymtab *subpst = new dwarf2_include_psymtab (name, objfile);
+ dwarf2_include_psymtab *subpst
+ = new dwarf2_include_psymtab (name, partial_symtabs, objfile_per_bfd);
if (!IS_ABSOLUTE_PATH (subpst->filename))
subpst->dirname = pst->dirname;
- subpst->dependencies = objfile->partial_symtabs->allocate_dependencies (1);
+ subpst->dependencies = per_bfd->partial_symtabs->allocate_dependencies (1);
subpst->dependencies[0] = pst;
subpst->number_of_dependencies = 1;
}
struct dwarf2_per_cu_data *per_cu;
struct type_unit_group *tu_group;
- tu_group = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack, type_unit_group);
+ tu_group = OBSTACK_ZALLOC (&per_bfd->obstack, type_unit_group);
per_cu = &tu_group->per_cu;
per_cu->per_bfd = per_bfd;
dwarf2_per_objfile *per_objfile,
const char *name)
{
- struct objfile *objfile = per_objfile->objfile;
- dwarf2_psymtab *pst;
-
- pst = new dwarf2_psymtab (name, objfile, per_cu);
+ dwarf2_psymtab *pst
+ = new dwarf2_psymtab (name, per_objfile->per_bfd->partial_symtabs.get (),
+ per_objfile->objfile->per_bfd, per_cu);
pst->psymtabs_addrmap_supported = true;
{
struct dwarf2_cu *cu = reader->cu;
dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
struct objfile *objfile = per_objfile->objfile;
struct gdbarch *gdbarch = objfile->arch ();
struct dwarf2_per_cu_data *per_cu = cu->per_cu;
- baseaddr - 1);
/* Store the contiguous range if it is not empty; it can be
empty for CUs with no code. */
- addrmap_set_empty (objfile->partial_symtabs->psymtabs_addrmap,
+ addrmap_set_empty (per_bfd->partial_symtabs->psymtabs_addrmap,
low, high, pst);
}
post-pass. */
pst->number_of_dependencies = len;
pst->dependencies
- = objfile->partial_symtabs->allocate_dependencies (len);
+ = per_bfd->partial_symtabs->allocate_dependencies (len);
for (i = 0; i < len; ++i)
{
pst->dependencies[i]
this_cu->unit_type = DW_UT_type;
break;
default:
- abort ();
+ error (_("Dwarf Error: unexpected tag '%s' at offset %s [in module %s]"),
+ dwarf_tag_name (reader.comp_unit_die->tag),
+ sect_offset_str (reader.cu->per_cu->sect_off),
+ objfile_name (per_objfile->objfile));
}
if (reader.dummy_p)
build_type_psymtab_dependencies (void **slot, void *info)
{
dwarf2_per_objfile *per_objfile = (dwarf2_per_objfile *) info;
- struct objfile *objfile = per_objfile->objfile;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
struct type_unit_group *tu_group = (struct type_unit_group *) *slot;
struct dwarf2_per_cu_data *per_cu = &tu_group->per_cu;
dwarf2_psymtab *pst = per_cu->v.psymtab;
gdb_assert (per_cu->type_unit_group_p ());
pst->number_of_dependencies = len;
- pst->dependencies = objfile->partial_symtabs->allocate_dependencies (len);
+ pst->dependencies = per_bfd->partial_symtabs->allocate_dependencies (len);
for (i = 0; i < len; ++i)
{
struct signatured_type *iter = tu_group->tus->at (i);
dwarf2_build_psymtabs_hard (dwarf2_per_objfile *per_objfile)
{
struct objfile *objfile = per_objfile->objfile;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
dwarf_read_debug_printf ("Building psymtabs of objfile %s ...",
objfile_name (objfile));
scoped_restore restore_reading_psyms
- = make_scoped_restore (&per_objfile->per_bfd->reading_partial_symbols,
- true);
+ = make_scoped_restore (&per_bfd->reading_partial_symbols, true);
- per_objfile->per_bfd->info.read (objfile);
+ per_bfd->info.read (objfile);
/* Any cached compilation units will be linked by the per-objfile
read_in_chain. Make sure to free them when we're done. */
auto_obstack temp_obstack;
scoped_restore save_psymtabs_addrmap
- = make_scoped_restore (&objfile->partial_symtabs->psymtabs_addrmap,
+ = make_scoped_restore (&per_bfd->partial_symtabs->psymtabs_addrmap,
addrmap_create_mutable (&temp_obstack));
- for (dwarf2_per_cu_data *per_cu : per_objfile->per_bfd->all_comp_units)
+ for (dwarf2_per_cu_data *per_cu : per_bfd->all_comp_units)
{
if (per_cu->v.psymtab != NULL)
/* In case a forward DW_TAG_imported_unit has read the CU already. */
process_skeletonless_type_units (per_objfile);
/* Now that all TUs have been processed we can fill in the dependencies. */
- if (per_objfile->per_bfd->type_unit_groups != NULL)
+ if (per_bfd->type_unit_groups != NULL)
{
- htab_traverse_noresize (per_objfile->per_bfd->type_unit_groups.get (),
+ htab_traverse_noresize (per_bfd->type_unit_groups.get (),
build_type_psymtab_dependencies, per_objfile);
}
set_partial_user (per_objfile);
- objfile->partial_symtabs->psymtabs_addrmap
- = addrmap_create_fixed (objfile->partial_symtabs->psymtabs_addrmap,
- objfile->partial_symtabs->obstack ());
+ per_bfd->partial_symtabs->psymtabs_addrmap
+ = addrmap_create_fixed (per_bfd->partial_symtabs->psymtabs_addrmap,
+ per_bfd->partial_symtabs->obstack ());
/* At this point we want to keep the address map. */
save_psymtabs_addrmap.release ();
&objfile->objfile_obstack);
psymbol.ginfo.set_linkage_name (pdi->linkage_name);
}
- cu->per_cu->v.psymtab->add_psymbol (psymbol, *where, objfile);
+ cu->per_cu->v.psymtab->add_psymbol
+ (psymbol, *where, per_objfile->per_bfd->partial_symtabs.get (),
+ objfile);
}
}
if (set_addrmap)
{
struct objfile *objfile = cu->per_objfile->objfile;
+ dwarf2_per_bfd *per_bfd = cu->per_objfile->per_bfd;
struct gdbarch *gdbarch = objfile->arch ();
CORE_ADDR baseaddr;
CORE_ADDR this_highpc;
= (gdbarch_adjust_dwarf2_addr (gdbarch,
pdi->highpc + baseaddr)
- baseaddr);
- addrmap_set_empty (objfile->partial_symtabs->psymtabs_addrmap,
+ addrmap_set_empty (per_bfd->partial_symtabs->psymtabs_addrmap,
this_lowpc, this_highpc - 1,
cu->per_cu->v.psymtab);
}
dwarf2_find_base_address (cu->dies, cu);
+ /* Before we start reading the top-level DIE, ensure it has a valid tag
+ type. */
+ switch (cu->dies->tag)
+ {
+ case DW_TAG_compile_unit:
+ case DW_TAG_partial_unit:
+ case DW_TAG_type_unit:
+ break;
+ default:
+ error (_("Dwarf Error: unexpected tag '%s' at offset %s [in module %s]"),
+ dwarf_tag_name (cu->dies->tag),
+ sect_offset_str (cu->per_cu->sect_off),
+ objfile_name (per_objfile->objfile));
+ }
+
/* Do line number decoding in read_file_scope () */
process_die (cu->dies, cu);
else
search_path = debug_file_directory;
+ /* Add the path for the executable binary to the list of search paths. */
+ std::string objfile_dir = ldirname (objfile_name (per_objfile->objfile));
+ search_path_holder.reset (concat (objfile_dir.c_str (),
+ dirname_separator_string,
+ search_path, nullptr));
+ search_path = search_path_holder.get ();
+
openp_flags flags = OPF_RETURN_REALPATH;
if (is_dwp)
flags |= OPF_SEARCH_IN_PATH;
sect_offset_str (die->sect_off),
sect_offset_str (origin_die->sect_off));
+ /* Find if the concrete and abstract trees are structurally the
+ same. This is a shallow traversal and it is not bullet-proof;
+ the compiler can trick the debugger into believing that the trees
+ are isomorphic, whereas they actually are not. However, the
+ likelyhood of this happening is pretty low, and a full-fledged
+ check would be an overkill. */
+ bool are_isomorphic = true;
+ die_info *concrete_child = die->child;
+ die_info *abstract_child = origin_die->child;
+ while (concrete_child != nullptr || abstract_child != nullptr)
+ {
+ if (concrete_child == nullptr
+ || abstract_child == nullptr
+ || concrete_child->tag != abstract_child->tag)
+ {
+ are_isomorphic = false;
+ break;
+ }
+
+ concrete_child = concrete_child->sibling;
+ abstract_child = abstract_child->sibling;
+ }
+
+ /* Walk the origin's children in parallel to the concrete children.
+ This helps match an origin child in case the debug info misses
+ DW_AT_abstract_origin attributes. Keep in mind that the abstract
+ origin tree may not have the same tree structure as the concrete
+ DIE, though. */
+ die_info *corresponding_abstract_child
+ = are_isomorphic ? origin_die->child : nullptr;
+
std::vector<sect_offset> offsets;
for (child_die = die->child;
one. */
if (child_die->tag == DW_TAG_call_site
|| child_die->tag == DW_TAG_GNU_call_site)
- continue;
+ {
+ if (are_isomorphic)
+ corresponding_abstract_child
+ = corresponding_abstract_child->sibling;
+ continue;
+ }
/* For each CHILD_DIE, find the corresponding child of
ORIGIN_DIE. If there is more than one layer of
&child_origin_cu);
}
+ /* If missing DW_AT_abstract_origin, try the corresponding child
+ of the origin. Clang emits such lexical scopes. */
+ if (child_origin_die == child_die
+ && dwarf2_attr (child_die, DW_AT_abstract_origin, cu) == nullptr
+ && are_isomorphic
+ && child_die->tag == DW_TAG_lexical_block)
+ child_origin_die = corresponding_abstract_child;
+
/* According to DWARF3 3.3.8.2 #3 new entries without their abstract
counterpart may exist. */
if (child_origin_die != child_die)
else
offsets.push_back (child_origin_die->sect_off);
}
+
+ if (are_isomorphic)
+ corresponding_abstract_child = corresponding_abstract_child->sibling;
}
std::sort (offsets.begin (), offsets.end ());
sect_offset *offsets_end = offsets.data () + offsets.size ();
}
}
+ gdb_assert (cu->get_builder () != nullptr);
newobj = cu->get_builder ()->push_context (0, lowpc);
newobj->name = new_symbol (die, read_type_die (die, cu), cu,
(struct symbol *) templ_func);
/* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
Return 1 if the attributes are present and valid, otherwise, return 0.
- If RANGES_PST is not NULL we should setup `objfile->psymtabs_addrmap'. */
+ If RANGES_PST is not NULL we should set up the `psymtabs_addrmap'. */
static int
dwarf2_ranges_read (unsigned offset, CORE_ADDR *low_return,
dwarf2_psymtab *ranges_pst, dwarf_tag tag)
{
struct objfile *objfile = cu->per_objfile->objfile;
+ dwarf2_per_bfd *per_bfd = cu->per_objfile->per_bfd;
struct gdbarch *gdbarch = objfile->arch ();
const CORE_ADDR baseaddr = objfile->text_section_offset ();
int low_set = 0;
highpc = (gdbarch_adjust_dwarf2_addr (gdbarch,
range_end + baseaddr)
- baseaddr);
- addrmap_set_empty (objfile->partial_symtabs->psymtabs_addrmap,
+ addrmap_set_empty (per_bfd->partial_symtabs->psymtabs_addrmap,
lowpc, highpc - 1, ranges_pst);
}
}
if (cu->language == language_cplus && die->tag == DW_TAG_class_type)
- TYPE_DECLARED_CLASS (type) = 1;
+ type->set_is_declared_class (true);
/* Store the calling convention in the type if it's available in
the die. Otherwise the calling convention remains set to
type->set_is_unsigned (true);
if (flag_enum)
- TYPE_FLAG_ENUM (type) = 1;
+ type->set_is_flag_enum (true);
}
/* Given a DW_AT_enumeration_type die, set its type. We do not
set_type_align (type, TYPE_RAW_ALIGN (underlying_type));
}
- TYPE_DECLARED_CLASS (type) = dwarf2_flag_true_p (die, DW_AT_enum_class, cu);
+ type->set_is_declared_class (dwarf2_flag_true_p (die, DW_AT_enum_class, cu));
set_die_type (die, type, cu);
psymtab_include_file_name (lh, file_entry, pst,
comp_dir, &name_holder);
if (include_name != NULL)
- dwarf2_create_include_psymtab (include_name, pst, objfile);
+ dwarf2_create_include_psymtab
+ (cu->per_objfile->per_bfd, include_name, pst,
+ cu->per_objfile->per_bfd->partial_symtabs.get (),
+ objfile->per_bfd);
}
}
else
return determine_prefix (parent, cu);
case DW_TAG_enumeration_type:
parent_type = read_type_die (parent, cu);
- if (TYPE_DECLARED_CLASS (parent_type))
+ if (parent_type->is_declared_class ())
{
if (parent_type->name () != NULL)
return parent_type->name ();