#include "dwarf2/read.h"
#include "dwarf2/abbrev.h"
#include "dwarf2/attribute.h"
-#include "dwarf2/comp-unit.h"
+#include "dwarf2/comp-unit-head.h"
+#include "dwarf2/cu.h"
#include "dwarf2/index-cache.h"
#include "dwarf2/index-common.h"
#include "dwarf2/leb.h"
#include "dwarf2/die.h"
#include "dwarf2/sect-names.h"
#include "dwarf2/stringify.h"
+#include "dwarf2/public.h"
#include "bfd.h"
#include "elf-bfd.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "objfiles.h"
#include "dwarf2.h"
-#include "buildsym.h"
#include "demangle.h"
#include "gdb-demangle.h"
#include "filenames.h" /* for DOSish file names */
#include "rust-lang.h"
#include "gdbsupport/pathstuff.h"
#include "count-one-bits.h"
+#include <unordered_set>
/* When == 1, print basic high level tracing messages.
When > 1, be more verbose.
~mapped_index_base() = default;
};
+/* This is a view into the index that converts from bytes to an
+ offset_type, and allows indexing. Unaligned bytes are specifically
+ allowed here, and handled via unpacking. */
+
+class offset_view
+{
+public:
+ offset_view () = default;
+
+ explicit offset_view (gdb::array_view<const gdb_byte> bytes)
+ : m_bytes (bytes)
+ {
+ }
+
+ /* Extract the INDEXth offset_type from the array. */
+ offset_type operator[] (size_t index) const
+ {
+ const gdb_byte *bytes = &m_bytes[index * sizeof (offset_type)];
+ return (offset_type) extract_unsigned_integer (bytes,
+ sizeof (offset_type),
+ BFD_ENDIAN_LITTLE);
+ }
+
+ /* Return the number of offset_types in this array. */
+ size_t size () const
+ {
+ return m_bytes.size () / sizeof (offset_type);
+ }
+
+ /* Return true if this view is empty. */
+ bool empty () const
+ {
+ return m_bytes.empty ();
+ }
+
+private:
+ /* The underlying bytes. */
+ gdb::array_view<const gdb_byte> m_bytes;
+};
+
/* A description of the mapped index. The file format is described in
a comment by the code that writes the index. */
struct mapped_index final : public mapped_index_base
{
- /* A slot/bucket in the symbol table hash. */
- struct symbol_table_slot
- {
- const offset_type name;
- const offset_type vec;
- };
-
/* Index data format version. */
int version = 0;
gdb::array_view<const gdb_byte> address_table;
/* The symbol table, implemented as a hash table. */
- gdb::array_view<symbol_table_slot> symbol_table;
+ offset_view symbol_table;
/* A pointer to the constant pool. */
- const char *constant_pool = nullptr;
+ gdb::array_view<const gdb_byte> constant_pool;
+
+ /* Return the index into the constant pool of the name of the IDXth
+ symbol in the symbol table. */
+ offset_type symbol_name_index (offset_type idx) const
+ {
+ return symbol_table[2 * idx];
+ }
+
+ /* Return the index into the constant pool of the CU vector of the
+ IDXth symbol in the symbol table. */
+ offset_type symbol_vec_index (offset_type idx) const
+ {
+ return symbol_table[2 * idx + 1];
+ }
bool symbol_name_slot_invalid (offset_type idx) const override
{
- const auto &bucket = this->symbol_table[idx];
- return bucket.name == 0 && bucket.vec == 0;
+ return (symbol_name_index (idx) == 0
+ && symbol_vec_index (idx) == 0);
}
/* Convenience method to get at the name of the symbol at IDX in the
symbol table. */
const char *symbol_name_at
(offset_type idx, dwarf2_per_objfile *per_objfile) const override
- { return this->constant_pool + MAYBE_SWAP (this->symbol_table[idx].name); }
+ {
+ return (const char *) (this->constant_pool.data ()
+ + symbol_name_index (idx));
+ }
size_t symbol_name_count () const override
- { return this->symbol_table.size (); }
+ { return this->symbol_table.size () / 2; }
};
/* A description of the mapped .debug_names.
unsigned int offset_entry_count;
};
-/* Type used for delaying computation of method physnames.
- See comments for compute_delayed_physnames. */
-struct delayed_method_info
-{
- /* The type to which the method is attached, i.e., its parent class. */
- struct type *type;
-
- /* The index of the method in the type's function fieldlists. */
- int fnfield_index;
-
- /* The index of the method in the fieldlist. */
- int index;
-
- /* The name of the DIE. */
- const char *name;
-
- /* The DIE associated with this method. */
- struct die_info *die;
-};
-
-/* Internal state when decoding a particular compilation unit. */
-struct dwarf2_cu
-{
- explicit dwarf2_cu (dwarf2_per_cu_data *per_cu,
- dwarf2_per_objfile *per_objfile);
-
- DISABLE_COPY_AND_ASSIGN (dwarf2_cu);
-
- /* TU version of handle_DW_AT_stmt_list for read_type_unit_scope.
- Create the set of symtabs used by this TU, or if this TU is sharing
- symtabs with another TU and the symtabs have already been created
- then restore those symtabs in the line header.
- We don't need the pc/line-number mapping for type units. */
- void setup_type_unit_groups (struct die_info *die);
-
- /* Start a symtab for DWARF. NAME, COMP_DIR, LOW_PC are passed to the
- buildsym_compunit constructor. */
- struct compunit_symtab *start_symtab (const char *name,
- const char *comp_dir,
- CORE_ADDR low_pc);
-
- /* Reset the builder. */
- void reset_builder () { m_builder.reset (); }
-
- /* Return a type that is a generic pointer type, the size of which
- matches the address size given in the compilation unit header for
- this CU. */
- struct type *addr_type () const;
-
- /* Find an integer type the same size as the address size given in
- the compilation unit header for this CU. UNSIGNED_P controls if
- the integer is unsigned or not. */
- struct type *addr_sized_int_type (bool unsigned_p) const;
-
- /* The header of the compilation unit. */
- struct comp_unit_head header {};
-
- /* Base address of this compilation unit. */
- gdb::optional<CORE_ADDR> base_address;
-
- /* The language we are debugging. */
- enum language language = language_unknown;
- const struct language_defn *language_defn = nullptr;
-
- const char *producer = nullptr;
-
-private:
- /* The symtab builder for this CU. This is only non-NULL when full
- symbols are being read. */
- std::unique_ptr<buildsym_compunit> m_builder;
-
-public:
- /* The generic symbol table building routines have separate lists for
- file scope symbols and all all other scopes (local scopes). So
- we need to select the right one to pass to add_symbol_to_list().
- We do it by keeping a pointer to the correct list in list_in_scope.
-
- FIXME: The original dwarf code just treated the file scope as the
- first local scope, and all other local scopes as nested local
- scopes, and worked fine. Check to see if we really need to
- distinguish these in buildsym.c. */
- struct pending **list_in_scope = nullptr;
-
- /* Hash table holding all the loaded partial DIEs
- with partial_die->offset.SECT_OFF as hash. */
- htab_t partial_dies = nullptr;
-
- /* Storage for things with the same lifetime as this read-in compilation
- unit, including partial DIEs. */
- auto_obstack comp_unit_obstack;
-
- /* Backlink to our per_cu entry. */
- struct dwarf2_per_cu_data *per_cu;
-
- /* The dwarf2_per_objfile that owns this. */
- dwarf2_per_objfile *per_objfile;
-
- /* How many compilation units ago was this CU last referenced? */
- int last_used = 0;
-
- /* A hash table of DIE cu_offset for following references with
- die_info->offset.sect_off as hash. */
- htab_t die_hash = nullptr;
-
- /* Full DIEs if read in. */
- struct die_info *dies = nullptr;
-
- /* A set of pointers to dwarf2_per_cu_data objects for compilation
- units referenced by this one. Only set during full symbol processing;
- partial symbol tables do not have dependencies. */
- htab_t dependencies = nullptr;
-
- /* Header data from the line table, during full symbol processing. */
- struct line_header *line_header = nullptr;
- /* Non-NULL if LINE_HEADER is owned by this DWARF_CU. Otherwise,
- it's owned by dwarf2_per_bfd::line_header_hash. If non-NULL,
- this is the DW_TAG_compile_unit die for this CU. We'll hold on
- to the line header as long as this DIE is being processed. See
- process_die_scope. */
- die_info *line_header_die_owner = nullptr;
-
- /* A list of methods which need to have physnames computed
- after all type information has been read. */
- std::vector<delayed_method_info> method_list;
-
- /* To be copied to symtab->call_site_htab. */
- htab_t call_site_htab = nullptr;
-
- /* Non-NULL if this CU came from a DWO file.
- There is an invariant here that is important to remember:
- Except for attributes copied from the top level DIE in the "main"
- (or "stub") file in preparation for reading the DWO file
- (e.g., DW_AT_addr_base), we KISS: there is only *one* CU.
- Either there isn't a DWO file (in which case this is NULL and the point
- is moot), or there is and either we're not going to read it (in which
- case this is NULL) or there is and we are reading it (in which case this
- is non-NULL). */
- struct dwo_unit *dwo_unit = nullptr;
-
- /* The DW_AT_addr_base (DW_AT_GNU_addr_base) attribute if present.
- Note this value comes from the Fission stub CU/TU's DIE. */
- gdb::optional<ULONGEST> addr_base;
-
- /* The DW_AT_GNU_ranges_base attribute, if present.
-
- This is only relevant in the context of pre-DWARF 5 split units. In this
- context, there is a .debug_ranges section in the linked executable,
- containing all the ranges data for all the compilation units. Each
- skeleton/stub unit has (if needed) a DW_AT_GNU_ranges_base attribute that
- indicates the base of its contribution to that section. The DW_AT_ranges
- attributes in the split-unit are of the form DW_FORM_sec_offset and point
- into the .debug_ranges section of the linked file. However, they are not
- "true" DW_FORM_sec_offset, because they are relative to the base of their
- compilation unit's contribution, rather than relative to the beginning of
- the section. The DW_AT_GNU_ranges_base value must be added to it to make
- it relative to the beginning of the section.
-
- Note that the value is zero when we are not in a pre-DWARF 5 split-unit
- case, so this value can be added without needing to know whether we are in
- this case or not.
-
- N.B. If a DW_AT_ranges attribute is found on the DW_TAG_compile_unit in the
- skeleton/stub, it must not have the base added, as it already points to the
- right place. And since the DW_TAG_compile_unit DIE in the split-unit can't
- have a DW_AT_ranges attribute, we can use the
-
- die->tag != DW_AT_compile_unit
-
- to determine whether the base should be added or not. */
- ULONGEST gnu_ranges_base = 0;
-
- /* The DW_AT_rnglists_base attribute, if present.
-
- This is used when processing attributes of form DW_FORM_rnglistx in
- non-split units. Attributes of this form found in a split unit don't
- use it, as split-unit files have their own non-shared .debug_rnglists.dwo
- section. */
- ULONGEST rnglists_base = 0;
-
- /* The DW_AT_loclists_base attribute if present. */
- ULONGEST loclist_base = 0;
-
- /* When reading debug info generated by older versions of rustc, we
- have to rewrite some union types to be struct types with a
- variant part. This rewriting must be done after the CU is fully
- read in, because otherwise at the point of rewriting some struct
- type might not have been fully processed. So, we keep a list of
- all such types here and process them after expansion. */
- std::vector<struct type *> rust_unions;
-
- /* The DW_AT_str_offsets_base attribute if present. For DWARF 4 version DWO
- files, the value is implicitly zero. For DWARF 5 version DWO files, the
- value is often implicit and is the size of the header of
- .debug_str_offsets section (8 or 4, depending on the address size). */
- gdb::optional<ULONGEST> str_offsets_base;
-
- /* Mark used when releasing cached dies. */
- bool mark : 1;
-
- /* This CU references .debug_loc. See the symtab->locations_valid field.
- This test is imperfect as there may exist optimized debug code not using
- any location list and still facing inlining issues if handled as
- unoptimized code. For a future better test see GCC PR other/32998. */
- bool has_loclist : 1;
-
- /* These cache the results for producer_is_* fields. CHECKED_PRODUCER is true
- if all the producer_is_* fields are valid. This information is cached
- because profiling CU expansion showed excessive time spent in
- producer_is_gxx_lt_4_6. */
- bool checked_producer : 1;
- bool producer_is_gxx_lt_4_6 : 1;
- bool producer_is_gcc_lt_4_3 : 1;
- bool producer_is_icc : 1;
- bool producer_is_icc_lt_14 : 1;
- bool producer_is_codewarrior : 1;
-
- /* When true, the file that we're processing is known to have
- debugging info for C++ namespaces. GCC 3.3.x did not produce
- this information, but later versions do. */
-
- bool processing_has_namespace_info : 1;
-
- struct partial_die_info *find_partial_die (sect_offset sect_off);
-
- /* If this CU was inherited by another CU (via specification,
- abstract_origin, etc), this is the ancestor CU. */
- dwarf2_cu *ancestor;
-
- /* Get the buildsym_compunit for this CU. */
- buildsym_compunit *get_builder ()
- {
- /* If this CU has a builder associated with it, use that. */
- if (m_builder != nullptr)
- return m_builder.get ();
-
- /* Otherwise, search ancestors for a valid builder. */
- if (ancestor != nullptr)
- return ancestor->get_builder ();
-
- return nullptr;
- }
-};
-
/* A struct that can be used as a hash key for tables based on DW_AT_stmt_list.
This includes type_unit_group and quick_file_names. */
that can be shared across objfiles. The non-shareable parts are in
type_unit_group_unshareable. */
-struct type_unit_group
+struct type_unit_group : public dwarf2_per_cu_data
{
- /* dwarf2read.c's main "handle" on a TU symtab.
- To simplify things we create an artificial CU that "includes" all the
- type units using this stmt_list so that the rest of the code still has
- a "per_cu" handle on the symtab. */
- struct dwarf2_per_cu_data per_cu;
-
/* The TUs that share this DW_AT_stmt_list entry.
This is added to while parsing type units to build partial symtabs,
and is deleted afterwards and not used again. */
- std::vector<signatured_type *> *tus;
+ std::vector<signatured_type *> *tus = nullptr;
/* The data used to construct the hash key. */
- struct stmt_list_hash hash;
+ struct stmt_list_hash hash {};
};
/* These sections are what may appear in a (real or virtual) DWO file. */
static void create_all_comp_units (dwarf2_per_objfile *per_objfile);
-static int create_all_type_units (dwarf2_per_objfile *per_objfile);
-
static void load_full_comp_unit (dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile,
dwarf2_cu *existing_cu,
static void process_full_type_unit (dwarf2_cu *cu,
enum language pretend_language);
-static void dwarf2_add_dependence (struct dwarf2_cu *,
- struct dwarf2_per_cu_data *);
-
-static void dwarf2_mark (struct dwarf2_cu *);
-
static struct type *get_die_type_at_offset (sect_offset,
dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile);
}
}
+/* See dwarf2/read.h. */
+
+void
+dwarf2_per_cu_data_deleter::operator() (dwarf2_per_cu_data *data)
+{
+ if (data->is_debug_types)
+ delete static_cast<signatured_type *> (data);
+ else
+ delete data;
+}
+
/* The return type of find_file_and_directory. Note, the enclosed
string pointers are only valid while this object is valid. */
static void process_cu_includes (dwarf2_per_objfile *per_objfile);
static void check_producer (struct dwarf2_cu *cu);
-
-static void free_line_header_voidp (void *arg);
\f
/* Various complaints about symbol reading that don't abort the process. */
dwarf2_per_bfd::~dwarf2_per_bfd ()
{
- for (dwarf2_per_cu_data *per_cu : all_comp_units)
+ for (auto &per_cu : all_comp_units)
per_cu->imported_symtabs_free ();
- for (signatured_type *sig_type : all_type_units)
- sig_type->per_cu.imported_symtabs_free ();
-
/* Everything else should be on this->obstack. */
}
{
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 (objfile)
- && !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);
}
\f
-/* DWARF quick_symbols_functions support. */
+/* DWARF quick_symbol_functions support. */
/* TUs can share .debug_line entries, and there can be a lot more TUs than
unique line tables, so we maintain a separate table of all .debug_line
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;
+
+ struct symtab *find_last_source_symtab (struct objfile *objfile) override;
+
+ void forget_cached_source_info (struct objfile *objfile) override;
+
+ enum language lookup_global_symbol_language (struct objfile *objfile,
+ const char *name,
+ domain_enum domain,
+ bool *symbol_found_p) override
+ {
+ *symbol_found_p = false;
+ return language_unknown;
+ }
+
+ void print_stats (struct objfile *objfile, bool print_bcache) override;
+
+ void expand_all_symtabs (struct objfile *objfile) override;
+
+ struct compunit_symtab *find_pc_sect_compunit_symtab
+ (struct objfile *objfile, struct bound_minimal_symbol msymbol,
+ CORE_ADDR pc, struct obj_section *section, int warn_if_readin) override;
+
+ struct compunit_symtab *find_compunit_symtab_by_address
+ (struct objfile *objfile, CORE_ADDR address) override
+ {
+ return nullptr;
+ }
+
+ void map_symbol_filenames (struct objfile *objfile,
+ gdb::function_view<symbol_filename_ftype> fun,
+ bool need_fullname) override;
+};
+
+struct dwarf2_gdb_index : public dwarf2_base_index_functions
+{
+ void dump (struct objfile *objfile) override;
+
+ void expand_matching_symbols
+ (struct objfile *,
+ const lookup_name_info &lookup_name,
+ domain_enum domain,
+ int global,
+ symbol_compare_ftype *ordered_compare) override;
+
+ 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,
+ domain_enum domain,
+ enum search_domain kind) override;
+};
+
+struct dwarf2_debug_names_index : public dwarf2_base_index_functions
+{
+ void dump (struct objfile *objfile) override;
+
+ void expand_matching_symbols
+ (struct objfile *,
+ const lookup_name_info &lookup_name,
+ domain_enum domain,
+ int global,
+ symbol_compare_ftype *ordered_compare) override;
+
+ 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,
+ domain_enum domain,
+ enum search_domain kind) override;
+};
+
+static quick_symbol_functions_up
+make_dwarf_gdb_index ()
+{
+ return quick_symbol_functions_up (new dwarf2_gdb_index);
+}
+
+static quick_symbol_functions_up
+make_dwarf_debug_names ()
+{
+ return quick_symbol_functions_up (new dwarf2_debug_names_index);
+}
+
/* Utility hash function for a stmt_list_hash. */
static hashval_t
return per_objfile->get_symtab (per_cu);
}
-/* See declaration. */
-
-dwarf2_per_cu_data *
-dwarf2_per_bfd::get_cutu (int index)
-{
- if (index >= this->all_comp_units.size ())
- {
- index -= this->all_comp_units.size ();
- gdb_assert (index < this->all_type_units.size ());
- return &this->all_type_units[index]->per_cu;
- }
-
- return this->all_comp_units[index];
-}
-
-/* See declaration. */
-
-dwarf2_per_cu_data *
-dwarf2_per_bfd::get_cu (int index)
-{
- gdb_assert (index >= 0 && index < this->all_comp_units.size ());
-
- return this->all_comp_units[index];
-}
-
-/* See declaration. */
-
-signatured_type *
-dwarf2_per_bfd::get_tu (int index)
-{
- gdb_assert (index >= 0 && index < this->all_type_units.size ());
-
- return this->all_type_units[index];
-}
-
/* See read.h. */
-dwarf2_per_cu_data *
+dwarf2_per_cu_data_up
dwarf2_per_bfd::allocate_per_cu ()
{
- dwarf2_per_cu_data *result = OBSTACK_ZALLOC (&obstack, dwarf2_per_cu_data);
+ dwarf2_per_cu_data_up result (new dwarf2_per_cu_data);
result->per_bfd = this;
result->index = m_num_psymtabs++;
return result;
/* See read.h. */
-signatured_type *
+std::unique_ptr<signatured_type>
dwarf2_per_bfd::allocate_signatured_type ()
{
- signatured_type *result = OBSTACK_ZALLOC (&obstack, signatured_type);
- result->per_cu.per_bfd = this;
- result->per_cu.index = m_num_psymtabs++;
+ std::unique_ptr<signatured_type> result (new signatured_type);
+ result->per_bfd = this;
+ result->index = m_num_psymtabs++;
+ tu_stats.nr_tus++;
return result;
}
/* Return a new dwarf2_per_cu_data allocated on the per-bfd
obstack, and constructed with the specified field values. */
-static dwarf2_per_cu_data *
+static dwarf2_per_cu_data_up
create_cu_from_index_list (dwarf2_per_bfd *per_bfd,
struct dwarf2_section_info *section,
int is_dwz,
sect_offset sect_off, ULONGEST length)
{
- dwarf2_per_cu_data *the_cu = per_bfd->allocate_per_cu ();
+ dwarf2_per_cu_data_up the_cu = per_bfd->allocate_per_cu ();
the_cu->sect_off = sect_off;
the_cu->length = length;
the_cu->section = section;
ULONGEST length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE);
cu_list += 2 * 8;
- dwarf2_per_cu_data *per_cu
+ dwarf2_per_cu_data_up per_cu
= create_cu_from_index_list (per_bfd, section, is_dwz, sect_off,
length);
- per_bfd->all_comp_units.push_back (per_cu);
+ per_bfd->all_comp_units.push_back (std::move (per_cu));
}
}
(dwarf2_per_bfd *per_bfd, struct dwarf2_section_info *section,
const gdb_byte *bytes, offset_type elements)
{
- gdb_assert (per_bfd->all_type_units.empty ());
- per_bfd->all_type_units.reserve (elements / 3);
-
htab_up sig_types_hash = allocate_signatured_type_table ();
for (offset_type i = 0; i < elements; i += 3)
{
- struct signatured_type *sig_type;
+ std::unique_ptr<signatured_type> sig_type;
ULONGEST signature;
void **slot;
cu_offset type_offset_in_tu;
sig_type = per_bfd->allocate_signatured_type ();
sig_type->signature = signature;
sig_type->type_offset_in_tu = type_offset_in_tu;
- sig_type->per_cu.is_debug_types = 1;
- sig_type->per_cu.section = section;
- sig_type->per_cu.sect_off = sect_off;
- sig_type->per_cu.v.quick
+ sig_type->is_debug_types = 1;
+ sig_type->section = section;
+ sig_type->sect_off = sect_off;
+ sig_type->v.quick
= OBSTACK_ZALLOC (&per_bfd->obstack,
struct dwarf2_per_cu_quick_data);
- slot = htab_find_slot (sig_types_hash.get (), sig_type, INSERT);
- *slot = sig_type;
+ slot = htab_find_slot (sig_types_hash.get (), sig_type.get (), INSERT);
+ *slot = sig_type.get ();
- per_bfd->all_type_units.push_back (sig_type);
+ per_bfd->all_comp_units.emplace_back (sig_type.release ());
}
per_bfd->signatured_types = std::move (sig_types_hash);
section->read (objfile);
abbrev_section->read (objfile);
- gdb_assert (per_objfile->per_bfd->all_type_units.empty ());
- per_objfile->per_bfd->all_type_units.reserve (map.tu_count);
-
htab_up sig_types_hash = allocate_signatured_type_table ();
for (uint32_t i = 0; i < map.tu_count; ++i)
{
- struct signatured_type *sig_type;
+ std::unique_ptr<signatured_type> sig_type;
void **slot;
sect_offset sect_off
sig_type = per_objfile->per_bfd->allocate_signatured_type ();
sig_type->signature = cu_header.signature;
sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
- sig_type->per_cu.is_debug_types = 1;
- sig_type->per_cu.section = section;
- sig_type->per_cu.sect_off = sect_off;
- sig_type->per_cu.v.quick
+ sig_type->is_debug_types = 1;
+ sig_type->section = section;
+ sig_type->sect_off = sect_off;
+ sig_type->v.quick
= OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack,
struct dwarf2_per_cu_quick_data);
- slot = htab_find_slot (sig_types_hash.get (), sig_type, INSERT);
- *slot = sig_type;
+ slot = htab_find_slot (sig_types_hash.get (), sig_type.get (), INSERT);
+ *slot = sig_type.get ();
- per_objfile->per_bfd->all_type_units.push_back (sig_type);
+ per_objfile->per_bfd->all_comp_units.emplace_back (sig_type.release ());
}
per_objfile->per_bfd->signatured_types = std::move (sig_types_hash);
}
/* 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 (const auto &per_cu : per_bfd->all_comp_units)
{
const auto insertpair
- = debug_info_offset_to_per_cu.emplace (per_cu->sect_off, per_cu);
+ = debug_info_offset_to_per_cu.emplace (per_cu->sect_off,
+ per_cu.get ());
if (!insertpair.second)
{
warning (_("Section .debug_aranges in %s has duplicate "
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 ());
-}
-
-/* Find a slot in the mapped index INDEX for the object named NAME.
- If NAME is found, set *VEC_OUT to point to the CU vector in the
- constant pool and return true. If NAME cannot be found, return
- false. */
-
-static bool
-find_slot_in_mapped_hash (struct mapped_index *index, const char *name,
- offset_type **vec_out)
-{
- offset_type hash;
- offset_type slot, step;
- int (*cmp) (const char *, const char *);
-
- gdb::unique_xmalloc_ptr<char> without_params;
- if (current_language->la_language == language_cplus
- || current_language->la_language == language_fortran
- || current_language->la_language == language_d)
- {
- /* NAME is already canonical. Drop any qualifiers as .gdb_index does
- not contain any. */
-
- if (strchr (name, '(') != NULL)
- {
- without_params = cp_remove_params (name);
-
- if (without_params != NULL)
- name = without_params.get ();
- }
- }
-
- /* Index version 4 did not support case insensitive searches. But the
- indices for case insensitive languages are built in lowercase, therefore
- simulate our NAME being searched is also lowercased. */
- hash = mapped_index_string_hash ((index->version == 4
- && case_sensitivity == case_sensitive_off
- ? 5 : index->version),
- name);
-
- slot = hash & (index->symbol_table.size () - 1);
- step = ((hash * 17) & (index->symbol_table.size () - 1)) | 1;
- cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp);
-
- for (;;)
- {
- const char *str;
-
- const auto &bucket = index->symbol_table[slot];
- if (bucket.name == 0 && bucket.vec == 0)
- return false;
-
- str = index->constant_pool + MAYBE_SWAP (bucket.name);
- if (!cmp (name, str))
- {
- *vec_out = (offset_type *) (index->constant_pool
- + MAYBE_SWAP (bucket.vec));
- return true;
- }
-
- slot = (slot + step) & (index->symbol_table.size () - 1);
- }
+ per_bfd->index_addrmap = addrmap_create_fixed (mutable_map,
+ &per_bfd->obstack);
}
/* A helper function that reads the .gdb_index from BUFFER and fills
offset_type *types_list_elements)
{
const gdb_byte *addr = &buffer[0];
+ offset_view metadata (buffer);
/* Version check. */
- offset_type version = MAYBE_SWAP (*(offset_type *) addr);
+ offset_type version = metadata[0];
/* Versions earlier than 3 emitted every copy of a psymbol. This
causes the index to behave very poorly for certain requests. Version 3
contained incomplete addrmap. So, it seems better to just ignore such
map->version = version;
- offset_type *metadata = (offset_type *) (addr + sizeof (offset_type));
-
- int i = 0;
- *cu_list = addr + MAYBE_SWAP (metadata[i]);
- *cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i]))
- / 8);
+ int i = 1;
+ *cu_list = addr + metadata[i];
+ *cu_list_elements = (metadata[i + 1] - metadata[i]) / 8;
++i;
- *types_list = addr + MAYBE_SWAP (metadata[i]);
- *types_list_elements = ((MAYBE_SWAP (metadata[i + 1])
- - MAYBE_SWAP (metadata[i]))
- / 8);
+ *types_list = addr + metadata[i];
+ *types_list_elements = (metadata[i + 1] - metadata[i]) / 8;
++i;
- const gdb_byte *address_table = addr + MAYBE_SWAP (metadata[i]);
- const gdb_byte *address_table_end = addr + MAYBE_SWAP (metadata[i + 1]);
+ const gdb_byte *address_table = addr + metadata[i];
+ const gdb_byte *address_table_end = addr + metadata[i + 1];
map->address_table
= gdb::array_view<const gdb_byte> (address_table, address_table_end);
++i;
- const gdb_byte *symbol_table = addr + MAYBE_SWAP (metadata[i]);
- const gdb_byte *symbol_table_end = addr + MAYBE_SWAP (metadata[i + 1]);
+ const gdb_byte *symbol_table = addr + metadata[i];
+ const gdb_byte *symbol_table_end = addr + metadata[i + 1];
map->symbol_table
- = gdb::array_view<mapped_index::symbol_table_slot>
- ((mapped_index::symbol_table_slot *) symbol_table,
- (mapped_index::symbol_table_slot *) symbol_table_end);
+ = offset_view (gdb::array_view<const gdb_byte> (symbol_table,
+ symbol_table_end));
++i;
- map->constant_pool = (char *) (addr + MAYBE_SWAP (metadata[i]));
+ map->constant_pool = buffer.slice (metadata[i]);
return 1;
}
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;
}
return qfn->real_names[index];
}
-static struct symtab *
-dw2_find_last_source_symtab (struct objfile *objfile)
+struct symtab *
+dwarf2_base_index_functions::find_last_source_symtab (struct objfile *objfile)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
- dwarf2_per_cu_data *dwarf_cu = per_objfile->per_bfd->all_comp_units.back ();
+ dwarf2_per_cu_data *dwarf_cu
+ = per_objfile->per_bfd->all_comp_units.back ().get ();
compunit_symtab *cust = dw2_instantiate_symtab (dwarf_cu, per_objfile, false);
if (cust == NULL)
return 1;
}
-static void
-dw2_forget_cached_source_info (struct objfile *objfile)
+void
+dwarf2_base_index_functions::forget_cached_source_info
+ (struct objfile *objfile)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
dw2_free_cached_file_names, NULL);
}
-/* Helper function for dw2_map_symtabs_matching_filename that expands
- the symtabs and calls the iterator. */
-
-static int
-dw2_map_expand_apply (struct objfile *objfile,
- struct dwarf2_per_cu_data *per_cu,
- const char *name, const char *real_path,
- gdb::function_view<bool (symtab *)> callback)
-{
- struct compunit_symtab *last_made = objfile->compunit_symtabs;
-
- /* Don't visit already-expanded CUs. */
- dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
- if (per_objfile->symtab_set_p (per_cu))
- return 0;
-
- /* This may expand more than one symtab, and we want to iterate over
- all of them. */
- dw2_instantiate_symtab (per_cu, per_objfile, false);
-
- return iterate_over_some_symtabs (name, real_path, objfile->compunit_symtabs,
- last_made, callback);
-}
-
-/* Implementation of the map_symtabs_matching_filename method. */
-
-static bool
-dw2_map_symtabs_matching_filename
- (struct objfile *objfile, const char *name, const char *real_path,
- gdb::function_view<bool (symtab *)> callback)
-{
- const char *name_basename = lbasename (name);
- dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
-
- /* The rule is CUs specify all the files, including those used by
- any TU, so there's no need to scan TUs here. */
-
- for (dwarf2_per_cu_data *per_cu : per_objfile->per_bfd->all_comp_units)
- {
- /* We only need to look at symtabs not already expanded. */
- if (per_objfile->symtab_set_p (per_cu))
- continue;
-
- quick_file_names *file_data = dw2_get_file_names (per_cu, per_objfile);
- if (file_data == NULL)
- continue;
-
- for (int j = 0; j < file_data->num_file_names; ++j)
- {
- const char *this_name = file_data->file_names[j];
- const char *this_real_name;
-
- if (compare_filenames_for_search (this_name, name))
- {
- if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
- callback))
- return true;
- continue;
- }
-
- /* Before we invoke realpath, which can get expensive when many
- files are involved, do a quick comparison of the basenames. */
- if (! basenames_may_differ
- && FILENAME_CMP (lbasename (this_name), name_basename) != 0)
- continue;
-
- this_real_name = dw2_get_real_path (per_objfile, file_data, j);
- if (compare_filenames_for_search (this_real_name, name))
- {
- if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
- callback))
- return true;
- continue;
- }
-
- if (real_path != NULL)
- {
- gdb_assert (IS_ABSOLUTE_PATH (real_path));
- gdb_assert (IS_ABSOLUTE_PATH (name));
- if (this_real_name != NULL
- && FILENAME_CMP (real_path, this_real_name) == 0)
- {
- if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
- callback))
- return true;
- continue;
- }
- }
- }
- }
-
- return false;
-}
-
/* Struct used to manage iterating over all CUs looking for a symbol. */
struct dw2_symtab_iterator
domain_enum domain;
/* The list of CUs from the index entry of the symbol,
or NULL if not found. */
- offset_type *vec;
+ offset_view 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 global_seen;
};
-/* Initialize the index symtab iterator ITER, common part. */
+/* Initialize the index symtab iterator ITER, offset_type NAMEI variant. */
static void
-dw2_symtab_iter_init_common (struct dw2_symtab_iterator *iter,
- dwarf2_per_objfile *per_objfile,
- gdb::optional<block_enum> block_index,
- domain_enum domain)
+dw2_symtab_iter_init (struct dw2_symtab_iterator *iter,
+ dwarf2_per_objfile *per_objfile,
+ gdb::optional<block_enum> block_index,
+ domain_enum domain, offset_type namei)
{
iter->per_objfile = per_objfile;
iter->block_index = block_index;
iter->domain = domain;
iter->next = 0;
iter->global_seen = 0;
- iter->vec = NULL;
+ iter->vec = {};
iter->length = 0;
-}
-
-/* Initialize the index symtab iterator ITER, const char *NAME variant. */
-
-static void
-dw2_symtab_iter_init (struct dw2_symtab_iterator *iter,
- dwarf2_per_objfile *per_objfile,
- gdb::optional<block_enum> block_index,
- domain_enum domain,
- const char *name)
-{
- dw2_symtab_iter_init_common (iter, per_objfile, block_index, domain);
-
- mapped_index *index = per_objfile->per_bfd->index_table.get ();
- /* index is NULL if OBJF_READNOW. */
- if (index == NULL)
- return;
-
- if (find_slot_in_mapped_hash (index, name, &iter->vec))
- iter->length = MAYBE_SWAP (*iter->vec);
-}
-
-/* Initialize the index symtab iterator ITER, offset_type NAMEI variant. */
-
-static void
-dw2_symtab_iter_init (struct dw2_symtab_iterator *iter,
- dwarf2_per_objfile *per_objfile,
- gdb::optional<block_enum> block_index,
- domain_enum domain, offset_type namei)
-{
- dw2_symtab_iter_init_common (iter, per_objfile, block_index, domain);
mapped_index *index = per_objfile->per_bfd->index_table.get ();
/* index is NULL if OBJF_READNOW. */
return;
gdb_assert (!index->symbol_name_slot_invalid (namei));
- const auto &bucket = index->symbol_table[namei];
+ offset_type vec_idx = index->symbol_vec_index (namei);
- iter->vec = (offset_type *) (index->constant_pool
- + MAYBE_SWAP (bucket.vec));
- iter->length = MAYBE_SWAP (*iter->vec);
+ iter->vec = offset_view (index->constant_pool.slice (vec_idx));
+ iter->length = iter->vec[0];
}
/* Return the next matching CU or NULL if there are no more. */
for ( ; iter->next < iter->length; ++iter->next)
{
- offset_type cu_index_and_attrs =
- MAYBE_SWAP (iter->vec[iter->next + 1]);
+ offset_type cu_index_and_attrs = iter->vec[iter->next + 1];
offset_type cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs);
gdb_index_symbol_kind symbol_kind =
GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs);
&& symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE);
/* Don't crash on bad data. */
- if (cu_index >= (per_objfile->per_bfd->all_comp_units.size ()
- + per_objfile->per_bfd->all_type_units.size ()))
+ if (cu_index >= per_objfile->per_bfd->all_comp_units.size ())
{
complaint (_(".gdb_index entry has bad CU index"
" [in module %s]"), objfile_name (per_objfile->objfile));
continue;
}
- dwarf2_per_cu_data *per_cu = per_objfile->per_bfd->get_cutu (cu_index);
+ dwarf2_per_cu_data *per_cu = per_objfile->per_bfd->get_cu (cu_index);
/* Skip if already read in. */
if (per_objfile->symtab_set_p (per_cu))
return NULL;
}
-static struct compunit_symtab *
-dw2_lookup_symbol (struct objfile *objfile, block_enum block_index,
- const char *name, domain_enum domain)
+void
+dwarf2_base_index_functions::print_stats (struct objfile *objfile,
+ bool print_bcache)
{
- struct compunit_symtab *stab_best = NULL;
- dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
-
- lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
-
- struct dw2_symtab_iterator iter;
- struct dwarf2_per_cu_data *per_cu;
-
- dw2_symtab_iter_init (&iter, per_objfile, block_index, domain, name);
-
- while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
- {
- struct symbol *sym, *with_opaque = NULL;
- struct compunit_symtab *stab
- = dw2_instantiate_symtab (per_cu, per_objfile, false);
- const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
- const struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
-
- sym = block_find_symbol (block, name, domain,
- block_find_non_opaque_type_preferred,
- &with_opaque);
-
- /* 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 (sym != NULL
- && SYMBOL_MATCHES_SEARCH_NAME (sym, lookup_name))
- return stab;
- if (with_opaque != NULL
- && SYMBOL_MATCHES_SEARCH_NAME (with_opaque, lookup_name))
- stab_best = stab;
-
- /* Keep looking through other CUs. */
- }
-
- return stab_best;
-}
+ if (print_bcache)
+ return;
-static void
-dw2_print_stats (struct objfile *objfile)
-{
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 ());
+ int total = per_objfile->per_bfd->all_comp_units.size ();
int count = 0;
for (int i = 0; i < total; ++i)
{
- dwarf2_per_cu_data *per_cu = per_objfile->per_bfd->get_cutu (i);
+ dwarf2_per_cu_data *per_cu = per_objfile->per_bfd->get_cu (i);
if (!per_objfile->symtab_set_p (per_cu))
++count;
One use is to verify .gdb_index has been loaded by the
gdb.dwarf2/gdb-index.exp testcase. */
-static void
-dw2_dump (struct objfile *objfile)
+void
+dwarf2_gdb_index::dump (struct objfile *objfile)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
printf_filtered ("\n");
}
-static void
-dw2_expand_symtabs_for_function (struct objfile *objfile,
- const char *func_name)
-{
- dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
-
- struct dw2_symtab_iterator iter;
- struct dwarf2_per_cu_data *per_cu;
-
- dw2_symtab_iter_init (&iter, per_objfile, {}, VAR_DOMAIN, func_name);
-
- while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
- dw2_instantiate_symtab (per_cu, per_objfile, false);
-
-}
-
-static void
-dw2_expand_all_symtabs (struct objfile *objfile)
+void
+dwarf2_base_index_functions::expand_all_symtabs (struct objfile *objfile)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
- int total_units = (per_objfile->per_bfd->all_comp_units.size ()
- + per_objfile->per_bfd->all_type_units.size ());
+ int total_units = per_objfile->per_bfd->all_comp_units.size ();
for (int i = 0; i < total_units; ++i)
{
- dwarf2_per_cu_data *per_cu = per_objfile->per_bfd->get_cutu (i);
+ dwarf2_per_cu_data *per_cu = per_objfile->per_bfd->get_cu (i);
/* We don't want to directly expand a partial CU, because if we
read it with the wrong language, then assertion failures can
}
}
-static void
-dw2_expand_symtabs_with_fullname (struct objfile *objfile,
- const char *fullname)
-{
- dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
-
- /* We don't need to consider type units here.
- This is only called for examining code, e.g. expand_line_sal.
- There can be an order of magnitude (or more) more type units
- than comp units, and we avoid them if we can. */
-
- for (dwarf2_per_cu_data *per_cu : per_objfile->per_bfd->all_comp_units)
- {
- /* We only need to look at symtabs not already expanded. */
- if (per_objfile->symtab_set_p (per_cu))
- continue;
-
- quick_file_names *file_data = dw2_get_file_names (per_cu, per_objfile);
- if (file_data == NULL)
- continue;
-
- for (int j = 0; j < file_data->num_file_names; ++j)
- {
- const char *this_fullname = file_data->file_names[j];
-
- if (filename_cmp (this_fullname, fullname) == 0)
- {
- dw2_instantiate_symtab (per_cu, per_objfile, false);
- break;
- }
- }
- }
-}
-
-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::expand_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)
{
/* Used for Ada. */
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;
/* We have -readnow: no .gdb_index, but no partial symtabs either. So,
proceed assuming all symtabs have been read in. */
}
-
- for (compunit_symtab *cust : objfile->compunits ())
- {
- const struct block *block;
-
- if (cust == NULL)
- continue;
- block = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), block_kind);
- if (!iterate_over_symbols_terminated (block, name,
- domain, callback))
- return;
- }
}
/* Starting from a search name, return the string that finds the upper
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;
+ offset_type vec_len, vec_idx;
bool global_seen = false;
mapped_index &index = *per_objfile->per_bfd->index_table;
- vec = (offset_type *) (index.constant_pool
- + MAYBE_SWAP (index.symbol_table[idx].vec));
- vec_len = MAYBE_SWAP (vec[0]);
+ offset_view vec (index.constant_pool.slice (index.symbol_vec_index (idx)));
+ vec_len = vec[0];
for (vec_idx = 0; vec_idx < vec_len; ++vec_idx)
{
- offset_type cu_index_and_attrs = MAYBE_SWAP (vec[vec_idx + 1]);
+ offset_type cu_index_and_attrs = vec[vec_idx + 1];
/* 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 =
/* 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:
}
/* Don't crash on bad data. */
- if (cu_index >= (per_objfile->per_bfd->all_comp_units.size ()
- + per_objfile->per_bfd->all_type_units.size ()))
+ if (cu_index >= per_objfile->per_bfd->all_comp_units.size ())
{
complaint (_(".gdb_index entry has bad CU index"
" [in module %s]"), objfile_name (per_objfile->objfile));
continue;
}
- 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);
+ dwarf2_per_cu_data *per_cu = per_objfile->per_bfd->get_cu (cu_index);
+ 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
/* The rule is CUs specify all the files, including those used by
any TU, so there's no need to scan TUs here. */
- for (dwarf2_per_cu_data *per_cu : per_objfile->per_bfd->all_comp_units)
+ for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
{
QUIT;
+ if (per_cu->is_debug_types)
+ continue;
per_cu->v.quick->mark = 0;
/* We only need to look at symtabs not already expanded. */
- if (per_objfile->symtab_set_p (per_cu))
+ if (per_objfile->symtab_set_p (per_cu.get ()))
continue;
- quick_file_names *file_data = dw2_get_file_names (per_cu, per_objfile);
+ quick_file_names *file_data = dw2_get_file_names (per_cu.get (),
+ per_objfile);
if (file_data == NULL)
continue;
}
}
-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,
+ domain_enum domain,
+ 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);
if (symbol_matcher == NULL && lookup_name == NULL)
{
- for (dwarf2_per_cu_data *per_cu : per_objfile->per_bfd->all_comp_units)
+ for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
{
QUIT;
- dw2_expand_symtabs_matching_one (per_cu, per_objfile,
- file_matcher, expansion_notify);
+ if (!dw2_expand_symtabs_matching_one (per_cu.get (), 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);
+
+ return result;
}
/* A helper for dw2_find_pc_sect_compunit_symtab which finds the most specific
return NULL;
}
-static struct compunit_symtab *
-dw2_find_pc_sect_compunit_symtab (struct objfile *objfile,
- struct bound_minimal_symbol msymbol,
- CORE_ADDR pc,
- struct obj_section *section,
- int warn_if_readin)
+struct compunit_symtab *
+dwarf2_base_index_functions::find_pc_sect_compunit_symtab
+ (struct objfile *objfile,
+ struct bound_minimal_symbol msymbol,
+ CORE_ADDR pc,
+ struct obj_section *section,
+ int warn_if_readin)
{
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));
return result;
}
-static void
-dw2_map_symbol_filenames (struct objfile *objfile, symbol_filename_ftype *fun,
- void *data, int need_fullname)
+void
+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 (!per_objfile->per_bfd->filenames_cache)
- {
- per_objfile->per_bfd->filenames_cache.emplace ();
-
- htab_up visited (htab_create_alloc (10,
- htab_hash_pointer, htab_eq_pointer,
- NULL, xcalloc, xfree));
+ /* Use caches to ensure we only call FUN once for each filename. */
+ filename_seen_cache filenames_cache;
+ std::unordered_set<quick_file_names *> qfn_cache;
- /* 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. */
+ /* 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. It is possible that an expanded CU might
+ reuse the file names data from a currently unexpanded CU, in this
+ case we don't want to report the files from the unexpanded CU. */
- for (dwarf2_per_cu_data *per_cu : per_objfile->per_bfd->all_comp_units)
+ for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
+ {
+ if (per_objfile->symtab_set_p (per_cu.get ()))
{
- if (per_objfile->symtab_set_p (per_cu))
- {
- void **slot = htab_find_slot (visited.get (),
- per_cu->v.quick->file_names,
- INSERT);
-
- *slot = per_cu->v.quick->file_names;
- }
+ if (per_cu->v.quick->file_names != nullptr)
+ qfn_cache.insert (per_cu->v.quick->file_names);
}
+ }
- for (dwarf2_per_cu_data *per_cu : per_objfile->per_bfd->all_comp_units)
- {
- /* We only need to look at symtabs not already expanded. */
- if (per_objfile->symtab_set_p (per_cu))
- continue;
-
- quick_file_names *file_data
- = dw2_get_file_names (per_cu, per_objfile);
- if (file_data == NULL)
- continue;
+ for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
+ {
+ /* We only need to look at symtabs not already expanded. */
+ if (per_objfile->symtab_set_p (per_cu.get ()))
+ continue;
- void **slot = htab_find_slot (visited.get (), file_data, INSERT);
- if (*slot)
- {
- /* Already visited. */
- continue;
- }
- *slot = file_data;
+ quick_file_names *file_data = dw2_get_file_names (per_cu.get (),
+ per_objfile);
+ if (file_data == nullptr
+ || qfn_cache.find (file_data) != qfn_cache.end ())
+ continue;
- for (int j = 0; j < file_data->num_file_names; ++j)
- {
- const char *filename = file_data->file_names[j];
- per_objfile->per_bfd->filenames_cache->seen (filename);
- }
+ for (int j = 0; j < file_data->num_file_names; ++j)
+ {
+ const char *filename = file_data->file_names[j];
+ filenames_cache.seen (filename);
}
}
- per_objfile->per_bfd->filenames_cache->traverse ([&] (const char *filename)
+ filenames_cache.traverse ([&] (const char *filename)
{
gdb::unique_xmalloc_ptr<char> this_real_name;
if (need_fullname)
this_real_name = gdb_realpath (filename);
- (*fun) (filename, this_real_name.get (), data);
+ fun (filename, this_real_name.get ());
});
}
-static int
-dw2_has_symbols (struct objfile *objfile)
+bool
+dwarf2_base_index_functions::has_symbols (struct objfile *objfile)
{
- return 1;
+ return true;
}
-const struct quick_symbol_functions dwarf2_gdb_index_functions =
-{
- dw2_has_symbols,
- dw2_find_last_source_symtab,
- dw2_forget_cached_source_info,
- dw2_map_symtabs_matching_filename,
- dw2_lookup_symbol,
- NULL,
- dw2_print_stats,
- dw2_dump,
- dw2_expand_symtabs_for_function,
- dw2_expand_all_symtabs,
- dw2_expand_symtabs_with_fullname,
- dw2_map_matching_symbols,
- dw2_expand_symtabs_matching,
- dw2_find_pc_sect_compunit_symtab,
- NULL,
- dw2_map_symbol_filenames
-};
-
/* DWARF-5 debug_names reader. */
/* DWARF-5 augmentation string for GDB's DW_IDX_GNU_* extension. */
of the next CU as end of this CU. We create the CUs here with
length 0, and in cutu_reader::cutu_reader we'll fill in the
actual length. */
- dwarf2_per_cu_data *per_cu
+ dwarf2_per_cu_data_up per_cu
= create_cu_from_index_list (per_bfd, §ion, is_dwz,
sect_off, 0);
- per_bfd->all_comp_units.push_back (per_cu);
+ per_bfd->all_comp_units.push_back (std::move (per_cu));
}
return;
}
if (i >= 1)
{
const ULONGEST length = sect_off_next - sect_off_prev;
- dwarf2_per_cu_data *per_cu
+ dwarf2_per_cu_data_up per_cu
= create_cu_from_index_list (per_bfd, §ion, is_dwz,
sect_off_prev, length);
- per_bfd->all_comp_units.push_back (per_cu);
+ per_bfd->all_comp_units.push_back (std::move (per_cu));
}
sect_off_prev = sect_off_next;
}
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,
+ domain_enum domain = UNDEF_DOMAIN)
: m_map (map),
+ m_domain (domain),
m_search (search),
m_addr (find_vec_in_debug_names (map, namei, per_objfile)),
m_per_objfile (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]"),
objfile_name (objfile));
continue;
}
- per_cu = per_bfd->get_cutu (ull);
+ per_cu = per_bfd->get_cu (ull);
break;
case DW_IDX_type_unit:
/* Don't crash on bad data. */
- if (ull >= per_bfd->all_type_units.size ())
+ if (ull >= per_bfd->tu_stats.nr_tus)
{
complaint (_(".debug_names entry has bad TU index %s"
" [in module %s]"),
objfile_name (objfile));
continue;
}
- per_cu = &per_bfd->get_tu (ull)->per_cu;
+ per_cu = per_bfd->get_cu (ull + per_bfd->tu_stats.nr_tus);
break;
case DW_IDX_die_offset:
/* In a per-CU index (as opposed to a per-module index), index
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
return per_cu;
}
-static struct compunit_symtab *
-dw2_debug_names_lookup_symbol (struct objfile *objfile, block_enum block_index,
- const char *name, domain_enum domain)
-{
- dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
-
- const auto &mapp = per_objfile->per_bfd->debug_names_table;
- if (!mapp)
- {
- /* index is NULL if OBJF_READNOW. */
- return NULL;
- }
- const auto &map = *mapp;
-
- dw2_debug_names_iterator iter (map, block_index, domain, name, per_objfile);
-
- struct compunit_symtab *stab_best = NULL;
- struct dwarf2_per_cu_data *per_cu;
- while ((per_cu = iter.next ()) != NULL)
- {
- struct symbol *sym, *with_opaque = NULL;
- compunit_symtab *stab
- = dw2_instantiate_symtab (per_cu, per_objfile, false);
- const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
- const struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
-
- sym = block_find_symbol (block, name, domain,
- block_find_non_opaque_type_preferred,
- &with_opaque);
-
- /* 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 (sym != NULL
- && strcmp_iw (sym->search_name (), name) == 0)
- return stab;
- if (with_opaque != NULL
- && strcmp_iw (with_opaque->search_name (), name) == 0)
- stab_best = stab;
-
- /* Keep looking through other CUs. */
- }
-
- return stab_best;
-}
-
/* This dumps minimal information about .debug_names. It is called
via "mt print objfiles". The gdb.dwarf2/gdb-index.exp testcase
uses this to verify that .debug_names has been loaded. */
-static void
-dw2_debug_names_dump (struct objfile *objfile)
+void
+dwarf2_debug_names_index::dump (struct objfile *objfile)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
if (per_objfile->per_bfd->debug_names_table)
printf_filtered (" exists\n");
else
- printf_filtered (" faked for \"readnow\"\n");
- printf_filtered ("\n");
-}
-
-static void
-dw2_debug_names_expand_symtabs_for_function (struct objfile *objfile,
- const char *func_name)
-{
- dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
-
- /* per_objfile->per_bfd->debug_names_table is NULL if OBJF_READNOW. */
- if (per_objfile->per_bfd->debug_names_table)
- {
- const mapped_debug_names &map = *per_objfile->per_bfd->debug_names_table;
-
- dw2_debug_names_iterator iter (map, {}, VAR_DOMAIN, func_name,
- per_objfile);
-
- struct dwarf2_per_cu_data *per_cu;
- while ((per_cu = iter.next ()) != NULL)
- dw2_instantiate_symtab (per_cu, per_objfile, false);
- }
+ printf_filtered (" faked for \"readnow\"\n");
+ printf_filtered ("\n");
}
-static void
-dw2_debug_names_map_matching_symbols
+void
+dwarf2_debug_names_index::expand_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)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
return;
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;
nullptr);
return true;
}, per_objfile);
-
- /* It's a shame we couldn't do this inside the
- dw2_expand_symtabs_matching_symbol callback, but that skips CUs
- that have already been expanded. Instead, this loop matches what
- the psymtab code does. */
- for (dwarf2_per_cu_data *per_cu : per_objfile->per_bfd->all_comp_units)
- {
- compunit_symtab *symtab = per_objfile->get_symtab (per_cu);
- if (symtab != nullptr)
- {
- const struct block *block
- = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (symtab), block_kind);
- if (!iterate_over_symbols_terminated (block, name,
- domain, callback))
- break;
- }
- }
}
-static void
-dw2_debug_names_expand_symtabs_matching
+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,
+ domain_enum domain,
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);
if (symbol_matcher == NULL && lookup_name == NULL)
{
- for (dwarf2_per_cu_data *per_cu : per_objfile->per_bfd->all_comp_units)
+ for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
{
QUIT;
- dw2_expand_symtabs_matching_one (per_cu, per_objfile, file_matcher,
- expansion_notify);
+ if (!dw2_expand_symtabs_matching_one (per_cu.get (), 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. */
- dw2_debug_names_iterator iter (map, kind, namei, per_objfile);
+ dw2_debug_names_iterator iter (map, kind, namei, per_objfile, domain);
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);
-}
-const struct quick_symbol_functions dwarf2_debug_names_functions =
-{
- dw2_has_symbols,
- dw2_find_last_source_symtab,
- dw2_forget_cached_source_info,
- dw2_map_symtabs_matching_filename,
- dw2_debug_names_lookup_symbol,
- NULL,
- dw2_print_stats,
- dw2_debug_names_dump,
- dw2_debug_names_expand_symtabs_for_function,
- dw2_expand_all_symtabs,
- dw2_expand_symtabs_with_fullname,
- dw2_debug_names_map_matching_symbols,
- dw2_debug_names_expand_symtabs_matching,
- dw2_find_pc_sect_compunit_symtab,
- NULL,
- dw2_map_symbol_filenames
-};
+ return result;
+}
/* Get the content of the .gdb_index section of OBJ. SECTION_OWNER should point
to either a dwarf2_per_bfd or dwz_file object. */
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;
create_all_comp_units (per_objfile);
- create_all_type_units (per_objfile);
per_bfd->quick_file_names_table
= create_quick_file_names_table (per_bfd->all_comp_units.size ());
per_objfile->resize_symtabs ();
- for (int i = 0; i < (per_bfd->all_comp_units.size ()
- + per_bfd->all_type_units.size ()); ++i)
+ for (int i = 0; i < per_bfd->all_comp_units.size (); ++i)
{
- dwarf2_per_cu_data *per_cu = per_bfd->get_cutu (i);
+ dwarf2_per_cu_data *per_cu = per_bfd->get_cu (i);
per_cu->v.quick = OBSTACK_ZALLOC (&per_bfd->obstack,
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 = 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);
+ psymtab_discarder psymtabs (partial_symtabs.get ());
dwarf2_build_psymtabs_hard (per_objfile);
psymtabs.keep ();
{
exception_print (gdb_stderr, except);
}
-
- /* Finish by setting 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;
}
/* Find the base address of the compilation unit for range lists and
/* 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;
}
NULL, xcalloc, xfree));
}
-/* A helper function to add a signatured type CU to a table. */
-
-static int
-add_signatured_type_cu_to_table (void **slot, void *datum)
-{
- struct signatured_type *sigt = (struct signatured_type *) *slot;
- std::vector<signatured_type *> *all_type_units
- = (std::vector<signatured_type *> *) datum;
-
- all_type_units->push_back (sigt);
-
- return 1;
-}
-
/* A helper for create_debug_types_hash_table. Read types from SECTION
and fill them into TYPES_HTAB. It will process only type units,
therefore DW_UT_type. */
bfd *abfd;
const gdb_byte *info_ptr, *end_ptr;
- abbrev_section = (dwo_file != NULL
- ? &dwo_file->sections.abbrev
- : &per_objfile->per_bfd->abbrev);
+ abbrev_section = &dwo_file->sections.abbrev;
- dwarf_read_debug_printf ("Reading %s for %s:",
+ dwarf_read_debug_printf ("Reading %s for %s",
section->get_name (),
abbrev_section->get_file_name ());
end_ptr = info_ptr + section->size;
while (info_ptr < end_ptr)
{
- struct signatured_type *sig_type;
+ std::unique_ptr<signatured_type> sig_type;
struct dwo_unit *dwo_tu;
void **slot;
const gdb_byte *ptr = info_ptr;
}
if (types_htab == NULL)
- {
- if (dwo_file)
- types_htab = allocate_dwo_unit_table ();
- else
- types_htab = allocate_signatured_type_table ();
- }
+ types_htab = allocate_dwo_unit_table ();
- if (dwo_file)
- {
- sig_type = NULL;
- dwo_tu = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack, dwo_unit);
- dwo_tu->dwo_file = dwo_file;
- dwo_tu->signature = header.signature;
- dwo_tu->type_offset_in_tu = header.type_cu_offset_in_tu;
- dwo_tu->section = section;
- dwo_tu->sect_off = sect_off;
- dwo_tu->length = length;
- }
- else
- {
- /* N.B.: type_offset is not usable if this type uses a DWO file.
- The real type_offset is in the DWO file. */
- dwo_tu = NULL;
- sig_type = per_objfile->per_bfd->allocate_signatured_type ();
- sig_type->signature = header.signature;
- sig_type->type_offset_in_tu = header.type_cu_offset_in_tu;
- sig_type->per_cu.is_debug_types = 1;
- sig_type->per_cu.section = section;
- sig_type->per_cu.sect_off = sect_off;
- sig_type->per_cu.length = length;
- }
-
- slot = htab_find_slot (types_htab.get (),
- dwo_file ? (void*) dwo_tu : (void *) sig_type,
- INSERT);
+ dwo_tu = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack, dwo_unit);
+ dwo_tu->dwo_file = dwo_file;
+ dwo_tu->signature = header.signature;
+ dwo_tu->type_offset_in_tu = header.type_cu_offset_in_tu;
+ dwo_tu->section = section;
+ dwo_tu->sect_off = sect_off;
+ dwo_tu->length = length;
+
+ slot = htab_find_slot (types_htab.get (), dwo_tu, INSERT);
gdb_assert (slot != NULL);
if (*slot != NULL)
- {
- sect_offset dup_sect_off;
-
- if (dwo_file)
- {
- const struct dwo_unit *dup_tu
- = (const struct dwo_unit *) *slot;
-
- dup_sect_off = dup_tu->sect_off;
- }
- else
- {
- const struct signatured_type *dup_tu
- = (const struct signatured_type *) *slot;
-
- dup_sect_off = dup_tu->per_cu.sect_off;
- }
-
- complaint (_("debug type entry at offset %s is duplicate to"
- " the entry at offset %s, signature %s"),
- sect_offset_str (sect_off), sect_offset_str (dup_sect_off),
- hex_string (header.signature));
- }
- *slot = dwo_file ? (void *) dwo_tu : (void *) sig_type;
+ complaint (_("debug type entry at offset %s is duplicate to"
+ " the entry at offset %s, signature %s"),
+ sect_offset_str (sect_off),
+ sect_offset_str (dwo_tu->sect_off),
+ hex_string (header.signature));
+ *slot = dwo_tu;
dwarf_read_debug_printf_v (" offset %s, signature %s",
sect_offset_str (sect_off),
/* Create the hash table of all entries in the .debug_types
(or .debug_types.dwo) section(s).
- If reading a DWO file, then DWO_FILE is a pointer to the DWO file object,
- otherwise it is NULL.
+ DWO_FILE is a pointer to the DWO file object.
The result is a pointer to the hash table or NULL if there are no types.
rcuh_kind::TYPE);
}
-/* Create the hash table of all entries in the .debug_types section,
- and initialize all_type_units.
- The result is zero if there is an error (e.g. missing .debug_types section),
- otherwise non-zero. */
-
-static int
-create_all_type_units (dwarf2_per_objfile *per_objfile)
-{
- htab_up types_htab;
-
- create_debug_type_hash_table (per_objfile, NULL, &per_objfile->per_bfd->info,
- types_htab, rcuh_kind::COMPILE);
- create_debug_types_hash_table (per_objfile, NULL, per_objfile->per_bfd->types,
- types_htab);
- if (types_htab == NULL)
- {
- per_objfile->per_bfd->signatured_types = NULL;
- return 0;
- }
-
- per_objfile->per_bfd->signatured_types = std::move (types_htab);
-
- gdb_assert (per_objfile->per_bfd->all_type_units.empty ());
- per_objfile->per_bfd->all_type_units.reserve
- (htab_elements (per_objfile->per_bfd->signatured_types.get ()));
-
- htab_traverse_noresize (per_objfile->per_bfd->signatured_types.get (),
- add_signatured_type_cu_to_table,
- &per_objfile->per_bfd->all_type_units);
-
- return 1;
-}
-
/* Add an entry for signature SIG to dwarf2_per_objfile->per_bfd->signatured_types.
If SLOT is non-NULL, it is the entry to use in the hash table.
Otherwise we find one. */
static struct signatured_type *
add_type_unit (dwarf2_per_objfile *per_objfile, ULONGEST sig, void **slot)
{
- if (per_objfile->per_bfd->all_type_units.size ()
- == per_objfile->per_bfd->all_type_units.capacity ())
+ if (per_objfile->per_bfd->all_comp_units.size ()
+ == per_objfile->per_bfd->all_comp_units.capacity ())
++per_objfile->per_bfd->tu_stats.nr_all_type_units_reallocs;
- signatured_type *sig_type = per_objfile->per_bfd->allocate_signatured_type ();
+ std::unique_ptr<signatured_type> sig_type_holder
+ = per_objfile->per_bfd->allocate_signatured_type ();
+ signatured_type *sig_type = sig_type_holder.get ();
per_objfile->resize_symtabs ();
- per_objfile->per_bfd->all_type_units.push_back (sig_type);
+ per_objfile->per_bfd->all_comp_units.emplace_back
+ (sig_type_holder.release ());
sig_type->signature = sig;
- sig_type->per_cu.is_debug_types = 1;
+ sig_type->is_debug_types = 1;
if (per_objfile->per_bfd->using_index)
{
- sig_type->per_cu.v.quick =
+ sig_type->v.quick =
OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack,
struct dwarf2_per_cu_quick_data);
}
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
/* Make sure we're not clobbering something we don't expect to. */
- gdb_assert (! sig_entry->per_cu.queued);
- gdb_assert (per_objfile->get_cu (&sig_entry->per_cu) == NULL);
+ gdb_assert (! sig_entry->queued);
+ gdb_assert (per_objfile->get_cu (sig_entry) == NULL);
if (per_bfd->using_index)
{
- gdb_assert (sig_entry->per_cu.v.quick != NULL);
- gdb_assert (!per_objfile->symtab_set_p (&sig_entry->per_cu));
+ gdb_assert (sig_entry->v.quick != NULL);
+ gdb_assert (!per_objfile->symtab_set_p (sig_entry));
}
else
- gdb_assert (sig_entry->per_cu.v.psymtab == NULL);
+ gdb_assert (sig_entry->v.psymtab == NULL);
gdb_assert (sig_entry->signature == dwo_entry->signature);
gdb_assert (to_underlying (sig_entry->type_offset_in_section) == 0);
gdb_assert (sig_entry->type_unit_group == NULL);
gdb_assert (sig_entry->dwo_unit == NULL);
- sig_entry->per_cu.section = dwo_entry->section;
- sig_entry->per_cu.sect_off = dwo_entry->sect_off;
- sig_entry->per_cu.length = dwo_entry->length;
- sig_entry->per_cu.reading_dwo_directly = 1;
- sig_entry->per_cu.per_bfd = per_bfd;
+ sig_entry->section = dwo_entry->section;
+ sig_entry->sect_off = dwo_entry->sect_off;
+ sig_entry->length = dwo_entry->length;
+ sig_entry->reading_dwo_directly = 1;
+ sig_entry->per_bfd = per_bfd;
sig_entry->type_offset_in_tu = dwo_entry->type_offset_in_tu;
sig_entry->dwo_unit = dwo_entry;
}
/* Have we already tried to read this TU?
Note: sig_entry can be NULL if the skeleton TU was removed (thus it
needn't exist in the global table yet). */
- if (sig_entry != NULL && sig_entry->per_cu.tu_read)
+ if (sig_entry != NULL && sig_entry->tu_read)
return sig_entry;
/* Note: cu->dwo_unit is the dwo_unit that references this TU, not the
sig_entry = add_type_unit (per_objfile, sig, slot);
fill_in_sig_entry_from_dwo_entry (per_objfile, sig_entry, dwo_entry);
- sig_entry->per_cu.tu_read = 1;
+ sig_entry->tu_read = 1;
return sig_entry;
}
return htab_up (htab_create_alloc (3,
hash_type_unit_group,
eq_type_unit_group,
- NULL, xcalloc, xfree));
+ htab_delete_entry<type_unit_group>,
+ xcalloc, xfree));
}
/* Type units that don't have DW_AT_stmt_list are grouped into their own
/* Helper routine for get_type_unit_group.
Create the type_unit_group object used to hold one or more TUs. */
-static struct type_unit_group *
+static std::unique_ptr<type_unit_group>
create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
- 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);
- per_cu = &tu_group->per_cu;
- per_cu->per_bfd = per_bfd;
+ std::unique_ptr<type_unit_group> tu_group (new type_unit_group);
+ tu_group->per_bfd = per_bfd;
if (per_bfd->using_index)
{
- per_cu->v.quick = OBSTACK_ZALLOC (&per_bfd->obstack,
- struct dwarf2_per_cu_quick_data);
+ tu_group->v.quick = OBSTACK_ZALLOC (&per_bfd->obstack,
+ struct dwarf2_per_cu_quick_data);
}
else
{
else
name = string_printf ("<type_units_at_0x%x>", line_offset);
- pst = create_partial_symtab (per_cu, per_objfile, name.c_str ());
+ pst = create_partial_symtab (tu_group.get (), per_objfile,
+ name.c_str ());
pst->anonymous = true;
}
type_unit_group_for_lookup.hash.line_sect_off = (sect_offset) line_offset;
slot = htab_find_slot (per_objfile->per_bfd->type_unit_groups.get (),
&type_unit_group_for_lookup, INSERT);
- if (*slot != NULL)
- {
- tu_group = (struct type_unit_group *) *slot;
- gdb_assert (tu_group != NULL);
- }
- else
+ if (*slot == nullptr)
{
sect_offset line_offset_struct = (sect_offset) line_offset;
- tu_group = create_type_unit_group (cu, line_offset_struct);
- *slot = tu_group;
+ std::unique_ptr<type_unit_group> grp
+ = create_type_unit_group (cu, line_offset_struct);
+ *slot = grp.release ();
++tu_stats->nr_symtabs;
}
+ tu_group = (struct type_unit_group *) *slot;
+ gdb_assert (tu_group != nullptr);
return tu_group;
}
\f
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)
: sig_type (sig_type_), abbrev_offset (abbrev_offset_)
{}
+ /* This is used when sorting. */
+ bool operator< (const tu_abbrev_offset &other) const
+ {
+ return abbrev_offset < other.abbrev_offset;
+ }
+
signatured_type *sig_type;
sect_offset abbrev_offset;
};
-/* Helper routine for build_type_psymtabs_1, passed to std::sort. */
-
-static bool
-sort_tu_by_abbrev_offset (const struct tu_abbrev_offset &a,
- const struct tu_abbrev_offset &b)
-{
- return a.abbrev_offset < b.abbrev_offset;
-}
-
/* Efficiently read all the type units.
- This does the bulk of the work for build_type_psymtabs.
The efficiency is because we sort TUs by the abbrev table they use and
only read each abbrev table once. In one program there are 200K TUs
dwarf2_per_objfile->per_bfd->type_unit_groups. */
static void
-build_type_psymtabs_1 (dwarf2_per_objfile *per_objfile)
+build_type_psymtabs (dwarf2_per_objfile *per_objfile)
{
struct tu_stats *tu_stats = &per_objfile->per_bfd->tu_stats;
abbrev_table_up abbrev_table;
/* It's up to the caller to not call us multiple times. */
gdb_assert (per_objfile->per_bfd->type_unit_groups == NULL);
- if (per_objfile->per_bfd->all_type_units.empty ())
+ if (per_objfile->per_bfd->tu_stats.nr_tus == 0)
return;
/* TUs typically share abbrev tables, and there can be way more TUs than
dwarf_read_debug_printf ("Building type unit groups ...");
- /* Sort in a separate table to maintain the order of all_type_units
+ /* Sort in a separate table to maintain the order of all_comp_units
for .gdb_index: TU indices directly index all_type_units. */
std::vector<tu_abbrev_offset> sorted_by_abbrev;
- sorted_by_abbrev.reserve (per_objfile->per_bfd->all_type_units.size ());
+ sorted_by_abbrev.reserve (per_objfile->per_bfd->tu_stats.nr_tus);
- for (signatured_type *sig_type : per_objfile->per_bfd->all_type_units)
- sorted_by_abbrev.emplace_back
- (sig_type, read_abbrev_offset (per_objfile, sig_type->per_cu.section,
- sig_type->per_cu.sect_off));
+ for (const auto &cu : per_objfile->per_bfd->all_comp_units)
+ {
+ if (cu->is_debug_types)
+ {
+ auto sig_type = static_cast<signatured_type *> (cu.get ());
+ sorted_by_abbrev.emplace_back
+ (sig_type, read_abbrev_offset (per_objfile, sig_type->section,
+ sig_type->sect_off));
+ }
+ }
- std::sort (sorted_by_abbrev.begin (), sorted_by_abbrev.end (),
- sort_tu_by_abbrev_offset);
+ std::sort (sorted_by_abbrev.begin (), sorted_by_abbrev.end ());
abbrev_offset = (sect_offset) ~(unsigned) 0;
++tu_stats->nr_uniq_abbrev_tables;
}
- cutu_reader reader (&tu.sig_type->per_cu, per_objfile,
+ cutu_reader reader (tu.sig_type, per_objfile,
abbrev_table.get (), nullptr, false);
if (!reader.dummy_p)
build_type_psymtabs_reader (&reader, reader.info_ptr,
struct tu_stats *tu_stats = &per_objfile->per_bfd->tu_stats;
dwarf_read_debug_printf ("Type unit statistics:");
- dwarf_read_debug_printf (" %zu TUs",
- per_objfile->per_bfd->all_type_units.size ());
+ dwarf_read_debug_printf (" %d TUs", tu_stats->nr_tus);
dwarf_read_debug_printf (" %d uniq abbrev tables",
tu_stats->nr_uniq_abbrev_tables);
dwarf_read_debug_printf (" %d symtabs from stmt_list entries",
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;
+ dwarf2_psymtab *pst = tu_group->v.psymtab;
int len = (tu_group->tus == nullptr) ? 0 : tu_group->tus->size ();
int i;
gdb_assert (len > 0);
- gdb_assert (per_cu->type_unit_group_p ());
+ gdb_assert (tu_group->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);
- gdb_assert (iter->per_cu.is_debug_types);
- pst->dependencies[i] = iter->per_cu.v.psymtab;
+ gdb_assert (iter->is_debug_types);
+ pst->dependencies[i] = iter->v.psymtab;
iter->type_unit_group = tu_group;
}
return 1;
}
-/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
- Build partial symbol tables for the .debug_types comp-units. */
-
-static void
-build_type_psymtabs (dwarf2_per_objfile *per_objfile)
-{
- if (! create_all_type_units (per_objfile))
- return;
-
- build_type_psymtabs_1 (per_objfile);
-}
-
/* Traversal function for process_skeletonless_type_unit.
Read a TU in a DWO file and build partial symbols for it. */
if (*slot != NULL)
return 1;
- /* This does the job that create_all_type_units would have done for
+ /* This does the job that create_all_comp_units would have done for
this TU. */
entry = add_type_unit (per_objfile, dwo_unit->signature, slot);
fill_in_sig_entry_from_dwo_entry (per_objfile, entry, dwo_unit);
*slot = entry;
- /* This does the job that build_type_psymtabs_1 would have done. */
- cutu_reader reader (&entry->per_cu, per_objfile, nullptr, nullptr, false);
+ /* This does the job that build_type_psymtabs would have done. */
+ cutu_reader reader (entry, per_objfile, nullptr, nullptr, false);
if (!reader.dummy_p)
build_type_psymtabs_reader (&reader, reader.info_ptr,
reader.comp_unit_die);
static void
set_partial_user (dwarf2_per_objfile *per_objfile)
{
- for (dwarf2_per_cu_data *per_cu : per_objfile->per_bfd->all_comp_units)
+ for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
{
dwarf2_psymtab *pst = per_cu->v.psymtab;
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. */
free_cached_comp_units freer (per_objfile);
- build_type_psymtabs (per_objfile);
-
create_all_comp_units (per_objfile);
+ build_type_psymtabs (per_objfile);
/* Create a temporary address map on a temporary obstack. We later
copy this to the final obstack. */
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 (const auto &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. */
continue;
- process_psymtab_comp_unit (per_cu, per_objfile, false,
+ process_psymtab_comp_unit (per_cu.get (), per_objfile, false,
language_minimal);
}
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 ();
read_comp_units_from_section (dwarf2_per_objfile *per_objfile,
struct dwarf2_section_info *section,
struct dwarf2_section_info *abbrev_section,
- unsigned int is_dwz)
+ unsigned int is_dwz,
+ htab_up &types_htab,
+ rcuh_kind section_kind)
{
const gdb_byte *info_ptr;
struct objfile *objfile = per_objfile->objfile;
while (info_ptr < section->buffer + section->size)
{
- struct dwarf2_per_cu_data *this_cu;
+ dwarf2_per_cu_data_up this_cu;
sect_offset sect_off = (sect_offset) (info_ptr - section->buffer);
comp_unit_head cu_header;
read_and_check_comp_unit_head (per_objfile, &cu_header, section,
abbrev_section, info_ptr,
- rcuh_kind::COMPILE);
+ section_kind);
/* Save the compilation unit for later lookup. */
if (cu_header.unit_type != DW_UT_type)
this_cu = per_objfile->per_bfd->allocate_per_cu ();
else
{
+ if (types_htab == nullptr)
+ types_htab = allocate_signatured_type_table ();
+
auto sig_type = per_objfile->per_bfd->allocate_signatured_type ();
+ signatured_type *sig_ptr = sig_type.get ();
sig_type->signature = cu_header.signature;
sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
- this_cu = &sig_type->per_cu;
+ this_cu.reset (sig_type.release ());
+
+ void **slot = htab_find_slot (types_htab.get (), sig_ptr, INSERT);
+ gdb_assert (slot != nullptr);
+ if (*slot != nullptr)
+ complaint (_("debug type entry at offset %s is duplicate to"
+ " the entry at offset %s, signature %s"),
+ sect_offset_str (sect_off),
+ sect_offset_str (sig_ptr->sect_off),
+ hex_string (sig_ptr->signature));
+ *slot = sig_ptr;
}
this_cu->is_debug_types = (cu_header.unit_type == DW_UT_type);
this_cu->sect_off = sect_off;
this_cu->is_dwz = is_dwz;
this_cu->section = section;
- per_objfile->per_bfd->all_comp_units.push_back (this_cu);
-
info_ptr = info_ptr + this_cu->length;
+ per_objfile->per_bfd->all_comp_units.push_back (std::move (this_cu));
}
}
static void
create_all_comp_units (dwarf2_per_objfile *per_objfile)
{
- gdb_assert (per_objfile->per_bfd->all_comp_units.empty ());
+ htab_up types_htab;
+
read_comp_units_from_section (per_objfile, &per_objfile->per_bfd->info,
- &per_objfile->per_bfd->abbrev, 0);
+ &per_objfile->per_bfd->abbrev, 0,
+ types_htab, rcuh_kind::COMPILE);
+ for (dwarf2_section_info §ion : per_objfile->per_bfd->types)
+ read_comp_units_from_section (per_objfile, §ion,
+ &per_objfile->per_bfd->abbrev, 0,
+ types_htab, rcuh_kind::TYPE);
dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
if (dwz != NULL)
- read_comp_units_from_section (per_objfile, &dwz->info, &dwz->abbrev, 1);
+ read_comp_units_from_section (per_objfile, &dwz->info, &dwz->abbrev, 1,
+ types_htab, rcuh_kind::COMPILE);
+
+ per_objfile->per_bfd->signatured_types = std::move (types_htab);
}
/* Process all loaded DIEs for compilation unit CU, starting at
&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);
}
/* Mark the dependence relation so that we don't flush PER_CU
too early. */
if (dependent_cu != NULL)
- dwarf2_add_dependence (dependent_cu, per_cu);
+ dependent_cu->add_dependence (per_cu);
/* If it's already on the queue, we have nothing to do. */
if (per_cu->queued)
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);
per_objfile->line_header_hash
.reset (htab_create_alloc (127, line_header_hash_voidp,
line_header_eq_voidp,
- free_line_header_voidp,
+ htab_delete_entry<line_header>,
xcalloc, xfree));
}
static htab_up
allocate_dwo_file_hash_table ()
{
- auto delete_dwo_file = [] (void *item)
- {
- struct dwo_file *dwo_file = (struct dwo_file *) item;
-
- delete dwo_file;
- };
-
return htab_up (htab_create_alloc (41,
hash_dwo_file,
eq_dwo_file,
- delete_dwo_file,
+ htab_delete_entry<dwo_file>,
xcalloc, xfree));
}
void **slot;
sect_offset sect_off = (sect_offset) (info_ptr - section.buffer);
- memset (&per_cu, 0, sizeof (per_cu));
per_cu.per_bfd = per_bfd;
per_cu.is_debug_types = 0;
per_cu.sect_off = sect_offset (info_ptr - section.buffer);
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;
if (sig_type != NULL)
{
- struct dwarf2_per_cu_data *sig_cu = &sig_type->per_cu;
-
/* We pass NULL for DEPENDENT_CU because we don't yet know if there's
a real dependency of PER_CU on SIG_TYPE. That is detected later
while processing PER_CU. */
- if (maybe_queue_comp_unit (NULL, sig_cu, cu->per_objfile, cu->language))
- load_full_type_unit (sig_cu, cu->per_objfile);
- cu->per_cu->imported_symtabs_push (sig_cu);
+ if (maybe_queue_comp_unit (NULL, sig_type, cu->per_objfile,
+ cu->language))
+ load_full_type_unit (sig_type, cu->per_objfile);
+ cu->per_cu->imported_symtabs_push (sig_type);
}
return 1;
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);
gdb_assert_not_reached ("unable to find suitable integer type");
}
-/* See read.h. */
-
-struct type *
-dwarf2_cu::addr_sized_int_type (bool unsigned_p) const
-{
- int addr_size = this->per_cu->addr_size ();
- return this->per_objfile->int_type (addr_size, unsigned_p);
-}
-
/* Read the DW_AT_type attribute for a sub-range. If this attribute is not
present (which is valid) then compute the default type based on the
compilation units address size. */
last_die = NULL;
gdb_assert (cu->per_cu != NULL);
- if (cu->per_cu->load_all_dies)
+ if (cu->load_all_dies)
load_all = 1;
cu->partial_dies
/* If we didn't find it, and not all dies have been loaded,
load them all and try again. */
- if (pd == NULL && cu->per_cu->load_all_dies == 0)
+ if (pd == NULL && cu->load_all_dies == 0)
{
- cu->per_cu->load_all_dies = 1;
+ cu->load_all_dies = 1;
/* This is nasty. When we reread the DIEs, somewhere up the call chain
THIS_CU->cu may already be in use. So we can't just free it and
return follow_die_ref (die, spec_attr, spec_cu);
}
-/* Stub for free_line_header to match void * callback types. */
-
-static void
-free_line_header_voidp (void *arg)
-{
- struct line_header *lh = (struct line_header *) arg;
-
- delete lh;
-}
-
/* A convenience function to find the proper .debug_line section for a CU. */
static struct dwarf2_section_info *
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
cu->get_builder ()->start_subfile (filename);
}
-/* Start a symtab for DWARF. NAME, COMP_DIR, LOW_PC are passed to the
- buildsym_compunit constructor. */
-
-struct compunit_symtab *
-dwarf2_cu::start_symtab (const char *name, const char *comp_dir,
- CORE_ADDR low_pc)
-{
- gdb_assert (m_builder == nullptr);
-
- m_builder.reset (new struct buildsym_compunit
- (this->per_objfile->objfile,
- name, comp_dir, language, low_pc));
-
- list_in_scope = get_builder ()->get_file_symbols ();
-
- get_builder ()->record_debugformat ("DWARF 2");
- get_builder ()->record_producer (producer);
-
- processing_has_namespace_info = false;
-
- return get_builder ()->get_compunit_symtab ();
-}
-
static void
var_decode_location (struct attribute *attr, struct symbol *sym,
struct dwarf2_cu *cu)
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 ();
Even if maybe_queue_comp_unit doesn't require us to load the CU's DIEs,
it doesn't mean they are currently loaded. Since we require them
to be loaded, we must check for ourselves. */
- if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu, per_objfile,
+ if (maybe_queue_comp_unit (*ref_cu, sig_type, per_objfile,
language_minimal)
- || per_objfile->get_cu (&sig_type->per_cu) == nullptr)
+ || per_objfile->get_cu (sig_type) == nullptr)
read_signatured_type (sig_type, per_objfile);
- sig_cu = per_objfile->get_cu (&sig_type->per_cu);
+ sig_cu = per_objfile->get_cu (sig_type);
gdb_assert (sig_cu != NULL);
gdb_assert (to_underlying (sig_type->type_offset_in_section) != 0);
temp_die.sect_off = sig_type->type_offset_in_section;
read_signatured_type (signatured_type *sig_type,
dwarf2_per_objfile *per_objfile)
{
- struct dwarf2_per_cu_data *per_cu = &sig_type->per_cu;
-
- gdb_assert (per_cu->is_debug_types);
- gdb_assert (per_objfile->get_cu (per_cu) == nullptr);
+ gdb_assert (sig_type->is_debug_types);
+ gdb_assert (per_objfile->get_cu (sig_type) == nullptr);
- cutu_reader reader (per_cu, per_objfile, nullptr, nullptr, false);
+ cutu_reader reader (sig_type, per_objfile, nullptr, nullptr, false);
if (!reader.dummy_p)
{
reader.keep ();
}
- sig_type->per_cu.tu_read = 1;
+ sig_type->tu_read = 1;
}
/* Decode simple location descriptions.
return header->offset_size;
}
-/* See read.h. */
-
-struct type *
-dwarf2_cu::addr_type () const
-{
- struct objfile *objfile = this->per_objfile->objfile;
- struct type *void_type = objfile_type (objfile)->builtin_void;
- struct type *addr_type = lookup_pointer_type (void_type);
- int addr_size = this->per_cu->addr_size ();
-
- if (TYPE_LENGTH (addr_type) == addr_size)
- return addr_type;
-
- addr_type = addr_sized_int_type (addr_type->is_unsigned ());
- return addr_type;
-}
-
/* A helper function for dwarf2_find_containing_comp_unit that returns
the index of the result, and that searches a vector. It will
return a result even if the offset in question does not actually
dwarf2_find_containing_comp_unit
(sect_offset sect_off,
unsigned int offset_in_dwz,
- const std::vector<dwarf2_per_cu_data *> &all_comp_units)
+ const std::vector<dwarf2_per_cu_data_up> &all_comp_units)
{
int low, high;
struct dwarf2_per_cu_data *mid_cu;
int mid = low + (high - low) / 2;
- mid_cu = all_comp_units[mid];
+ mid_cu = all_comp_units[mid].get ();
if (mid_cu->is_dwz > offset_in_dwz
|| (mid_cu->is_dwz == offset_in_dwz
&& mid_cu->sect_off + mid_cu->length > sect_off))
{
int low = dwarf2_find_containing_comp_unit
(sect_off, offset_in_dwz, per_objfile->per_bfd->all_comp_units);
- dwarf2_per_cu_data *this_cu = per_objfile->per_bfd->all_comp_units[low];
+ dwarf2_per_cu_data *this_cu
+ = per_objfile->per_bfd->all_comp_units[low].get ();
if (this_cu->is_dwz != offset_in_dwz || this_cu->sect_off > sect_off)
{
gdb_assert (per_objfile->per_bfd->all_comp_units[low-1]->sect_off
<= sect_off);
- return per_objfile->per_bfd->all_comp_units[low-1];
+ return per_objfile->per_bfd->all_comp_units[low - 1].get ();
}
else
{
static void
run_test ()
{
- struct dwarf2_per_cu_data one {};
- struct dwarf2_per_cu_data two {};
- struct dwarf2_per_cu_data three {};
- struct dwarf2_per_cu_data four {};
-
- one.length = 5;
- two.sect_off = sect_offset (one.length);
- two.length = 7;
-
- three.length = 5;
- three.is_dwz = 1;
- four.sect_off = sect_offset (three.length);
- four.length = 7;
- four.is_dwz = 1;
-
- std::vector<dwarf2_per_cu_data *> units;
- units.push_back (&one);
- units.push_back (&two);
- units.push_back (&three);
- units.push_back (&four);
+ dwarf2_per_cu_data_up one (new dwarf2_per_cu_data);
+ dwarf2_per_cu_data *one_ptr = one.get ();
+ dwarf2_per_cu_data_up two (new dwarf2_per_cu_data);
+ dwarf2_per_cu_data *two_ptr = two.get ();
+ dwarf2_per_cu_data_up three (new dwarf2_per_cu_data);
+ dwarf2_per_cu_data *three_ptr = three.get ();
+ dwarf2_per_cu_data_up four (new dwarf2_per_cu_data);
+ dwarf2_per_cu_data *four_ptr = four.get ();
+
+ one->length = 5;
+ two->sect_off = sect_offset (one->length);
+ two->length = 7;
+
+ three->length = 5;
+ three->is_dwz = 1;
+ four->sect_off = sect_offset (three->length);
+ four->length = 7;
+ four->is_dwz = 1;
+
+ std::vector<dwarf2_per_cu_data_up> units;
+ units.push_back (std::move (one));
+ units.push_back (std::move (two));
+ units.push_back (std::move (three));
+ units.push_back (std::move (four));
int result;
result = dwarf2_find_containing_comp_unit (sect_offset (0), 0, units);
- SELF_CHECK (units[result] == &one);
+ SELF_CHECK (units[result].get () == one_ptr);
result = dwarf2_find_containing_comp_unit (sect_offset (3), 0, units);
- SELF_CHECK (units[result] == &one);
+ SELF_CHECK (units[result].get () == one_ptr);
result = dwarf2_find_containing_comp_unit (sect_offset (5), 0, units);
- SELF_CHECK (units[result] == &two);
+ SELF_CHECK (units[result].get () == two_ptr);
result = dwarf2_find_containing_comp_unit (sect_offset (0), 1, units);
- SELF_CHECK (units[result] == &three);
+ SELF_CHECK (units[result].get () == three_ptr);
result = dwarf2_find_containing_comp_unit (sect_offset (3), 1, units);
- SELF_CHECK (units[result] == &three);
+ SELF_CHECK (units[result].get () == three_ptr);
result = dwarf2_find_containing_comp_unit (sect_offset (5), 1, units);
- SELF_CHECK (units[result] == &four);
+ SELF_CHECK (units[result].get () == four_ptr);
}
}
#endif /* GDB_SELF_TEST */
-/* Initialize dwarf2_cu to read PER_CU, in the context of PER_OBJFILE. */
-
-dwarf2_cu::dwarf2_cu (dwarf2_per_cu_data *per_cu,
- dwarf2_per_objfile *per_objfile)
- : per_cu (per_cu),
- per_objfile (per_objfile),
- mark (false),
- has_loclist (false),
- checked_producer (false),
- producer_is_gxx_lt_4_6 (false),
- producer_is_gcc_lt_4_3 (false),
- producer_is_icc (false),
- producer_is_icc_lt_14 (false),
- producer_is_codewarrior (false),
- processing_has_namespace_info (false)
-{
-}
-
/* Initialize basic fields of dwarf_cu CU according to DIE COMP_UNIT_DIE. */
static void
/* Start by clearing all marks. */
for (auto pair : m_dwarf2_cus)
- pair.second->mark = false;
+ pair.second->clear_mark ();
/* Traverse all CUs, mark them and their dependencies if used recently
enough. */
cu->last_used++;
if (cu->last_used <= dwarf_max_cache_age)
- dwarf2_mark (cu);
+ cu->mark ();
}
/* Delete all CUs still not marked. */
{
dwarf2_cu *cu = it->second;
- if (!cu->mark)
+ if (!cu->is_marked ())
{
dwarf_read_debug_printf_v ("deleting old CU %s",
sect_offset_str (cu->per_cu->sect_off));
return get_die_type_at_offset (die->sect_off, cu->per_cu, cu->per_objfile);
}
-/* Add a dependence relationship from CU to REF_PER_CU. */
-
-static void
-dwarf2_add_dependence (struct dwarf2_cu *cu,
- struct dwarf2_per_cu_data *ref_per_cu)
-{
- void **slot;
-
- if (cu->dependencies == NULL)
- cu->dependencies
- = htab_create_alloc_ex (5, htab_hash_pointer, htab_eq_pointer,
- NULL, &cu->comp_unit_obstack,
- hashtab_obstack_allocate,
- dummy_obstack_deallocate);
-
- slot = htab_find_slot (cu->dependencies, ref_per_cu, INSERT);
- if (*slot == NULL)
- *slot = ref_per_cu;
-}
-
-/* Subroutine of dwarf2_mark to pass to htab_traverse.
- Set the mark field in every compilation unit in the
- cache that we must keep because we are keeping CU.
-
- DATA is the dwarf2_per_objfile object in which to look up CUs. */
-
-static int
-dwarf2_mark_helper (void **slot, void *data)
-{
- dwarf2_per_cu_data *per_cu = (dwarf2_per_cu_data *) *slot;
- dwarf2_per_objfile *per_objfile = (dwarf2_per_objfile *) data;
- dwarf2_cu *cu = per_objfile->get_cu (per_cu);
-
- /* cu->dependencies references may not yet have been ever read if QUIT aborts
- reading of the chain. As such dependencies remain valid it is not much
- useful to track and undo them during QUIT cleanups. */
- if (cu == nullptr)
- return 1;
-
- if (cu->mark)
- return 1;
-
- cu->mark = true;
-
- if (cu->dependencies != nullptr)
- htab_traverse (cu->dependencies, dwarf2_mark_helper, per_objfile);
-
- return 1;
-}
-
-/* Set the mark field in CU and in every other compilation unit in the
- cache that we must keep because we are keeping CU. */
-
-static void
-dwarf2_mark (struct dwarf2_cu *cu)
-{
- if (cu->mark)
- return;
-
- cu->mark = true;
-
- if (cu->dependencies != nullptr)
- htab_traverse (cu->dependencies, dwarf2_mark_helper, cu->per_objfile);
-}
-
/* Trivial hash function for partial_die_info: the hash value of a DIE
is its offset in .debug_info for this objfile. */
add_basic_prefix_cmd ("dwarf", class_maintenance, _("\
Set DWARF specific variables.\n\
Configure DWARF variables such as the cache size."),
- &set_dwarf_cmdlist, "maintenance set dwarf ",
+ &set_dwarf_cmdlist,
0/*allow-unknown*/, &maintenance_set_cmdlist);
add_show_prefix_cmd ("dwarf", class_maintenance, _("\
Show DWARF specific variables.\n\
Show DWARF variables such as the cache size."),
- &show_dwarf_cmdlist, "maintenance show dwarf ",
+ &show_dwarf_cmdlist,
0/*allow-unknown*/, &maintenance_show_cmdlist);
add_setshow_zinteger_cmd ("max-cache-age", class_obscure,