/* When true, do not reject deprecated .gdb_index sections. */
static bool use_deprecated_index_sections = false;
-static const struct objfile_key<dwarf2_per_objfile> dwarf2_objfile_data_key;
+/* This is used to store the data that is always per objfile. */
+static const objfile_key<dwarf2_per_objfile> dwarf2_objfile_data_key;
+
+/* These are used to store the dwarf2_per_bfd objects.
+
+ objfiles having the same BFD, which doesn't require relocations, are going to
+ share a dwarf2_per_bfd object, which is held in the _bfd_data_key version.
+
+ Other objfiles are not going to share a dwarf2_per_bfd with any other
+ objfiles, so they'll have their own version kept in the _objfile_data_key
+ version. */
+static const struct bfd_key<dwarf2_per_bfd> dwarf2_per_bfd_bfd_data_key;
+static const struct objfile_key<dwarf2_per_bfd> dwarf2_per_bfd_objfile_data_key;
/* The "aclass" indices for various kinds of computed DWARF symbols. */
static int dwarf2_locexpr_block_index;
static int dwarf2_loclist_block_index;
+/* Size of .debug_loclists section header for 32-bit DWARF format. */
+#define LOCLIST_HEADER_SIZE32 12
+
+/* Size of .debug_loclists section header for 64-bit DWARF format. */
+#define LOCLIST_HEADER_SIZE64 20
+
/* An index into a (C++) symbol name component in a symbol name as
recorded in the mapped_index's symbol table. For each C++ symbol
in the symbol table, we record one entry for the start of each
virtual size_t symbol_name_count () const = 0;
/* Get the name of the symbol at IDX in the symbol table. */
- virtual const char *symbol_name_at (offset_type idx) const = 0;
+ virtual const char *symbol_name_at
+ (offset_type idx, dwarf2_per_objfile *per_objfile) const = 0;
/* Return whether the name at IDX in the symbol table should be
ignored. */
/* Build the symbol name component sorted vector, if we haven't
yet. */
- void build_name_components ();
+ void build_name_components (dwarf2_per_objfile *per_objfile);
/* Returns the lower (inclusive) and upper (exclusive) bounds of the
possible matches for LN_NO_PARAMS in the name component
std::pair<std::vector<name_component>::const_iterator,
std::vector<name_component>::const_iterator>
find_name_components_bounds (const lookup_name_info &ln_no_params,
- enum language lang) const;
+ enum language lang,
+ dwarf2_per_objfile *per_objfile) const;
/* Prevent deleting/destroying via a base class pointer. */
protected:
/* Convenience method to get at the name of the symbol at IDX in the
symbol table. */
- const char *symbol_name_at (offset_type idx) const override
+ 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); }
size_t symbol_name_count () const override
Uninitialized map has CU_COUNT 0. */
struct mapped_debug_names final : public mapped_index_base
{
- mapped_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile_)
- : dwarf2_per_objfile (dwarf2_per_objfile_)
- {}
-
- struct dwarf2_per_objfile *dwarf2_per_objfile;
bfd_endian dwarf5_byte_order;
bool dwarf5_is_dwarf64;
bool augmentation_is_gdb;
std::unordered_map<ULONGEST, index_val> abbrev_map;
- const char *namei_to_name (uint32_t namei) const;
+ const char *namei_to_name
+ (uint32_t namei, dwarf2_per_objfile *per_objfile) const;
/* Implementation of the mapped_index_base virtual interface, for
the name_components cache. */
- const char *symbol_name_at (offset_type idx) const override
- { return namei_to_name (idx); }
+ const char *symbol_name_at
+ (offset_type idx, dwarf2_per_objfile *per_objfile) const override
+ { return namei_to_name (idx, per_objfile); }
size_t symbol_name_count () const override
{ return this->name_count; }
/* local data types */
+/* The location list section (.debug_loclists) begins with a header,
+ which contains the following information. */
+struct loclist_header
+{
+ /* A 4-byte or 12-byte length containing the length of the
+ set of entries for this compilation unit, not including the
+ length field itself. */
+ unsigned int length;
+
+ /* A 2-byte version identifier. */
+ short version;
+
+ /* A 1-byte unsigned integer containing the size in bytes of an address on
+ the target system. */
+ unsigned char addr_size;
+
+ /* A 1-byte unsigned integer containing the size in bytes of a segment selector
+ on the target system. */
+ unsigned char segment_collector_size;
+
+ /* A 4-byte count of the number of offsets that follow the header. */
+ unsigned int offset_entry_count;
+};
+
/* Type used for delaying computation of method physnames.
See comments for compute_delayed_physnames. */
struct delayed_method_info
/* Internal state when decoding a particular compilation unit. */
struct dwarf2_cu
{
- explicit dwarf2_cu (struct dwarf2_per_cu_data *per_cu);
- ~dwarf2_cu ();
+ explicit dwarf2_cu (dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile);
DISABLE_COPY_AND_ASSIGN (dwarf2_cu);
/* 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 {};
unit, including partial DIEs. */
auto_obstack comp_unit_obstack;
- /* When multiple dwarf2_cu structures are living in memory, this field
- chains them all together, so that they can be released efficiently.
- We will probably also want a generation counter so that most-recently-used
- compilation units are cached... */
- struct dwarf2_per_cu_data *read_in_chain = nullptr;
-
/* Backlink to our per_cu entry. */
struct dwarf2_per_cu_data *per_cu;
+ /* The dwarf2_per_objfile that owns this. */
+ struct dwarf2_per_objfile *per_objfile;
+
/* How many compilation units ago was this CU last referenced? */
int last_used = 0;
/* 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_objfile::line_header_hash. If non-NULL,
+ 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. */
whether the DW_AT_ranges attribute came from the skeleton or DWO. */
ULONGEST ranges_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
sect_offset line_sect_off;
};
-/* Each element of dwarf2_per_objfile->type_unit_groups is a pointer to
- an object of this type. */
+/* Each element of dwarf2_per_bfd->type_unit_groups is a pointer to
+ an object of this type. This contains elements of type unit groups
+ that can be shared across objfiles. The non-shareable parts are in
+ type_unit_group_unshareable. */
struct type_unit_group
{
and is deleted afterwards and not used again. */
std::vector<signatured_type *> *tus;
- /* The compunit symtab.
- Type units in a group needn't all be defined in the same source file,
- so we create an essentially anonymous symtab as the compunit symtab. */
- struct compunit_symtab *compunit_symtab;
-
/* The data used to construct the hash key. */
struct stmt_list_hash hash;
-
- /* The symbol tables for this TU (obtained from the files listed in
- DW_AT_stmt_list).
- WARNING: The order of entries here must match the order of entries
- in the line header. After the first TU using this type_unit_group, the
- line header for the subsequent TUs is recreated from this. This is done
- because we need to use the same symtabs for each TU using the same
- DW_AT_stmt_list value. Also note that symtabs may be repeated here,
- there's no guarantee the line header doesn't have duplicate entries. */
- struct symtab **symtabs;
};
/* These sections are what may appear in a (real or virtual) DWO file. */
{
public:
- cutu_reader (struct dwarf2_per_cu_data *this_cu,
+ cutu_reader (dwarf2_per_cu_data *this_cu,
+ dwarf2_per_objfile *per_objfile,
struct abbrev_table *abbrev_table,
- int use_existing_cu,
+ dwarf2_cu *existing_cu,
bool skip_partial);
explicit cutu_reader (struct dwarf2_per_cu_data *this_cu,
+ dwarf2_per_objfile *per_objfile,
struct dwarf2_cu *parent_cu = nullptr,
struct dwo_file *dwo_file = nullptr);
void keep ();
private:
- void init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
- int use_existing_cu);
+ void init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
+ dwarf2_per_objfile *per_objfile,
+ dwarf2_cu *existing_cu);
struct dwarf2_per_cu_data *m_this_cu;
std::unique_ptr<dwarf2_cu> m_new_cu;
const struct abbrev_info &abbrev,
const gdb_byte *info_ptr);
+ /* Compute the name of this partial DIE. This memoizes the
+ result, so it is safe to call multiple times. */
+ const char *name (dwarf2_cu *cu);
+
/* Offset of this DIE. */
const sect_offset sect_off;
/* Flag set if spec_offset uses DW_FORM_GNU_ref_alt. */
unsigned int spec_is_dwz : 1;
+ unsigned int canonical_name : 1;
+
/* The name of this DIE. Normally the value of DW_AT_name, but
sometimes a default name for unnamed DIEs. */
- const char *name = nullptr;
+ const char *raw_name = nullptr;
/* The linkage name, if present. */
const char *linkage_name = nullptr;
fixup_called = 0;
is_dwz = 0;
spec_is_dwz = 0;
+ canonical_name = 0;
}
};
and friends. */
static int bits_per_byte = 8;
-/* When reading a variant or variant part, we track a bit more
- information about the field, and store it in an object of this
- type. */
+struct variant_part_builder;
+
+/* When reading a variant, we track a bit more information about the
+ field, and store it in an object of this type. */
struct variant_field
{
- /* If we see a DW_TAG_variant, then this will be the discriminant
- value. */
- ULONGEST discriminant_value;
+ int first_field = -1;
+ int last_field = -1;
+
+ /* A variant can contain other variant parts. */
+ std::vector<variant_part_builder> variant_parts;
+
/* If we see a DW_TAG_variant, then this will be set if this is the
default branch. */
- bool default_branch;
- /* While reading a DW_TAG_variant_part, this will be set if this
- field is the discriminant. */
- bool is_discriminant;
+ bool default_branch = false;
+ /* If we see a DW_AT_discr_value, then this will be the discriminant
+ value. */
+ ULONGEST discriminant_value = 0;
+ /* If we see a DW_AT_discr_list, then this is a pointer to the list
+ data. */
+ struct dwarf_block *discr_list_data = nullptr;
+};
+
+/* This represents a DW_TAG_variant_part. */
+
+struct variant_part_builder
+{
+ /* The offset of the discriminant field. */
+ sect_offset discriminant_offset {};
+
+ /* Variants that are direct children of this variant part. */
+ std::vector<variant_field> variants;
+
+ /* True if we're currently reading a variant. */
+ bool processing_variant = false;
};
struct nextfield
{
int accessibility = 0;
int virtuality = 0;
- /* Extra information to describe a variant or variant part. */
- struct variant_field variant {};
+ /* Variant parts need to find the discriminant, which is a DIE
+ reference. We track the section offset of each field to make
+ this link. */
+ sect_offset offset;
struct field field {};
};
list. */
std::vector<struct decl_field> nested_types_list;
+ /* If non-null, this is the variant part we are currently
+ reading. */
+ variant_part_builder *current_variant_part = nullptr;
+ /* This holds all the top-level variant parts attached to the type
+ we're reading. */
+ std::vector<variant_part_builder> variant_parts;
+
/* Return the total number of fields (including baseclasses). */
int nfields () const
{
struct dwarf2_cu *cu);
static dwarf2_psymtab *create_partial_symtab
- (struct dwarf2_per_cu_data *per_cu, const char *name);
+ (dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
+ const char *name);
static void build_type_psymtabs_reader (const struct die_reader_specs *reader,
const gdb_byte *info_ptr,
static int dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *,
struct dwarf2_cu *, dwarf2_psymtab *);
+/* Return the .debug_loclists section to use for cu. */
+static struct dwarf2_section_info *cu_debug_loc_section (struct dwarf2_cu *cu);
+
/* How dwarf2_get_pc_bounds constructed its *LOWPC and *HIGHPC return
values. Keep the items ordered with increasing constraints compliance. */
enum pc_bounds_kind
static void process_enumeration_scope (struct die_info *, struct dwarf2_cu *);
-static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *);
+static CORE_ADDR decode_locdesc (struct dwarf_block *, struct dwarf2_cu *,
+ bool * = nullptr);
static enum dwarf_array_dim_ordering read_array_order (struct die_info *,
struct dwarf2_cu *);
const struct attribute *,
struct dwarf2_cu *);
-static void load_full_type_unit (struct dwarf2_per_cu_data *per_cu);
+static void load_full_type_unit (dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile);
-static void read_signatured_type (struct signatured_type *);
+static void read_signatured_type (signatured_type *sig_type,
+ dwarf2_per_objfile *per_objfile);
static int attr_to_dynamic_prop (const struct attribute *attr,
struct die_info *die, struct dwarf2_cu *cu,
struct die_info *comp_unit_die,
enum language pretend_language);
-static void age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile);
-
-static void free_one_cached_comp_unit (struct dwarf2_per_cu_data *);
-
static struct type *set_die_type (struct die_info *, struct type *,
struct dwarf2_cu *);
static int create_all_type_units (struct dwarf2_per_objfile *dwarf2_per_objfile);
-static void load_full_comp_unit (struct dwarf2_per_cu_data *, bool,
- enum language);
+static void load_full_comp_unit (dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile,
+ bool skip_partial,
+ enum language pretend_language);
-static void process_full_comp_unit (struct dwarf2_per_cu_data *,
- enum language);
+static void process_full_comp_unit (dwarf2_cu *cu,
+ enum language pretend_language);
-static void process_full_type_unit (struct dwarf2_per_cu_data *,
- enum language);
+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 void dwarf2_clear_marks (struct dwarf2_per_cu_data *);
-
static struct type *get_die_type_at_offset (sect_offset,
- struct dwarf2_per_cu_data *);
+ dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile);
static struct type *get_die_type (struct die_info *die, struct dwarf2_cu *cu);
-static void queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
+static void queue_comp_unit (dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile,
enum language pretend_language);
static void process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile);
{
/* Ensure that no memory is allocated by the queue. */
std::queue<dwarf2_queue_item> empty;
- std::swap (m_per_objfile->queue, empty);
+ std::swap (m_per_objfile->per_bfd->queue, empty);
}
DISABLE_COPY_AND_ASSIGN (dwarf2_queue_guard);
inconsistent state, so discard it. */
if (per_cu->queued)
{
- if (per_cu->cu != NULL)
- free_one_cached_comp_unit (per_cu);
+ per_objfile->remove_cu (per_cu);
per_cu->queued = 0;
}
}
(struct dwarf2_per_objfile *dwarf2_per_objfile);
static struct dwo_unit *lookup_dwo_comp_unit
- (struct dwarf2_per_cu_data *, const char *, const char *, ULONGEST);
+ (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
+ ULONGEST signature);
static struct dwo_unit *lookup_dwo_type_unit
- (struct signatured_type *, const char *, const char *);
+ (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir);
-static void queue_and_load_all_dwo_tus (struct dwarf2_per_cu_data *);
+static void queue_and_load_all_dwo_tus (dwarf2_cu *cu);
/* A unique pointer to a dwo_file. */
/* See declaration. */
-dwarf2_per_objfile::dwarf2_per_objfile (struct objfile *objfile_,
- const dwarf2_debug_sections *names,
- bool can_copy_)
- : objfile (objfile_),
+dwarf2_per_bfd::dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names,
+ bool can_copy_)
+ : obfd (obfd),
can_copy (can_copy_)
{
if (names == NULL)
names = &dwarf2_elf_names;
- bfd *obfd = objfile->obfd;
-
for (asection *sec = obfd->sections; sec != NULL; sec = sec->next)
locate_sections (obfd, sec, *names);
}
-dwarf2_per_objfile::~dwarf2_per_objfile ()
+dwarf2_per_bfd::~dwarf2_per_bfd ()
{
- /* Cached DIE trees use xmalloc and the comp_unit_obstack. */
- free_cached_comp_units ();
-
for (dwarf2_per_cu_data *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 the objfile obstack. */
+ /* Everything else should be on this->obstack. */
}
-/* See declaration. */
+/* See read.h. */
void
-dwarf2_per_objfile::free_cached_comp_units ()
+dwarf2_per_objfile::remove_all_cus ()
{
- dwarf2_per_cu_data *per_cu = read_in_chain;
- dwarf2_per_cu_data **last_chain = &read_in_chain;
- while (per_cu != NULL)
- {
- dwarf2_per_cu_data *next_cu = per_cu->cu->read_in_chain;
+ for (auto pair : m_dwarf2_cus)
+ delete pair.second;
- delete per_cu->cu;
- *last_chain = next_cu;
- per_cu = next_cu;
- }
+ m_dwarf2_cus.clear ();
}
/* A helper class that calls free_cached_comp_units on
~free_cached_comp_units ()
{
- m_per_objfile->free_cached_comp_units ();
+ m_per_objfile->remove_all_cus ();
}
DISABLE_COPY_AND_ASSIGN (free_cached_comp_units);
dwarf2_per_objfile *m_per_objfile;
};
+/* See read.h. */
+
+bool
+dwarf2_per_objfile::symtab_set_p (const dwarf2_per_cu_data *per_cu) const
+{
+ gdb_assert (per_cu->index < this->m_symtabs.size ());
+
+ return this->m_symtabs[per_cu->index] != nullptr;
+}
+
+/* See read.h. */
+
+compunit_symtab *
+dwarf2_per_objfile::get_symtab (const dwarf2_per_cu_data *per_cu) const
+{
+ gdb_assert (per_cu->index < this->m_symtabs.size ());
+
+ return this->m_symtabs[per_cu->index];
+}
+
+/* See read.h. */
+
+void
+dwarf2_per_objfile::set_symtab (const dwarf2_per_cu_data *per_cu,
+ compunit_symtab *symtab)
+{
+ gdb_assert (per_cu->index < this->m_symtabs.size ());
+ gdb_assert (this->m_symtabs[per_cu->index] == nullptr);
+
+ this->m_symtabs[per_cu->index] = symtab;
+}
+
/* Try to locate the sections we need for DWARF 2 debugging
information and return true if we have enough to do something.
NAMES points to the dwarf2 section names, or is NULL if the standard
= get_dwarf2_per_objfile (objfile);
if (dwarf2_per_objfile == NULL)
- dwarf2_per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile,
- names,
- can_copy);
+ {
+ 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))
+ {
+ /* See if one has been created for this BFD yet. */
+ per_bfd = dwarf2_per_bfd_bfd_data_key.get (objfile->obfd);
+
+ if (per_bfd == nullptr)
+ {
+ /* No, create it now. */
+ per_bfd = new dwarf2_per_bfd (objfile->obfd, names, can_copy);
+ dwarf2_per_bfd_bfd_data_key.set (objfile->obfd, per_bfd);
+ }
+ }
+ else
+ {
+ /* No sharing possible, create one specifically for this objfile. */
+ per_bfd = new dwarf2_per_bfd (objfile->obfd, names, can_copy);
+ dwarf2_per_bfd_objfile_data_key.set (objfile, per_bfd);
+ }
+
+ dwarf2_per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile, per_bfd);
+ }
- return (!dwarf2_per_objfile->info.is_virtual
- && dwarf2_per_objfile->info.s.section != NULL
- && !dwarf2_per_objfile->abbrev.is_virtual
- && dwarf2_per_objfile->abbrev.s.section != NULL);
+ return (!dwarf2_per_objfile->per_bfd->info.is_virtual
+ && dwarf2_per_objfile->per_bfd->info.s.section != NULL
+ && !dwarf2_per_objfile->per_bfd->abbrev.is_virtual
+ && dwarf2_per_objfile->per_bfd->abbrev.s.section != NULL);
}
/* When loading sections, we look either for uncompressed section or for
/* See declaration. */
void
-dwarf2_per_objfile::locate_sections (bfd *abfd, asection *sectp,
- const dwarf2_debug_sections &names)
+dwarf2_per_bfd::locate_sections (bfd *abfd, asection *sectp,
+ const dwarf2_debug_sections &names)
{
flagword aflag = bfd_section_flags (sectp);
asection **sectp, const gdb_byte **bufp,
bfd_size_type *sizep)
{
- struct dwarf2_per_objfile *data = dwarf2_objfile_data_key.get (objfile);
+ struct dwarf2_per_objfile *data = get_dwarf2_per_objfile (objfile);
struct dwarf2_section_info *info;
/* We may see an objfile without any DWARF, in which case we just
switch (sect)
{
case DWARF2_DEBUG_FRAME:
- info = &data->frame;
+ info = &data->per_bfd->frame;
break;
case DWARF2_EH_FRAME:
- info = &data->eh_frame;
+ info = &data->per_bfd->eh_frame;
break;
default:
gdb_assert_not_reached ("unexpected section");
/* See dwarf2read.h. */
struct dwz_file *
-dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
+dwarf2_get_dwz_file (dwarf2_per_bfd *per_bfd)
{
const char *filename;
bfd_size_type buildid_len_arg;
size_t buildid_len;
bfd_byte *buildid;
- if (dwarf2_per_objfile->dwz_file != NULL)
- return dwarf2_per_objfile->dwz_file.get ();
+ if (per_bfd->dwz_file != NULL)
+ return per_bfd->dwz_file.get ();
bfd_set_error (bfd_error_no_error);
gdb::unique_xmalloc_ptr<char> data
- (bfd_get_alt_debug_link_info (dwarf2_per_objfile->objfile->obfd,
+ (bfd_get_alt_debug_link_info (per_bfd->obfd,
&buildid_len_arg, &buildid));
if (data == NULL)
{
if (!IS_ABSOLUTE_PATH (filename))
{
gdb::unique_xmalloc_ptr<char> abs
- = gdb_realpath (objfile_name (dwarf2_per_objfile->objfile));
+ = gdb_realpath (bfd_get_filename (per_bfd->obfd));
abs_storage = ldirname (abs.get ()) + SLASH_STRING + filename;
filename = abs_storage.c_str ();
/* First try the file name given in the section. If that doesn't
work, try to use the build-id instead. */
- gdb_bfd_ref_ptr dwz_bfd (gdb_bfd_open (filename, gnutarget, -1));
+ gdb_bfd_ref_ptr dwz_bfd (gdb_bfd_open (filename, gnutarget));
if (dwz_bfd != NULL)
{
if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid))
if (dwz_bfd == nullptr)
{
gdb::unique_xmalloc_ptr<char> alt_filename;
- const char *origname = dwarf2_per_objfile->objfile->original_name;
+ const char *origname = bfd_get_filename (per_bfd->obfd);
scoped_fd fd (debuginfod_debuginfo_query (buildid,
buildid_len,
if (fd.get () >= 0)
{
/* File successfully retrieved from server. */
- dwz_bfd = gdb_bfd_open (alt_filename.get (), gnutarget, -1);
+ dwz_bfd = gdb_bfd_open (alt_filename.get (), gnutarget);
if (dwz_bfd == nullptr)
warning (_("File \"%s\" from debuginfod cannot be opened as bfd"),
if (dwz_bfd == NULL)
error (_("could not find '.gnu_debugaltlink' file for %s"),
- objfile_name (dwarf2_per_objfile->objfile));
+ bfd_get_filename (per_bfd->obfd));
std::unique_ptr<struct dwz_file> result
(new struct dwz_file (std::move (dwz_bfd)));
bfd_map_over_sections (result->dwz_bfd.get (), locate_dwz_sections,
result.get ());
- gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd,
- result->dwz_bfd.get ());
- dwarf2_per_objfile->dwz_file = std::move (result);
- return dwarf2_per_objfile->dwz_file.get ();
+ gdb_bfd_record_inclusion (per_bfd->obfd, result->dwz_bfd.get ());
+ per_bfd->dwz_file = std::move (result);
+ return per_bfd->dwz_file.get ();
}
\f
/* DWARF quick_symbols_functions support. */
{
/* The file table. This can be NULL if there was no file table
or it's currently not read in.
- NOTE: This points into dwarf2_per_objfile->quick_file_names_table. */
+ NOTE: This points into dwarf2_per_objfile->per_bfd->quick_file_names_table. */
struct quick_file_names *file_names;
- /* The corresponding symbol table. This is NULL if symbols for this
- CU have not yet been read. */
- struct compunit_symtab *compunit_symtab;
-
/* A temporary mark bit used when iterating over all CUs in
expand_symtabs_matching. */
unsigned int mark : 1;
xfree ((void*) file_data->real_names[i]);
}
- /* The space for the struct itself lives on objfile_obstack,
- so we don't free it here. */
+ /* The space for the struct itself lives on the obstack, so we don't
+ free it here. */
}
/* Create a quick_file_names hash table. */
delete_file_name_entry, xcalloc, xfree));
}
-/* Read in PER_CU->CU. This function is unrelated to symtabs, symtab would
- have to be created afterwards. You should call age_cached_comp_units after
- processing PER_CU->CU. dw2_setup must have been already called. */
+/* Read in CU (dwarf2_cu object) for PER_CU in the context of PER_OBJFILE. This
+ function is unrelated to symtabs, symtab would have to be created afterwards.
+ You should call age_cached_comp_units after processing the CU. */
-static void
-load_cu (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
+static dwarf2_cu *
+load_cu (dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
+ bool skip_partial)
{
if (per_cu->is_debug_types)
- load_full_type_unit (per_cu);
+ load_full_type_unit (per_cu, per_objfile);
else
- load_full_comp_unit (per_cu, skip_partial, language_minimal);
+ load_full_comp_unit (per_cu, per_objfile, skip_partial, language_minimal);
+
+ dwarf2_cu *cu = per_objfile->get_cu (per_cu);
+ if (cu == nullptr)
+ return nullptr; /* Dummy CU. */
- if (per_cu->cu == NULL)
- return; /* Dummy CU. */
+ dwarf2_find_base_address (cu->dies, cu);
- dwarf2_find_base_address (per_cu->cu->dies, per_cu->cu);
+ return cu;
}
-/* Read in the symbols for PER_CU. */
+/* Read in the symbols for PER_CU in the context of DWARF"_PER_OBJFILE. */
static void
-dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
+dw2_do_instantiate_symtab (dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *dwarf2_per_objfile,
+ bool skip_partial)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
-
/* Skip type_unit_groups, reading the type units they contain
is handled elsewhere. */
if (per_cu->type_unit_group_p ())
with the dwarf queue empty. */
dwarf2_queue_guard q_guard (dwarf2_per_objfile);
- if (dwarf2_per_objfile->using_index
- ? per_cu->v.quick->compunit_symtab == NULL
- : (per_cu->v.psymtab == NULL || !per_cu->v.psymtab->readin))
+ if (!dwarf2_per_objfile->symtab_set_p (per_cu))
{
- queue_comp_unit (per_cu, language_minimal);
- load_cu (per_cu, skip_partial);
+ queue_comp_unit (per_cu, dwarf2_per_objfile, language_minimal);
+ dwarf2_cu *cu = load_cu (per_cu, dwarf2_per_objfile, skip_partial);
/* If we just loaded a CU from a DWO, and we're working with an index
that may badly handle TUs, load all the TUs in that DWO as well.
http://sourceware.org/bugzilla/show_bug.cgi?id=15021 */
if (!per_cu->is_debug_types
- && per_cu->cu != NULL
- && per_cu->cu->dwo_unit != NULL
- && dwarf2_per_objfile->index_table != NULL
- && dwarf2_per_objfile->index_table->version <= 7
+ && cu != NULL
+ && cu->dwo_unit != NULL
+ && dwarf2_per_objfile->per_bfd->index_table != NULL
+ && dwarf2_per_objfile->per_bfd->index_table->version <= 7
/* DWP files aren't supported yet. */
&& get_dwp_file (dwarf2_per_objfile) == NULL)
- queue_and_load_all_dwo_tus (per_cu);
+ queue_and_load_all_dwo_tus (cu);
}
process_queue (dwarf2_per_objfile);
/* Age the cache, releasing compilation units that have not
been used recently. */
- age_cached_comp_units (dwarf2_per_objfile);
+ dwarf2_per_objfile->age_comp_units ();
}
-/* Ensure that the symbols for PER_CU have been read in. OBJFILE is
- the objfile from which this CU came. Returns the resulting symbol
- table. */
+/* Ensure that the symbols for PER_CU have been read in. DWARF2_PER_OBJFILE is
+ the per-objfile for which this symtab is instantiated.
+
+ Returns the resulting symbol table. */
static struct compunit_symtab *
-dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
+dw2_instantiate_symtab (dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *dwarf2_per_objfile,
+ bool skip_partial)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
+ gdb_assert (dwarf2_per_objfile->per_bfd->using_index);
- gdb_assert (dwarf2_per_objfile->using_index);
- if (!per_cu->v.quick->compunit_symtab)
+ if (!dwarf2_per_objfile->symtab_set_p (per_cu))
{
free_cached_comp_units freer (dwarf2_per_objfile);
scoped_restore decrementer = increment_reading_symtab ();
- dw2_do_instantiate_symtab (per_cu, skip_partial);
+ dw2_do_instantiate_symtab (per_cu, dwarf2_per_objfile, skip_partial);
process_cu_includes (dwarf2_per_objfile);
}
- return per_cu->v.quick->compunit_symtab;
+ return dwarf2_per_objfile->get_symtab (per_cu);
}
/* See declaration. */
dwarf2_per_cu_data *
-dwarf2_per_objfile::get_cutu (int index)
+dwarf2_per_bfd::get_cutu (int index)
{
if (index >= this->all_comp_units.size ())
{
/* See declaration. */
dwarf2_per_cu_data *
-dwarf2_per_objfile::get_cu (int index)
+dwarf2_per_bfd::get_cu (int index)
{
gdb_assert (index >= 0 && index < this->all_comp_units.size ());
/* See declaration. */
signatured_type *
-dwarf2_per_objfile::get_tu (int index)
+dwarf2_per_bfd::get_tu (int index)
{
gdb_assert (index >= 0 && index < this->all_type_units.size ());
return this->all_type_units[index];
}
-/* Return a new dwarf2_per_cu_data allocated on OBJFILE's
- objfile_obstack, and constructed with the specified field
- values. */
+/* See read.h. */
+
+dwarf2_per_cu_data *
+dwarf2_per_bfd::allocate_per_cu ()
+{
+ dwarf2_per_cu_data *result = OBSTACK_ZALLOC (&obstack, dwarf2_per_cu_data);
+ result->per_bfd = this;
+ result->index = m_num_psymtabs++;
+ return result;
+}
+
+/* See read.h. */
+
+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++;
+ 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 *
-create_cu_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
- struct dwarf2_section_info *section,
- int is_dwz,
- sect_offset sect_off, ULONGEST length)
+create_cu_from_index_list (dwarf2_per_bfd *per_bfd,
+ struct dwarf2_section_info *section,
+ int is_dwz,
+ sect_offset sect_off, ULONGEST length)
{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
- dwarf2_per_cu_data *the_cu
- = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct dwarf2_per_cu_data);
+ dwarf2_per_cu_data *the_cu = per_bfd->allocate_per_cu ();
the_cu->sect_off = sect_off;
the_cu->length = length;
- the_cu->dwarf2_per_objfile = dwarf2_per_objfile;
the_cu->section = section;
- the_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct dwarf2_per_cu_quick_data);
+ the_cu->v.quick = OBSTACK_ZALLOC (&per_bfd->obstack,
+ struct dwarf2_per_cu_quick_data);
the_cu->is_dwz = is_dwz;
return the_cu;
}
CUs. */
static void
-create_cus_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
+create_cus_from_index_list (dwarf2_per_bfd *per_bfd,
const gdb_byte *cu_list, offset_type n_elements,
struct dwarf2_section_info *section,
int is_dwz)
cu_list += 2 * 8;
dwarf2_per_cu_data *per_cu
- = create_cu_from_index_list (dwarf2_per_objfile, section, is_dwz,
- sect_off, length);
- dwarf2_per_objfile->all_comp_units.push_back (per_cu);
+ = create_cu_from_index_list (per_bfd, section, is_dwz, sect_off,
+ length);
+ per_bfd->all_comp_units.push_back (per_cu);
}
}
/* Read the CU list from the mapped index, and use it to create all
- the CU objects for this objfile. */
+ the CU objects for PER_BFD. */
static void
-create_cus_from_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
+create_cus_from_index (dwarf2_per_bfd *per_bfd,
const gdb_byte *cu_list, offset_type cu_list_elements,
const gdb_byte *dwz_list, offset_type dwz_elements)
{
- gdb_assert (dwarf2_per_objfile->all_comp_units.empty ());
- dwarf2_per_objfile->all_comp_units.reserve
- ((cu_list_elements + dwz_elements) / 2);
+ gdb_assert (per_bfd->all_comp_units.empty ());
+ per_bfd->all_comp_units.reserve ((cu_list_elements + dwz_elements) / 2);
- create_cus_from_index_list (dwarf2_per_objfile, cu_list, cu_list_elements,
- &dwarf2_per_objfile->info, 0);
+ create_cus_from_index_list (per_bfd, cu_list, cu_list_elements,
+ &per_bfd->info, 0);
if (dwz_elements == 0)
return;
- dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
- create_cus_from_index_list (dwarf2_per_objfile, dwz_list, dwz_elements,
+ dwz_file *dwz = dwarf2_get_dwz_file (per_bfd);
+ create_cus_from_index_list (per_bfd, dwz_list, dwz_elements,
&dwz->info, 1);
}
static void
create_signatured_type_table_from_index
- (struct dwarf2_per_objfile *dwarf2_per_objfile,
- struct dwarf2_section_info *section,
- const gdb_byte *bytes,
- offset_type elements)
+ (dwarf2_per_bfd *per_bfd, struct dwarf2_section_info *section,
+ const gdb_byte *bytes, offset_type elements)
{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
-
- gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
- dwarf2_per_objfile->all_type_units.reserve (elements / 3);
+ 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 ();
signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
bytes += 3 * 8;
- sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct signatured_type);
+ 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.dwarf2_per_objfile = dwarf2_per_objfile;
sig_type->per_cu.v.quick
- = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ = 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;
- dwarf2_per_objfile->all_type_units.push_back (sig_type);
+ per_bfd->all_type_units.push_back (sig_type);
}
- dwarf2_per_objfile->signatured_types = std::move (sig_types_hash);
+ per_bfd->signatured_types = std::move (sig_types_hash);
}
/* Create the signatured type hash table from .debug_names. */
section->read (objfile);
abbrev_section->read (objfile);
- gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
- dwarf2_per_objfile->all_type_units.reserve (map.tu_count);
+ gdb_assert (dwarf2_per_objfile->per_bfd->all_type_units.empty ());
+ dwarf2_per_objfile->per_bfd->all_type_units.reserve (map.tu_count);
htab_up sig_types_hash = allocate_signatured_type_table ();
section->buffer + to_underlying (sect_off),
rcuh_kind::TYPE);
- sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct signatured_type);
+ sig_type = dwarf2_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.dwarf2_per_objfile = dwarf2_per_objfile;
sig_type->per_cu.v.quick
- = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ = OBSTACK_ZALLOC (&dwarf2_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;
- dwarf2_per_objfile->all_type_units.push_back (sig_type);
+ dwarf2_per_objfile->per_bfd->all_type_units.push_back (sig_type);
}
- dwarf2_per_objfile->signatured_types = std::move (sig_types_hash);
+ dwarf2_per_objfile->per_bfd->signatured_types = std::move (sig_types_hash);
}
/* Read the address map data from the mapped index, and use it to
struct mapped_index *index)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
const gdb_byte *iter, *end;
struct addrmap *mutable_map;
CORE_ADDR baseaddr;
continue;
}
- if (cu_index >= dwarf2_per_objfile->all_comp_units.size ())
+ if (cu_index >= dwarf2_per_objfile->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,
- dwarf2_per_objfile->get_cu (cu_index));
+ dwarf2_per_objfile->per_bfd->get_cu (cu_index));
}
objfile->partial_symtabs->psymtabs_addrmap
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
bfd *abfd = objfile->obfd;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
const CORE_ADDR baseaddr = objfile->text_section_offset ();
auto_obstack temp_obstack;
dwarf2_per_cu_data *,
gdb::hash_enum<sect_offset>>
debug_info_offset_to_per_cu;
- for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
{
const auto insertpair
= debug_info_offset_to_per_cu.emplace (per_cu->sect_off, per_cu);
addr += address_size;
if (start == 0 && length == 0)
break;
- if (start == 0 && !dwarf2_per_objfile->has_section_at_zero)
+ if (start == 0 && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
{
/* Symbol was eliminated due to a COMDAT group. */
continue;
Returns true if all went well, false otherwise. */
static bool
-read_gdb_index_from_buffer (struct objfile *objfile,
- const char *filename,
+read_gdb_index_from_buffer (const char *filename,
bool deprecated_ok,
gdb::array_view<const gdb_byte> buffer,
struct mapped_index *map,
/* Callback types for dwarf2_read_gdb_index. */
typedef gdb::function_view
- <gdb::array_view<const gdb_byte>(objfile *, dwarf2_per_objfile *)>
+ <gdb::array_view<const gdb_byte>(objfile *, dwarf2_per_bfd *)>
get_gdb_index_contents_ftype;
typedef gdb::function_view
<gdb::array_view<const gdb_byte>(objfile *, dwz_file *)>
struct objfile *objfile = dwarf2_per_objfile->objfile;
gdb::array_view<const gdb_byte> main_index_contents
- = get_gdb_index_contents (objfile, dwarf2_per_objfile);
+ = get_gdb_index_contents (objfile, dwarf2_per_objfile->per_bfd);
if (main_index_contents.empty ())
return 0;
std::unique_ptr<struct mapped_index> map (new struct mapped_index);
- if (!read_gdb_index_from_buffer (objfile, objfile_name (objfile),
+ if (!read_gdb_index_from_buffer (objfile_name (objfile),
use_deprecated_index_sections,
main_index_contents, map.get (), &cu_list,
&cu_list_elements, &types_list,
/* If there is a .dwz file, read it so we can get its CU list as
well. */
- dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+ dwz = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
if (dwz != NULL)
{
struct mapped_index dwz_map;
if (dwz_index_content.empty ())
return 0;
- if (!read_gdb_index_from_buffer (objfile,
- bfd_get_filename (dwz->dwz_bfd.get ()),
+ if (!read_gdb_index_from_buffer (bfd_get_filename (dwz->dwz_bfd.get ()),
1, dwz_index_content, &dwz_map,
&dwz_list, &dwz_list_elements,
&dwz_types_ignore,
}
}
- create_cus_from_index (dwarf2_per_objfile, cu_list, cu_list_elements,
+ create_cus_from_index (dwarf2_per_objfile->per_bfd, cu_list, cu_list_elements,
dwz_list, dwz_list_elements);
if (types_list_elements)
{
/* We can only handle a single .debug_types when we have an
index. */
- if (dwarf2_per_objfile->types.size () != 1)
+ if (dwarf2_per_objfile->per_bfd->types.size () != 1)
return 0;
- dwarf2_section_info *section = &dwarf2_per_objfile->types[0];
+ dwarf2_section_info *section = &dwarf2_per_objfile->per_bfd->types[0];
- create_signatured_type_table_from_index (dwarf2_per_objfile, section,
- types_list, types_list_elements);
+ create_signatured_type_table_from_index (dwarf2_per_objfile->per_bfd,
+ section, types_list,
+ types_list_elements);
}
create_addrmap_from_index (dwarf2_per_objfile, map.get ());
- dwarf2_per_objfile->index_table = std::move (map);
- dwarf2_per_objfile->using_index = 1;
- dwarf2_per_objfile->quick_file_names_table =
- create_quick_file_names_table (dwarf2_per_objfile->all_comp_units.size ());
+ dwarf2_per_objfile->per_bfd->index_table = std::move (map);
+ dwarf2_per_objfile->per_bfd->using_index = 1;
+ dwarf2_per_objfile->per_bfd->quick_file_names_table =
+ create_quick_file_names_table (dwarf2_per_objfile->per_bfd->all_comp_units.size ());
return 1;
}
{
struct dwarf2_cu *cu = reader->cu;
struct dwarf2_per_cu_data *this_cu = cu->per_cu;
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
- struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct dwarf2_per_cu_data *lh_cu;
struct attribute *attr;
void **slot;
If we have we're done. */
find_entry.hash.dwo_unit = cu->dwo_unit;
find_entry.hash.line_sect_off = line_offset;
- slot = htab_find_slot (dwarf2_per_objfile->quick_file_names_table.get (),
+ slot = htab_find_slot (dwarf2_per_objfile->per_bfd->quick_file_names_table.get (),
&find_entry, INSERT);
if (*slot != NULL)
{
return;
}
- qfn = XOBNEW (&objfile->objfile_obstack, struct quick_file_names);
+ qfn = XOBNEW (&dwarf2_per_objfile->per_bfd->obstack, struct quick_file_names);
qfn->hash.dwo_unit = cu->dwo_unit;
qfn->hash.line_sect_off = line_offset;
gdb_assert (slot != NULL);
qfn->num_file_names = offset + lh->file_names_size ();
qfn->file_names =
- XOBNEWVEC (&objfile->objfile_obstack, const char *, qfn->num_file_names);
+ XOBNEWVEC (&dwarf2_per_objfile->per_bfd->obstack, const char *,
+ qfn->num_file_names);
if (offset != 0)
qfn->file_names[0] = xstrdup (fnd.name);
for (int i = 0; i < lh->file_names_size (); ++i)
table for THIS_CU. */
static struct quick_file_names *
-dw2_get_file_names (struct dwarf2_per_cu_data *this_cu)
+dw2_get_file_names (dwarf2_per_cu_data *this_cu,
+ dwarf2_per_objfile *per_objfile)
{
/* This should never be called for TUs. */
gdb_assert (! this_cu->is_debug_types);
if (this_cu->v.quick->no_file_data)
return NULL;
- cutu_reader reader (this_cu);
+ cutu_reader reader (this_cu, per_objfile);
if (!reader.dummy_p)
dw2_get_file_names_reader (&reader, reader.info_ptr, reader.comp_unit_die);
real path for a given file name from the line table. */
static const char *
-dw2_get_real_path (struct objfile *objfile,
+dw2_get_real_path (struct dwarf2_per_objfile *dwarf2_per_objfile,
struct quick_file_names *qfn, int index)
{
if (qfn->real_names == NULL)
- qfn->real_names = OBSTACK_CALLOC (&objfile->objfile_obstack,
+ qfn->real_names = OBSTACK_CALLOC (&dwarf2_per_objfile->per_bfd->obstack,
qfn->num_file_names, const char *);
if (qfn->real_names[index] == NULL)
{
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
- dwarf2_per_cu_data *dwarf_cu = dwarf2_per_objfile->all_comp_units.back ();
- compunit_symtab *cust = dw2_instantiate_symtab (dwarf_cu, false);
+ dwarf2_per_cu_data *dwarf_cu = dwarf2_per_objfile->per_bfd->all_comp_units.back ();
+ compunit_symtab *cust
+ = dw2_instantiate_symtab (dwarf_cu, dwarf2_per_objfile, false);
if (cust == NULL)
return NULL;
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
- htab_traverse_noresize (dwarf2_per_objfile->quick_file_names_table.get (),
+ htab_traverse_noresize (dwarf2_per_objfile->per_bfd->quick_file_names_table.get (),
dw2_free_cached_file_names, NULL);
}
struct compunit_symtab *last_made = objfile->compunit_symtabs;
/* Don't visit already-expanded CUs. */
- if (per_cu->v.quick->compunit_symtab)
+ 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, false);
+ dw2_instantiate_symtab (per_cu, per_objfile, false);
return iterate_over_some_symtabs (name, real_path, objfile->compunit_symtabs,
last_made, callback);
/* 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 : dwarf2_per_objfile->all_comp_units)
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
{
/* We only need to look at symtabs not already expanded. */
- if (per_cu->v.quick->compunit_symtab)
+ if (dwarf2_per_objfile->symtab_set_p (per_cu))
continue;
- quick_file_names *file_data = dw2_get_file_names (per_cu);
+ quick_file_names *file_data
+ = dw2_get_file_names (per_cu, dwarf2_per_objfile);
if (file_data == NULL)
continue;
&& FILENAME_CMP (lbasename (this_name), name_basename) != 0)
continue;
- this_real_name = dw2_get_real_path (objfile, file_data, j);
+ this_real_name = dw2_get_real_path (dwarf2_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,
iter->next = 0;
iter->global_seen = 0;
- mapped_index *index = dwarf2_per_objfile->index_table.get ();
+ mapped_index *index = dwarf2_per_objfile->per_bfd->index_table.get ();
/* index is NULL if OBJF_READNOW. */
if (index != NULL && find_slot_in_mapped_hash (index, name, &iter->vec))
and indices >= 7 may elide them for certain symbols
(gold does this). */
int attrs_valid =
- (dwarf2_per_objfile->index_table->version >= 7
+ (dwarf2_per_objfile->per_bfd->index_table->version >= 7
&& symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE);
/* Don't crash on bad data. */
- if (cu_index >= (dwarf2_per_objfile->all_comp_units.size ()
- + dwarf2_per_objfile->all_type_units.size ()))
+ if (cu_index >= (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
+ + dwarf2_per_objfile->per_bfd->all_type_units.size ()))
{
complaint (_(".gdb_index entry has bad CU index"
" [in module %s]"),
continue;
}
- dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (cu_index);
+ dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (cu_index);
/* Skip if already read in. */
- if (per_cu->v.quick->compunit_symtab)
+ if (dwarf2_per_objfile->symtab_set_p (per_cu))
continue;
/* Check static vs global. */
while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
{
struct symbol *sym, *with_opaque = NULL;
- struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu, false);
+ struct compunit_symtab *stab
+ = dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, false);
const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
const struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
{
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
- int total = (dwarf2_per_objfile->all_comp_units.size ()
- + dwarf2_per_objfile->all_type_units.size ());
+ int total = (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
+ + dwarf2_per_objfile->per_bfd->all_type_units.size ());
int count = 0;
for (int i = 0; i < total; ++i)
{
- dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
+ dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (i);
- if (!per_cu->v.quick->compunit_symtab)
+ if (!dwarf2_per_objfile->symtab_set_p (per_cu))
++count;
}
printf_filtered (_(" Number of read CUs: %d\n"), total - count);
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
- gdb_assert (dwarf2_per_objfile->using_index);
+ gdb_assert (dwarf2_per_objfile->per_bfd->using_index);
printf_filtered (".gdb_index:");
- if (dwarf2_per_objfile->index_table != NULL)
+ if (dwarf2_per_objfile->per_bfd->index_table != NULL)
{
printf_filtered (" version %d\n",
- dwarf2_per_objfile->index_table->version);
+ dwarf2_per_objfile->per_bfd->index_table->version);
}
else
printf_filtered (" faked for \"readnow\"\n");
dw2_symtab_iter_init (&iter, dwarf2_per_objfile, {}, VAR_DOMAIN, func_name);
while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
- dw2_instantiate_symtab (per_cu, false);
+ dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, false);
}
{
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
- int total_units = (dwarf2_per_objfile->all_comp_units.size ()
- + dwarf2_per_objfile->all_type_units.size ());
+ int total_units = (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
+ + dwarf2_per_objfile->per_bfd->all_type_units.size ());
for (int i = 0; i < total_units; ++i)
{
- dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
+ dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (i);
/* We don't want to directly expand a partial CU, because if we
read it with the wrong language, then assertion failures can
be triggered later on. See PR symtab/23010. So, tell
dw2_instantiate_symtab to skip partial CUs -- any important
partial CU will be read via DW_TAG_imported_unit anyway. */
- dw2_instantiate_symtab (per_cu, true);
+ dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, true);
}
}
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 : dwarf2_per_objfile->all_comp_units)
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
{
/* We only need to look at symtabs not already expanded. */
- if (per_cu->v.quick->compunit_symtab)
+ if (dwarf2_per_objfile->symtab_set_p (per_cu))
continue;
- quick_file_names *file_data = dw2_get_file_names (per_cu);
+ quick_file_names *file_data
+ = dw2_get_file_names (per_cu, dwarf2_per_objfile);
if (file_data == NULL)
continue;
if (filename_cmp (this_fullname, fullname) == 0)
{
- dw2_instantiate_symtab (per_cu, false);
+ dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, false);
break;
}
}
}
}
+static void
+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
+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
(struct objfile *objfile,
gdb::function_view<symbol_found_callback_ftype> callback,
symbol_compare_ftype *ordered_compare)
{
- /* Currently unimplemented; used for Ada. The function can be called if the
- current language is Ada for a non-Ada objfile using GNU index. As Ada
- does not look for non-Ada symbols this function should just return. */
+ /* Used for Ada. */
+ struct dwarf2_per_objfile *dwarf2_per_objfile
+ = get_dwarf2_per_objfile (objfile);
+
+ const block_enum block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
+
+ if (dwarf2_per_objfile->per_bfd->index_table != nullptr)
+ {
+ /* Ada currently doesn't support .gdb_index (see PR24713). We can get
+ here though if the current language is Ada for a non-Ada objfile
+ using GNU index. */
+ mapped_index &index = *dwarf2_per_objfile->per_bfd->index_table;
+
+ const char *match_name = name.ada ().lookup_name ().c_str ();
+ auto matcher = [&] (const char *symname)
+ {
+ if (ordered_compare == nullptr)
+ return true;
+ return ordered_compare (symname, match_name) == 0;
+ };
+
+ dw2_expand_symtabs_matching_symbol (index, name, matcher, ALL_DOMAIN,
+ [&] (offset_type namei)
+ {
+ struct dw2_symtab_iterator iter;
+ struct dwarf2_per_cu_data *per_cu;
+
+ dw2_symtab_iter_init (&iter, dwarf2_per_objfile, block_kind, domain,
+ match_name);
+ while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
+ dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile, nullptr,
+ nullptr);
+ return true;
+ }, dwarf2_per_objfile);
+ }
+ else
+ {
+ /* 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
std::pair<std::vector<name_component>::const_iterator,
std::vector<name_component>::const_iterator>
mapped_index_base::find_name_components_bounds
- (const lookup_name_info &lookup_name_without_params, language lang) const
+ (const lookup_name_info &lookup_name_without_params, language lang,
+ dwarf2_per_objfile *per_objfile) const
{
auto *name_cmp
= this->name_components_casing == case_sensitive_on ? strcmp : strcasecmp;
const char *lang_name
- = lookup_name_without_params.language_lookup_name (lang).c_str ();
+ = lookup_name_without_params.language_lookup_name (lang);
/* Comparison function object for lower_bound that matches against a
given symbol name. */
auto lookup_compare_lower = [&] (const name_component &elem,
const char *name)
{
- const char *elem_qualified = this->symbol_name_at (elem.idx);
+ const char *elem_qualified = this->symbol_name_at (elem.idx, per_objfile);
const char *elem_name = elem_qualified + elem.name_offset;
return name_cmp (elem_name, name) < 0;
};
auto lookup_compare_upper = [&] (const char *name,
const name_component &elem)
{
- const char *elem_qualified = this->symbol_name_at (elem.idx);
+ const char *elem_qualified = this->symbol_name_at (elem.idx, per_objfile);
const char *elem_name = elem_qualified + elem.name_offset;
return name_cmp (name, elem_name) < 0;
};
/* See declaration. */
void
-mapped_index_base::build_name_components ()
+mapped_index_base::build_name_components (dwarf2_per_objfile *per_objfile)
{
if (!this->name_components.empty ())
return;
if (this->symbol_name_slot_invalid (idx))
continue;
- const char *name = this->symbol_name_at (idx);
+ const char *name = this->symbol_name_at (idx, per_objfile);
/* Add each name component to the name component table. */
unsigned int previous_len = 0;
auto name_comp_compare = [&] (const name_component &left,
const name_component &right)
{
- const char *left_qualified = this->symbol_name_at (left.idx);
- const char *right_qualified = this->symbol_name_at (right.idx);
+ const char *left_qualified
+ = this->symbol_name_at (left.idx, per_objfile);
+ const char *right_qualified
+ = this->symbol_name_at (right.idx, per_objfile);
const char *left_name = left_qualified + left.name_offset;
const char *right_name = right_qualified + right.name_offset;
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)
+ gdb::function_view<bool (offset_type)> match_callback,
+ dwarf2_per_objfile *per_objfile)
{
lookup_name_info lookup_name_without_params
= lookup_name_in.make_ignore_params ();
/* Build the symbol name component sorted vector, if we haven't
yet. */
- index.build_name_components ();
+ index.build_name_components (per_objfile);
/* The same symbol may appear more than once in the range though.
E.g., if we're looking for symbols that complete "w", and we have
struct name_and_matcher
{
symbol_name_matcher_ftype *matcher;
- const std::string &name;
+ const char *name;
bool operator== (const name_and_matcher &other) const
{
- return matcher == other.matcher && name == other.name;
+ return matcher == other.matcher && strcmp (name, other.name) == 0;
}
};
auto bounds
= index.find_name_components_bounds (lookup_name_without_params,
- lang_e);
+ lang_e, per_objfile);
/* Now for each symbol name in range, check to see if we have a name
match, and if so, call the MATCH_CALLBACK callback. */
for (; bounds.first != bounds.second; ++bounds.first)
{
- const char *qualified = index.symbol_name_at (bounds.first->idx);
+ const char *qualified
+ = index.symbol_name_at (bounds.first->idx, per_objfile);
if (!name_matcher (qualified, lookup_name_without_params, NULL)
|| (symbol_matcher != NULL && !symbol_matcher (qualified)))
}
/* Get the name of the symbol at IDX in the symbol table. */
- const char *symbol_name_at (offset_type idx) const override
+ const char *symbol_name_at
+ (offset_type idx, dwarf2_per_objfile *per_objfile) const override
{
return m_symbol_table[idx];
}
mock_mapped_index &mock_index,
const char *name, symbol_name_match_type match_type,
bool completion_mode,
- std::initializer_list<const char *> expected_list)
+ std::initializer_list<const char *> expected_list,
+ dwarf2_per_objfile *per_objfile)
{
lookup_name_info lookup_name (name, match_type, completion_mode);
NULL, ALL_DOMAIN,
[&] (offset_type idx)
{
- const char *matched_name = mock_index.symbol_name_at (idx);
+ const char *matched_name = mock_index.symbol_name_at (idx, per_objfile);
const char *expected_str
= expected_it == expected_end ? NULL : *expected_it++;
if (expected_str == NULL || strcmp (expected_str, matched_name) != 0)
mismatch (expected_str, matched_name);
return true;
- });
+ }, per_objfile);
const char *expected_str
= expected_it == expected_end ? NULL : *expected_it++;
static bool
check_find_bounds_finds (mapped_index_base &index,
const char *search_name,
- gdb::array_view<const char *> expected_syms)
+ gdb::array_view<const char *> expected_syms,
+ dwarf2_per_objfile *per_objfile)
{
lookup_name_info lookup_name (search_name,
symbol_name_match_type::FULL, true);
auto bounds = index.find_name_components_bounds (lookup_name,
- language_cplus);
+ language_cplus,
+ per_objfile);
size_t distance = std::distance (bounds.first, bounds.second);
if (distance != expected_syms.size ())
for (size_t exp_elem = 0; exp_elem < distance; exp_elem++)
{
auto nc_elem = bounds.first + exp_elem;
- const char *qualified = index.symbol_name_at (nc_elem->idx);
+ const char *qualified = index.symbol_name_at (nc_elem->idx, per_objfile);
if (strcmp (qualified, expected_syms[exp_elem]) != 0)
return false;
}
{
mock_mapped_index mock_index (test_symbols);
- mock_index.build_name_components ();
+ mock_index.build_name_components (NULL /* per_objfile */);
/* Test the lower-level mapped_index::find_name_component_bounds
method in completion mode. */
"t1_func1",
};
- SELF_CHECK (check_find_bounds_finds (mock_index,
- "t1_func", expected_syms));
+ SELF_CHECK (check_find_bounds_finds
+ (mock_index, "t1_func", expected_syms,
+ NULL /* per_objfile */));
}
/* Check that the increment-last-char in the name matching algorithm
"\377",
"\377\377123",
};
- SELF_CHECK (check_find_bounds_finds (mock_index,
- "\377", expected_syms1));
+ SELF_CHECK (check_find_bounds_finds
+ (mock_index, "\377", expected_syms1, NULL /* per_objfile */));
static const char *expected_syms2[] = {
"\377\377123",
};
- SELF_CHECK (check_find_bounds_finds (mock_index,
- "\377\377", expected_syms2));
+ SELF_CHECK (check_find_bounds_finds
+ (mock_index, "\377\377", expected_syms2,
+ NULL /* per_objfile */));
}
}
any_mismatch |= !check_match (__FILE__, __LINE__, \
mock_index, \
NAME, MATCH_TYPE, COMPLETION_MODE, \
- EXPECTED_LIST)
+ EXPECTED_LIST, NULL)
/* Identity checks. */
for (const char *sym : test_symbols)
static void
dw2_expand_symtabs_matching_one
- (struct dwarf2_per_cu_data *per_cu,
+ (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)
{
if (file_matcher == NULL || per_cu->v.quick->mark)
{
- bool symtab_was_null
- = (per_cu->v.quick->compunit_symtab == NULL);
+ bool symtab_was_null = !per_objfile->symtab_set_p (per_cu);
- dw2_instantiate_symtab (per_cu, false);
+ compunit_symtab *symtab
+ = dw2_instantiate_symtab (per_cu, per_objfile, false);
+ gdb_assert (symtab != nullptr);
- if (expansion_notify != NULL
- && symtab_was_null
- && per_cu->v.quick->compunit_symtab != NULL)
- expansion_notify (per_cu->v.quick->compunit_symtab);
+ if (expansion_notify != NULL && symtab_was_null)
+ expansion_notify (symtab);
}
}
static void
dw2_expand_marked_cus
- (struct dwarf2_per_objfile *dwarf2_per_objfile, offset_type idx,
+ (dwarf2_per_objfile *dwarf2_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,
search_domain kind)
{
offset_type *vec, vec_len, vec_idx;
bool global_seen = false;
- mapped_index &index = *dwarf2_per_objfile->index_table;
+ mapped_index &index = *dwarf2_per_objfile->per_bfd->index_table;
vec = (offset_type *) (index.constant_pool
+ MAYBE_SWAP (index.symbol_table[idx].vec));
}
/* Don't crash on bad data. */
- if (cu_index >= (dwarf2_per_objfile->all_comp_units.size ()
- + dwarf2_per_objfile->all_type_units.size ()))
+ if (cu_index >= (dwarf2_per_objfile->per_bfd->all_comp_units.size ()
+ + dwarf2_per_objfile->per_bfd->all_type_units.size ()))
{
complaint (_(".gdb_index entry has bad CU index"
" [in module %s]"),
continue;
}
- dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (cu_index);
- dw2_expand_symtabs_matching_one (per_cu, file_matcher,
+ dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->per_bfd->get_cutu (cu_index);
+ dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile, file_matcher,
expansion_notify);
}
}
if (file_matcher == NULL)
return;
- objfile *const objfile = dwarf2_per_objfile->objfile;
-
htab_up visited_found (htab_create_alloc (10, htab_hash_pointer,
htab_eq_pointer,
NULL, xcalloc, xfree));
/* 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 : dwarf2_per_objfile->all_comp_units)
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
{
QUIT;
per_cu->v.quick->mark = 0;
/* We only need to look at symtabs not already expanded. */
- if (per_cu->v.quick->compunit_symtab)
+ if (dwarf2_per_objfile->symtab_set_p (per_cu))
continue;
- quick_file_names *file_data = dw2_get_file_names (per_cu);
+ quick_file_names *file_data
+ = dw2_get_file_names (per_cu, dwarf2_per_objfile);
if (file_data == NULL)
continue;
true))
continue;
- this_real_name = dw2_get_real_path (objfile, file_data, j);
+ this_real_name = dw2_get_real_path (dwarf2_per_objfile,
+ file_data, j);
if (file_matcher (this_real_name, false))
{
per_cu->v.quick->mark = 1;
dw2_expand_symtabs_matching
(struct objfile *objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
- const lookup_name_info &lookup_name,
+ 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)
= get_dwarf2_per_objfile (objfile);
/* index_table is NULL if OBJF_READNOW. */
- if (!dwarf2_per_objfile->index_table)
+ if (!dwarf2_per_objfile->per_bfd->index_table)
return;
dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
- mapped_index &index = *dwarf2_per_objfile->index_table;
+ if (symbol_matcher == NULL && lookup_name == NULL)
+ {
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
+ {
+ QUIT;
+
+ dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile,
+ file_matcher, expansion_notify);
+ }
+ return;
+ }
+
+ mapped_index &index = *dwarf2_per_objfile->per_bfd->index_table;
- dw2_expand_symtabs_matching_symbol (index, lookup_name,
+ dw2_expand_symtabs_matching_symbol (index, *lookup_name,
symbol_matcher,
kind, [&] (offset_type idx)
{
dw2_expand_marked_cus (dwarf2_per_objfile, idx, file_matcher,
expansion_notify, kind);
return true;
- });
+ }, dwarf2_per_objfile);
}
/* A helper for dw2_find_pc_sect_compunit_symtab which finds the most specific
if (!data)
return NULL;
- if (warn_if_readin && data->v.quick->compunit_symtab)
+ 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 (get_objfile_arch (objfile), pc));
+ paddress (objfile->arch (), pc));
+
+ result = recursively_find_pc_sect_compunit_symtab
+ (dw2_instantiate_symtab (data, per_objfile, false), pc);
- result
- = recursively_find_pc_sect_compunit_symtab (dw2_instantiate_symtab (data,
- false),
- pc);
gdb_assert (result != NULL);
return result;
}
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
- if (!dwarf2_per_objfile->filenames_cache)
+ if (!dwarf2_per_objfile->per_bfd->filenames_cache)
{
- dwarf2_per_objfile->filenames_cache.emplace ();
+ dwarf2_per_objfile->per_bfd->filenames_cache.emplace ();
htab_up visited (htab_create_alloc (10,
htab_hash_pointer, htab_eq_pointer,
by any TU, so there's no need to scan TUs here. We can
ignore file names coming from already-expanded CUs. */
- for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
{
- if (per_cu->v.quick->compunit_symtab)
+ if (dwarf2_per_objfile->symtab_set_p (per_cu))
{
void **slot = htab_find_slot (visited.get (),
per_cu->v.quick->file_names,
}
}
- for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
{
/* We only need to look at symtabs not already expanded. */
- if (per_cu->v.quick->compunit_symtab)
+ if (dwarf2_per_objfile->symtab_set_p (per_cu))
continue;
- quick_file_names *file_data = dw2_get_file_names (per_cu);
+ quick_file_names *file_data
+ = dw2_get_file_names (per_cu, dwarf2_per_objfile);
if (file_data == NULL)
continue;
for (int j = 0; j < file_data->num_file_names; ++j)
{
const char *filename = file_data->file_names[j];
- dwarf2_per_objfile->filenames_cache->seen (filename);
+ dwarf2_per_objfile->per_bfd->filenames_cache->seen (filename);
}
}
}
- dwarf2_per_objfile->filenames_cache->traverse ([&] (const char *filename)
+ dwarf2_per_objfile->per_bfd->filenames_cache->traverse ([&] (const char *filename)
{
gdb::unique_xmalloc_ptr<char> this_real_name;
dw2_forget_cached_source_info,
dw2_map_symtabs_matching_filename,
dw2_lookup_symbol,
+ NULL,
dw2_print_stats,
dw2_dump,
dw2_expand_symtabs_for_function,
section->read (objfile);
- map.dwarf5_byte_order = gdbarch_byte_order (get_objfile_arch (objfile));
+ map.dwarf5_byte_order = gdbarch_byte_order (objfile->arch ());
const gdb_byte *addr = section->buffer;
list. */
static void
-create_cus_from_debug_names_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
+create_cus_from_debug_names_list (dwarf2_per_bfd *per_bfd,
const mapped_debug_names &map,
dwarf2_section_info §ion,
bool is_dwz)
{
+ if (!map.augmentation_is_gdb)
+ {
+ for (uint32_t i = 0; i < map.cu_count; ++i)
+ {
+ sect_offset sect_off
+ = (sect_offset) (extract_unsigned_integer
+ (map.cu_table_reordered + i * map.offset_size,
+ map.offset_size,
+ map.dwarf5_byte_order));
+ /* We don't know the length of the CU, because the CU list in a
+ .debug_names index can be incomplete, so we can't use the start 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
+ = create_cu_from_index_list (per_bfd, §ion, is_dwz, sect_off, 0);
+ per_bfd->all_comp_units.push_back (per_cu);
+ }
+ }
+
sect_offset sect_off_prev;
for (uint32_t i = 0; i <= map.cu_count; ++i)
{
{
const ULONGEST length = sect_off_next - sect_off_prev;
dwarf2_per_cu_data *per_cu
- = create_cu_from_index_list (dwarf2_per_objfile, §ion, is_dwz,
+ = create_cu_from_index_list (per_bfd, §ion, is_dwz,
sect_off_prev, length);
- dwarf2_per_objfile->all_comp_units.push_back (per_cu);
+ per_bfd->all_comp_units.push_back (per_cu);
}
sect_off_prev = sect_off_next;
}
the CU objects for this dwarf2_per_objfile. */
static void
-create_cus_from_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile,
+create_cus_from_debug_names (dwarf2_per_bfd *per_bfd,
const mapped_debug_names &map,
const mapped_debug_names &dwz_map)
{
- gdb_assert (dwarf2_per_objfile->all_comp_units.empty ());
- dwarf2_per_objfile->all_comp_units.reserve (map.cu_count + dwz_map.cu_count);
+ gdb_assert (per_bfd->all_comp_units.empty ());
+ per_bfd->all_comp_units.reserve (map.cu_count + dwz_map.cu_count);
- create_cus_from_debug_names_list (dwarf2_per_objfile, map,
- dwarf2_per_objfile->info,
+ create_cus_from_debug_names_list (per_bfd, map, per_bfd->info,
false /* is_dwz */);
if (dwz_map.cu_count == 0)
return;
- dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
- create_cus_from_debug_names_list (dwarf2_per_objfile, dwz_map, dwz->info,
+ dwz_file *dwz = dwarf2_get_dwz_file (per_bfd);
+ create_cus_from_debug_names_list (per_bfd, dwz_map, dwz->info,
true /* is_dwz */);
}
static bool
dwarf2_read_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
- std::unique_ptr<mapped_debug_names> map
- (new mapped_debug_names (dwarf2_per_objfile));
- mapped_debug_names dwz_map (dwarf2_per_objfile);
+ std::unique_ptr<mapped_debug_names> map (new mapped_debug_names);
+ mapped_debug_names dwz_map;
struct objfile *objfile = dwarf2_per_objfile->objfile;
if (!read_debug_names_from_section (objfile, objfile_name (objfile),
- &dwarf2_per_objfile->debug_names,
+ &dwarf2_per_objfile->per_bfd->debug_names,
*map))
return false;
/* If there is a .dwz file, read it so we can get its CU list as
well. */
- dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+ dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
if (dwz != NULL)
{
if (!read_debug_names_from_section (objfile,
}
}
- create_cus_from_debug_names (dwarf2_per_objfile, *map, dwz_map);
+ create_cus_from_debug_names (dwarf2_per_objfile->per_bfd, *map, dwz_map);
if (map->tu_count != 0)
{
/* We can only handle a single .debug_types when we have an
index. */
- if (dwarf2_per_objfile->types.size () != 1)
+ if (dwarf2_per_objfile->per_bfd->types.size () != 1)
return false;
- dwarf2_section_info *section = &dwarf2_per_objfile->types[0];
+ dwarf2_section_info *section = &dwarf2_per_objfile->per_bfd->types[0];
create_signatured_type_table_from_debug_names
- (dwarf2_per_objfile, *map, section, &dwarf2_per_objfile->abbrev);
+ (dwarf2_per_objfile, *map, section, &dwarf2_per_objfile->per_bfd->abbrev);
}
create_addrmap_from_aranges (dwarf2_per_objfile,
- &dwarf2_per_objfile->debug_aranges);
+ &dwarf2_per_objfile->per_bfd->debug_aranges);
- dwarf2_per_objfile->debug_names_table = std::move (map);
- dwarf2_per_objfile->using_index = 1;
- dwarf2_per_objfile->quick_file_names_table =
- create_quick_file_names_table (dwarf2_per_objfile->all_comp_units.size ());
+ dwarf2_per_objfile->per_bfd->debug_names_table = std::move (map);
+ dwarf2_per_objfile->per_bfd->using_index = 1;
+ dwarf2_per_objfile->per_bfd->quick_file_names_table =
+ create_quick_file_names_table (dwarf2_per_objfile->per_bfd->all_comp_units.size ());
return true;
}
dw2_debug_names_iterator (const mapped_debug_names &map,
gdb::optional<block_enum> block_index,
domain_enum domain,
- const char *name)
+ const char *name, dwarf2_per_objfile *per_objfile)
: m_map (map), m_block_index (block_index), m_domain (domain),
- m_addr (find_vec_in_debug_names (map, name))
+ m_addr (find_vec_in_debug_names (map, name, per_objfile)),
+ m_per_objfile (per_objfile)
{}
dw2_debug_names_iterator (const mapped_debug_names &map,
- search_domain search, uint32_t namei)
+ search_domain search, uint32_t namei, dwarf2_per_objfile *per_objfile)
: m_map (map),
m_search (search),
- m_addr (find_vec_in_debug_names (map, namei))
+ 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,
- uint32_t namei)
+ 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))
+ m_addr (find_vec_in_debug_names (map, namei, per_objfile)),
+ m_per_objfile (per_objfile)
{}
/* Return the next matching CU or NULL if there are no more. */
private:
static const gdb_byte *find_vec_in_debug_names (const mapped_debug_names &map,
- const char *name);
+ const char *name, dwarf2_per_objfile *per_objfile);
static const gdb_byte *find_vec_in_debug_names (const mapped_debug_names &map,
- uint32_t namei);
+ uint32_t namei, dwarf2_per_objfile *per_objfile);
/* The internalized form of .debug_names. */
const mapped_debug_names &m_map;
/* The list of CUs from the index entry of the symbol, or NULL if
not found. */
const gdb_byte *m_addr;
+
+ dwarf2_per_objfile *m_per_objfile;
};
const char *
-mapped_debug_names::namei_to_name (uint32_t namei) const
+mapped_debug_names::namei_to_name
+ (uint32_t namei, dwarf2_per_objfile *dwarf2_per_objfile) const
{
const ULONGEST namei_string_offs
= extract_unsigned_integer ((name_table_string_offs_reordered
const gdb_byte *
dw2_debug_names_iterator::find_vec_in_debug_names
- (const mapped_debug_names &map, const char *name)
+ (const mapped_debug_names &map, const char *name, dwarf2_per_objfile *per_objfile)
{
int (*cmp) (const char *, const char *);
complaint (_("Wrong .debug_names with name index %u but name_count=%u "
"[in module %s]"),
namei, map.name_count,
- objfile_name (map.dwarf2_per_objfile->objfile));
+ objfile_name (per_objfile->objfile));
return NULL;
}
if (full_hash == namei_full_hash)
{
- const char *const namei_string = map.namei_to_name (namei);
+ const char *const namei_string = map.namei_to_name (namei, per_objfile);
#if 0 /* An expensive sanity check. */
if (namei_full_hash != dwarf5_djb_hash (namei_string))
const gdb_byte *
dw2_debug_names_iterator::find_vec_in_debug_names
- (const mapped_debug_names &map, uint32_t namei)
+ (const mapped_debug_names &map, uint32_t namei, dwarf2_per_objfile *per_objfile)
{
if (namei >= map.name_count)
{
complaint (_("Wrong .debug_names with name index %u but name_count=%u "
"[in module %s]"),
namei, map.name_count,
- objfile_name (map.dwarf2_per_objfile->objfile));
+ objfile_name (per_objfile->objfile));
return NULL;
}
if (m_addr == NULL)
return NULL;
- struct dwarf2_per_objfile *dwarf2_per_objfile = m_map.dwarf2_per_objfile;
- struct objfile *objfile = dwarf2_per_objfile->objfile;
+ dwarf2_per_bfd *per_bfd = m_per_objfile->per_bfd;
+ struct objfile *objfile = m_per_objfile->objfile;
bfd *const abfd = objfile->obfd;
again:
ull = read_unsigned_leb128 (abfd, m_addr, &bytes_read);
m_addr += bytes_read;
break;
+ case DW_FORM_ref4:
+ ull = read_4_bytes (abfd, m_addr);
+ m_addr += 4;
+ break;
+ case DW_FORM_ref8:
+ ull = read_8_bytes (abfd, m_addr);
+ m_addr += 8;
+ break;
+ case DW_FORM_ref_sig8:
+ ull = read_8_bytes (abfd, m_addr);
+ m_addr += 8;
+ break;
default:
complaint (_("Unsupported .debug_names form %s [in module %s]"),
dwarf_form_name (attr.form),
{
case DW_IDX_compile_unit:
/* Don't crash on bad data. */
- if (ull >= dwarf2_per_objfile->all_comp_units.size ())
+ if (ull >= m_per_objfile->per_bfd->all_comp_units.size ())
{
complaint (_(".debug_names entry has bad CU index %s"
" [in module %s]"),
pulongest (ull),
- objfile_name (dwarf2_per_objfile->objfile));
+ objfile_name (objfile));
continue;
}
- per_cu = dwarf2_per_objfile->get_cutu (ull);
+ per_cu = per_bfd->get_cutu (ull);
break;
case DW_IDX_type_unit:
/* Don't crash on bad data. */
- if (ull >= dwarf2_per_objfile->all_type_units.size ())
+ if (ull >= per_bfd->all_type_units.size ())
{
complaint (_(".debug_names entry has bad TU index %s"
" [in module %s]"),
pulongest (ull),
- objfile_name (dwarf2_per_objfile->objfile));
+ objfile_name (objfile));
continue;
}
- per_cu = &dwarf2_per_objfile->get_tu (ull)->per_cu;
+ per_cu = &per_bfd->get_tu (ull)->per_cu;
+ break;
+ case DW_IDX_die_offset:
+ /* In a per-CU index (as opposed to a per-module index), index
+ entries without CU attribute implicitly refer to the single CU. */
+ if (per_cu == NULL)
+ per_cu = per_bfd->get_cu (0);
break;
case DW_IDX_GNU_internal:
if (!m_map.augmentation_is_gdb)
}
/* Skip if already read in. */
- if (per_cu->v.quick->compunit_symtab)
+ if (m_per_objfile->symtab_set_p (per_cu))
goto again;
/* Check static vs global. */
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
- const auto &mapp = dwarf2_per_objfile->debug_names_table;
+ const auto &mapp = dwarf2_per_objfile->per_bfd->debug_names_table;
if (!mapp)
{
/* index is NULL if OBJF_READNOW. */
}
const auto &map = *mapp;
- dw2_debug_names_iterator iter (map, block_index, domain, name);
+ dw2_debug_names_iterator iter (map, block_index, domain, name,
+ dwarf2_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;
- struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu, false);
+ compunit_symtab *stab
+ = dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, false);
const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
const struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
- gdb_assert (dwarf2_per_objfile->using_index);
+ gdb_assert (dwarf2_per_objfile->per_bfd->using_index);
printf_filtered (".debug_names:");
- if (dwarf2_per_objfile->debug_names_table)
+ if (dwarf2_per_objfile->per_bfd->debug_names_table)
printf_filtered (" exists\n");
else
printf_filtered (" faked for \"readnow\"\n");
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
- /* dwarf2_per_objfile->debug_names_table is NULL if OBJF_READNOW. */
- if (dwarf2_per_objfile->debug_names_table)
+ /* dwarf2_per_objfile->per_bfd->debug_names_table is NULL if OBJF_READNOW. */
+ if (dwarf2_per_objfile->per_bfd->debug_names_table)
{
- const mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
+ const mapped_debug_names &map = *dwarf2_per_objfile->per_bfd->debug_names_table;
- dw2_debug_names_iterator iter (map, {}, VAR_DOMAIN, func_name);
+ dw2_debug_names_iterator iter (map, {}, VAR_DOMAIN, func_name,
+ dwarf2_per_objfile);
struct dwarf2_per_cu_data *per_cu;
while ((per_cu = iter.next ()) != NULL)
- dw2_instantiate_symtab (per_cu, false);
+ dw2_instantiate_symtab (per_cu, dwarf2_per_objfile, false);
}
}
= get_dwarf2_per_objfile (objfile);
/* debug_names_table is NULL if OBJF_READNOW. */
- if (!dwarf2_per_objfile->debug_names_table)
+ if (!dwarf2_per_objfile->per_bfd->debug_names_table)
return;
- mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
+ mapped_debug_names &map = *dwarf2_per_objfile->per_bfd->debug_names_table;
const block_enum block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
const char *match_name = name.ada ().lookup_name ().c_str ();
{
/* 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_kind, domain, namei,
+ dwarf2_per_objfile);
struct dwarf2_per_cu_data *per_cu;
while ((per_cu = iter.next ()) != NULL)
- dw2_expand_symtabs_matching_one (per_cu, nullptr, nullptr);
+ dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile, nullptr,
+ nullptr);
return true;
- });
+ }, dwarf2_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 : dwarf2_per_objfile->all_comp_units)
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
{
- struct compunit_symtab *cust = per_cu->v.quick->compunit_symtab;
- if (cust != nullptr)
+ compunit_symtab *symtab = dwarf2_per_objfile->get_symtab (per_cu);
+ if (symtab != nullptr)
{
const struct block *block
- = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (cust), block_kind);
+ = BLOCKVECTOR_BLOCK (COMPUNIT_BLOCKVECTOR (symtab), block_kind);
if (!iterate_over_symbols_terminated (block, name,
domain, callback))
break;
dw2_debug_names_expand_symtabs_matching
(struct objfile *objfile,
gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
- const lookup_name_info &lookup_name,
+ 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)
= get_dwarf2_per_objfile (objfile);
/* debug_names_table is NULL if OBJF_READNOW. */
- if (!dwarf2_per_objfile->debug_names_table)
+ if (!dwarf2_per_objfile->per_bfd->debug_names_table)
return;
dw_expand_symtabs_matching_file_matcher (dwarf2_per_objfile, file_matcher);
- mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
+ if (symbol_matcher == NULL && lookup_name == NULL)
+ {
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
+ {
+ QUIT;
+
+ dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile,
+ file_matcher, expansion_notify);
+ }
+ return;
+ }
+
+ mapped_debug_names &map = *dwarf2_per_objfile->per_bfd->debug_names_table;
- dw2_expand_symtabs_matching_symbol (map, lookup_name,
+ dw2_expand_symtabs_matching_symbol (map, *lookup_name,
symbol_matcher,
kind, [&] (offset_type namei)
{
/* The name was matched, now expand corresponding CUs that were
marked. */
- dw2_debug_names_iterator iter (map, kind, namei);
+ dw2_debug_names_iterator iter (map, kind, namei, dwarf2_per_objfile);
struct dwarf2_per_cu_data *per_cu;
while ((per_cu = iter.next ()) != NULL)
- dw2_expand_symtabs_matching_one (per_cu, file_matcher,
- expansion_notify);
+ dw2_expand_symtabs_matching_one (per_cu, dwarf2_per_objfile,
+ file_matcher, expansion_notify);
return true;
- });
+ }, dwarf2_per_objfile);
}
const struct quick_symbol_functions dwarf2_debug_names_functions =
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,
};
/* Get the content of the .gdb_index section of OBJ. SECTION_OWNER should point
- to either a dwarf2_per_objfile or dwz_file object. */
+ to either a dwarf2_per_bfd or dwz_file object. */
template <typename T>
static gdb::array_view<const gdb_byte>
DWARF2_OBJ. */
static gdb::array_view<const gdb_byte>
-get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_objfile *dwarf2_obj)
+get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_bfd *dwarf2_per_bfd)
{
const bfd_build_id *build_id = build_id_bfd_get (obj->obfd);
if (build_id == nullptr)
return {};
return global_index_cache.lookup_gdb_index (build_id,
- &dwarf2_obj->index_cache_res);
+ &dwarf2_per_bfd->index_cache_res);
}
/* Same as the above, but for DWZ. */
{
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
+ dwarf2_per_bfd *per_bfd = dwarf2_per_objfile->per_bfd;
/* If we're about to read full symbols, don't bother with the
indices. In this case we also don't care if some other debug
expanded anyway. */
if ((objfile->flags & OBJF_READNOW))
{
- dwarf2_per_objfile->using_index = 1;
+ /* When using READNOW, the using_index flag (set below) indicates that
+ PER_BFD was already initialized, when we loaded some other objfile. */
+ if (per_bfd->using_index)
+ {
+ *index_kind = dw_index_kind::GDB_INDEX;
+ dwarf2_per_objfile->resize_symtabs ();
+ return true;
+ }
+
+ per_bfd->using_index = 1;
create_all_comp_units (dwarf2_per_objfile);
create_all_type_units (dwarf2_per_objfile);
- dwarf2_per_objfile->quick_file_names_table
- = create_quick_file_names_table
- (dwarf2_per_objfile->all_comp_units.size ());
+ per_bfd->quick_file_names_table
+ = create_quick_file_names_table (per_bfd->all_comp_units.size ());
+ dwarf2_per_objfile->resize_symtabs ();
- for (int i = 0; i < (dwarf2_per_objfile->all_comp_units.size ()
- + dwarf2_per_objfile->all_type_units.size ()); ++i)
+ for (int i = 0; i < (per_bfd->all_comp_units.size ()
+ + per_bfd->all_type_units.size ()); ++i)
{
- dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
+ dwarf2_per_cu_data *per_cu = per_bfd->get_cutu (i);
- per_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ per_cu->v.quick = OBSTACK_ZALLOC (&per_bfd->obstack,
struct dwarf2_per_cu_quick_data);
}
return true;
}
+ /* Was a debug names index already read when we processed an objfile sharing
+ PER_BFD? */
+ if (per_bfd->debug_names_table != nullptr)
+ {
+ *index_kind = dw_index_kind::DEBUG_NAMES;
+ dwarf2_per_objfile->resize_symtabs ();
+ return true;
+ }
+
+ /* Was a GDB index already read when we processed an objfile sharing
+ PER_BFD? */
+ if (per_bfd->index_table != nullptr)
+ {
+ *index_kind = dw_index_kind::GDB_INDEX;
+ dwarf2_per_objfile->resize_symtabs ();
+ return true;
+ }
+
if (dwarf2_read_debug_names (dwarf2_per_objfile))
{
*index_kind = dw_index_kind::DEBUG_NAMES;
+ dwarf2_per_objfile->resize_symtabs ();
return true;
}
if (dwarf2_read_gdb_index (dwarf2_per_objfile,
- get_gdb_index_contents_from_section<struct dwarf2_per_objfile>,
+ get_gdb_index_contents_from_section<struct dwarf2_per_bfd>,
get_gdb_index_contents_from_section<dwz_file>))
{
*index_kind = dw_index_kind::GDB_INDEX;
+ dwarf2_per_objfile->resize_symtabs ();
return true;
}
{
global_index_cache.hit ();
*index_kind = dw_index_kind::GDB_INDEX;
+ dwarf2_per_objfile->resize_symtabs ();
return true;
}
{
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
+ dwarf2_per_bfd *per_bfd = dwarf2_per_objfile->per_bfd;
+
+ if (per_bfd->partial_symtabs != nullptr)
+ {
+ /* Partial symbols were already read, so now we can simply
+ attach them. */
+ objfile->partial_symtabs = per_bfd->partial_symtabs;
+ dwarf2_per_objfile->resize_symtabs ();
+ return;
+ }
init_psymbol_list (objfile, 1024);
dwarf2_build_psymtabs_hard (dwarf2_per_objfile);
psymtabs.keep ();
+ dwarf2_per_objfile->resize_symtabs ();
+
/* (maybe) store an index in the cache. */
global_index_cache.store (dwarf2_per_objfile);
}
{
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
get_abbrev_section_for_cu (struct dwarf2_per_cu_data *this_cu)
{
struct dwarf2_section_info *abbrev;
- struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile;
+ dwarf2_per_bfd *per_bfd = this_cu->per_bfd;
if (this_cu->is_dwz)
- abbrev = &dwarf2_get_dwz_file (dwarf2_per_objfile)->abbrev;
+ abbrev = &dwarf2_get_dwz_file (per_bfd)->abbrev;
else
- abbrev = &dwarf2_per_objfile->abbrev;
+ abbrev = &per_bfd->abbrev;
return abbrev;
}
void read_symtab (struct objfile *objfile) override
{
- expand_psymtab (objfile);
+ /* It's an include file, no symbols to read for it.
+ Everything is in the includer symtab. */
+
+ /* The expansion of a dwarf2_include_psymtab is just a trigger for
+ expansion of the includer psymtab. We use the dependencies[0] field to
+ model the includer. But if we go the regular route of calling
+ expand_psymtab here, and having expand_psymtab call expand_dependencies
+ to expand the includer, we'll only use expand_psymtab on the includer
+ (making it a non-toplevel psymtab), while if we expand the includer via
+ another path, we'll use read_symtab (making it a toplevel psymtab).
+ So, don't pretend a dwarf2_include_psymtab is an actual toplevel
+ psymtab, and trigger read_symtab on the includer here directly. */
+ includer ()->read_symtab (objfile);
}
void expand_psymtab (struct objfile *objfile) override
{
- if (m_readin)
- return;
- /* It's an include file, no symbols to read for it.
- Everything is in the parent symtab. */
- expand_dependencies (objfile);
- m_readin = true;
+ /* This is not called by read_symtab, and should not be called by any
+ expand_dependencies. */
+ gdb_assert (false);
}
- bool readin_p () const override
+ bool readin_p (struct objfile *objfile) const override
{
- return m_readin;
+ return includer ()->readin_p (objfile);
}
- struct compunit_symtab *get_compunit_symtab () const override
+ compunit_symtab *get_compunit_symtab (struct objfile *objfile) const override
{
return nullptr;
}
private:
-
- bool m_readin = false;
+ partial_symtab *includer () const
+ {
+ /* An include psymtab has exactly one dependency: the psymtab that
+ includes it. */
+ gdb_assert (this->number_of_dependencies == 1);
+ return this->dependencies[0];
+ }
};
/* Allocate a new partial symtab for file named NAME and mark this new
dwarf2_include_psymtab *subpst = new dwarf2_include_psymtab (name, objfile);
if (!IS_ABSOLUTE_PATH (subpst->filename))
- {
- /* It shares objfile->objfile_obstack. */
- subpst->dirname = pst->dirname;
- }
+ subpst->dirname = pst->dirname;
subpst->dependencies = objfile->partial_symtabs->allocate_dependencies (1);
subpst->dependencies[0] = pst;
abbrev_section = (dwo_file != NULL
? &dwo_file->sections.abbrev
- : &dwarf2_per_objfile->abbrev);
+ : &dwarf2_per_objfile->per_bfd->abbrev);
if (dwarf_read_debug)
fprintf_unfiltered (gdb_stdlog, "Reading %s for %s:\n",
if (dwo_file)
{
sig_type = NULL;
- dwo_tu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ dwo_tu = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
struct dwo_unit);
dwo_tu->dwo_file = dwo_file;
dwo_tu->signature = header.signature;
/* 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 = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct signatured_type);
+ sig_type = dwarf2_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.dwarf2_per_objfile = dwarf2_per_objfile;
sig_type->per_cu.is_debug_types = 1;
sig_type->per_cu.section = section;
sig_type->per_cu.sect_off = sect_off;
htab_up types_htab;
create_debug_type_hash_table (dwarf2_per_objfile, NULL,
- &dwarf2_per_objfile->info, types_htab,
+ &dwarf2_per_objfile->per_bfd->info, types_htab,
rcuh_kind::COMPILE);
create_debug_types_hash_table (dwarf2_per_objfile, NULL,
- dwarf2_per_objfile->types, types_htab);
+ dwarf2_per_objfile->per_bfd->types, types_htab);
if (types_htab == NULL)
{
- dwarf2_per_objfile->signatured_types = NULL;
+ dwarf2_per_objfile->per_bfd->signatured_types = NULL;
return 0;
}
- dwarf2_per_objfile->signatured_types = std::move (types_htab);
+ dwarf2_per_objfile->per_bfd->signatured_types = std::move (types_htab);
- gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
- dwarf2_per_objfile->all_type_units.reserve
- (htab_elements (dwarf2_per_objfile->signatured_types.get ()));
+ gdb_assert (dwarf2_per_objfile->per_bfd->all_type_units.empty ());
+ dwarf2_per_objfile->per_bfd->all_type_units.reserve
+ (htab_elements (dwarf2_per_objfile->per_bfd->signatured_types.get ()));
- htab_traverse_noresize (dwarf2_per_objfile->signatured_types.get (),
+ htab_traverse_noresize (dwarf2_per_objfile->per_bfd->signatured_types.get (),
add_signatured_type_cu_to_table,
- &dwarf2_per_objfile->all_type_units);
+ &dwarf2_per_objfile->per_bfd->all_type_units);
return 1;
}
-/* Add an entry for signature SIG to dwarf2_per_objfile->signatured_types.
+/* 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. */
add_type_unit (struct dwarf2_per_objfile *dwarf2_per_objfile, ULONGEST sig,
void **slot)
{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
+ if (dwarf2_per_objfile->per_bfd->all_type_units.size ()
+ == dwarf2_per_objfile->per_bfd->all_type_units.capacity ())
+ ++dwarf2_per_objfile->per_bfd->tu_stats.nr_all_type_units_reallocs;
- if (dwarf2_per_objfile->all_type_units.size ()
- == dwarf2_per_objfile->all_type_units.capacity ())
- ++dwarf2_per_objfile->tu_stats.nr_all_type_units_reallocs;
+ signatured_type *sig_type = dwarf2_per_objfile->per_bfd->allocate_signatured_type ();
- signatured_type *sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct signatured_type);
+ dwarf2_per_objfile->resize_symtabs ();
- dwarf2_per_objfile->all_type_units.push_back (sig_type);
+ dwarf2_per_objfile->per_bfd->all_type_units.push_back (sig_type);
sig_type->signature = sig;
sig_type->per_cu.is_debug_types = 1;
- if (dwarf2_per_objfile->using_index)
+ if (dwarf2_per_objfile->per_bfd->using_index)
{
sig_type->per_cu.v.quick =
- OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
struct dwarf2_per_cu_quick_data);
}
if (slot == NULL)
{
- slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
+ slot = htab_find_slot (dwarf2_per_objfile->per_bfd->signatured_types.get (),
sig_type, INSERT);
}
gdb_assert (*slot == NULL);
struct signatured_type *sig_entry,
struct dwo_unit *dwo_entry)
{
+ dwarf2_per_bfd *per_bfd = dwarf2_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 (sig_entry->per_cu.cu == NULL);
- if (dwarf2_per_objfile->using_index)
+ gdb_assert (dwarf2_per_objfile->get_cu (&sig_entry->per_cu) == NULL);
+ if (per_bfd->using_index)
{
gdb_assert (sig_entry->per_cu.v.quick != NULL);
- gdb_assert (sig_entry->per_cu.v.quick->compunit_symtab == NULL);
+ gdb_assert (!dwarf2_per_objfile->symtab_set_p (&sig_entry->per_cu));
}
else
gdb_assert (sig_entry->per_cu.v.psymtab == NULL);
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.dwarf2_per_objfile = dwarf2_per_objfile;
+ sig_entry->per_cu.per_bfd = per_bfd;
sig_entry->type_offset_in_tu = dwo_entry->type_offset_in_tu;
sig_entry->dwo_unit = dwo_entry;
}
static struct signatured_type *
lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct dwo_file *dwo_file;
struct dwo_unit find_dwo_entry, *dwo_entry;
struct signatured_type find_sig_entry, *sig_entry;
void **slot;
- gdb_assert (cu->dwo_unit && dwarf2_per_objfile->using_index);
+ gdb_assert (cu->dwo_unit && dwarf2_per_objfile->per_bfd->using_index);
/* If TU skeletons have been removed then we may not have read in any
TUs yet. */
- if (dwarf2_per_objfile->signatured_types == NULL)
- dwarf2_per_objfile->signatured_types = allocate_signatured_type_table ();
+ if (dwarf2_per_objfile->per_bfd->signatured_types == NULL)
+ dwarf2_per_objfile->per_bfd->signatured_types = allocate_signatured_type_table ();
/* We only ever need to read in one copy of a signatured type.
Use the global signatured_types array to do our own comdat-folding
.gdb_index with this TU. */
find_sig_entry.signature = sig;
- slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
+ slot = htab_find_slot (dwarf2_per_objfile->per_bfd->signatured_types.get (),
&find_sig_entry, INSERT);
sig_entry = (struct signatured_type *) *slot;
static struct signatured_type *
lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct dwp_file *dwp_file = get_dwp_file (dwarf2_per_objfile);
struct dwo_unit *dwo_entry;
struct signatured_type find_sig_entry, *sig_entry;
void **slot;
- gdb_assert (cu->dwo_unit && dwarf2_per_objfile->using_index);
+ gdb_assert (cu->dwo_unit && dwarf2_per_objfile->per_bfd->using_index);
gdb_assert (dwp_file != NULL);
/* If TU skeletons have been removed then we may not have read in any
TUs yet. */
- if (dwarf2_per_objfile->signatured_types == NULL)
- dwarf2_per_objfile->signatured_types = allocate_signatured_type_table ();
+ if (dwarf2_per_objfile->per_bfd->signatured_types == NULL)
+ dwarf2_per_objfile->per_bfd->signatured_types = allocate_signatured_type_table ();
find_sig_entry.signature = sig;
- slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
+ slot = htab_find_slot (dwarf2_per_objfile->per_bfd->signatured_types.get (),
&find_sig_entry, INSERT);
sig_entry = (struct signatured_type *) *slot;
static struct signatured_type *
lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
if (cu->dwo_unit
- && dwarf2_per_objfile->using_index)
+ && dwarf2_per_objfile->per_bfd->using_index)
{
/* We're in a DWO/DWP file, and we're using .gdb_index.
These cases require special processing. */
{
struct signatured_type find_entry, *entry;
- if (dwarf2_per_objfile->signatured_types == NULL)
+ if (dwarf2_per_objfile->per_bfd->signatured_types == NULL)
return NULL;
find_entry.signature = sig;
entry = ((struct signatured_type *)
- htab_find (dwarf2_per_objfile->signatured_types.get (),
+ htab_find (dwarf2_per_objfile->per_bfd->signatured_types.get (),
&find_entry));
return entry;
}
The result is non-zero if a valid (non-dummy) DIE was found. */
static int
-read_cutu_die_from_dwo (struct dwarf2_per_cu_data *this_cu,
+read_cutu_die_from_dwo (dwarf2_cu *cu,
struct dwo_unit *dwo_unit,
struct die_info *stub_comp_unit_die,
const char *stub_comp_dir,
struct die_info **result_comp_unit_die,
abbrev_table_up *result_dwo_abbrev_table)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
+ dwarf2_per_cu_data *per_cu = cu->per_cu;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct dwarf2_cu *cu = this_cu->cu;
bfd *abfd;
const gdb_byte *begin_info_ptr, *info_ptr;
struct attribute *comp_dir, *stmt_list, *low_pc, *high_pc, *ranges;
{
/* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
DWO file. */
- if (! this_cu->is_debug_types)
+ if (!per_cu->is_debug_types)
stmt_list = dwarf2_attr (stub_comp_unit_die, DW_AT_stmt_list, cu);
low_pc = dwarf2_attr (stub_comp_unit_die, DW_AT_low_pc, cu);
high_pc = dwarf2_attr (stub_comp_unit_die, DW_AT_high_pc, cu);
+ to_underlying (dwo_unit->sect_off));
dwo_abbrev_section = &dwo_unit->dwo_file->sections.abbrev;
- if (this_cu->is_debug_types)
+ if (per_cu->is_debug_types)
{
- struct signatured_type *sig_type = (struct signatured_type *) this_cu;
+ signatured_type *sig_type = (struct signatured_type *) per_cu;
info_ptr = read_and_check_comp_unit_head (dwarf2_per_objfile,
&cu->header, section,
Returns NULL if the specified DWO unit cannot be found. */
static struct dwo_unit *
-lookup_dwo_unit (struct dwarf2_per_cu_data *this_cu,
- struct die_info *comp_unit_die,
- const char *dwo_name)
+lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die, const char *dwo_name)
{
- struct dwarf2_cu *cu = this_cu->cu;
+ dwarf2_per_cu_data *per_cu = cu->per_cu;
struct dwo_unit *dwo_unit;
const char *comp_dir;
dwo_name = dwarf2_dwo_name (comp_unit_die, cu);
comp_dir = dwarf2_string_attr (comp_unit_die, DW_AT_comp_dir, cu);
- if (this_cu->is_debug_types)
- {
- struct signatured_type *sig_type;
-
- /* Since this_cu is the first member of struct signatured_type,
- we can go from a pointer to one to a pointer to the other. */
- sig_type = (struct signatured_type *) this_cu;
- dwo_unit = lookup_dwo_type_unit (sig_type, dwo_name, comp_dir);
- }
+ if (per_cu->is_debug_types)
+ dwo_unit = lookup_dwo_type_unit (cu, dwo_name, comp_dir);
else
{
gdb::optional<ULONGEST> signature = lookup_dwo_id (cu, comp_unit_die);
+
if (!signature.has_value ())
error (_("Dwarf Error: missing dwo_id for dwo_name %s"
" [in module %s]"),
- dwo_name, objfile_name (this_cu->dwarf2_per_objfile->objfile));
- dwo_unit = lookup_dwo_comp_unit (this_cu, dwo_name, comp_dir,
- *signature);
+ dwo_name, bfd_get_filename (per_cu->per_bfd->obfd));
+
+ dwo_unit = lookup_dwo_comp_unit (cu, dwo_name, comp_dir, *signature);
}
return dwo_unit;
Read a TU directly from a DWO file, bypassing the stub. */
void
-cutu_reader::init_tu_and_read_dwo_dies (struct dwarf2_per_cu_data *this_cu,
- int use_existing_cu)
+cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
+ dwarf2_per_objfile *per_objfile,
+ dwarf2_cu *existing_cu)
{
struct signatured_type *sig_type;
sig_type = (struct signatured_type *) this_cu;
gdb_assert (sig_type->dwo_unit != NULL);
- if (use_existing_cu && this_cu->cu != NULL)
+ dwarf2_cu *cu;
+
+ if (existing_cu != nullptr)
{
- gdb_assert (this_cu->cu->dwo_unit == sig_type->dwo_unit);
+ cu = existing_cu;
+ gdb_assert (cu->dwo_unit == sig_type->dwo_unit);
/* There's no need to do the rereading_dwo_cu handling that
cutu_reader does since we don't read the stub. */
}
else
{
- /* If !use_existing_cu, this_cu->cu must be NULL. */
- gdb_assert (this_cu->cu == NULL);
- m_new_cu.reset (new dwarf2_cu (this_cu));
+ /* If an existing_cu is provided, a dwarf2_cu must not exist for this_cu
+ in per_objfile yet. */
+ gdb_assert (per_objfile->get_cu (this_cu) == nullptr);
+ m_new_cu.reset (new dwarf2_cu (this_cu, per_objfile));
+ cu = m_new_cu.get ();
}
/* A future optimization, if needed, would be to use an existing
abbrev table. When reading DWOs with skeletonless TUs, all the TUs
could share abbrev tables. */
- if (read_cutu_die_from_dwo (this_cu, sig_type->dwo_unit,
+ if (read_cutu_die_from_dwo (cu, sig_type->dwo_unit,
NULL /* stub_comp_unit_die */,
sig_type->dwo_unit->dwo_file->comp_dir,
this, &info_ptr,
Otherwise the table specified in the comp unit header is read in and used.
This is an optimization for when we already have the abbrev table.
- If USE_EXISTING_CU is non-zero, and THIS_CU->cu is non-NULL, then use it.
- Otherwise, a new CU is allocated with xmalloc. */
+ If EXISTING_CU is non-NULL, then use it. Otherwise, a new CU is
+ allocated. */
-cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu,
+cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
+ dwarf2_per_objfile *dwarf2_per_objfile,
struct abbrev_table *abbrev_table,
- int use_existing_cu,
+ dwarf2_cu *existing_cu,
bool skip_partial)
: die_reader_specs {},
m_this_cu (this_cu)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct dwarf2_section_info *section = this_cu->section;
bfd *abfd = section->get_bfd_owner ();
- struct dwarf2_cu *cu;
const gdb_byte *begin_info_ptr;
struct signatured_type *sig_type = NULL;
struct dwarf2_section_info *abbrev_section;
/* Narrow down the scope of possibilities to have to understand. */
gdb_assert (this_cu->is_debug_types);
gdb_assert (abbrev_table == NULL);
- init_tu_and_read_dwo_dies (this_cu, use_existing_cu);
+ init_tu_and_read_dwo_dies (this_cu, dwarf2_per_objfile, existing_cu);
return;
}
abbrev_section = get_abbrev_section_for_cu (this_cu);
- if (use_existing_cu && this_cu->cu != NULL)
+ dwarf2_cu *cu;
+
+ if (existing_cu != nullptr)
{
- cu = this_cu->cu;
+ cu = existing_cu;
/* If this CU is from a DWO file we need to start over, we need to
refetch the attributes from the skeleton CU.
This could be optimized by retrieving those attributes from when we
}
else
{
- /* If !use_existing_cu, this_cu->cu must be NULL. */
- gdb_assert (this_cu->cu == NULL);
- m_new_cu.reset (new dwarf2_cu (this_cu));
+ /* If an existing_cu is provided, a dwarf2_cu must not exist for this_cu
+ in per_objfile yet. */
+ gdb_assert (dwarf2_per_objfile->get_cu (this_cu) == nullptr);
+ m_new_cu.reset (new dwarf2_cu (this_cu, dwarf2_per_objfile));
cu = m_new_cu.get ();
}
rcuh_kind::COMPILE);
gdb_assert (this_cu->sect_off == cu->header.sect_off);
- gdb_assert (this_cu->length == cu->header.get_length ());
+ if (this_cu->length == 0)
+ this_cu->length = cu->header.get_length ();
+ else
+ gdb_assert (this_cu->length == cu->header.get_length ());
this_cu->dwarf_version = cu->header.version;
}
}
sect_offset_str (this_cu->sect_off),
bfd_get_filename (abfd));
}
- dwo_unit = lookup_dwo_unit (this_cu, comp_unit_die, dwo_name);
+ dwo_unit = lookup_dwo_unit (cu, comp_unit_die, dwo_name);
if (dwo_unit != NULL)
{
- if (read_cutu_die_from_dwo (this_cu, dwo_unit,
+ if (read_cutu_die_from_dwo (cu, dwo_unit,
comp_unit_die, NULL,
this, &info_ptr,
&dwo_comp_unit_die,
gdb_assert (!dummy_p);
if (m_new_cu != NULL)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = m_this_cu->dwarf2_per_objfile;
- /* Link this CU into read_in_chain. */
- m_this_cu->cu->read_in_chain = dwarf2_per_objfile->read_in_chain;
- dwarf2_per_objfile->read_in_chain = m_this_cu;
- /* The chain owns it now. */
- m_new_cu.release ();
+ /* Save this dwarf2_cu in the per_objfile. The per_objfile owns it
+ now. */
+ dwarf2_per_objfile *per_objfile = m_new_cu->per_objfile;
+ per_objfile->set_cu (m_this_cu, m_new_cu.release ());
}
}
When parent_cu is passed, it is used to provide a default value for
str_offsets_base and addr_base from the parent. */
-cutu_reader::cutu_reader (struct dwarf2_per_cu_data *this_cu,
+cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
+ dwarf2_per_objfile *dwarf2_per_objfile,
struct dwarf2_cu *parent_cu,
struct dwo_file *dwo_file)
: die_reader_specs {},
m_this_cu (this_cu)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile = this_cu->dwarf2_per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct dwarf2_section_info *section = this_cu->section;
bfd *abfd = section->get_bfd_owner ();
this_cu->is_debug_types ? "type" : "comp",
sect_offset_str (this_cu->sect_off));
- gdb_assert (this_cu->cu == NULL);
+ gdb_assert (dwarf2_per_objfile->get_cu (this_cu) == nullptr);
abbrev_section = (dwo_file != NULL
? &dwo_file->sections.abbrev
/* This is cheap if the section is already read in. */
section->read (objfile);
- m_new_cu.reset (new dwarf2_cu (this_cu));
+ m_new_cu.reset (new dwarf2_cu (this_cu, dwarf2_per_objfile));
begin_info_ptr = info_ptr = section->buffer + to_underlying (this_cu->sect_off);
info_ptr = read_and_check_comp_unit_head (dwarf2_per_objfile,
static struct type_unit_group *
create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
- struct objfile *objfile = dwarf2_per_objfile->objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
+ dwarf2_per_bfd *per_bfd = dwarf2_per_objfile->per_bfd;
struct dwarf2_per_cu_data *per_cu;
struct type_unit_group *tu_group;
- tu_group = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ tu_group = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack,
struct type_unit_group);
per_cu = &tu_group->per_cu;
- per_cu->dwarf2_per_objfile = dwarf2_per_objfile;
+ per_cu->per_bfd = per_bfd;
- if (dwarf2_per_objfile->using_index)
+ if (per_bfd->using_index)
{
- per_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ per_cu->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, name.c_str ());
+ pst = create_partial_symtab (per_cu, dwarf2_per_objfile, name.c_str ());
pst->anonymous = true;
}
static struct type_unit_group *
get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
- struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
+ struct tu_stats *tu_stats = &dwarf2_per_objfile->per_bfd->tu_stats;
struct type_unit_group *tu_group;
void **slot;
unsigned int line_offset;
struct type_unit_group type_unit_group_for_lookup;
- if (dwarf2_per_objfile->type_unit_groups == NULL)
- dwarf2_per_objfile->type_unit_groups = allocate_type_unit_groups_table ();
+ if (dwarf2_per_objfile->per_bfd->type_unit_groups == NULL)
+ dwarf2_per_objfile->per_bfd->type_unit_groups = allocate_type_unit_groups_table ();
/* Do we need to create a new group, or can we use an existing one? */
type_unit_group_for_lookup.hash.dwo_unit = cu->dwo_unit;
type_unit_group_for_lookup.hash.line_sect_off = (sect_offset) line_offset;
- slot = htab_find_slot (dwarf2_per_objfile->type_unit_groups.get (),
+ slot = htab_find_slot (dwarf2_per_objfile->per_bfd->type_unit_groups.get (),
&type_unit_group_for_lookup, INSERT);
if (*slot != NULL)
{
dirname, textlow, texthigh. */
static dwarf2_psymtab *
-create_partial_symtab (struct dwarf2_per_cu_data *per_cu, const char *name)
+create_partial_symtab (dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile,
+ const char *name)
{
- struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = per_objfile->objfile;
dwarf2_psymtab *pst;
- pst = new dwarf2_psymtab (name, objfile, 0);
+ pst = new dwarf2_psymtab (name, objfile, per_cu);
pst->psymtabs_addrmap_supported = true;
/* This is the glue that links PST into GDB's symbol API. */
- pst->per_cu_data = per_cu;
per_cu->v.psymtab = pst;
return pst;
enum language pretend_language)
{
struct dwarf2_cu *cu = reader->cu;
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ struct objfile *objfile = per_objfile->objfile;
+ struct gdbarch *gdbarch = objfile->arch ();
struct dwarf2_per_cu_data *per_cu = cu->per_cu;
CORE_ADDR baseaddr;
CORE_ADDR best_lowpc = 0, best_highpc = 0;
filename = debug_filename.get ();
}
- pst = create_partial_symtab (per_cu, filename);
+ pst = create_partial_symtab (per_cu, per_objfile, filename);
/* This must be done before calling dwarf2_build_include_psymtabs. */
pst->dirname = dwarf2_string_attr (comp_unit_die, DW_AT_comp_dir, cu);
Process compilation unit THIS_CU for a psymtab. */
static void
-process_psymtab_comp_unit (struct dwarf2_per_cu_data *this_cu,
+process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
+ dwarf2_per_objfile *per_objfile,
bool want_partial_unit,
enum language pretend_language)
{
necessary because we skipped some symbols when we first
read in the compilation unit (see load_partial_dies).
This problem could be avoided, but the benefit is unclear. */
- if (this_cu->cu != NULL)
- free_one_cached_comp_unit (this_cu);
+ per_objfile->remove_cu (this_cu);
- cutu_reader reader (this_cu, NULL, 0, false);
+ cutu_reader reader (this_cu, per_objfile, nullptr, nullptr, false);
switch (reader.comp_unit_die->tag)
{
reader.comp_unit_die,
pretend_language);
- this_cu->lang = this_cu->cu->language;
+ this_cu->lang = reader.cu->language;
/* Age out any secondary CUs. */
- age_cached_comp_units (this_cu->dwarf2_per_objfile);
+ per_objfile->age_comp_units ();
}
/* Reader function for build_type_psymtabs. */
const gdb_byte *info_ptr,
struct die_info *type_unit_die)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = reader->cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = reader->cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct dwarf2_cu *cu = reader->cu;
struct dwarf2_per_cu_data *per_cu = cu->per_cu;
tu_group->tus->push_back (sig_type);
prepare_one_comp_unit (cu, type_unit_die, language_minimal);
- pst = create_partial_symtab (per_cu, "");
+ pst = create_partial_symtab (per_cu, dwarf2_per_objfile, "");
pst->anonymous = true;
first_die = load_partial_dies (reader, info_ptr, 1);
sharing 8K abbrev tables.
The main purpose of this function is to support building the
- dwarf2_per_objfile->type_unit_groups table.
+ dwarf2_per_objfile->per_bfd->type_unit_groups table.
TUs typically share the DW_AT_stmt_list of the CU they came from, so we
can collapse the search space by grouping them by stmt_list.
The savings can be significant, in the same program from above the 200K TUs
FUNC is expected to call get_type_unit_group, which will create the
struct type_unit_group if necessary and add it to
- dwarf2_per_objfile->type_unit_groups. */
+ dwarf2_per_objfile->per_bfd->type_unit_groups. */
static void
build_type_psymtabs_1 (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
- struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
+ struct tu_stats *tu_stats = &dwarf2_per_objfile->per_bfd->tu_stats;
abbrev_table_up abbrev_table;
sect_offset abbrev_offset;
/* It's up to the caller to not call us multiple times. */
- gdb_assert (dwarf2_per_objfile->type_unit_groups == NULL);
+ gdb_assert (dwarf2_per_objfile->per_bfd->type_unit_groups == NULL);
- if (dwarf2_per_objfile->all_type_units.empty ())
+ if (dwarf2_per_objfile->per_bfd->all_type_units.empty ())
return;
/* TUs typically share abbrev tables, and there can be way more TUs than
/* Sort in a separate table to maintain the order of all_type_units
for .gdb_index: TU indices directly index all_type_units. */
std::vector<tu_abbrev_offset> sorted_by_abbrev;
- sorted_by_abbrev.reserve (dwarf2_per_objfile->all_type_units.size ());
+ sorted_by_abbrev.reserve (dwarf2_per_objfile->per_bfd->all_type_units.size ());
- for (signatured_type *sig_type : dwarf2_per_objfile->all_type_units)
+ for (signatured_type *sig_type : dwarf2_per_objfile->per_bfd->all_type_units)
sorted_by_abbrev.emplace_back
(sig_type, read_abbrev_offset (dwarf2_per_objfile,
sig_type->per_cu.section,
abbrev_offset = tu.abbrev_offset;
abbrev_table =
abbrev_table::read (dwarf2_per_objfile->objfile,
- &dwarf2_per_objfile->abbrev,
+ &dwarf2_per_objfile->per_bfd->abbrev,
abbrev_offset);
++tu_stats->nr_uniq_abbrev_tables;
}
- cutu_reader reader (&tu.sig_type->per_cu, abbrev_table.get (),
- 0, false);
+ cutu_reader reader (&tu.sig_type->per_cu, dwarf2_per_objfile,
+ abbrev_table.get (), nullptr, false);
if (!reader.dummy_p)
build_type_psymtabs_reader (&reader, reader.info_ptr,
reader.comp_unit_die);
static void
print_tu_stats (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
- struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
+ struct tu_stats *tu_stats = &dwarf2_per_objfile->per_bfd->tu_stats;
fprintf_unfiltered (gdb_stdlog, "Type unit statistics:\n");
fprintf_unfiltered (gdb_stdlog, " %zu TUs\n",
- dwarf2_per_objfile->all_type_units.size ());
+ dwarf2_per_objfile->per_bfd->all_type_units.size ());
fprintf_unfiltered (gdb_stdlog, " %d uniq abbrev tables\n",
tu_stats->nr_uniq_abbrev_tables);
fprintf_unfiltered (gdb_stdlog, " %d symtabs from stmt_list entries\n",
/* If this TU doesn't exist in the global table, add it and read it in. */
- if (dwarf2_per_objfile->signatured_types == NULL)
- dwarf2_per_objfile->signatured_types = allocate_signatured_type_table ();
+ if (dwarf2_per_objfile->per_bfd->signatured_types == NULL)
+ dwarf2_per_objfile->per_bfd->signatured_types = allocate_signatured_type_table ();
find_entry.signature = dwo_unit->signature;
- slot = htab_find_slot (dwarf2_per_objfile->signatured_types.get (),
+ slot = htab_find_slot (dwarf2_per_objfile->per_bfd->signatured_types.get (),
&find_entry, INSERT);
/* If we've already seen this type there's nothing to do. What's happening
is we're doing our own version of comdat-folding here. */
*slot = entry;
/* This does the job that build_type_psymtabs_1 would have done. */
- cutu_reader reader (&entry->per_cu, NULL, 0, false);
+ cutu_reader reader (&entry->per_cu, dwarf2_per_objfile, nullptr, nullptr,
+ false);
if (!reader.dummy_p)
build_type_psymtabs_reader (&reader, reader.info_ptr,
reader.comp_unit_die);
{
/* Skeletonless TUs in DWP files without .gdb_index is not supported yet. */
if (get_dwp_file (dwarf2_per_objfile) == NULL
- && dwarf2_per_objfile->dwo_files != NULL)
+ && dwarf2_per_objfile->per_bfd->dwo_files != NULL)
{
- htab_traverse_noresize (dwarf2_per_objfile->dwo_files.get (),
+ htab_traverse_noresize (dwarf2_per_objfile->per_bfd->dwo_files.get (),
process_dwo_file_for_skeletonless_type_units,
dwarf2_per_objfile);
}
static void
set_partial_user (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
- for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->per_bfd->all_comp_units)
{
dwarf2_psymtab *pst = per_cu->v.psymtab;
}
scoped_restore restore_reading_psyms
- = make_scoped_restore (&dwarf2_per_objfile->reading_partial_symbols,
+ = make_scoped_restore (&dwarf2_per_objfile->per_bfd->reading_partial_symbols,
true);
- dwarf2_per_objfile->info.read (objfile);
+ dwarf2_per_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. */
= make_scoped_restore (&objfile->partial_symtabs->psymtabs_addrmap,
addrmap_create_mutable (&temp_obstack));
- for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
- process_psymtab_comp_unit (per_cu, false, language_minimal);
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->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, dwarf2_per_objfile, false,
+ language_minimal);
+ }
/* This has to wait until we read the CUs, we need the list of DWOs. */
process_skeletonless_type_units (dwarf2_per_objfile);
/* Now that all TUs have been processed we can fill in the dependencies. */
- if (dwarf2_per_objfile->type_unit_groups != NULL)
+ if (dwarf2_per_objfile->per_bfd->type_unit_groups != NULL)
{
- htab_traverse_noresize (dwarf2_per_objfile->type_unit_groups.get (),
+ htab_traverse_noresize (dwarf2_per_objfile->per_bfd->type_unit_groups.get (),
build_type_psymtab_dependencies, dwarf2_per_objfile);
}
This is also used when rereading a primary CU with load_all_dies. */
static void
-load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu)
+load_partial_comp_unit (dwarf2_per_cu_data *this_cu,
+ dwarf2_per_objfile *per_objfile,
+ dwarf2_cu *existing_cu)
{
- cutu_reader reader (this_cu, NULL, 1, false);
+ cutu_reader reader (this_cu, per_objfile, nullptr, existing_cu, false);
if (!reader.dummy_p)
{
/* Save the compilation unit for later lookup. */
if (cu_header.unit_type != DW_UT_type)
- {
- this_cu = XOBNEW (&objfile->objfile_obstack,
- struct dwarf2_per_cu_data);
- memset (this_cu, 0, sizeof (*this_cu));
- }
+ this_cu = dwarf2_per_objfile->per_bfd->allocate_per_cu ();
else
{
- auto sig_type = XOBNEW (&objfile->objfile_obstack,
- struct signatured_type);
- memset (sig_type, 0, sizeof (*sig_type));
+ auto sig_type = dwarf2_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;
this_cu = &sig_type->per_cu;
this_cu->sect_off = sect_off;
this_cu->length = cu_header.length + cu_header.initial_length_size;
this_cu->is_dwz = is_dwz;
- this_cu->dwarf2_per_objfile = dwarf2_per_objfile;
this_cu->section = section;
- dwarf2_per_objfile->all_comp_units.push_back (this_cu);
+ dwarf2_per_objfile->per_bfd->all_comp_units.push_back (this_cu);
info_ptr = info_ptr + this_cu->length;
}
static void
create_all_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
- gdb_assert (dwarf2_per_objfile->all_comp_units.empty ());
- read_comp_units_from_section (dwarf2_per_objfile, &dwarf2_per_objfile->info,
- &dwarf2_per_objfile->abbrev, 0);
+ gdb_assert (dwarf2_per_objfile->per_bfd->all_comp_units.empty ());
+ read_comp_units_from_section (dwarf2_per_objfile, &dwarf2_per_objfile->per_bfd->info,
+ &dwarf2_per_objfile->per_bfd->abbrev, 0);
- dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+ dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
if (dwz != NULL)
read_comp_units_from_section (dwarf2_per_objfile, &dwz->info, &dwz->abbrev,
1);
children, so we need to look at them. Ditto for anonymous
enums. */
- if (pdi->name != NULL || pdi->tag == DW_TAG_namespace
+ if (pdi->raw_name != NULL || pdi->tag == DW_TAG_namespace
|| pdi->tag == DW_TAG_module || pdi->tag == DW_TAG_enumeration_type
|| pdi->tag == DW_TAG_imported_unit
|| pdi->tag == DW_TAG_inlined_subroutine)
case DW_TAG_variable:
case DW_TAG_typedef:
case DW_TAG_union_type:
- if (!pdi->is_declaration)
+ if (!pdi->is_declaration
+ || (pdi->tag == DW_TAG_variable && pdi->is_external))
{
add_partial_symbol (pdi, cu);
}
{
error (_("Dwarf Error: DW_TAG_imported_unit is not"
" supported in type units [in module %s]"),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name (cu->per_objfile->objfile));
}
per_cu = dwarf2_find_containing_comp_unit
- (pdi->d.sect_off, pdi->is_dwz,
- cu->per_cu->dwarf2_per_objfile);
+ (pdi->d.sect_off, pdi->is_dwz, cu->per_objfile);
/* Go read the partial unit, if needed. */
if (per_cu->v.psymtab == NULL)
- process_psymtab_comp_unit (per_cu, true, cu->language);
+ process_psymtab_comp_unit (per_cu, cu->per_objfile, true,
+ cu->language);
cu->per_cu->imported_symtabs_push (per_cu);
}
Work around this problem here. */
if (cu->language == language_cplus
&& parent->tag == DW_TAG_namespace
- && strcmp (parent->name, "::") == 0
+ && strcmp (parent->name (cu), "::") == 0
&& grandparent_scope == NULL)
{
parent->scope = NULL;
&& pdi->tag == DW_TAG_subprogram))
{
if (grandparent_scope == NULL)
- parent->scope = parent->name;
+ parent->scope = parent->name (cu);
else
parent->scope = typename_concat (&cu->comp_unit_obstack,
grandparent_scope,
- parent->name, 0, cu);
+ parent->name (cu), 0, cu);
}
else
{
{
pdi->fixup (cu);
- if (pdi->name != NULL && strchr (pdi->name, '<') == NULL)
+ if (pdi->name (cu) != NULL && strchr (pdi->name (cu), '<') == NULL)
{
struct die_info *die;
struct attribute attr;
return NULL;
else
return gdb::unique_xmalloc_ptr<char> (typename_concat (NULL, parent_scope,
- pdi->name, 0, cu));
+ pdi->name (cu),
+ 0, cu));
}
static void
add_partial_symbol (struct partial_die_info *pdi, struct dwarf2_cu *cu)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
CORE_ADDR addr = 0;
const char *actual_name = NULL;
CORE_ADDR baseaddr;
actual_name = built_actual_name.get ();
if (actual_name == NULL)
- actual_name = pdi->name;
+ actual_name = pdi->name (cu);
+
+ partial_symbol psymbol;
+ memset (&psymbol, 0, sizeof (psymbol));
+ psymbol.ginfo.set_language (cu->language, &objfile->objfile_obstack);
+ psymbol.ginfo.section = -1;
+
+ /* The code below indicates that the psymbol should be installed by
+ setting this. */
+ gdb::optional<psymbol_placement> where;
switch (pdi->tag)
{
But in Ada and Fortran, we want to be able to access nested
procedures globally. So all Ada and Fortran subprograms are
stored in the global scope. */
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- VAR_DOMAIN, LOC_BLOCK,
- SECT_OFF_TEXT (objfile),
- psymbol_placement::GLOBAL,
- addr,
- cu->language, objfile);
+ where = psymbol_placement::GLOBAL;
}
else
- {
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- VAR_DOMAIN, LOC_BLOCK,
- SECT_OFF_TEXT (objfile),
- psymbol_placement::STATIC,
- addr, cu->language, objfile);
- }
+ where = psymbol_placement::STATIC;
+
+ psymbol.domain = VAR_DOMAIN;
+ psymbol.aclass = LOC_BLOCK;
+ psymbol.ginfo.section = SECT_OFF_TEXT (objfile);
+ psymbol.ginfo.value.address = addr;
if (pdi->main_subprogram && actual_name != NULL)
set_objfile_main_name (objfile, actual_name, cu->language);
break;
case DW_TAG_constant:
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC,
- -1, (pdi->is_external
- ? psymbol_placement::GLOBAL
- : psymbol_placement::STATIC),
- 0, cu->language, objfile);
+ psymbol.domain = VAR_DOMAIN;
+ psymbol.aclass = LOC_STATIC;
+ where = (pdi->is_external
+ ? psymbol_placement::GLOBAL
+ : psymbol_placement::STATIC);
break;
case DW_TAG_variable:
if (pdi->d.locdesc)
if (pdi->d.locdesc
&& addr == 0
- && !dwarf2_per_objfile->has_section_at_zero)
+ && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
{
/* A global or static variable may also have been stripped
out by the linker if unused, in which case its address
table building. */
if (pdi->d.locdesc || pdi->has_type)
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- VAR_DOMAIN, LOC_STATIC,
- SECT_OFF_TEXT (objfile),
- psymbol_placement::GLOBAL,
- addr, cu->language, objfile);
+ {
+ psymbol.domain = VAR_DOMAIN;
+ psymbol.aclass = LOC_STATIC;
+ psymbol.ginfo.section = SECT_OFF_TEXT (objfile);
+ psymbol.ginfo.value.address = addr;
+ where = psymbol_placement::GLOBAL;
+ }
}
else
{
if (!has_loc && !pdi->has_const_value)
return;
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- VAR_DOMAIN, LOC_STATIC,
- SECT_OFF_TEXT (objfile),
- psymbol_placement::STATIC,
- has_loc ? addr : 0,
- cu->language, objfile);
+ psymbol.domain = VAR_DOMAIN;
+ psymbol.aclass = LOC_STATIC;
+ psymbol.ginfo.section = SECT_OFF_TEXT (objfile);
+ if (has_loc)
+ psymbol.ginfo.value.address = addr;
+ where = psymbol_placement::STATIC;
}
break;
case DW_TAG_typedef:
case DW_TAG_base_type:
case DW_TAG_subrange_type:
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- VAR_DOMAIN, LOC_TYPEDEF, -1,
- psymbol_placement::STATIC,
- 0, cu->language, objfile);
+ psymbol.domain = VAR_DOMAIN;
+ psymbol.aclass = LOC_TYPEDEF;
+ where = psymbol_placement::STATIC;
break;
case DW_TAG_imported_declaration:
case DW_TAG_namespace:
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- VAR_DOMAIN, LOC_TYPEDEF, -1,
- psymbol_placement::GLOBAL,
- 0, cu->language, objfile);
+ psymbol.domain = VAR_DOMAIN;
+ psymbol.aclass = LOC_TYPEDEF;
+ where = psymbol_placement::GLOBAL;
break;
case DW_TAG_module:
/* With Fortran 77 there might be a "BLOCK DATA" module
available without any name. If so, we skip the module as it
doesn't bring any value. */
if (actual_name != nullptr)
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- MODULE_DOMAIN, LOC_TYPEDEF, -1,
- psymbol_placement::GLOBAL,
- 0, cu->language, objfile);
+ {
+ psymbol.domain = MODULE_DOMAIN;
+ psymbol.aclass = LOC_TYPEDEF;
+ where = psymbol_placement::GLOBAL;
+ }
break;
case DW_TAG_class_type:
case DW_TAG_interface_type:
/* NOTE: carlton/2003-10-07: See comment in new_symbol about
static vs. global. */
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- STRUCT_DOMAIN, LOC_TYPEDEF, -1,
- cu->language == language_cplus
- ? psymbol_placement::GLOBAL
- : psymbol_placement::STATIC,
- 0, cu->language, objfile);
-
+ psymbol.domain = STRUCT_DOMAIN;
+ psymbol.aclass = LOC_TYPEDEF;
+ where = (cu->language == language_cplus
+ ? psymbol_placement::GLOBAL
+ : psymbol_placement::STATIC);
break;
case DW_TAG_enumerator:
- add_psymbol_to_list (actual_name,
- built_actual_name != NULL,
- VAR_DOMAIN, LOC_CONST, -1,
- cu->language == language_cplus
- ? psymbol_placement::GLOBAL
- : psymbol_placement::STATIC,
- 0, cu->language, objfile);
+ psymbol.domain = VAR_DOMAIN;
+ psymbol.aclass = LOC_CONST;
+ where = (cu->language == language_cplus
+ ? psymbol_placement::GLOBAL
+ : psymbol_placement::STATIC);
break;
default:
break;
}
+
+ if (where.has_value ())
+ {
+ if (built_actual_name != nullptr)
+ actual_name = objfile->intern (actual_name);
+ if (pdi->linkage_name == nullptr || cu->language == language_ada)
+ psymbol.ginfo.set_linkage_name (actual_name);
+ else
+ {
+ psymbol.ginfo.set_demangled_name (actual_name,
+ &objfile->objfile_obstack);
+ psymbol.ginfo.set_linkage_name (pdi->linkage_name);
+ }
+ add_psymbol_to_list (psymbol, *where, objfile);
+ }
}
/* Read a partial die corresponding to a namespace; also, add a symbol
*highpc = pdi->highpc;
if (set_addrmap)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct objfile *objfile = cu->per_objfile->objfile;
+ struct gdbarch *gdbarch = objfile->arch ();
CORE_ADDR baseaddr;
CORE_ADDR this_highpc;
CORE_ADDR this_lowpc;
/* Ignore subprogram DIEs that do not have a name, they are
illegal. Do not emit a complaint at this point, we will
do so when we convert this psymtab into a symtab. */
- if (pdi->name)
+ if (pdi->name (cu))
add_partial_symbol (pdi, cu);
}
}
{
struct partial_die_info *pdi;
- if (enum_pdi->name != NULL)
+ if (enum_pdi->name (cu) != NULL)
add_partial_symbol (enum_pdi, cu);
pdi = enum_pdi->die_child;
while (pdi)
{
- if (pdi->tag != DW_TAG_enumerator || pdi->name == NULL)
+ if (pdi->tag != DW_TAG_enumerator || pdi->raw_name == NULL)
complaint (_("malformed enumerator DIE ignored"));
else
add_partial_symbol (pdi, cu);
const gdb_byte *info_ptr, unsigned int *bytes_read)
{
dwarf2_cu *cu = reader.cu;
- bfd *abfd = cu->per_cu->dwarf2_per_objfile->objfile->obfd;
+ bfd *abfd = cu->per_objfile->objfile->obfd;
unsigned int abbrev_number
= read_unsigned_leb128 (abfd, info_ptr, bytes_read);
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
case DW_FORM_rnglistx:
+ case DW_FORM_loclistx:
info_ptr = safe_skip_leb128 (info_ptr, buffer_end);
break;
case DW_FORM_indirect:
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
- gdb_assert (!readin);
+ gdb_assert (!dwarf2_per_objfile->symtab_set_p (per_cu_data));
+
/* If this psymtab is constructed from a debug-only objfile, the
has_section_at_zero flag will not necessarily be correct. We
can get the correct value for this flag by looking at the data
struct dwarf2_per_objfile *dpo_backlink
= get_dwarf2_per_objfile (objfile->separate_debug_objfile_backlink);
- dwarf2_per_objfile->has_section_at_zero
- = dpo_backlink->has_section_at_zero;
+ dwarf2_per_objfile->per_bfd->has_section_at_zero
+ = dpo_backlink->per_bfd->has_section_at_zero;
}
expand_psymtab (objfile);
/* Add PER_CU to the queue. */
static void
-queue_comp_unit (struct dwarf2_per_cu_data *per_cu,
+queue_comp_unit (dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile,
enum language pretend_language)
{
per_cu->queued = 1;
- per_cu->dwarf2_per_objfile->queue.emplace (per_cu, pretend_language);
+ per_cu->per_bfd->queue.emplace (per_cu, per_objfile, pretend_language);
}
/* If PER_CU is not yet queued, add it to the queue.
static int
maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
- struct dwarf2_per_cu_data *per_cu,
+ dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile,
enum language pretend_language)
{
/* We may arrive here during partial symbol reading, if we need full
DIEs to process an unusual case (e.g. template arguments). Do
not queue PER_CU, just tell our caller to load its DIEs. */
- if (per_cu->dwarf2_per_objfile->reading_partial_symbols)
+ if (per_cu->per_bfd->reading_partial_symbols)
{
- if (per_cu->cu == NULL || per_cu->cu->dies == NULL)
+ dwarf2_cu *cu = per_objfile->get_cu (per_cu);
+
+ if (cu == NULL || cu->dies == NULL)
return 1;
return 0;
}
/* If the compilation unit is already loaded, just mark it as
used. */
- if (per_cu->cu != NULL)
+ dwarf2_cu *cu = per_objfile->get_cu (per_cu);
+ if (cu != nullptr)
{
- per_cu->cu->last_used = 0;
+ cu->last_used = 0;
return 0;
}
/* Add it to the queue. */
- queue_comp_unit (per_cu, pretend_language);
+ queue_comp_unit (per_cu, per_objfile, pretend_language);
return 1;
}
/* The queue starts out with one item, but following a DIE reference
may load a new CU, adding it to the end of the queue. */
- while (!dwarf2_per_objfile->queue.empty ())
+ while (!dwarf2_per_objfile->per_bfd->queue.empty ())
{
- dwarf2_queue_item &item = dwarf2_per_objfile->queue.front ();
+ dwarf2_queue_item &item = dwarf2_per_objfile->per_bfd->queue.front ();
+ dwarf2_per_cu_data *per_cu = item.per_cu;
- if ((dwarf2_per_objfile->using_index
- ? !item.per_cu->v.quick->compunit_symtab
- : (item.per_cu->v.psymtab && !item.per_cu->v.psymtab->readin))
- /* Skip dummy CUs. */
- && item.per_cu->cu != NULL)
+ if (!dwarf2_per_objfile->symtab_set_p (per_cu))
{
- struct dwarf2_per_cu_data *per_cu = item.per_cu;
- unsigned int debug_print_threshold;
- char buf[100];
+ dwarf2_cu *cu = dwarf2_per_objfile->get_cu (per_cu);
- if (per_cu->is_debug_types)
+ /* Skip dummy CUs. */
+ if (cu != nullptr)
{
- struct signatured_type *sig_type =
- (struct signatured_type *) per_cu;
-
- sprintf (buf, "TU %s at offset %s",
- hex_string (sig_type->signature),
- sect_offset_str (per_cu->sect_off));
- /* There can be 100s of TUs.
- Only print them in verbose mode. */
- debug_print_threshold = 2;
- }
- else
- {
- sprintf (buf, "CU at offset %s",
- sect_offset_str (per_cu->sect_off));
- debug_print_threshold = 1;
- }
+ unsigned int debug_print_threshold;
+ char buf[100];
- if (dwarf_read_debug >= debug_print_threshold)
- fprintf_unfiltered (gdb_stdlog, "Expanding symtab of %s\n", buf);
+ if (per_cu->is_debug_types)
+ {
+ struct signatured_type *sig_type =
+ (struct signatured_type *) per_cu;
+
+ sprintf (buf, "TU %s at offset %s",
+ hex_string (sig_type->signature),
+ sect_offset_str (per_cu->sect_off));
+ /* There can be 100s of TUs.
+ Only print them in verbose mode. */
+ debug_print_threshold = 2;
+ }
+ else
+ {
+ sprintf (buf, "CU at offset %s",
+ sect_offset_str (per_cu->sect_off));
+ debug_print_threshold = 1;
+ }
- if (per_cu->is_debug_types)
- process_full_type_unit (per_cu, item.pretend_language);
- else
- process_full_comp_unit (per_cu, item.pretend_language);
+ if (dwarf_read_debug >= debug_print_threshold)
+ fprintf_unfiltered (gdb_stdlog, "Expanding symtab of %s\n", buf);
- if (dwarf_read_debug >= debug_print_threshold)
- fprintf_unfiltered (gdb_stdlog, "Done expanding %s\n", buf);
+ if (per_cu->is_debug_types)
+ process_full_type_unit (cu, item.pretend_language);
+ else
+ process_full_comp_unit (cu, item.pretend_language);
+
+ if (dwarf_read_debug >= debug_print_threshold)
+ fprintf_unfiltered (gdb_stdlog, "Done expanding %s\n", buf);
+ }
}
- item.per_cu->queued = 0;
- dwarf2_per_objfile->queue.pop ();
+ per_cu->queued = 0;
+ dwarf2_per_objfile->per_bfd->queue.pop ();
}
if (dwarf_read_debug)
void
dwarf2_psymtab::expand_psymtab (struct objfile *objfile)
{
- if (readin)
- return;
+ gdb_assert (!readin_p (objfile));
+ dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+ free_cached_comp_units freer (per_objfile);
expand_dependencies (objfile);
- dw2_do_instantiate_symtab (per_cu_data, false);
- gdb_assert (get_compunit_symtab () != nullptr);
+ dw2_do_instantiate_symtab (per_cu_data, per_objfile, false);
+ gdb_assert (get_compunit_symtab (objfile) != nullptr);
+}
+
+/* See psympriv.h. */
+
+bool
+dwarf2_psymtab::readin_p (struct objfile *objfile) const
+{
+ dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+ return per_objfile->symtab_set_p (per_cu_data);
+}
+
+/* See psympriv.h. */
+
+compunit_symtab *
+dwarf2_psymtab::get_compunit_symtab (struct objfile *objfile) const
+{
+ dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+ return per_objfile->get_symtab (per_cu_data);
}
/* Trivial hash function for die_info: the hash value of a DIE
/* Load the DIEs associated with PER_CU into memory. */
static void
-load_full_comp_unit (struct dwarf2_per_cu_data *this_cu,
+load_full_comp_unit (dwarf2_per_cu_data *this_cu,
+ dwarf2_per_objfile *per_objfile,
bool skip_partial,
enum language pretend_language)
{
gdb_assert (! this_cu->is_debug_types);
- cutu_reader reader (this_cu, NULL, 1, skip_partial);
+ dwarf2_cu *existing_cu = per_objfile->get_cu (this_cu);
+ cutu_reader reader (this_cu, per_objfile, NULL, existing_cu, skip_partial);
if (reader.dummy_p)
return;
package_name = std::move (this_package_name);
else
{
- struct objfile *objfile
- = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
if (strcmp (package_name.get (), this_package_name.get ()) != 0)
complaint (_("Symtab %s has objects from two different Go packages: %s and %s"),
(symbol_symtab (sym) != NULL
if (package_name != NULL)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
const char *saved_package_name = objfile->intern (package_name.get ());
struct type *type = init_type (objfile, TYPE_CODE_MODULE, 0,
saved_package_name);
struct symbol *sym;
- sym = allocate_symbol (objfile);
+ sym = new (&objfile->objfile_obstack) symbol;
sym->set_language (language_go, &objfile->objfile_obstack);
sym->compute_and_set_names (saved_package_name, false, objfile->per_bfd);
/* This is not VAR_DOMAIN because we want a way to ensure a lookup of,
return obconcat (obstack, p1, "::", p2, (char *) NULL);
}
-/* A helper that allocates a struct discriminant_info to attach to a
- union type. */
+/* A helper that allocates a variant part to attach to a Rust enum
+ type. OBSTACK is where the results should be allocated. TYPE is
+ the type we're processing. DISCRIMINANT_INDEX is the index of the
+ discriminant. It must be the index of one of the fields of TYPE.
+ DEFAULT_INDEX is the index of the default field; or -1 if there is
+ no default. RANGES is indexed by "effective" field number (the
+ field index, but omitting the discriminant and default fields) and
+ must hold the discriminant values used by the variants. Note that
+ RANGES must have a lifetime at least as long as OBSTACK -- either
+ already allocated on it, or static. */
-static struct discriminant_info *
-alloc_discriminant_info (struct type *type, int discriminant_index,
- int default_index)
-{
- gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION);
- gdb_assert (discriminant_index == -1
- || (discriminant_index >= 0
- && discriminant_index < TYPE_NFIELDS (type)));
+static void
+alloc_rust_variant (struct obstack *obstack, struct type *type,
+ int discriminant_index, int default_index,
+ gdb::array_view<discriminant_range> ranges)
+{
+ /* When DISCRIMINANT_INDEX == -1, we have a univariant enum. Those
+ must be handled by the caller. */
+ gdb_assert (discriminant_index >= 0
+ && discriminant_index < type->num_fields ());
gdb_assert (default_index == -1
- || (default_index >= 0 && default_index < TYPE_NFIELDS (type)));
+ || (default_index >= 0 && default_index < type->num_fields ()));
- TYPE_FLAG_DISCRIMINATED_UNION (type) = 1;
+ /* We have one variant for each non-discriminant field. */
+ int n_variants = type->num_fields () - 1;
- struct discriminant_info *disc
- = ((struct discriminant_info *)
- TYPE_ZALLOC (type,
- offsetof (struct discriminant_info, discriminants)
- + TYPE_NFIELDS (type) * sizeof (disc->discriminants[0])));
- disc->default_index = default_index;
- disc->discriminant_index = discriminant_index;
+ variant *variants = new (obstack) variant[n_variants];
+ int var_idx = 0;
+ int range_idx = 0;
+ for (int i = 0; i < type->num_fields (); ++i)
+ {
+ if (i == discriminant_index)
+ continue;
- struct dynamic_prop prop;
- prop.kind = PROP_UNDEFINED;
- prop.data.baton = disc;
+ variants[var_idx].first_field = i;
+ variants[var_idx].last_field = i + 1;
+
+ /* The default field does not need a range, but other fields do.
+ We skipped the discriminant above. */
+ if (i != default_index)
+ {
+ variants[var_idx].discriminants = ranges.slice (range_idx, 1);
+ ++range_idx;
+ }
+
+ ++var_idx;
+ }
+
+ gdb_assert (range_idx == ranges.size ());
+ gdb_assert (var_idx == n_variants);
+
+ variant_part *part = new (obstack) variant_part;
+ part->discriminant_index = discriminant_index;
+ part->is_unsigned = TYPE_UNSIGNED (TYPE_FIELD_TYPE (type,
+ discriminant_index));
+ part->variants = gdb::array_view<variant> (variants, n_variants);
- add_dyn_prop (DYN_PROP_DISCRIMINATED, prop, type);
+ void *storage = obstack_alloc (obstack, sizeof (gdb::array_view<variant_part>));
+ gdb::array_view<variant_part> *prop_value
+ = new (storage) gdb::array_view<variant_part> (part, 1);
- return disc;
+ struct dynamic_prop prop;
+ prop.kind = PROP_VARIANT_PARTS;
+ prop.data.variant_parts = prop_value;
+
+ type->add_dyn_prop (DYN_PROP_VARIANT_PARTS, prop);
}
/* Some versions of rustc emitted enums in an unusual way.
static void
quirk_rust_enum (struct type *type, struct objfile *objfile)
{
- gdb_assert (TYPE_CODE (type) == TYPE_CODE_UNION);
+ gdb_assert (type->code () == TYPE_CODE_UNION);
/* We don't need to deal with empty enums. */
- if (TYPE_NFIELDS (type) == 0)
+ if (type->num_fields () == 0)
return;
#define RUST_ENUM_PREFIX "RUST$ENCODED$ENUM$"
- if (TYPE_NFIELDS (type) == 1
+ if (type->num_fields () == 1
&& startswith (TYPE_FIELD_NAME (type, 0), RUST_ENUM_PREFIX))
{
const char *name = TYPE_FIELD_NAME (type, 0) + strlen (RUST_ENUM_PREFIX);
unsigned long index = strtoul (name, &tail, 10);
name = tail;
if (*name != '$'
- || index >= TYPE_NFIELDS (field_type)
+ || index >= field_type->num_fields ()
|| (TYPE_FIELD_LOC_KIND (field_type, index)
!= FIELD_LOC_KIND_BITPOS))
{
field_type = TYPE_FIELD_TYPE (field_type, index);
}
- /* Make a union to hold the variants. */
- struct type *union_type = alloc_type (objfile);
- TYPE_CODE (union_type) = TYPE_CODE_UNION;
- TYPE_NFIELDS (union_type) = 3;
- TYPE_FIELDS (union_type)
- = (struct field *) TYPE_ZALLOC (type, 3 * sizeof (struct field));
- TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
- set_type_align (union_type, TYPE_RAW_ALIGN (type));
-
- /* Put the discriminant must at index 0. */
- TYPE_FIELD_TYPE (union_type, 0) = field_type;
- TYPE_FIELD_ARTIFICIAL (union_type, 0) = 1;
- TYPE_FIELD_NAME (union_type, 0) = "<<discriminant>>";
- SET_FIELD_BITPOS (TYPE_FIELD (union_type, 0), bit_offset);
+ /* Smash this type to be a structure type. We have to do this
+ because the type has already been recorded. */
+ type->set_code (TYPE_CODE_STRUCT);
+ type->set_num_fields (3);
+ /* Save the field we care about. */
+ struct field saved_field = type->field (0);
+ type->set_fields
+ ((struct field *) TYPE_ZALLOC (type, 3 * sizeof (struct field)));
+
+ /* Put the discriminant at index 0. */
+ TYPE_FIELD_TYPE (type, 0) = field_type;
+ TYPE_FIELD_ARTIFICIAL (type, 0) = 1;
+ TYPE_FIELD_NAME (type, 0) = "<<discriminant>>";
+ SET_FIELD_BITPOS (type->field (0), bit_offset);
/* The order of fields doesn't really matter, so put the real
field at index 1 and the data-less field at index 2. */
- struct discriminant_info *disc
- = alloc_discriminant_info (union_type, 0, 1);
- TYPE_FIELD (union_type, 1) = TYPE_FIELD (type, 0);
- TYPE_FIELD_NAME (union_type, 1)
- = rust_last_path_segment (TYPE_NAME (TYPE_FIELD_TYPE (union_type, 1)));
- TYPE_NAME (TYPE_FIELD_TYPE (union_type, 1))
- = rust_fully_qualify (&objfile->objfile_obstack, TYPE_NAME (type),
- TYPE_FIELD_NAME (union_type, 1));
+ type->field (1) = saved_field;
+ TYPE_FIELD_NAME (type, 1)
+ = rust_last_path_segment (TYPE_FIELD_TYPE (type, 1)->name ());
+ TYPE_FIELD_TYPE (type, 1)->set_name
+ (rust_fully_qualify (&objfile->objfile_obstack, type->name (),
+ TYPE_FIELD_NAME (type, 1)));
const char *dataless_name
- = rust_fully_qualify (&objfile->objfile_obstack, TYPE_NAME (type),
+ = rust_fully_qualify (&objfile->objfile_obstack, type->name (),
name);
struct type *dataless_type = init_type (objfile, TYPE_CODE_VOID, 0,
dataless_name);
- TYPE_FIELD_TYPE (union_type, 2) = dataless_type;
+ TYPE_FIELD_TYPE (type, 2) = dataless_type;
/* NAME points into the original discriminant name, which
already has the correct lifetime. */
- TYPE_FIELD_NAME (union_type, 2) = name;
- SET_FIELD_BITPOS (TYPE_FIELD (union_type, 2), 0);
- disc->discriminants[2] = 0;
+ TYPE_FIELD_NAME (type, 2) = name;
+ SET_FIELD_BITPOS (type->field (2), 0);
- /* Smash this type to be a structure type. We have to do this
- because the type has already been recorded. */
- TYPE_CODE (type) = TYPE_CODE_STRUCT;
- TYPE_NFIELDS (type) = 1;
- TYPE_FIELDS (type)
- = (struct field *) TYPE_ZALLOC (type, sizeof (struct field));
-
- /* Install the variant part. */
- TYPE_FIELD_TYPE (type, 0) = union_type;
- SET_FIELD_BITPOS (TYPE_FIELD (type, 0), 0);
- TYPE_FIELD_NAME (type, 0) = "<<variants>>";
+ /* Indicate that this is a variant type. */
+ static discriminant_range ranges[1] = { { 0, 0 } };
+ alloc_rust_variant (&objfile->objfile_obstack, type, 0, 1, ranges);
}
/* A union with a single anonymous field is probably an old-style
univariant enum. */
- else if (TYPE_NFIELDS (type) == 1 && streq (TYPE_FIELD_NAME (type, 0), ""))
+ else if (type->num_fields () == 1 && streq (TYPE_FIELD_NAME (type, 0), ""))
{
/* Smash this type to be a structure type. We have to do this
because the type has already been recorded. */
- TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ type->set_code (TYPE_CODE_STRUCT);
- /* Make a union to hold the variants. */
- struct type *union_type = alloc_type (objfile);
- TYPE_CODE (union_type) = TYPE_CODE_UNION;
- TYPE_NFIELDS (union_type) = TYPE_NFIELDS (type);
- TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
- set_type_align (union_type, TYPE_RAW_ALIGN (type));
- TYPE_FIELDS (union_type) = TYPE_FIELDS (type);
-
- struct type *field_type = TYPE_FIELD_TYPE (union_type, 0);
+ struct type *field_type = TYPE_FIELD_TYPE (type, 0);
const char *variant_name
- = rust_last_path_segment (TYPE_NAME (field_type));
- TYPE_FIELD_NAME (union_type, 0) = variant_name;
- TYPE_NAME (field_type)
- = rust_fully_qualify (&objfile->objfile_obstack,
- TYPE_NAME (type), variant_name);
-
- /* Install the union in the outer struct type. */
- TYPE_NFIELDS (type) = 1;
- TYPE_FIELDS (type)
- = (struct field *) TYPE_ZALLOC (union_type, sizeof (struct field));
- TYPE_FIELD_TYPE (type, 0) = union_type;
- TYPE_FIELD_NAME (type, 0) = "<<variants>>";
- SET_FIELD_BITPOS (TYPE_FIELD (type, 0), 0);
-
- alloc_discriminant_info (union_type, -1, 0);
+ = rust_last_path_segment (field_type->name ());
+ TYPE_FIELD_NAME (type, 0) = variant_name;
+ field_type->set_name
+ (rust_fully_qualify (&objfile->objfile_obstack,
+ type->name (), variant_name));
}
else
{
struct type *disr_type = nullptr;
- for (int i = 0; i < TYPE_NFIELDS (type); ++i)
+ for (int i = 0; i < type->num_fields (); ++i)
{
disr_type = TYPE_FIELD_TYPE (type, i);
- if (TYPE_CODE (disr_type) != TYPE_CODE_STRUCT)
+ if (disr_type->code () != TYPE_CODE_STRUCT)
{
/* All fields of a true enum will be structs. */
return;
}
- else if (TYPE_NFIELDS (disr_type) == 0)
+ else if (disr_type->num_fields () == 0)
{
/* Could be data-less variant, so keep going. */
disr_type = nullptr;
/* Smash this type to be a structure type. We have to do this
because the type has already been recorded. */
- TYPE_CODE (type) = TYPE_CODE_STRUCT;
-
- /* Make a union to hold the variants. */
- struct field *disr_field = &TYPE_FIELD (disr_type, 0);
- struct type *union_type = alloc_type (objfile);
- TYPE_CODE (union_type) = TYPE_CODE_UNION;
- TYPE_NFIELDS (union_type) = 1 + TYPE_NFIELDS (type);
- TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
- set_type_align (union_type, TYPE_RAW_ALIGN (type));
- TYPE_FIELDS (union_type)
- = (struct field *) TYPE_ZALLOC (union_type,
- (TYPE_NFIELDS (union_type)
- * sizeof (struct field)));
-
- memcpy (TYPE_FIELDS (union_type) + 1, TYPE_FIELDS (type),
- TYPE_NFIELDS (type) * sizeof (struct field));
+ type->set_code (TYPE_CODE_STRUCT);
+
+ /* Make space for the discriminant field. */
+ struct field *disr_field = &disr_type->field (0);
+ field *new_fields
+ = (struct field *) TYPE_ZALLOC (type, ((type->num_fields () + 1)
+ * sizeof (struct field)));
+ memcpy (new_fields + 1, type->fields (),
+ type->num_fields () * sizeof (struct field));
+ type->set_fields (new_fields);
+ type->set_num_fields (type->num_fields () + 1);
/* Install the discriminant at index 0 in the union. */
- TYPE_FIELD (union_type, 0) = *disr_field;
- TYPE_FIELD_ARTIFICIAL (union_type, 0) = 1;
- TYPE_FIELD_NAME (union_type, 0) = "<<discriminant>>";
-
- /* Install the union in the outer struct type. */
- TYPE_FIELD_TYPE (type, 0) = union_type;
- TYPE_FIELD_NAME (type, 0) = "<<variants>>";
- TYPE_NFIELDS (type) = 1;
-
- /* Set the size and offset of the union type. */
- SET_FIELD_BITPOS (TYPE_FIELD (type, 0), 0);
+ type->field (0) = *disr_field;
+ TYPE_FIELD_ARTIFICIAL (type, 0) = 1;
+ TYPE_FIELD_NAME (type, 0) = "<<discriminant>>";
/* We need a way to find the correct discriminant given a
variant name. For convenience we build a map here. */
struct type *enum_type = FIELD_TYPE (*disr_field);
std::unordered_map<std::string, ULONGEST> discriminant_map;
- for (int i = 0; i < TYPE_NFIELDS (enum_type); ++i)
+ for (int i = 0; i < enum_type->num_fields (); ++i)
{
if (TYPE_FIELD_LOC_KIND (enum_type, i) == FIELD_LOC_KIND_ENUMVAL)
{
}
}
- int n_fields = TYPE_NFIELDS (union_type);
- struct discriminant_info *disc
- = alloc_discriminant_info (union_type, 0, -1);
+ int n_fields = type->num_fields ();
+ /* We don't need a range entry for the discriminant, but we do
+ need one for every other field, as there is no default
+ variant. */
+ discriminant_range *ranges = XOBNEWVEC (&objfile->objfile_obstack,
+ discriminant_range,
+ n_fields - 1);
/* Skip the discriminant here. */
for (int i = 1; i < n_fields; ++i)
{
That name can be used to look up the correct
discriminant. */
const char *variant_name
- = rust_last_path_segment (TYPE_NAME (TYPE_FIELD_TYPE (union_type,
- i)));
+ = rust_last_path_segment (TYPE_FIELD_TYPE (type, i)->name ());
auto iter = discriminant_map.find (variant_name);
if (iter != discriminant_map.end ())
- disc->discriminants[i] = iter->second;
+ {
+ ranges[i].low = iter->second;
+ ranges[i].high = iter->second;
+ }
/* Remove the discriminant field, if it exists. */
- struct type *sub_type = TYPE_FIELD_TYPE (union_type, i);
- if (TYPE_NFIELDS (sub_type) > 0)
+ struct type *sub_type = TYPE_FIELD_TYPE (type, i);
+ if (sub_type->num_fields () > 0)
{
- --TYPE_NFIELDS (sub_type);
- ++TYPE_FIELDS (sub_type);
+ sub_type->set_num_fields (sub_type->num_fields () - 1);
+ sub_type->set_fields (sub_type->fields () + 1);
}
- TYPE_FIELD_NAME (union_type, i) = variant_name;
- TYPE_NAME (sub_type)
- = rust_fully_qualify (&objfile->objfile_obstack,
- TYPE_NAME (type), variant_name);
+ TYPE_FIELD_NAME (type, i) = variant_name;
+ sub_type->set_name
+ (rust_fully_qualify (&objfile->objfile_obstack,
+ type->name (), variant_name));
}
+
+ /* Indicate that this is a variant type. */
+ alloc_rust_variant (&objfile->objfile_obstack, type, 0, 1,
+ gdb::array_view<discriminant_range> (ranges,
+ n_fields - 1));
}
}
{
gdb_assert (cu->language == language_rust);
for (type *type_ : cu->rust_unions)
- quirk_rust_enum (type_, cu->per_cu->dwarf2_per_objfile->objfile);
+ quirk_rust_enum (type_, cu->per_objfile->objfile);
/* We don't need this any more. */
cu->rust_unions.clear ();
}
-/* Return the symtab for PER_CU. This works properly regardless of
- whether we're using the index or psymtabs. */
+/* See read.h. */
-static struct compunit_symtab *
-get_compunit_symtab (struct dwarf2_per_cu_data *per_cu)
+type_unit_group_unshareable *
+dwarf2_per_objfile::get_type_unit_group_unshareable (type_unit_group *tu_group)
+{
+ auto iter = this->m_type_units.find (tu_group);
+ if (iter != this->m_type_units.end ())
+ return iter->second.get ();
+
+ type_unit_group_unshareable_up uniq (new type_unit_group_unshareable);
+ type_unit_group_unshareable *result = uniq.get ();
+ this->m_type_units[tu_group] = std::move (uniq);
+ return result;
+}
+
+struct type *
+dwarf2_per_objfile::get_type_for_signatured_type
+ (signatured_type *sig_type) const
{
- return (per_cu->dwarf2_per_objfile->using_index
- ? per_cu->v.quick->compunit_symtab
- : per_cu->v.psymtab->compunit_symtab);
+ auto iter = this->m_type_map.find (sig_type);
+ if (iter == this->m_type_map.end ())
+ return nullptr;
+
+ return iter->second;
+}
+
+void dwarf2_per_objfile::set_type_for_signatured_type
+ (signatured_type *sig_type, struct type *type)
+{
+ gdb_assert (this->m_type_map.find (sig_type) == this->m_type_map.end ());
+
+ this->m_type_map[sig_type] = type;
}
/* A helper function for computing the list of all symbol tables
static void
recursively_compute_inclusions (std::vector<compunit_symtab *> *result,
htab_t all_children, htab_t all_type_symtabs,
- struct dwarf2_per_cu_data *per_cu,
+ dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile,
struct compunit_symtab *immediate_parent)
{
- void **slot;
- struct compunit_symtab *cust;
-
- slot = htab_find_slot (all_children, per_cu, INSERT);
+ void **slot = htab_find_slot (all_children, per_cu, INSERT);
if (*slot != NULL)
{
/* This inclusion and its children have been processed. */
}
*slot = per_cu;
+
/* Only add a CU if it has a symbol table. */
- cust = get_compunit_symtab (per_cu);
+ compunit_symtab *cust = per_objfile->get_symtab (per_cu);
if (cust != NULL)
{
/* If this is a type unit only add its symbol table if we haven't
for (dwarf2_per_cu_data *ptr : *per_cu->imported_symtabs)
{
recursively_compute_inclusions (result, all_children,
- all_type_symtabs, ptr, cust);
+ all_type_symtabs, ptr, per_objfile,
+ cust);
}
}
PER_CU. */
static void
-compute_compunit_symtab_includes (struct dwarf2_per_cu_data *per_cu)
+compute_compunit_symtab_includes (dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile)
{
gdb_assert (! per_cu->is_debug_types);
int len;
std::vector<compunit_symtab *> result_symtabs;
htab_t all_children, all_type_symtabs;
- struct compunit_symtab *cust = get_compunit_symtab (per_cu);
+ compunit_symtab *cust = per_objfile->get_symtab (per_cu);
/* If we don't have a symtab, we can just skip this case. */
if (cust == NULL)
for (dwarf2_per_cu_data *ptr : *per_cu->imported_symtabs)
{
recursively_compute_inclusions (&result_symtabs, all_children,
- all_type_symtabs, ptr, cust);
+ all_type_symtabs, ptr, per_objfile,
+ cust);
}
/* Now we have a transitive closure of all the included symtabs. */
len = result_symtabs.size ();
cust->includes
- = XOBNEWVEC (&per_cu->dwarf2_per_objfile->objfile->objfile_obstack,
+ = XOBNEWVEC (&per_objfile->objfile->objfile_obstack,
struct compunit_symtab *, len + 1);
memcpy (cust->includes, result_symtabs.data (),
len * sizeof (compunit_symtab *));
static void
process_cu_includes (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
- for (dwarf2_per_cu_data *iter : dwarf2_per_objfile->just_read_cus)
+ for (dwarf2_per_cu_data *iter : dwarf2_per_objfile->per_bfd->just_read_cus)
{
if (! iter->is_debug_types)
- compute_compunit_symtab_includes (iter);
+ compute_compunit_symtab_includes (iter, dwarf2_per_objfile);
}
- dwarf2_per_objfile->just_read_cus.clear ();
+ dwarf2_per_objfile->per_bfd->just_read_cus.clear ();
}
-/* Generate full symbol information for PER_CU, whose DIEs have
+/* Generate full symbol information for CU, whose DIEs have
already been loaded into memory. */
static void
-process_full_comp_unit (struct dwarf2_per_cu_data *per_cu,
- enum language pretend_language)
+process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
{
- struct dwarf2_cu *cu = per_cu->cu;
- struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
+ dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
CORE_ADDR lowpc, highpc;
struct compunit_symtab *cust;
CORE_ADDR baseaddr;
cust->call_site_htab = cu->call_site_htab;
}
- if (dwarf2_per_objfile->using_index)
- per_cu->v.quick->compunit_symtab = cust;
- else
- {
- dwarf2_psymtab *pst = per_cu->v.psymtab;
- pst->compunit_symtab = cust;
- pst->readin = true;
- }
+ dwarf2_per_objfile->set_symtab (cu->per_cu, cust);
/* Push it for inclusion processing later. */
- dwarf2_per_objfile->just_read_cus.push_back (per_cu);
+ dwarf2_per_objfile->per_bfd->just_read_cus.push_back (cu->per_cu);
/* Not needed any more. */
cu->reset_builder ();
}
-/* Generate full symbol information for type unit PER_CU, whose DIEs have
+/* Generate full symbol information for type unit CU, whose DIEs have
already been loaded into memory. */
static void
-process_full_type_unit (struct dwarf2_per_cu_data *per_cu,
+process_full_type_unit (dwarf2_cu *cu,
enum language pretend_language)
{
- struct dwarf2_cu *cu = per_cu->cu;
- struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
+ dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct compunit_symtab *cust;
struct signatured_type *sig_type;
- gdb_assert (per_cu->is_debug_types);
- sig_type = (struct signatured_type *) per_cu;
+ gdb_assert (cu->per_cu->is_debug_types);
+ sig_type = (struct signatured_type *) cu->per_cu;
/* Clear the list here in case something was left over. */
cu->method_list.clear ();
If this is the first TU to use this symtab, complete the construction
of it with end_expandable_symtab. Otherwise, complete the addition of
this TU's symbols to the existing symtab. */
- if (sig_type->type_unit_group->compunit_symtab == NULL)
+ type_unit_group_unshareable *tug_unshare =
+ dwarf2_per_objfile->get_type_unit_group_unshareable (sig_type->type_unit_group);
+ if (tug_unshare->compunit_symtab == NULL)
{
buildsym_compunit *builder = cu->get_builder ();
cust = builder->end_expandable_symtab (0, SECT_OFF_TEXT (objfile));
- sig_type->type_unit_group->compunit_symtab = cust;
+ tug_unshare->compunit_symtab = cust;
if (cust != NULL)
{
else
{
cu->get_builder ()->augment_type_symtab ();
- cust = sig_type->type_unit_group->compunit_symtab;
+ cust = tug_unshare->compunit_symtab;
}
- if (dwarf2_per_objfile->using_index)
- per_cu->v.quick->compunit_symtab = cust;
- else
- {
- dwarf2_psymtab *pst = per_cu->v.psymtab;
- pst->compunit_symtab = cust;
- pst->readin = true;
- }
+ dwarf2_per_objfile->set_symtab (cu->per_cu, cust);
/* Not needed any more. */
cu->reset_builder ();
{
error (_("Dwarf Error: DW_TAG_imported_unit is not"
" supported in type units [in module %s]"),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name (cu->per_objfile->objfile));
}
attr = dwarf2_attr (die, DW_AT_import, cu);
{
sect_offset sect_off = attr->get_ref_die_offset ();
bool is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
+ dwarf2_per_objfile *per_objfile = cu->per_objfile;
dwarf2_per_cu_data *per_cu
- = dwarf2_find_containing_comp_unit (sect_off, is_dwz,
- cu->per_cu->dwarf2_per_objfile);
+ = dwarf2_find_containing_comp_unit (sect_off, is_dwz, per_objfile);
/* We're importing a C++ compilation unit with tag DW_TAG_compile_unit
into another compilation unit, at root level. Regard this as a hint,
return;
/* If necessary, add it to the queue and load its DIEs. */
- if (maybe_queue_comp_unit (cu, per_cu, cu->language))
- load_full_comp_unit (per_cu, false, cu->language);
+ if (maybe_queue_comp_unit (cu, per_cu, per_objfile, cu->language))
+ load_full_comp_unit (per_cu, per_objfile, false, cu->language);
cu->per_cu->imported_symtabs_push (per_cu);
}
if (linkage_name == NULL)
linkage_name = dwarf2_string_attr (die, DW_AT_MIPS_linkage_name, cu);
+ /* rustc emits invalid values for DW_AT_linkage_name. Ignore these.
+ See https://github.com/rust-lang/rust/issues/32925. */
+ if (cu->language == language_rust && linkage_name != NULL
+ && strchr (linkage_name, '{') != NULL)
+ linkage_name = NULL;
+
return linkage_name;
}
For Ada, return the DIE's linkage name rather than the fully qualified
name. PHYSNAME is ignored..
- The result is allocated on the objfile_obstack and canonicalized. */
+ The result is allocated on the objfile->per_bfd's obstack and
+ canonicalized. */
static const char *
dwarf2_compute_name (const char *name,
struct die_info *die, struct dwarf2_cu *cu,
int physname)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
if (name == NULL)
name = dwarf2_name (die, cu);
v = dwarf2_evaluate_loc_desc (type, NULL,
baton->data,
baton->size,
- baton->per_cu);
+ baton->per_cu,
+ baton->per_objfile);
else if (bytes != NULL)
{
v = allocate_value (type);
marks unnamed (and thus unused) parameters as
artificial; there is no way to differentiate
the two cases. */
- if (TYPE_NFIELDS (type) > 0
+ if (type->num_fields () > 0
&& TYPE_FIELD_ARTIFICIAL (type, 0)
- && TYPE_CODE (TYPE_FIELD_TYPE (type, 0)) == TYPE_CODE_PTR
+ && TYPE_FIELD_TYPE (type, 0)->code () == TYPE_CODE_PTR
&& TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type,
0))))
buf.puts (" const");
static const char *
dwarf2_physname (const char *name, struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
const char *retval, *mangled = NULL, *canon = NULL;
int need_copy = 1;
if (!die_needs_namespace (die, cu))
return dwarf2_compute_name (name, die, cu, 1);
- mangled = dw2_linkage_name (die, cu);
-
- /* rustc emits invalid values for DW_AT_linkage_name. Ignore these.
- See https://github.com/rust-lang/rust/issues/32925. */
- if (cu->language == language_rust && mangled != NULL
- && strchr (mangled, '{') != NULL)
- mangled = NULL;
+ if (cu->language != language_rust)
+ mangled = dw2_linkage_name (die, cu);
/* DW_AT_linkage_name is missing in some cases - depend on what GDB
has computed. */
struct type *type;
sect_offset sect_off = attr->get_ref_die_offset ();
- type = get_die_type_at_offset (sect_off, cu->per_cu);
- if (type != NULL && TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
+ type = get_die_type_at_offset (sect_off, cu->per_cu, cu->per_objfile);
+ if (type != NULL && type->code () == TYPE_CODE_NAMESPACE)
{
/* This declaration is a global namespace alias. Add
a symbol for it whose type is the aliased namespace. */
static void
read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
struct attribute *import_attr;
struct die_info *imported_die, *child_die;
struct dwarf2_cu *imported_cu;
handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
const char *comp_dir, CORE_ADDR lowpc) /* ARI: editCase function */
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct attribute *attr;
struct line_header line_header_local;
hashval_t line_header_local_hash;
static void
read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
CORE_ADDR lowpc = ((CORE_ADDR) -1);
CORE_ADDR highpc = ((CORE_ADDR) 0);
struct attribute *attr;
do it again, we could fake it and just recreate the part we need
(file name,index -> symtab mapping). If data shows this optimization
is useful we can do it then. */
- first_time = tu_group->compunit_symtab == NULL;
+ type_unit_group_unshareable *tug_unshare
+ = per_objfile->get_type_unit_group_unshareable (tu_group);
+ first_time = tug_unshare->compunit_symtab == NULL;
/* We have to handle the case of both a missing DW_AT_stmt_list or bad
debug info. */
start_symtab ("", NULL, 0);
else
{
- gdb_assert (tu_group->symtabs == NULL);
+ gdb_assert (tug_unshare->symtabs == NULL);
gdb_assert (m_builder == nullptr);
- struct compunit_symtab *cust = tu_group->compunit_symtab;
+ struct compunit_symtab *cust = tug_unshare->compunit_symtab;
m_builder.reset (new struct buildsym_compunit
(COMPUNIT_OBJFILE (cust), "",
COMPUNIT_DIRNAME (cust),
compunit_language (cust),
0, cust));
+ list_in_scope = get_builder ()->get_file_symbols ();
}
return;
}
process_full_type_unit still needs to know if this is the first
time. */
- tu_group->symtabs
+ tug_unshare->symtabs
= XOBNEWVEC (&COMPUNIT_OBJFILE (cust)->objfile_obstack,
struct symtab *, line_header->file_names_size ());
}
fe.symtab = b->get_current_subfile ()->symtab;
- tu_group->symtabs[i] = fe.symtab;
+ tug_unshare->symtabs[i] = fe.symtab;
}
}
else
{
gdb_assert (m_builder == nullptr);
- struct compunit_symtab *cust = tu_group->compunit_symtab;
+ struct compunit_symtab *cust = tug_unshare->compunit_symtab;
m_builder.reset (new struct buildsym_compunit
(COMPUNIT_OBJFILE (cust), "",
COMPUNIT_DIRNAME (cust),
compunit_language (cust),
0, cust));
+ list_in_scope = get_builder ()->get_file_symbols ();
auto &file_names = line_header->file_names ();
for (i = 0; i < file_names.size (); ++i)
{
file_entry &fe = file_names[i];
- fe.symtab = tu_group->symtabs[i];
+ fe.symtab = tug_unshare->symtabs[i];
}
}
struct dwo_file find_entry;
void **slot;
- if (dwarf2_per_objfile->dwo_files == NULL)
- dwarf2_per_objfile->dwo_files = allocate_dwo_file_hash_table ();
+ if (dwarf2_per_objfile->per_bfd->dwo_files == NULL)
+ dwarf2_per_objfile->per_bfd->dwo_files = allocate_dwo_file_hash_table ();
find_entry.dwo_name = dwo_name;
find_entry.comp_dir = comp_dir;
- slot = htab_find_slot (dwarf2_per_objfile->dwo_files.get (), &find_entry,
+ slot = htab_find_slot (dwarf2_per_objfile->per_bfd->dwo_files.get (), &find_entry,
INSERT);
return slot;
dwarf2_section_info §ion, htab_up &cus_htab)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
+ dwarf2_per_bfd *per_bfd = dwarf2_per_objfile->per_bfd;
const gdb_byte *info_ptr, *end_ptr;
section.read (objfile);
sect_offset sect_off = (sect_offset) (info_ptr - section.buffer);
memset (&per_cu, 0, sizeof (per_cu));
- per_cu.dwarf2_per_objfile = dwarf2_per_objfile;
+ per_cu.per_bfd = per_bfd;
per_cu.is_debug_types = 0;
per_cu.sect_off = sect_offset (info_ptr - section.buffer);
per_cu.section = §ion;
- cutu_reader reader (&per_cu, cu, &dwo_file);
+ cutu_reader reader (&per_cu, dwarf2_per_objfile, cu, &dwo_file);
if (!reader.dummy_p)
create_dwo_cu_reader (&reader, reader.info_ptr, reader.comp_unit_die,
&dwo_file, &read_unit);
if (cus_htab == NULL)
cus_htab = allocate_dwo_unit_table ();
- dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+ dwo_unit = OBSTACK_ZALLOC (&per_bfd->obstack,
+ struct dwo_unit);
*dwo_unit = read_unit;
slot = htab_find_slot (cus_htab.get (), dwo_unit, INSERT);
gdb_assert (slot != NULL);
pulongest (nr_slots), dwp_file->name);
}
- htab = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_hash_table);
+ htab = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack, struct dwp_hash_table);
htab->version = version;
htab->nr_columns = nr_columns;
htab->nr_units = nr_units;
const char *comp_dir,
ULONGEST signature, int is_debug_types)
{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
const struct dwp_hash_table *dwp_htab =
is_debug_types ? dwp_file->tus : dwp_file->cus;
bfd *dbfd = dwp_file->dbfd.get ();
virtual_dwo_name.c_str ());
}
dwo_file = new struct dwo_file;
- dwo_file->dwo_name = objfile->intern (virtual_dwo_name);
+ dwo_file->dwo_name = dwarf2_per_objfile->objfile->intern (virtual_dwo_name);
dwo_file->comp_dir = comp_dir;
dwo_file->sections.abbrev = sections.abbrev;
dwo_file->sections.line = sections.line;
dwo_file = (struct dwo_file *) *dwo_file_slot;
}
- dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+ dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack, struct dwo_unit);
dwo_unit->dwo_file = dwo_file;
dwo_unit->signature = signature;
dwo_unit->section =
- XOBNEW (&objfile->objfile_obstack, struct dwarf2_section_info);
+ XOBNEW (&dwarf2_per_objfile->per_bfd->obstack, struct dwarf2_section_info);
*dwo_unit->section = sections.info_or_types;
/* dwo_unit->{offset,length,type_offset_in_tu} are set later. */
const char *comp_dir,
ULONGEST signature, int is_debug_types)
{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
const struct dwp_hash_table *dwp_htab =
is_debug_types ? dwp_file->tus : dwp_file->cus;
bfd *dbfd = dwp_file->dbfd.get ();
virtual_dwo_name.c_str ());
}
dwo_file = new struct dwo_file;
- dwo_file->dwo_name = objfile->intern (virtual_dwo_name);
+ dwo_file->dwo_name = dwarf2_per_objfile->objfile->intern (virtual_dwo_name);
dwo_file->comp_dir = comp_dir;
dwo_file->sections.abbrev =
create_dwp_v2_section (dwarf2_per_objfile, &dwp_file->sections.abbrev,
dwo_file = (struct dwo_file *) *dwo_file_slot;
}
- dwo_unit = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_unit);
+ dwo_unit = OBSTACK_ZALLOC (&dwarf2_per_objfile->per_bfd->obstack, struct dwo_unit);
dwo_unit->dwo_file = dwo_file;
dwo_unit->signature = signature;
dwo_unit->section =
- XOBNEW (&objfile->objfile_obstack, struct dwarf2_section_info);
+ XOBNEW (&dwarf2_per_objfile->per_bfd->obstack, struct dwarf2_section_info);
*dwo_unit->section = create_dwp_v2_section (dwarf2_per_objfile,
is_debug_types
? &dwp_file->sections.types
dwo_sections->loc.s.section = sectp;
dwo_sections->loc.size = bfd_section_size (sectp);
}
+ else if (section_is_p (sectp->name, &names->loclists_dwo))
+ {
+ dwo_sections->loclists.s.section = sectp;
+ dwo_sections->loclists.size = bfd_section_size (sectp);
+ }
else if (section_is_p (sectp->name, &names->macinfo_dwo))
{
dwo_sections->macinfo.s.section = sectp;
The result is NULL if DWO_NAME can't be found. */
static struct dwo_file *
-open_and_init_dwo_file (struct dwarf2_per_cu_data *per_cu,
- const char *dwo_name, const char *comp_dir)
+open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
gdb_bfd_ref_ptr dbfd = open_dwo_file (dwarf2_per_objfile, dwo_name, comp_dir);
if (dbfd == NULL)
bfd_map_over_sections (dwo_file->dbfd.get (), dwarf2_locate_dwo_sections,
&dwo_file->sections);
- create_cus_hash_table (dwarf2_per_objfile, per_cu->cu, *dwo_file,
+ create_cus_hash_table (dwarf2_per_objfile, cu, *dwo_file,
dwo_file->sections.info, dwo_file->cus);
create_debug_types_hash_table (dwarf2_per_objfile, dwo_file.get (),
dwp_file->num_sections = elf_numsections (dwp_file->dbfd);
dwp_file->elf_sections =
- OBSTACK_CALLOC (&objfile->objfile_obstack,
+ OBSTACK_CALLOC (&dwarf2_per_objfile->per_bfd->obstack,
dwp_file->num_sections, asection *);
bfd_map_over_sections (dwp_file->dbfd.get (),
static struct dwp_file *
get_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
- if (! dwarf2_per_objfile->dwp_checked)
+ if (! dwarf2_per_objfile->per_bfd->dwp_checked)
{
- dwarf2_per_objfile->dwp_file
+ dwarf2_per_objfile->per_bfd->dwp_file
= open_and_init_dwp_file (dwarf2_per_objfile);
- dwarf2_per_objfile->dwp_checked = 1;
+ dwarf2_per_objfile->per_bfd->dwp_checked = 1;
}
- return dwarf2_per_objfile->dwp_file.get ();
+ return dwarf2_per_objfile->per_bfd->dwp_file.get ();
}
/* Subroutine of lookup_dwo_comp_unit, lookup_dwo_type_unit.
(dwo_id mismatch or couldn't find the DWO/DWP file). */
static struct dwo_unit *
-lookup_dwo_cutu (struct dwarf2_per_cu_data *this_unit,
- const char *dwo_name, const char *comp_dir,
+lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
ULONGEST signature, int is_debug_types)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile = this_unit->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
const char *kind = is_debug_types ? "TU" : "CU";
void **dwo_file_slot;
if (*dwo_file_slot == NULL)
{
/* Read in the file and build a table of the CUs/TUs it contains. */
- *dwo_file_slot = open_and_init_dwo_file (this_unit, dwo_name, comp_dir);
+ *dwo_file_slot = open_and_init_dwo_file (cu, dwo_name, comp_dir);
}
/* NOTE: This will be NULL if unable to open the file. */
dwo_file = (struct dwo_file *) *dwo_file_slot;
warning (_("Could not find DWO %s %s(%s)%s referenced by %s at offset %s"
" [in module %s]"),
- kind, dwo_name, hex_string (signature),
- dwp_text.c_str (),
- this_unit->is_debug_types ? "TU" : "CU",
- sect_offset_str (this_unit->sect_off), objfile_name (objfile));
+ kind, dwo_name, hex_string (signature), dwp_text.c_str (), kind,
+ sect_offset_str (cu->per_cu->sect_off), objfile_name (objfile));
}
return NULL;
}
See lookup_dwo_cutu_unit for details. */
static struct dwo_unit *
-lookup_dwo_comp_unit (struct dwarf2_per_cu_data *this_cu,
- const char *dwo_name, const char *comp_dir,
+lookup_dwo_comp_unit (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
ULONGEST signature)
{
- return lookup_dwo_cutu (this_cu, dwo_name, comp_dir, signature, 0);
+ gdb_assert (!cu->per_cu->is_debug_types);
+
+ return lookup_dwo_cutu (cu, dwo_name, comp_dir, signature, 0);
}
/* Lookup the DWO TU DWO_NAME/SIGNATURE referenced from THIS_TU.
See lookup_dwo_cutu_unit for details. */
static struct dwo_unit *
-lookup_dwo_type_unit (struct signatured_type *this_tu,
- const char *dwo_name, const char *comp_dir)
+lookup_dwo_type_unit (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir)
{
- return lookup_dwo_cutu (&this_tu->per_cu, dwo_name, comp_dir, this_tu->signature, 1);
+ gdb_assert (cu->per_cu->is_debug_types);
+
+ signatured_type *sig_type = (signatured_type *) cu->per_cu;
+
+ return lookup_dwo_cutu (cu, dwo_name, comp_dir, sig_type->signature, 1);
}
/* Traversal function for queue_and_load_all_dwo_tus. */
queue_and_load_dwo_tu (void **slot, void *info)
{
struct dwo_unit *dwo_unit = (struct dwo_unit *) *slot;
- struct dwarf2_per_cu_data *per_cu = (struct dwarf2_per_cu_data *) info;
+ dwarf2_cu *cu = (dwarf2_cu *) info;
ULONGEST signature = dwo_unit->signature;
- struct signatured_type *sig_type =
- lookup_dwo_signatured_type (per_cu->cu, signature);
+ signatured_type *sig_type = lookup_dwo_signatured_type (cu, signature);
if (sig_type != NULL)
{
/* 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, per_cu->cu->language))
- load_full_type_unit (sig_cu);
- per_cu->imported_symtabs_push (sig_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);
}
return 1;
}
-/* Queue all TUs contained in the DWO of PER_CU to be read in.
+/* Queue all TUs contained in the DWO of CU to be read in.
The DWO may have the only definition of the type, though it may not be
referenced anywhere in PER_CU. Thus we have to load *all* its TUs.
http://sourceware.org/bugzilla/show_bug.cgi?id=15021 */
static void
-queue_and_load_all_dwo_tus (struct dwarf2_per_cu_data *per_cu)
+queue_and_load_all_dwo_tus (dwarf2_cu *cu)
{
struct dwo_unit *dwo_unit;
struct dwo_file *dwo_file;
- gdb_assert (!per_cu->is_debug_types);
- gdb_assert (get_dwp_file (per_cu->dwarf2_per_objfile) == NULL);
- gdb_assert (per_cu->cu != NULL);
+ gdb_assert (cu != nullptr);
+ gdb_assert (!cu->per_cu->is_debug_types);
+ gdb_assert (get_dwp_file (cu->per_objfile) == nullptr);
- dwo_unit = per_cu->cu->dwo_unit;
+ dwo_unit = cu->dwo_unit;
gdb_assert (dwo_unit != NULL);
dwo_file = dwo_unit->dwo_file;
if (dwo_file->tus != NULL)
- htab_traverse_noresize (dwo_file->tus.get (), queue_and_load_dwo_tu,
- per_cu);
+ htab_traverse_noresize (dwo_file->tus.get (), queue_and_load_dwo_tu, cu);
}
/* Read in various DIEs. */
static void
read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct objfile *objfile = cu->per_objfile->objfile;
+ struct gdbarch *gdbarch = objfile->arch ();
struct context_stack *newobj;
CORE_ADDR lowpc;
CORE_ADDR highpc;
if (child_die->tag == DW_TAG_template_type_param
|| child_die->tag == DW_TAG_template_value_param)
{
- templ_func = allocate_template_symbol (objfile);
+ templ_func = new (&objfile->objfile_obstack) template_symbol;
templ_func->subclass = SYMBOL_TEMPLATE;
break;
}
newobj->static_link
= XOBNEW (&objfile->objfile_obstack, struct dynamic_prop);
attr_to_dynamic_prop (attr, die, cu, newobj->static_link,
- cu->per_cu->addr_type ());
+ cu->addr_type ());
}
cu->list_in_scope = cu->get_builder ()->get_local_symbols ();
static void
read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct objfile *objfile = cu->per_objfile->objfile;
+ struct gdbarch *gdbarch = objfile->arch ();
CORE_ADDR lowpc, highpc;
struct die_info *child_die;
CORE_ADDR baseaddr;
for (child_die = die->child;
child_die != NULL && child_die->tag;
child_die = child_die->sibling)
- process_die (child_die, cu);
+ {
+ /* We might already be processing this DIE. This can happen
+ in an unusual circumstance -- where a subroutine A
+ appears lexically in another subroutine B, but A actually
+ inlines B. The recursion is broken here, rather than in
+ inherit_abstract_dies, because it seems better to simply
+ drop concrete children here. */
+ if (!child_die->in_process)
+ process_die (child_die, cu);
+ }
return;
case PC_BOUNDS_INVALID:
return;
static void
read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ struct objfile *objfile = per_objfile->objfile;
+ struct gdbarch *gdbarch = objfile->arch ();
CORE_ADDR pc, baseaddr;
struct attribute *attr;
struct call_site *call_site, call_site_local;
func_type = get_die_type (func_die, cu);
if (func_type != NULL)
{
- gdb_assert (TYPE_CODE (func_type) == TYPE_CODE_FUNC);
+ gdb_assert (func_type->code () == TYPE_CODE_FUNC);
/* Enlist this call site to the function. */
call_site->tail_call_next = TYPE_TAIL_CALL_LIST (func_type);
dlbaton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton);
dlbaton->data = DW_BLOCK (attr)->data;
dlbaton->size = DW_BLOCK (attr)->size;
+ dlbaton->per_objfile = per_objfile;
dlbaton->per_cu = cu->per_cu;
SET_FIELD_DWARF_BLOCK (call_site->target, dlbaton);
struct die_info *target_die;
target_die = follow_die_ref (die, attr, &target_cu);
- gdb_assert (target_cu->per_cu->dwarf2_per_objfile->objfile == objfile);
+ gdb_assert (target_cu->per_objfile->objfile == objfile);
if (die_is_declaration (target_die, target_cu))
{
const char *target_physname;
sect_offset_str (die->sect_off), objfile_name (objfile));
call_site->per_cu = cu->per_cu;
+ call_site->per_objfile = per_objfile;
for (child_die = die->child;
child_die && child_die->tag;
if (containing_type != NULL)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
- storage = new (&objfile->objfile_obstack) rust_vtable_symbol ();
- initialize_objfile_symbol (storage);
+ storage = new (&objfile->objfile_obstack) rust_vtable_symbol;
storage->concrete_type = containing_type;
storage->subclass = SYMBOL_RUST_VTABLE;
}
struct dwarf2_cu *origin_cu = cu;
struct die_info *origin_die
= follow_die_ref (die, abstract_origin, &origin_cu);
- dwarf2_per_objfile *dpo = cu->per_cu->dwarf2_per_objfile;
- dpo->abstract_to_concrete[origin_die->sect_off].push_back (die->sect_off);
+ dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ per_objfile->per_bfd->abstract_to_concrete
+ [origin_die->sect_off].push_back (die->sect_off);
}
}
dwarf2_rnglists_process (unsigned offset, struct dwarf2_cu *cu,
Callback &&callback)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
bfd *obfd = objfile->obfd;
/* Base address selection entry. */
base = cu->base_address;
- dwarf2_per_objfile->rnglists.read (objfile);
- if (offset >= dwarf2_per_objfile->rnglists.size)
+ dwarf2_per_objfile->per_bfd->rnglists.read (objfile);
+ if (offset >= dwarf2_per_objfile->per_bfd->rnglists.size)
{
complaint (_("Offset %d out of bounds for DW_AT_ranges attribute"),
offset);
return false;
}
- buffer = dwarf2_per_objfile->rnglists.buffer + offset;
+ buffer = dwarf2_per_objfile->per_bfd->rnglists.buffer + offset;
baseaddr = objfile->text_section_offset ();
{
/* Initialize it due to a false compiler warning. */
CORE_ADDR range_beginning = 0, range_end = 0;
- const gdb_byte *buf_end = (dwarf2_per_objfile->rnglists.buffer
- + dwarf2_per_objfile->rnglists.size);
+ const gdb_byte *buf_end = (dwarf2_per_objfile->per_bfd->rnglists.buffer
+ + dwarf2_per_objfile->per_bfd->rnglists.size);
unsigned int bytes_read;
if (buffer == buf_end)
/* A not-uncommon case of bad debug info.
Don't pollute the addrmap with bad data. */
if (range_beginning + baseaddr == 0
- && !dwarf2_per_objfile->has_section_at_zero)
+ && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
{
complaint (_(".debug_rnglists entry has start address of zero"
" [in module %s]"), objfile_name (objfile));
dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu,
Callback &&callback)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
- struct objfile *objfile = dwarf2_per_objfile->objfile;
+ dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ struct objfile *objfile = per_objfile->objfile;
struct comp_unit_head *cu_header = &cu->header;
bfd *obfd = objfile->obfd;
unsigned int addr_size = cu_header->addr_size;
base = cu->base_address;
- dwarf2_per_objfile->ranges.read (objfile);
- if (offset >= dwarf2_per_objfile->ranges.size)
+ per_objfile->per_bfd->ranges.read (objfile);
+ if (offset >= per_objfile->per_bfd->ranges.size)
{
complaint (_("Offset %d out of bounds for DW_AT_ranges attribute"),
offset);
return 0;
}
- buffer = dwarf2_per_objfile->ranges.buffer + offset;
+ buffer = per_objfile->per_bfd->ranges.buffer + offset;
baseaddr = objfile->text_section_offset ();
/* A not-uncommon case of bad debug info.
Don't pollute the addrmap with bad data. */
if (range_beginning + baseaddr == 0
- && !dwarf2_per_objfile->has_section_at_zero)
+ && !per_objfile->per_bfd->has_section_at_zero)
{
complaint (_(".debug_ranges entry has start address of zero"
" [in module %s]"), objfile_name (objfile));
CORE_ADDR *high_return, struct dwarf2_cu *cu,
dwarf2_psymtab *ranges_pst)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct objfile *objfile = cu->per_objfile->objfile;
+ struct gdbarch *gdbarch = objfile->arch ();
const CORE_ADDR baseaddr = objfile->text_section_offset ();
int low_set = 0;
CORE_ADDR low = 0;
CORE_ADDR *highpc, struct dwarf2_cu *cu,
dwarf2_psymtab *pst)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct attribute *attr;
struct attribute *attr_high;
CORE_ADDR low = 0;
labels are not in the output, so the relocs get a value of 0.
If this is a discarded function, mark the pc bounds as invalid,
so that GDB will ignore it. */
- if (low == 0 && !dwarf2_per_objfile->has_section_at_zero)
+ if (low == 0 && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
return PC_BOUNDS_INVALID;
*lowpc = low;
dwarf2_record_block_ranges (struct die_info *die, struct block *block,
CORE_ADDR baseaddr, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct objfile *objfile = cu->per_objfile->objfile;
+ struct gdbarch *gdbarch = objfile->arch ();
struct attribute *attr;
struct attribute *attr_high;
return 0;
}
+/* Look for DW_AT_data_member_location and store the results in FIELD. */
+
+static void
+handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
+ struct field *field)
+{
+ struct attribute *attr;
+
+ attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
+ if (attr != NULL)
+ {
+ if (attr->form_is_constant ())
+ {
+ LONGEST offset = attr->constant_value (0);
+ SET_FIELD_BITPOS (*field, offset * bits_per_byte);
+ }
+ else if (attr->form_is_section_offset ())
+ dwarf2_complex_location_expr_complaint ();
+ else if (attr->form_is_block ())
+ {
+ bool handled;
+ CORE_ADDR offset = decode_locdesc (DW_BLOCK (attr), cu, &handled);
+ if (handled)
+ SET_FIELD_BITPOS (*field, offset * bits_per_byte);
+ else
+ {
+ dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ struct objfile *objfile = per_objfile->objfile;
+ struct dwarf2_locexpr_baton *dlbaton
+ = XOBNEW (&objfile->objfile_obstack,
+ struct dwarf2_locexpr_baton);
+ dlbaton->data = DW_BLOCK (attr)->data;
+ dlbaton->size = DW_BLOCK (attr)->size;
+ /* When using this baton, we want to compute the address
+ of the field, not the value. This is why
+ is_reference is set to false here. */
+ dlbaton->is_reference = false;
+ dlbaton->per_objfile = per_objfile;
+ dlbaton->per_cu = cu->per_cu;
+
+ SET_FIELD_DWARF_BLOCK (*field, dlbaton);
+ }
+ }
+ else
+ dwarf2_complex_location_expr_complaint ();
+ }
+}
+
/* Add an aggregate field to the field list. */
static void
dwarf2_add_field (struct field_info *fip, struct die_info *die,
struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct objfile *objfile = cu->per_objfile->objfile;
+ struct gdbarch *gdbarch = objfile->arch ();
struct nextfield *new_field;
struct attribute *attr;
struct field *fp;
new_field = &fip->fields.back ();
}
+ new_field->offset = die->sect_off;
+
attr = dwarf2_attr (die, DW_AT_accessibility, cu);
if (attr != nullptr)
new_field->accessibility = DW_UNSND (attr);
if (die->tag == DW_TAG_member && ! die_is_declaration (die, cu))
{
- LONGEST offset;
-
/* Data member other than a C++ static data member. */
/* Get type of field. */
}
/* Get bit offset of field. */
- if (handle_data_member_location (die, cu, &offset))
- SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
+ handle_data_member_location (die, cu, fp);
attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
if (attr != nullptr)
{
}
else if (die->tag == DW_TAG_inheritance)
{
- LONGEST offset;
-
/* C++ base class field. */
- if (handle_data_member_location (die, cu, &offset))
- SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
+ handle_data_member_location (die, cu, fp);
FIELD_BITSIZE (*fp) = 0;
FIELD_TYPE (*fp) = die_type (die, cu);
- FIELD_NAME (*fp) = TYPE_NAME (fp->type);
- }
- else if (die->tag == DW_TAG_variant_part)
- {
- /* process_structure_scope will treat this DIE as a union. */
- process_structure_scope (die, cu);
-
- /* The variant part is relative to the start of the enclosing
- structure. */
- SET_FIELD_BITPOS (*fp, 0);
- fp->type = get_die_type (die, cu);
- fp->artificial = 1;
- fp->name = "<<variant>>";
-
- /* Normally a DW_TAG_variant_part won't have a size, but our
- representation requires one, so set it to the maximum of the
- child sizes, being sure to account for the offset at which
- each child is seen. */
- if (TYPE_LENGTH (fp->type) == 0)
- {
- unsigned max = 0;
- for (int i = 0; i < TYPE_NFIELDS (fp->type); ++i)
- {
- unsigned len = ((TYPE_FIELD_BITPOS (fp->type, i) + 7) / 8
- + TYPE_LENGTH (TYPE_FIELD_TYPE (fp->type, i)));
- if (len > max)
- max = len;
- }
- TYPE_LENGTH (fp->type) = max;
- }
+ FIELD_NAME (*fp) = fp->type->name ();
}
else
gdb_assert_not_reached ("missing case in dwarf2_add_field");
fip->nested_types_list.push_back (fp);
}
+/* A convenience typedef that's used when finding the discriminant
+ field for a variant part. */
+typedef std::unordered_map<sect_offset, int, gdb::hash_enum<sect_offset>>
+ offset_map_type;
+
+/* Compute the discriminant range for a given variant. OBSTACK is
+ where the results will be stored. VARIANT is the variant to
+ process. IS_UNSIGNED indicates whether the discriminant is signed
+ or unsigned. */
+
+static const gdb::array_view<discriminant_range>
+convert_variant_range (struct obstack *obstack, const variant_field &variant,
+ bool is_unsigned)
+{
+ std::vector<discriminant_range> ranges;
+
+ if (variant.default_branch)
+ return {};
+
+ if (variant.discr_list_data == nullptr)
+ {
+ discriminant_range r
+ = {variant.discriminant_value, variant.discriminant_value};
+ ranges.push_back (r);
+ }
+ else
+ {
+ gdb::array_view<const gdb_byte> data (variant.discr_list_data->data,
+ variant.discr_list_data->size);
+ while (!data.empty ())
+ {
+ if (data[0] != DW_DSC_range && data[0] != DW_DSC_label)
+ {
+ complaint (_("invalid discriminant marker: %d"), data[0]);
+ break;
+ }
+ bool is_range = data[0] == DW_DSC_range;
+ data = data.slice (1);
+
+ ULONGEST low, high;
+ unsigned int bytes_read;
+
+ if (data.empty ())
+ {
+ complaint (_("DW_AT_discr_list missing low value"));
+ break;
+ }
+ if (is_unsigned)
+ low = read_unsigned_leb128 (nullptr, data.data (), &bytes_read);
+ else
+ low = (ULONGEST) read_signed_leb128 (nullptr, data.data (),
+ &bytes_read);
+ data = data.slice (bytes_read);
+
+ if (is_range)
+ {
+ if (data.empty ())
+ {
+ complaint (_("DW_AT_discr_list missing high value"));
+ break;
+ }
+ if (is_unsigned)
+ high = read_unsigned_leb128 (nullptr, data.data (),
+ &bytes_read);
+ else
+ high = (LONGEST) read_signed_leb128 (nullptr, data.data (),
+ &bytes_read);
+ data = data.slice (bytes_read);
+ }
+ else
+ high = low;
+
+ ranges.push_back ({ low, high });
+ }
+ }
+
+ discriminant_range *result = XOBNEWVEC (obstack, discriminant_range,
+ ranges.size ());
+ std::copy (ranges.begin (), ranges.end (), result);
+ return gdb::array_view<discriminant_range> (result, ranges.size ());
+}
+
+static const gdb::array_view<variant_part> create_variant_parts
+ (struct obstack *obstack,
+ const offset_map_type &offset_map,
+ struct field_info *fi,
+ const std::vector<variant_part_builder> &variant_parts);
+
+/* Fill in a "struct variant" for a given variant field. RESULT is
+ the variant to fill in. OBSTACK is where any needed allocations
+ will be done. OFFSET_MAP holds the mapping from section offsets to
+ fields for the type. FI describes the fields of the type we're
+ processing. FIELD is the variant field we're converting. */
+
+static void
+create_one_variant (variant &result, struct obstack *obstack,
+ const offset_map_type &offset_map,
+ struct field_info *fi, const variant_field &field)
+{
+ result.discriminants = convert_variant_range (obstack, field, false);
+ result.first_field = field.first_field + fi->baseclasses.size ();
+ result.last_field = field.last_field + fi->baseclasses.size ();
+ result.parts = create_variant_parts (obstack, offset_map, fi,
+ field.variant_parts);
+}
+
+/* Fill in a "struct variant_part" for a given variant part. RESULT
+ is the variant part to fill in. OBSTACK is where any needed
+ allocations will be done. OFFSET_MAP holds the mapping from
+ section offsets to fields for the type. FI describes the fields of
+ the type we're processing. BUILDER is the variant part to be
+ converted. */
+
+static void
+create_one_variant_part (variant_part &result,
+ struct obstack *obstack,
+ const offset_map_type &offset_map,
+ struct field_info *fi,
+ const variant_part_builder &builder)
+{
+ auto iter = offset_map.find (builder.discriminant_offset);
+ if (iter == offset_map.end ())
+ {
+ result.discriminant_index = -1;
+ /* Doesn't matter. */
+ result.is_unsigned = false;
+ }
+ else
+ {
+ result.discriminant_index = iter->second;
+ result.is_unsigned
+ = TYPE_UNSIGNED (FIELD_TYPE
+ (fi->fields[result.discriminant_index].field));
+ }
+
+ size_t n = builder.variants.size ();
+ variant *output = new (obstack) variant[n];
+ for (size_t i = 0; i < n; ++i)
+ create_one_variant (output[i], obstack, offset_map, fi,
+ builder.variants[i]);
+
+ result.variants = gdb::array_view<variant> (output, n);
+}
+
+/* Create a vector of variant parts that can be attached to a type.
+ OBSTACK is where any needed allocations will be done. OFFSET_MAP
+ holds the mapping from section offsets to fields for the type. FI
+ describes the fields of the type we're processing. VARIANT_PARTS
+ is the vector to convert. */
+
+static const gdb::array_view<variant_part>
+create_variant_parts (struct obstack *obstack,
+ const offset_map_type &offset_map,
+ struct field_info *fi,
+ const std::vector<variant_part_builder> &variant_parts)
+{
+ if (variant_parts.empty ())
+ return {};
+
+ size_t n = variant_parts.size ();
+ variant_part *result = new (obstack) variant_part[n];
+ for (size_t i = 0; i < n; ++i)
+ create_one_variant_part (result[i], obstack, offset_map, fi,
+ variant_parts[i]);
+
+ return gdb::array_view<variant_part> (result, n);
+}
+
+/* Compute the variant part vector for FIP, attaching it to TYPE when
+ done. */
+
+static void
+add_variant_property (struct field_info *fip, struct type *type,
+ struct dwarf2_cu *cu)
+{
+ /* Map section offsets of fields to their field index. Note the
+ field index here does not take the number of baseclasses into
+ account. */
+ offset_map_type offset_map;
+ for (int i = 0; i < fip->fields.size (); ++i)
+ offset_map[fip->fields[i].offset] = i;
+
+ struct objfile *objfile = cu->per_objfile->objfile;
+ gdb::array_view<variant_part> parts
+ = create_variant_parts (&objfile->objfile_obstack, offset_map, fip,
+ fip->variant_parts);
+
+ struct dynamic_prop prop;
+ prop.kind = PROP_VARIANT_PARTS;
+ prop.data.variant_parts
+ = ((gdb::array_view<variant_part> *)
+ obstack_copy (&objfile->objfile_obstack, &parts, sizeof (parts)));
+
+ type->add_dyn_prop (DYN_PROP_VARIANT_PARTS, prop);
+}
+
/* Create the vector of fields, and attach it to the type. */
static void
/* Record the field count, allocate space for the array of fields,
and create blank accessibility bitfields if necessary. */
- TYPE_NFIELDS (type) = nfields;
- TYPE_FIELDS (type) = (struct field *)
- TYPE_ZALLOC (type, sizeof (struct field) * nfields);
+ type->set_num_fields (nfields);
+ type->set_fields
+ ((struct field *) TYPE_ZALLOC (type, sizeof (struct field) * nfields));
if (fip->non_public_fields && cu->language != language_ada)
{
TYPE_N_BASECLASSES (type) = fip->baseclasses.size ();
}
- if (TYPE_FLAG_DISCRIMINATED_UNION (type))
- {
- struct discriminant_info *di = alloc_discriminant_info (type, -1, -1);
-
- for (int index = 0; index < nfields; ++index)
- {
- struct nextfield &field = fip->fields[index];
-
- if (field.variant.is_discriminant)
- di->discriminant_index = index;
- else if (field.variant.default_branch)
- di->default_index = index;
- else
- di->discriminants[index] = field.variant.discriminant_value;
- }
- }
+ if (!fip->variant_parts.empty ())
+ add_variant_property (fip, type, cu);
/* Copy the saved-up fields into the field vector. */
for (int i = 0; i < nfields; ++i)
= ((i < fip->baseclasses.size ()) ? fip->baseclasses[i]
: fip->fields[i - fip->baseclasses.size ()]);
- TYPE_FIELD (type, i) = field.field;
+ type->field (i) = field.field;
switch (field.accessibility)
{
case DW_ACCESS_private:
dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
struct type *type, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
struct attribute *attr;
int i;
struct fnfieldlist *flp = nullptr;
fnp->type = alloc_type (objfile);
this_type = read_type_die (die, cu);
- if (this_type && TYPE_CODE (this_type) == TYPE_CODE_FUNC)
+ if (this_type && this_type->code () == TYPE_CODE_FUNC)
{
- int nparams = TYPE_NFIELDS (this_type);
+ int nparams = this_type->num_fields ();
/* TYPE is the domain of this method, and THIS_TYPE is the type
of the method itself (TYPE_CODE_METHOD). */
smash_to_method_type (fnp->type, type,
TYPE_TARGET_TYPE (this_type),
- TYPE_FIELDS (this_type),
- TYPE_NFIELDS (this_type),
+ this_type->fields (),
+ this_type->num_fields (),
TYPE_VARARGS (this_type));
/* Handle static member functions.
/* If there is no `this' field and no DW_AT_containing_type,
we cannot actually find a base class context for the
vtable! */
- if (TYPE_NFIELDS (this_type) == 0
+ if (this_type->num_fields () == 0
|| !TYPE_FIELD_ARTIFICIAL (this_type, 0))
{
complaint (_("cannot determine context for virtual member "
struct type *pfn_type, *self_type, *new_type;
/* Check for a structure with no name and two children. */
- if (TYPE_CODE (type) != TYPE_CODE_STRUCT || TYPE_NFIELDS (type) != 2)
+ if (type->code () != TYPE_CODE_STRUCT || type->num_fields () != 2)
return;
/* Check for __pfn and __delta members. */
/* Find the type of the method. */
pfn_type = TYPE_FIELD_TYPE (type, 0);
if (pfn_type == NULL
- || TYPE_CODE (pfn_type) != TYPE_CODE_PTR
- || TYPE_CODE (TYPE_TARGET_TYPE (pfn_type)) != TYPE_CODE_FUNC)
+ || pfn_type->code () != TYPE_CODE_PTR
+ || TYPE_TARGET_TYPE (pfn_type)->code () != TYPE_CODE_FUNC)
return;
/* Look for the "this" argument. */
pfn_type = TYPE_TARGET_TYPE (pfn_type);
- if (TYPE_NFIELDS (pfn_type) == 0
+ if (pfn_type->num_fields () == 0
/* || TYPE_FIELD_TYPE (pfn_type, 0) == NULL */
- || TYPE_CODE (TYPE_FIELD_TYPE (pfn_type, 0)) != TYPE_CODE_PTR)
+ || TYPE_FIELD_TYPE (pfn_type, 0)->code () != TYPE_CODE_PTR)
return;
self_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
new_type = alloc_type (objfile);
smash_to_method_type (new_type, self_type, TYPE_TARGET_TYPE (pfn_type),
- TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type),
+ pfn_type->fields (), pfn_type->num_fields (),
TYPE_VARARGS (pfn_type));
smash_to_methodptr_type (type, new_type);
}
complaint (_("DW_AT_alignment must have constant form"
" - DIE at %s [in module %s]"),
sect_offset_str (die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name (cu->per_objfile->objfile));
return 0;
}
complaint (_("DW_AT_alignment value must not be negative"
" - DIE at %s [in module %s]"),
sect_offset_str (die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name (cu->per_objfile->objfile));
return 0;
}
align = val;
complaint (_("DW_AT_alignment value must not be zero"
" - DIE at %s [in module %s]"),
sect_offset_str (die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name (cu->per_objfile->objfile));
return 0;
}
if ((align & (align - 1)) != 0)
complaint (_("DW_AT_alignment value must be a power of 2"
" - DIE at %s [in module %s]"),
sect_offset_str (die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name (cu->per_objfile->objfile));
return 0;
}
complaint (_("DW_AT_alignment value too large"
" - DIE at %s [in module %s]"),
sect_offset_str (die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name (cu->per_objfile->objfile));
}
/* Check if the given VALUE is a valid enum dwarf_calling_convention
static struct type *
read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
struct type *type;
struct attribute *attr;
const char *name;
if (get_die_type (die, cu) != NULL)
return get_die_type (die, cu);
- TYPE_NAME (type) = full_name;
+ type->set_name (full_name);
}
else
{
/* The name is already allocated along with this objfile, so
we don't need to duplicate it for the type. */
- TYPE_NAME (type) = name;
+ type->set_name (name);
}
}
if (die->tag == DW_TAG_structure_type)
{
- TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ type->set_code (TYPE_CODE_STRUCT);
}
else if (die->tag == DW_TAG_union_type)
{
- TYPE_CODE (type) = TYPE_CODE_UNION;
- }
- else if (die->tag == DW_TAG_variant_part)
- {
- TYPE_CODE (type) = TYPE_CODE_UNION;
- TYPE_FLAG_DISCRIMINATED_UNION (type) = 1;
+ type->set_code (TYPE_CODE_UNION);
}
else
{
- TYPE_CODE (type) = TYPE_CODE_STRUCT;
+ type->set_code (TYPE_CODE_STRUCT);
}
if (cu->language == language_cplus && die->tag == DW_TAG_class_type)
TYPE_LENGTH (type) = DW_UNSND (attr);
else
{
- /* For the moment, dynamic type sizes are not supported
- by GDB's struct type. The actual size is determined
- on-demand when resolving the type of a given object,
- so set the type's length to zero for now. Otherwise,
- we record an expression as the length, and that expression
- could lead to a very large value, which could eventually
- lead to us trying to allocate that much memory when creating
- a value of that type. */
+ struct dynamic_prop prop;
+ if (attr_to_dynamic_prop (attr, die, cu, &prop, cu->addr_type ()))
+ type->add_dyn_prop (DYN_PROP_BYTE_SIZE, prop);
TYPE_LENGTH (type) = 0;
}
}
return type;
}
+static void handle_struct_member_die
+ (struct die_info *child_die,
+ struct type *type,
+ struct field_info *fi,
+ std::vector<struct symbol *> *template_args,
+ struct dwarf2_cu *cu);
+
+/* A helper for handle_struct_member_die that handles
+ DW_TAG_variant_part. */
+
+static void
+handle_variant_part (struct die_info *die, struct type *type,
+ struct field_info *fi,
+ std::vector<struct symbol *> *template_args,
+ struct dwarf2_cu *cu)
+{
+ variant_part_builder *new_part;
+ if (fi->current_variant_part == nullptr)
+ {
+ fi->variant_parts.emplace_back ();
+ new_part = &fi->variant_parts.back ();
+ }
+ else if (!fi->current_variant_part->processing_variant)
+ {
+ complaint (_("nested DW_TAG_variant_part seen "
+ "- DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_objfile->objfile));
+ return;
+ }
+ else
+ {
+ variant_field ¤t = fi->current_variant_part->variants.back ();
+ current.variant_parts.emplace_back ();
+ new_part = ¤t.variant_parts.back ();
+ }
+
+ /* When we recurse, we want callees to add to this new variant
+ part. */
+ scoped_restore save_current_variant_part
+ = make_scoped_restore (&fi->current_variant_part, new_part);
+
+ struct attribute *discr = dwarf2_attr (die, DW_AT_discr, cu);
+ if (discr == NULL)
+ {
+ /* It's a univariant form, an extension we support. */
+ }
+ else if (discr->form_is_ref ())
+ {
+ struct dwarf2_cu *target_cu = cu;
+ struct die_info *target_die = follow_die_ref (die, discr, &target_cu);
+
+ new_part->discriminant_offset = target_die->sect_off;
+ }
+ else
+ {
+ complaint (_("DW_AT_discr does not have DIE reference form"
+ " - DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_objfile->objfile));
+ }
+
+ for (die_info *child_die = die->child;
+ child_die != NULL;
+ child_die = child_die->sibling)
+ handle_struct_member_die (child_die, type, fi, template_args, cu);
+}
+
+/* A helper for handle_struct_member_die that handles
+ DW_TAG_variant. */
+
+static void
+handle_variant (struct die_info *die, struct type *type,
+ struct field_info *fi,
+ std::vector<struct symbol *> *template_args,
+ struct dwarf2_cu *cu)
+{
+ if (fi->current_variant_part == nullptr)
+ {
+ complaint (_("saw DW_TAG_variant outside DW_TAG_variant_part "
+ "- DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_objfile->objfile));
+ return;
+ }
+ if (fi->current_variant_part->processing_variant)
+ {
+ complaint (_("nested DW_TAG_variant seen "
+ "- DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_objfile->objfile));
+ return;
+ }
+
+ scoped_restore save_processing_variant
+ = make_scoped_restore (&fi->current_variant_part->processing_variant,
+ true);
+
+ fi->current_variant_part->variants.emplace_back ();
+ variant_field &variant = fi->current_variant_part->variants.back ();
+ variant.first_field = fi->fields.size ();
+
+ /* In a variant we want to get the discriminant and also add a
+ field for our sole member child. */
+ struct attribute *discr = dwarf2_attr (die, DW_AT_discr_value, cu);
+ if (discr == nullptr)
+ {
+ discr = dwarf2_attr (die, DW_AT_discr_list, cu);
+ if (discr == nullptr || DW_BLOCK (discr)->size == 0)
+ variant.default_branch = true;
+ else
+ variant.discr_list_data = DW_BLOCK (discr);
+ }
+ else
+ variant.discriminant_value = DW_UNSND (discr);
+
+ for (die_info *variant_child = die->child;
+ variant_child != NULL;
+ variant_child = variant_child->sibling)
+ handle_struct_member_die (variant_child, type, fi, template_args, cu);
+
+ variant.last_field = fi->fields.size ();
+}
+
/* A helper for process_structure_scope that handles a single member
DIE. */
struct dwarf2_cu *cu)
{
if (child_die->tag == DW_TAG_member
- || child_die->tag == DW_TAG_variable
- || child_die->tag == DW_TAG_variant_part)
+ || child_die->tag == DW_TAG_variable)
{
/* NOTE: carlton/2002-11-05: A C++ static data member
should be a DW_TAG_member that is a declaration, but
if (arg != NULL)
template_args->push_back (arg);
}
+ else if (child_die->tag == DW_TAG_variant_part)
+ handle_variant_part (child_die, type, fi, template_args, cu);
else if (child_die->tag == DW_TAG_variant)
- {
- /* In a variant we want to get the discriminant and also add a
- field for our sole member child. */
- struct attribute *discr = dwarf2_attr (child_die, DW_AT_discr_value, cu);
-
- for (die_info *variant_child = child_die->child;
- variant_child != NULL;
- variant_child = variant_child->sibling)
- {
- if (variant_child->tag == DW_TAG_member)
- {
- handle_struct_member_die (variant_child, type, fi,
- template_args, cu);
- /* Only handle the one. */
- break;
- }
- }
-
- /* We don't handle this but we might as well report it if we see
- it. */
- if (dwarf2_attr (child_die, DW_AT_discr_list, cu) != nullptr)
- complaint (_("DW_AT_discr_list is not supported yet"
- " - DIE at %s [in module %s]"),
- sect_offset_str (child_die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
-
- /* The first field was just added, so we can stash the
- discriminant there. */
- gdb_assert (!fi->fields.empty ());
- if (discr == NULL)
- fi->fields.back ().variant.default_branch = true;
- else
- fi->fields.back ().variant.discriminant_value = DW_UNSND (discr);
- }
+ handle_variant (child_die, type, fi, template_args, cu);
}
/* Finish creating a structure or union type, including filling in
static void
process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
struct die_info *child_die;
struct type *type;
if (type == NULL)
type = read_structure_type (die, cu);
- /* When reading a DW_TAG_variant_part, we need to notice when we
- read the discriminant member, so we can record it later in the
- discriminant_info. */
- bool is_variant_part = TYPE_FLAG_DISCRIMINATED_UNION (type);
- sect_offset discr_offset {};
bool has_template_parameters = false;
-
- if (is_variant_part)
- {
- struct attribute *discr = dwarf2_attr (die, DW_AT_discr, cu);
- if (discr == NULL)
- {
- /* Maybe it's a univariant form, an extension we support.
- In this case arrange not to check the offset. */
- is_variant_part = false;
- }
- else if (discr->form_is_ref ())
- {
- struct dwarf2_cu *target_cu = cu;
- struct die_info *target_die = follow_die_ref (die, discr, &target_cu);
-
- discr_offset = target_die->sect_off;
- }
- else
- {
- complaint (_("DW_AT_discr does not have DIE reference form"
- " - DIE at %s [in module %s]"),
- sect_offset_str (die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
- is_variant_part = false;
- }
- }
-
if (die->child != NULL && ! die_is_declaration (die, cu))
{
struct field_info fi;
while (child_die && child_die->tag)
{
handle_struct_member_die (child_die, type, &fi, &template_args, cu);
-
- if (is_variant_part && discr_offset == child_die->sect_off)
- fi.fields.back ().variant.is_discriminant = true;
-
child_die = child_die->sibling;
}
int i;
/* Our own class provides vtbl ptr. */
- for (i = TYPE_NFIELDS (t) - 1;
+ for (i = t->num_fields () - 1;
i >= TYPE_N_BASECLASSES (t);
--i)
{
if (i < TYPE_N_BASECLASSES (t))
complaint (_("virtual function table pointer "
"not found when defining class '%s'"),
- TYPE_NAME (type) ? TYPE_NAME (type) : "");
+ type->name () ? type->name () : "");
}
else
{
int i;
- for (i = TYPE_NFIELDS (type) - 1;
+ for (i = type->num_fields () - 1;
i >= TYPE_N_BASECLASSES (type);
--i)
{
these DIEs are identified by the fact that they have no byte_size
attribute, and a declaration attribute. */
if (dwarf2_attr (die, DW_AT_byte_size, cu) != NULL
- || !die_is_declaration (die, cu))
+ || !die_is_declaration (die, cu)
+ || dwarf2_attr (die, DW_AT_signature, cu) != NULL)
{
struct symbol *sym = new_symbol (die, type, cu);
}
}
-/* Assuming DIE is an enumeration type, and TYPE is its associated type,
- update TYPE using some information only available in DIE's children. */
+/* Assuming DIE is an enumeration type, and TYPE is its associated
+ type, update TYPE using some information only available in DIE's
+ children. In particular, the fields are computed. */
static void
update_enumeration_type_from_children (struct die_info *die,
int flag_enum = 1;
auto_obstack obstack;
+ std::vector<struct field> fields;
for (child_die = die->child;
child_die != NULL && child_die->tag;
flag_enum = 0;
}
- /* If we already know that the enum type is neither unsigned, nor
- a flag type, no need to look at the rest of the enumerates. */
- if (!unsigned_enum && !flag_enum)
- break;
+ fields.emplace_back ();
+ struct field &field = fields.back ();
+ FIELD_NAME (field) = dwarf2_physname (name, child_die, cu);
+ SET_FIELD_ENUMVAL (field, value);
+ }
+
+ if (!fields.empty ())
+ {
+ type->set_num_fields (fields.size ());
+ type->set_fields
+ ((struct field *)
+ TYPE_ALLOC (type, sizeof (struct field) * fields.size ()));
+ memcpy (type->fields (), fields.data (),
+ sizeof (struct field) * fields.size ());
}
if (unsigned_enum)
static struct type *
read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
struct type *type;
struct attribute *attr;
const char *name;
type = alloc_type (objfile);
- TYPE_CODE (type) = TYPE_CODE_ENUM;
+ type->set_code (TYPE_CODE_ENUM);
name = dwarf2_full_name (NULL, die, cu);
if (name != NULL)
- TYPE_NAME (type) = name;
+ type->set_name (name);
attr = dwarf2_attr (die, DW_AT_type, cu);
if (attr != NULL)
if (die_is_declaration (die, cu))
TYPE_STUB (type) = 1;
- /* Finish the creation of this type by using the enum's children.
- We must call this even when the underlying type has been provided
- so that we can determine if we're looking at a "flag" enum. */
- update_enumeration_type_from_children (die, type, cu);
-
/* If this type has an underlying type that is not a stub, then we
may use its attributes. We always use the "unsigned" attribute
in this situation, because ordinarily we guess whether the type
the underlying type if needed. */
if (TYPE_TARGET_TYPE (type) != NULL && !TYPE_STUB (TYPE_TARGET_TYPE (type)))
{
- TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TYPE_TARGET_TYPE (type));
+ struct type *underlying_type = TYPE_TARGET_TYPE (type);
+ underlying_type = check_typedef (underlying_type);
+ TYPE_UNSIGNED (type) = TYPE_UNSIGNED (underlying_type);
if (TYPE_LENGTH (type) == 0)
- TYPE_LENGTH (type) = TYPE_LENGTH (TYPE_TARGET_TYPE (type));
+ TYPE_LENGTH (type) = TYPE_LENGTH (underlying_type);
if (TYPE_RAW_ALIGN (type) == 0
- && TYPE_RAW_ALIGN (TYPE_TARGET_TYPE (type)) != 0)
- set_type_align (type, TYPE_RAW_ALIGN (TYPE_TARGET_TYPE (type)));
+ && TYPE_RAW_ALIGN (underlying_type) != 0)
+ set_type_align (type, TYPE_RAW_ALIGN (underlying_type));
}
TYPE_DECLARED_CLASS (type) = dwarf2_flag_true_p (die, DW_AT_enum_class, cu);
- return set_die_type (die, type, cu);
+ set_die_type (die, type, cu);
+
+ /* Finish the creation of this type by using the enum's children.
+ Note that, as usual, this must come after set_die_type to avoid
+ infinite recursion when trying to compute the names of the
+ enumerators. */
+ update_enumeration_type_from_children (die, type, cu);
+
+ return type;
}
/* Given a pointer to a die which begins an enumeration, process all
if (die->child != NULL)
{
struct die_info *child_die;
- struct symbol *sym;
- std::vector<struct field> fields;
const char *name;
child_die = die->child;
}
else
{
- name = dwarf2_name (child_die, cu);
- if (name)
- {
- sym = new_symbol (child_die, this_type, cu);
-
- fields.emplace_back ();
- struct field &field = fields.back ();
-
- FIELD_NAME (field) = sym->linkage_name ();
- FIELD_TYPE (field) = NULL;
- SET_FIELD_ENUMVAL (field, SYMBOL_VALUE (sym));
- FIELD_BITSIZE (field) = 0;
- }
+ name = dwarf2_name (child_die, cu);
+ if (name)
+ new_symbol (child_die, this_type, cu);
}
child_die = child_die->sibling;
}
-
- if (!fields.empty ())
- {
- TYPE_NFIELDS (this_type) = fields.size ();
- TYPE_FIELDS (this_type) = (struct field *)
- TYPE_ALLOC (this_type, sizeof (struct field) * fields.size ());
- memcpy (TYPE_FIELDS (this_type), fields.data (),
- sizeof (struct field) * fields.size ());
- }
}
/* If we are reading an enum from a .debug_types unit, and the enum
static struct type *
read_array_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
struct die_info *child_die;
struct type *type;
struct type *element_type, *range_type, *index_type;
if (attr != NULL)
{
int stride_ok;
- struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
+ struct type *prop_type = cu->addr_sized_int_type (false);
byte_stride_prop
= (struct dynamic_prop *) alloca (sizeof (struct dynamic_prop));
complaint (_("unable to read array DW_AT_byte_stride "
" - DIE at %s [in module %s]"),
sect_offset_str (die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name (cu->per_objfile->objfile));
/* Ignore this attribute. We will likely not be able to print
arrays of this type correctly, but there is little we can do
to help if we cannot read the attribute's value. */
name = dwarf2_name (die, cu);
if (name)
- TYPE_NAME (type) = name;
+ type->set_name (name);
maybe_set_alignment (cu, die, type);
struct attribute *member_loc,
struct dwarf2_cu *cu)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
- struct objfile *objfile = dwarf2_per_objfile->objfile;
+ dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ struct objfile *objfile = per_objfile->objfile;
struct dwarf2_locexpr_baton *baton;
gdb_byte *ptr;
unsigned int cu_off;
- enum bfd_endian byte_order = gdbarch_byte_order (get_objfile_arch (objfile));
+ enum bfd_endian byte_order = gdbarch_byte_order (objfile->arch ());
LONGEST offset = 0;
gdb_assert (common_loc && member_loc);
|| member_loc->form_is_constant ());
baton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton);
+ baton->per_objfile = per_objfile;
baton->per_cu = cu->per_cu;
gdb_assert (baton->per_cu);
if (die->child != NULL)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
struct die_info *child_die;
size_t n_entries = 0, size;
struct common_block *common_block;
static struct type *
read_namespace_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
const char *previous_prefix, *name;
int is_anonymous;
struct type *type;
static void
read_namespace (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
int is_anonymous;
/* Add a symbol associated to this if we haven't seen the namespace
std::vector<const char *> excludes;
add_using_directive (using_directives (cu),
- previous_prefix, TYPE_NAME (type), NULL,
+ previous_prefix, type->name (), NULL,
NULL, excludes, 0, &objfile->objfile_obstack);
}
}
static struct type *
read_module_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
const char *module_name;
struct type *type;
static struct type *
read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct gdbarch *gdbarch
- = get_objfile_arch (cu->per_cu->dwarf2_per_objfile->objfile);
+ struct gdbarch *gdbarch = cu->per_objfile->objfile->arch ();
struct comp_unit_head *cu_header = &cu->header;
struct type *type;
struct attribute *attr_byte_size;
complaint (_("Invalid DW_AT_alignment"
" - DIE at %s [in module %s]"),
sect_offset_str (die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name (cu->per_objfile->objfile));
}
else
{
if (type)
return type;
- if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_METHOD)
+ if (check_typedef (to_type)->code () == TYPE_CODE_METHOD)
type = lookup_methodptr_type (to_type);
- else if (TYPE_CODE (check_typedef (to_type)) == TYPE_CODE_FUNC)
+ else if (check_typedef (to_type)->code () == TYPE_CODE_FUNC)
{
- struct type *new_type
- = alloc_type (cu->per_cu->dwarf2_per_objfile->objfile);
+ struct type *new_type = alloc_type (cu->per_objfile->objfile);
smash_to_method_type (new_type, domain, TYPE_TARGET_TYPE (to_type),
- TYPE_FIELDS (to_type), TYPE_NFIELDS (to_type),
+ to_type->fields (), to_type->num_fields (),
TYPE_VARARGS (to_type));
type = lookup_methodptr_type (new_type);
}
base_type = copy_type (base_type);
inner_array = base_type;
- while (TYPE_CODE (TYPE_TARGET_TYPE (inner_array)) == TYPE_CODE_ARRAY)
+ while (TYPE_TARGET_TYPE (inner_array)->code () == TYPE_CODE_ARRAY)
{
TYPE_TARGET_TYPE (inner_array) =
copy_type (TYPE_TARGET_TYPE (inner_array));
/* In case the const qualifier is applied to an array type, the element type
is so qualified, not the array type (section 6.7.3 of C99). */
- if (TYPE_CODE (base_type) == TYPE_CODE_ARRAY)
+ if (base_type->code () == TYPE_CODE_ARRAY)
return add_array_cv_type (die, cu, base_type, 1, 0);
cv_type = make_cv_type (1, TYPE_VOLATILE (base_type), base_type, 0);
/* In case the volatile qualifier is applied to an array type, the
element type is so qualified, not the array type (section 6.7.3
of C99). */
- if (TYPE_CODE (base_type) == TYPE_CODE_ARRAY)
+ if (base_type->code () == TYPE_CODE_ARRAY)
return add_array_cv_type (die, cu, base_type, 0, 1);
cv_type = make_cv_type (TYPE_CONST (base_type), 1, base_type, 0);
static struct type *
read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct objfile *objfile = cu->per_objfile->objfile;
+ struct gdbarch *gdbarch = objfile->arch ();
struct type *type, *range_type, *index_type, *char_type;
struct attribute *attr;
struct dynamic_prop prop;
/* Pass 0 as the default as we know this attribute is constant
and the default value will not be returned. */
LONGEST sz = len->constant_value (0);
- prop_type = cu->per_cu->int_type (sz, true);
+ prop_type = cu->per_objfile->int_type (sz, true);
}
else
{
/* If the size is not specified then we assume it is the size of
an address on this target. */
- prop_type = cu->per_cu->addr_sized_int_type (true);
+ prop_type = cu->addr_sized_int_type (true);
}
/* Convert the attribute into a dynamic property. */
static struct type *
read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
struct type *type; /* Type that this function returns. */
struct type *ftype; /* Function that returns above type. */
struct attribute *attr;
}
/* Allocate storage for parameters and fill them in. */
- TYPE_NFIELDS (ftype) = nparams;
- TYPE_FIELDS (ftype) = (struct field *)
- TYPE_ZALLOC (ftype, nparams * sizeof (struct field));
+ ftype->set_num_fields (nparams);
+ ftype->set_fields
+ ((struct field *) TYPE_ZALLOC (ftype, nparams * sizeof (struct field)));
/* TYPE_FIELD_TYPE must never be NULL. Pre-fill the array to ensure it
even if we error out during the parameters reading below. */
static struct type *
read_typedef (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
const char *name = NULL;
struct type *this_type, *target_type;
dwarf2_init_float_type (struct objfile *objfile, int bits, const char *name,
const char *name_hint, enum bfd_endian byte_order)
{
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
const struct floatformat **format;
struct type *type;
int bits, const char *name_hint,
enum bfd_endian byte_order)
{
- gdbarch *gdbarch = get_objfile_arch (objfile);
+ gdbarch *gdbarch = objfile->arch ();
struct type *tt = nullptr;
/* Try to find a suitable floating point builtin type of size BITS.
if (tt != nullptr && TYPE_LENGTH (tt) * TARGET_CHAR_BIT != bits)
tt = nullptr;
- const char *name = (tt == nullptr) ? nullptr : TYPE_NAME (tt);
+ const char *name = (tt == nullptr) ? nullptr : tt->name ();
return dwarf2_init_float_type (objfile, bits, name, name_hint, byte_order);
}
static struct type *
read_base_type (struct die_info *die, struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
struct type *type;
struct attribute *attr;
int encoding = 0, bits = 0;
if (!name)
complaint (_("DW_AT_name missing from DW_TAG_base_type"));
- arch = get_objfile_arch (objfile);
+ arch = objfile->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (arch);
attr = dwarf2_attr (die, DW_AT_endianity, cu);
case DW_ATE_complex_float:
type = dwarf2_init_complex_target_type (cu, objfile, bits / 2, name,
byte_order);
- type = init_complex_type (objfile, name, type);
+ if (type->code () == TYPE_CODE_ERROR)
+ {
+ if (name == nullptr)
+ {
+ struct obstack *obstack
+ = &cu->per_objfile->objfile->objfile_obstack;
+ name = obconcat (obstack, "_Complex ", type->name (),
+ nullptr);
+ }
+ type = init_type (objfile, TYPE_CODE_ERROR, bits, name);
+ }
+ else
+ type = init_complex_type (name, type);
break;
case DW_ATE_decimal_float:
type = init_decfloat_type (objfile, bits, name);
struct type *default_type)
{
struct dwarf2_property_baton *baton;
- struct obstack *obstack
- = &cu->per_cu->dwarf2_per_objfile->objfile->objfile_obstack;
+ dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ struct objfile *objfile = per_objfile->objfile;
+ struct obstack *obstack = &objfile->objfile_obstack;
gdb_assert (default_type != NULL);
baton = XOBNEW (obstack, struct dwarf2_property_baton);
baton->property_type = default_type;
baton->locexpr.per_cu = cu->per_cu;
+ baton->locexpr.per_objfile = per_objfile;
baton->locexpr.size = DW_BLOCK (attr)->size;
baton->locexpr.data = DW_BLOCK (attr)->data;
switch (attr->name)
baton = XOBNEW (obstack, struct dwarf2_property_baton);
baton->property_type = die_type (target_die, target_cu);
baton->locexpr.per_cu = cu->per_cu;
+ baton->locexpr.per_objfile = per_objfile;
baton->locexpr.size = DW_BLOCK (target_attr)->size;
baton->locexpr.data = DW_BLOCK (target_attr)->data;
baton->locexpr.is_reference = true;
/* See read.h. */
struct type *
-dwarf2_per_cu_data::int_type (int size_in_bytes, bool unsigned_p) const
+dwarf2_per_objfile::int_type (int size_in_bytes, bool unsigned_p) const
{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
struct type *int_type;
/* Helper macro to examine the various builtin types. */
/* See read.h. */
struct type *
-dwarf2_per_cu_data::addr_sized_int_type (bool unsigned_p) const
+dwarf2_cu::addr_sized_int_type (bool unsigned_p) const
{
- int addr_size = this->addr_size ();
- return int_type (addr_size, unsigned_p);
+ 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
GCC produces an empty range DIE.
FIXME: muller/2010-05-28: Possible references to object for low bound,
high bound or count are not yet handled by this code. */
- if (TYPE_CODE (index_type) == TYPE_CODE_VOID)
- index_type = cu->per_cu->addr_sized_int_type (false);
+ if (index_type->code () == TYPE_CODE_VOID)
+ index_type = cu->addr_sized_int_type (false);
return index_type;
}
complaint (_("Missing DW_AT_lower_bound "
"- DIE at %s [in module %s]"),
sect_offset_str (die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name (cu->per_objfile->objfile));
struct attribute *attr_ub, *attr_count;
attr = attr_ub = dwarf2_attr (die, DW_AT_upper_bound, cu);
complaint (_("Unresolved DW_AT_upper_bound "
"- DIE at %s [in module %s]"),
sect_offset_str (die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name (cu->per_objfile->objfile));
if (attr_count != NULL)
complaint (_("Unresolved DW_AT_count "
"- DIE at %s [in module %s]"),
sect_offset_str (die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name (cu->per_objfile->objfile));
}
}
attribute *attr_byte_stride = dwarf2_attr (die, DW_AT_byte_stride, cu);
if (attr_byte_stride != nullptr)
{
- struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
+ struct type *prop_type = cu->addr_sized_int_type (false);
attr_to_dynamic_prop (attr_byte_stride, die, cu, &byte_stride_prop,
prop_type);
}
complaint (_("Found DW_AT_bit_stride and DW_AT_byte_stride "
"- DIE at %s [in module %s]"),
sect_offset_str (die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name (cu->per_objfile->objfile));
attr_bit_stride = nullptr;
}
else
{
- struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
+ struct type *prop_type = cu->addr_sized_int_type (false);
attr_to_dynamic_prop (attr_bit_stride, die, cu, &bit_stride_prop,
prop_type);
}
name = dwarf2_name (die, cu);
if (name)
- TYPE_NAME (range_type) = name;
+ range_type->set_name (name);
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr != nullptr)
{
struct type *type;
- type = init_type (cu->per_cu->dwarf2_per_objfile->objfile, TYPE_CODE_VOID,0,
- NULL);
- TYPE_NAME (type) = dwarf2_name (die, cu);
+ type = init_type (cu->per_objfile->objfile, TYPE_CODE_VOID, 0, NULL);
+ type->set_name (dwarf2_name (die, cu));
/* In Ada, an unspecified type is typically used when the description
of the type is deferred to a different unit. When encountering
if (attr != nullptr)
cu->str_offsets_base = DW_UNSND (attr);
+ attr = die->attr (DW_AT_loclists_base);
+ if (attr != nullptr)
+ cu->loclist_base = DW_UNSND (attr);
+
auto maybe_addr_base = die->addr_base ();
if (maybe_addr_base.has_value ())
cu->addr_base = *maybe_addr_base;
const gdb_byte *info_ptr, int building_psymtab)
{
struct dwarf2_cu *cu = reader->cu;
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
struct partial_die_info *parent_die, *last_die, *first_die = NULL;
unsigned int bytes_read;
unsigned int load_all = 0;
|| pdi.tag == DW_TAG_base_type
|| pdi.tag == DW_TAG_subrange_type))
{
- if (building_psymtab && pdi.name != NULL)
- add_psymbol_to_list (pdi.name, false,
- VAR_DOMAIN, LOC_TYPEDEF, -1,
- psymbol_placement::STATIC,
- 0, cu->language, objfile);
+ if (building_psymtab && pdi.raw_name != NULL)
+ add_partial_symbol (&pdi, cu);
+
info_ptr = locate_pdi_sibling (reader, &pdi, info_ptr);
continue;
}
&& parent_die->tag == DW_TAG_enumeration_type
&& parent_die->has_specification == 0)
{
- if (pdi.name == NULL)
+ if (pdi.raw_name == NULL)
complaint (_("malformed enumerator DIE ignored"));
else if (building_psymtab)
- add_psymbol_to_list (pdi.name, false,
- VAR_DOMAIN, LOC_CONST, -1,
- cu->language == language_cplus
- ? psymbol_placement::GLOBAL
- : psymbol_placement::STATIC,
- 0, cu->language, objfile);
+ add_partial_symbol (&pdi, cu);
info_ptr = locate_pdi_sibling (reader, &pdi, info_ptr);
continue;
|| last_die->tag == DW_TAG_enumeration_type
|| (cu->language == language_cplus
&& last_die->tag == DW_TAG_subprogram
- && (last_die->name == NULL
- || strchr (last_die->name, '<') == NULL))
+ && (last_die->raw_name == NULL
+ || strchr (last_die->raw_name, '<') == NULL))
|| (cu->language != language_c
&& (last_die->tag == DW_TAG_class_type
|| last_die->tag == DW_TAG_interface_type
{
}
+/* See class definition. */
+
+const char *
+partial_die_info::name (dwarf2_cu *cu)
+{
+ if (!canonical_name && raw_name != nullptr)
+ {
+ struct objfile *objfile = cu->per_objfile->objfile;
+ raw_name = dwarf2_canonicalize_name (raw_name, cu, objfile);
+ canonical_name = 1;
+ }
+
+ return raw_name;
+}
+
/* Read a minimal amount of information into the minimal die structure.
INFO_PTR should point just after the initial uleb128 of a DIE. */
const struct abbrev_info &abbrev, const gdb_byte *info_ptr)
{
struct dwarf2_cu *cu = reader->cu;
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
unsigned int i;
int has_low_pc_attr = 0;
int has_high_pc_attr = 0;
int high_pc_relative = 0;
- std::vector<struct attribute> attr_vec (abbrev.num_attrs);
for (i = 0; i < abbrev.num_attrs; ++i)
{
+ attribute attr;
bool need_reprocess;
- info_ptr = read_attribute (reader, &attr_vec[i], &abbrev.attrs[i],
+ info_ptr = read_attribute (reader, &attr, &abbrev.attrs[i],
info_ptr, &need_reprocess);
/* String and address offsets that need to do the reprocessing have
already been read at this point, so there is no need to wait until
the loop terminates to do the reprocessing. */
if (need_reprocess)
- read_attribute_reprocess (reader, &attr_vec[i]);
- attribute &attr = attr_vec[i];
+ read_attribute_reprocess (reader, &attr);
/* Store the data if it is of an attribute we want to keep in a
partial symbol table. */
switch (attr.name)
case DW_TAG_enumerator:
/* These tags always have simple identifiers already; no need
to canonicalize them. */
- name = DW_STRING (&attr);
+ canonical_name = 1;
+ raw_name = DW_STRING (&attr);
break;
default:
- {
- struct objfile *objfile = dwarf2_per_objfile->objfile;
-
- name
- = dwarf2_canonicalize_name (DW_STRING (&attr), cu, objfile);
- }
+ canonical_name = 0;
+ raw_name = DW_STRING (&attr);
break;
}
break;
/* Note that both forms of linkage name might appear. We
assume they will be the same, and we only store the last
one we see. */
- linkage_name = DW_STRING (&attr);
+ linkage_name = attr.value_as_string ();
+ /* rustc emits invalid values for DW_AT_linkage_name. Ignore these.
+ See https://github.com/rust-lang/rust/issues/32925. */
+ if (cu->language == language_rust && linkage_name != NULL
+ && strchr (linkage_name, '{') != NULL)
+ linkage_name = NULL;
break;
case DW_AT_low_pc:
has_low_pc_attr = 1;
Really, though, this is just a workaround for the fact that gdb
doesn't store both the name and the linkage name. */
if (cu->language == language_ada && linkage_name != nullptr)
- name = linkage_name;
+ raw_name = linkage_name;
if (high_pc_relative)
highpc += lowpc;
labels are not in the output, so the relocs get a value of 0.
If this is a discarded function, mark the pc bounds as invalid,
so that GDB will ignore it. */
- if (lowpc == 0 && !dwarf2_per_objfile->has_section_at_zero)
+ if (lowpc == 0 && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
complaint (_("DW_AT_low_pc %s is zero "
"for DIE at %s [in module %s]"),
else if (lowpc >= highpc)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
complaint (_("DW_AT_low_pc %s is not < DW_AT_high_pc %s "
"for DIE at %s [in module %s]"),
static const struct cu_partial_die_info
find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct dwarf2_per_cu_data *per_cu = NULL;
struct partial_die_info *pd = NULL;
if (offset_in_dwz == cu->per_cu->is_dwz
return { cu, pd };
/* We missed recording what we needed.
Load all dies and try again. */
- per_cu = cu->per_cu;
}
else
{
sect_offset_str (cu->header.sect_off), sect_offset_str (sect_off),
bfd_get_filename (objfile->obfd));
}
- per_cu = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
- dwarf2_per_objfile);
+ dwarf2_per_cu_data *per_cu
+ = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
+ dwarf2_per_objfile);
- if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
- load_partial_comp_unit (per_cu);
+ cu = dwarf2_per_objfile->get_cu (per_cu);
+ if (cu == NULL || cu->partial_dies == NULL)
+ load_partial_comp_unit (per_cu, dwarf2_per_objfile, nullptr);
- per_cu->cu->last_used = 0;
- pd = per_cu->cu->find_partial_die (sect_off);
+ cu = dwarf2_per_objfile->get_cu (per_cu);
+
+ cu->last_used = 0;
+ pd = cu->find_partial_die (sect_off);
}
/* If we didn't find it, and not all dies have been loaded,
load them all and try again. */
- if (pd == NULL && per_cu->load_all_dies == 0)
+ if (pd == NULL && cu->per_cu->load_all_dies == 0)
{
- per_cu->load_all_dies = 1;
+ cu->per_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
DIEs alone (which can still be in use, e.g. in scan_partial_symbols),
and clobber THIS_CU->cu->partial_dies with the hash table for the new
set. */
- load_partial_comp_unit (per_cu);
+ load_partial_comp_unit (cu->per_cu, dwarf2_per_objfile, cu);
- pd = per_cu->cu->find_partial_die (sect_off);
+ pd = cu->find_partial_die (sect_off);
}
if (pd == NULL)
_("could not find partial DIE %s "
"in cache [from module %s]\n"),
sect_offset_str (sect_off), bfd_get_filename (objfile->obfd));
- return { per_cu->cu, pd };
+ return { cu, pd };
}
/* See if we can figure out if the class lives in a namespace. We do
child_pdi->linkage_name));
if (actual_class_name != NULL)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct_pdi->name = objfile->intern (actual_class_name.get ());
+ struct objfile *objfile = cu->per_objfile->objfile;
+ struct_pdi->raw_name = objfile->intern (actual_class_name.get ());
+ struct_pdi->canonical_name = 1;
}
break;
}
}
}
+/* Return true if a DIE with TAG may have the DW_AT_const_value
+ attribute. */
+
+static bool
+can_have_DW_AT_const_value_p (enum dwarf_tag tag)
+{
+ switch (tag)
+ {
+ case DW_TAG_constant:
+ case DW_TAG_enumerator:
+ case DW_TAG_formal_parameter:
+ case DW_TAG_template_value_param:
+ case DW_TAG_variable:
+ return true;
+ }
+
+ return false;
+}
+
void
partial_die_info::fixup (struct dwarf2_cu *cu)
{
/* If we found a reference attribute and the DIE has no name, try
to find a name in the referred to DIE. */
- if (name == NULL && has_specification)
+ if (raw_name == NULL && has_specification)
{
struct partial_die_info *spec_die;
spec_die->fixup (cu);
- if (spec_die->name)
+ if (spec_die->raw_name)
{
- name = spec_die->name;
+ raw_name = spec_die->raw_name;
+ canonical_name = spec_die->canonical_name;
/* Copy DW_AT_external attribute if it is set. */
if (spec_die->is_external)
}
}
+ if (!has_const_value && has_specification
+ && can_have_DW_AT_const_value_p (tag))
+ {
+ struct partial_die_info *spec_die;
+
+ auto res = find_partial_die (spec_offset, spec_is_dwz, cu);
+ spec_die = res.pdi;
+ cu = res.cu;
+
+ spec_die->fixup (cu);
+
+ if (spec_die->has_const_value)
+ {
+ /* Copy DW_AT_const_value attribute if it is set. */
+ has_const_value = spec_die->has_const_value;
+ }
+ }
+
/* Set default names for some unnamed DIEs. */
- if (name == NULL && tag == DW_TAG_namespace)
- name = CP_ANONYMOUS_NAMESPACE_STR;
+ if (raw_name == NULL && tag == DW_TAG_namespace)
+ {
+ raw_name = CP_ANONYMOUS_NAMESPACE_STR;
+ canonical_name = 1;
+ }
/* If there is no parent die to provide a namespace, and there are
children, see if we can determine the namespace from their linkage
name. */
if (cu->language == language_cplus
- && !cu->per_cu->dwarf2_per_objfile->types.empty ()
+ && !cu->per_objfile->per_bfd->types.empty ()
&& die_parent == NULL
&& has_children
&& (tag == DW_TAG_class_type
/* GCC might emit a nameless struct or union that has a linkage
name. See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510. */
- if (name == NULL
+ if (raw_name == NULL
&& (tag == DW_TAG_class_type
|| tag == DW_TAG_interface_type
|| tag == DW_TAG_structure_type
else
base = demangled.get ();
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- name = objfile->intern (base);
+ struct objfile *objfile = cu->per_objfile->objfile;
+ raw_name = objfile->intern (base);
+ canonical_name = 1;
}
}
fixup_called = 1;
}
+/* Read the .debug_loclists header contents from the given SECTION in the
+ HEADER. */
+static void
+read_loclist_header (struct loclist_header *header,
+ struct dwarf2_section_info *section)
+{
+ unsigned int bytes_read;
+ bfd *abfd = section->get_bfd_owner ();
+ const gdb_byte *info_ptr = section->buffer;
+ header->length = read_initial_length (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ header->version = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ header->addr_size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ header->segment_collector_size = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ header->offset_entry_count = read_4_bytes (abfd, info_ptr);
+}
+
+/* Return the DW_AT_loclists_base value for the CU. */
+static ULONGEST
+lookup_loclist_base (struct dwarf2_cu *cu)
+{
+ /* For the .dwo unit, the loclist_base points to the first offset following
+ the header. The header consists of the following entities-
+ 1. Unit Length (4 bytes for 32 bit DWARF format, and 12 bytes for the 64
+ bit format)
+ 2. version (2 bytes)
+ 3. address size (1 byte)
+ 4. segment selector size (1 byte)
+ 5. offset entry count (4 bytes)
+ These sizes are derived as per the DWARFv5 standard. */
+ if (cu->dwo_unit != nullptr)
+ {
+ if (cu->header.initial_length_size == 4)
+ return LOCLIST_HEADER_SIZE32;
+ return LOCLIST_HEADER_SIZE64;
+ }
+ return cu->loclist_base;
+}
+
+/* Given a DW_FORM_loclistx value LOCLIST_INDEX, fetch the offset from the
+ array of offsets in the .debug_loclists section. */
+static CORE_ADDR
+read_loclist_index (struct dwarf2_cu *cu, ULONGEST loclist_index)
+{
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
+ bfd *abfd = objfile->obfd;
+ ULONGEST loclist_base = lookup_loclist_base (cu);
+ struct dwarf2_section_info *section = cu_debug_loc_section (cu);
+
+ section->read (objfile);
+ if (section->buffer == NULL)
+ complaint (_("DW_FORM_loclistx used without .debug_loclists "
+ "section [in module %s]"), objfile_name (objfile));
+ struct loclist_header header;
+ read_loclist_header (&header, section);
+ if (loclist_index >= header.offset_entry_count)
+ complaint (_("DW_FORM_loclistx pointing outside of "
+ ".debug_loclists offset array [in module %s]"),
+ objfile_name (objfile));
+ if (loclist_base + loclist_index * cu->header.offset_size
+ >= section->size)
+ complaint (_("DW_FORM_loclistx pointing outside of "
+ ".debug_loclists section [in module %s]"),
+ objfile_name (objfile));
+ const gdb_byte *info_ptr
+ = section->buffer + loclist_base + loclist_index * cu->header.offset_size;
+
+ if (cu->header.offset_size == 4)
+ return bfd_get_32 (abfd, info_ptr) + loclist_base;
+ else
+ return bfd_get_64 (abfd, info_ptr) + loclist_base;
+}
+
/* Process the attributes that had to be skipped in the first round. These
attributes are the ones that need str_offsets_base or addr_base attributes.
They could not have been processed in the first round, because at the time
case DW_FORM_GNU_addr_index:
DW_ADDR (attr) = read_addr_index (cu, DW_UNSND (attr));
break;
+ case DW_FORM_loclistx:
+ DW_UNSND (attr) = read_loclist_index (cu, DW_UNSND (attr));
+ break;
case DW_FORM_strx:
case DW_FORM_strx1:
case DW_FORM_strx2:
bool *need_reprocess)
{
struct dwarf2_cu *cu = reader->cu;
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
bfd *abfd = reader->abfd;
struct comp_unit_head *cu_header = &cu->header;
unsigned int bytes_read;
info_ptr += bytes_read;
break;
case DW_FORM_addr:
- DW_ADDR (attr) = cu->header.read_address (abfd, info_ptr, &bytes_read);
- DW_ADDR (attr) = gdbarch_adjust_dwarf2_addr (gdbarch, DW_ADDR (attr));
- info_ptr += bytes_read;
+ {
+ struct gdbarch *gdbarch = objfile->arch ();
+ DW_ADDR (attr) = cu->header.read_address (abfd, info_ptr, &bytes_read);
+ DW_ADDR (attr) = gdbarch_adjust_dwarf2_addr (gdbarch, DW_ADDR (attr));
+ info_ptr += bytes_read;
+ }
break;
case DW_FORM_block2:
blk = dwarf_alloc_block (cu);
DW_UNSND (attr) = cu->header.read_offset (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
break;
+ case DW_FORM_loclistx:
+ {
+ *need_reprocess = true;
+ DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ }
+ break;
case DW_FORM_string:
DW_STRING (attr) = read_direct_string (abfd, info_ptr, &bytes_read);
DW_STRING_IS_CANONICAL (attr) = 0;
/* FALLTHROUGH */
case DW_FORM_GNU_strp_alt:
{
- struct dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+ dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
LONGEST str_offset = cu_header->read_offset (abfd, info_ptr,
&bytes_read);
read_indirect_string_at_offset (struct dwarf2_per_objfile *dwarf2_per_objfile,
LONGEST str_offset)
{
- return dwarf2_per_objfile->str.read_string (dwarf2_per_objfile->objfile,
- str_offset, "DW_FORM_strp");
+ return dwarf2_per_objfile->per_bfd->str.read_string
+ (dwarf2_per_objfile->objfile, str_offset, "DW_FORM_strp");
}
/* Return pointer to string at .debug_str offset as read from BUF.
const char *
dwarf2_per_objfile::read_line_string (const gdb_byte *buf,
- const struct comp_unit_head *cu_header,
- unsigned int *bytes_read_ptr)
+ const struct comp_unit_head *cu_header,
+ unsigned int *bytes_read_ptr)
{
bfd *abfd = objfile->obfd;
LONGEST str_offset = cu_header->read_offset (abfd, buf, bytes_read_ptr);
- return line_str.read_string (objfile, str_offset, "DW_FORM_line_strp");
+ return per_bfd->line_str.read_string (objfile, str_offset, "DW_FORM_line_strp");
}
/* Given index ADDR_INDEX in .debug_addr, fetch the value.
const gdb_byte *info_ptr;
ULONGEST addr_base_or_zero = addr_base.has_value () ? *addr_base : 0;
- dwarf2_per_objfile->addr.read (objfile);
- if (dwarf2_per_objfile->addr.buffer == NULL)
+ dwarf2_per_objfile->per_bfd->addr.read (objfile);
+ if (dwarf2_per_objfile->per_bfd->addr.buffer == NULL)
error (_("DW_FORM_addr_index used without .debug_addr section [in module %s]"),
objfile_name (objfile));
if (addr_base_or_zero + addr_index * addr_size
- >= dwarf2_per_objfile->addr.size)
+ >= dwarf2_per_objfile->per_bfd->addr.size)
error (_("DW_FORM_addr_index pointing outside of "
".debug_addr section [in module %s]"),
objfile_name (objfile));
- info_ptr = (dwarf2_per_objfile->addr.buffer
+ info_ptr = (dwarf2_per_objfile->per_bfd->addr.buffer
+ addr_base_or_zero + addr_index * addr_size);
if (addr_size == 4)
return bfd_get_32 (abfd, info_ptr);
static CORE_ADDR
read_addr_index (struct dwarf2_cu *cu, unsigned int addr_index)
{
- return read_addr_index_1 (cu->per_cu->dwarf2_per_objfile, addr_index,
+ return read_addr_index_1 (cu->per_objfile, addr_index,
cu->addr_base, cu->header.addr_size);
}
read_addr_index_from_leb128 (struct dwarf2_cu *cu, const gdb_byte *info_ptr,
unsigned int *bytes_read)
{
- bfd *abfd = cu->per_cu->dwarf2_per_objfile->objfile->obfd;
+ bfd *abfd = cu->per_objfile->objfile->obfd;
unsigned int addr_index = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
return read_addr_index (cu, addr_index);
/* See read.h. */
CORE_ADDR
-dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu, unsigned int addr_index)
+dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *dwarf2_per_objfile,
+ unsigned int addr_index)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
- struct dwarf2_cu *cu = per_cu->cu;
+ struct dwarf2_cu *cu = dwarf2_per_objfile->get_cu (per_cu);
gdb::optional<ULONGEST> addr_base;
int addr_size;
}
else
{
- cutu_reader reader (per_cu, NULL, 0, false);
+ cutu_reader reader (per_cu, dwarf2_per_objfile, nullptr, nullptr, false);
addr_base = reader.cu->addr_base;
addr_size = reader.cu->header.addr_size;
}
struct dwarf2_section_info *str_offsets_section,
ULONGEST str_offsets_base, ULONGEST str_index)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
const char *objf_name = objfile_name (objfile);
bfd *abfd = objfile->obfd;
static const char *
read_stub_str_index (struct dwarf2_cu *cu, ULONGEST str_index)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
const char *objf_name = objfile_name (objfile);
static const char form_name[] = "DW_FORM_GNU_str_index";
static const char str_offsets_attr_name[] = "DW_AT_str_offsets";
(long) cu->header.offset_size, objf_name);
return read_str_index (cu,
- &cu->per_cu->dwarf2_per_objfile->str,
- &cu->per_cu->dwarf2_per_objfile->str_offsets,
+ &cu->per_objfile->per_bfd->str,
+ &cu->per_objfile->per_bfd->str_offsets,
*cu->str_offsets_base, str_index);
}
if (attr != NULL)
{
- if (attr->form == DW_FORM_strp || attr->form == DW_FORM_line_strp
- || attr->form == DW_FORM_string
- || attr->form == DW_FORM_strx
- || attr->form == DW_FORM_strx1
- || attr->form == DW_FORM_strx2
- || attr->form == DW_FORM_strx3
- || attr->form == DW_FORM_strx4
- || attr->form == DW_FORM_GNU_str_index
- || attr->form == DW_FORM_GNU_strp_alt)
- str = DW_STRING (attr);
- else
+ str = attr->value_as_string ();
+ if (str == nullptr)
complaint (_("string type expected for attribute %s for "
"DIE at %s in module %s"),
dwarf_attr_name (name), sect_offset_str (die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name (cu->per_objfile->objfile));
}
return str;
get_debug_line_section (struct dwarf2_cu *cu)
{
struct dwarf2_section_info *section;
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
/* For TUs in DWO files, the DW_AT_stmt_list attribute lives in the
DWO file. */
section = &cu->dwo_unit->dwo_file->sections.line;
else if (cu->per_cu->is_dwz)
{
- struct dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+ dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile->per_bfd);
section = &dwz->line;
}
else
- section = &dwarf2_per_objfile->line;
+ section = &dwarf2_per_objfile->per_bfd->line;
return section;
}
dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
{
struct dwarf2_section_info *section;
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
section = get_debug_line_section (cu);
section->read (dwarf2_per_objfile->objfile);
/* This line table is for a function which has been
GCd by the linker. Ignore it. PR gdb/12528 */
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
long line_offset = line_ptr - get_debug_line_section (cu)->buffer;
complaint (_(".debug_line address at offset 0x%lx is 0 [in module %s]"),
unsigned int bytes_read, extended_len;
unsigned char op_code, extended_op;
CORE_ADDR baseaddr;
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
bfd *abfd = objfile->obfd;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
/* True if we're recording line info (as opposed to building partial
symtabs and just interested in finding include files mentioned by
the line number program). */
struct dwarf2_cu *cu, dwarf2_psymtab *pst,
CORE_ADDR lowpc, int decode_mapping)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
const int decode_for_pst_p = (pst != NULL);
if (decode_mapping)
gdb_assert (m_builder == nullptr);
m_builder.reset (new struct buildsym_compunit
- (per_cu->dwarf2_per_objfile->objfile,
+ (this->per_objfile->objfile,
name, comp_dir, language, low_pc));
list_in_scope = get_builder ()->get_file_symbols ();
var_decode_location (struct attribute *attr, struct symbol *sym,
struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
struct comp_unit_head *cu_header = &cu->header;
/* NOTE drow/2003-01-30: There used to be a comment and some special
new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
struct symbol *space)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
struct symbol *sym = NULL;
const char *name;
struct attribute *attr = NULL;
name = dwarf2_name (die, cu);
if (name)
{
- const char *linkagename;
int suppress_add = 0;
if (space)
sym = space;
else
- sym = allocate_symbol (objfile);
+ sym = new (&objfile->objfile_obstack) symbol;
OBJSTAT (objfile, n_syms++);
/* Cache this symbol's name and the name's demangled form (if any). */
sym->set_language (cu->language, &objfile->objfile_obstack);
- linkagename = dwarf2_physname (name, die, cu);
- sym->compute_and_set_names (linkagename, false, objfile->per_bfd);
-
/* Fortran does not have mangling standard and the mangling does differ
between gfortran, iFort etc. */
- if (cu->language == language_fortran
- && symbol_get_demangled_name (sym) == NULL)
- symbol_set_demangled_name (sym,
- dwarf2_full_name (name, die, cu),
- NULL);
+ const char *physname
+ = (cu->language == language_fortran
+ ? dwarf2_full_name (name, die, cu)
+ : dwarf2_physname (name, die, cu));
+ const char *linkagename = dw2_linkage_name (die, cu);
+
+ if (linkagename == nullptr || cu->language == language_ada)
+ sym->set_linkage_name (physname);
+ else
+ {
+ sym->set_demangled_name (physname, &objfile->objfile_obstack);
+ sym->set_linkage_name (linkagename);
+ }
/* Default assumptions.
Use the passed type or decode it from the die. */
/* Compilation with minimal debug info may result in
variables with missing type entries. Change the
misleading `void' type to something sensible. */
- if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_VOID)
+ if (SYMBOL_TYPE (sym)->code () == TYPE_CODE_VOID)
SYMBOL_TYPE (sym) = objfile_type (objfile)->builtin_int;
attr = dwarf2_attr (die, DW_AT_const_value, cu);
if (SYMBOL_CLASS (sym) == LOC_STATIC
&& SYMBOL_VALUE_ADDRESS (sym) == 0
- && !dwarf2_per_objfile->has_section_at_zero)
+ && !dwarf2_per_objfile->per_bfd->has_section_at_zero)
{
/* When a static variable is eliminated by the linker,
the corresponding debug information is not stripped
{
if (SYMBOL_CLASS (sym) == LOC_STATIC
&& (objfile->flags & OBJF_MAINLINE) == 0
- && dwarf2_per_objfile->can_copy)
+ && dwarf2_per_objfile->per_bfd->can_copy)
{
/* A global static variable might be subject to
copy relocation. We first check for a local
/* The symbol's name is already allocated along
with this objfile, so we don't need to
duplicate it for the type. */
- if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
- TYPE_NAME (SYMBOL_TYPE (sym)) = sym->search_name ();
+ if (SYMBOL_TYPE (sym)->name () == 0)
+ SYMBOL_TYPE (sym)->set_name (sym->search_name ());
}
}
}
dwarf2_const_value_data (const struct attribute *attr, struct obstack *obstack,
struct dwarf2_cu *cu, LONGEST *value, int bits)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
enum bfd_endian byte_order = bfd_big_endian (objfile->obfd) ?
BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
LONGEST l = DW_UNSND (attr);
LONGEST *value, const gdb_byte **bytes,
struct dwarf2_locexpr_baton **baton)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ struct objfile *objfile = per_objfile->objfile;
struct comp_unit_head *cu_header = &cu->header;
struct dwarf_block *blk;
enum bfd_endian byte_order = (bfd_big_endian (objfile->obfd) ?
piggyback on the existing location code rather than writing
a new implementation of symbol_computed_ops. */
*baton = XOBNEW (obstack, struct dwarf2_locexpr_baton);
+ (*baton)->per_objfile = per_objfile;
(*baton)->per_cu = cu->per_cu;
gdb_assert ((*baton)->per_cu);
dwarf2_const_value (const struct attribute *attr, struct symbol *sym,
struct dwarf2_cu *cu)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
LONGEST value;
const gdb_byte *bytes;
struct dwarf2_locexpr_baton *baton;
type_attr = dwarf2_attr (die, DW_AT_type, cu);
if (!type_attr)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
/* A missing DW_AT_type represents a void type. */
return objfile_type (objfile)->builtin_void;
}
die_containing_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct attribute *type_attr;
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
type_attr = dwarf2_attr (die, DW_AT_containing_type, cu);
if (!type_attr)
static struct type *
build_error_marker_type (struct dwarf2_cu *cu, struct die_info *die)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
char *saved;
lookup_die_type (struct die_info *die, const struct attribute *attr,
struct dwarf2_cu *cu)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct type *this_type;
per_cu = dwarf2_find_containing_comp_unit (sect_off, 1,
dwarf2_per_objfile);
- this_type = get_die_type_at_offset (sect_off, per_cu);
+ this_type = get_die_type_at_offset (sect_off, per_cu, dwarf2_per_objfile);
}
else if (attr->form_is_ref ())
{
sect_offset sect_off = attr->get_ref_die_offset ();
- this_type = get_die_type_at_offset (sect_off, cu->per_cu);
+ this_type = get_die_type_at_offset (sect_off, cu->per_cu,
+ dwarf2_per_objfile);
}
else if (attr->form == DW_FORM_ref_sig8)
{
struct die_info *spec_die;
struct dwarf2_cu *spec_cu;
struct die_info *child;
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
spec_cu = cu;
spec_die = die_specification (die, &spec_cu);
if (base == NULL || base == DW_STRING (attr) || base[-1] != ':')
return "";
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
return obstack_strndup (&objfile->per_bfd->storage_obstack,
DW_STRING (attr),
&base[-1] - DW_STRING (attr));
static const char *
determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct die_info *parent, *spec_die;
struct dwarf2_cu *spec_cu;
struct type *parent_type;
DW_TAG_namespace DIEs with a name of "::" for the global namespace.
Work around this problem here. */
if (cu->language == language_cplus
- && strcmp (TYPE_NAME (parent_type), "::") == 0)
+ && strcmp (parent_type->name (), "::") == 0)
return "";
/* We give a name to even anonymous namespaces. */
- return TYPE_NAME (parent_type);
+ return parent_type->name ();
case DW_TAG_class_type:
case DW_TAG_interface_type:
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_module:
parent_type = read_type_die (parent, cu);
- if (TYPE_NAME (parent_type) != NULL)
- return TYPE_NAME (parent_type);
+ if (parent_type->name () != NULL)
+ return parent_type->name ();
else
/* An anonymous structure is only allowed non-static data
members; no typedefs, no member functions, et cetera.
case DW_TAG_partial_unit:
/* gcc-4.5 -gdwarf-4 can drop the enclosing namespace. Cope. */
if (cu->language == language_cplus
- && !dwarf2_per_objfile->types.empty ()
+ && !dwarf2_per_objfile->per_bfd->types.empty ()
&& die->child != NULL
&& (die->tag == DW_TAG_class_type
|| die->tag == DW_TAG_structure_type
parent_type = read_type_die (parent, cu);
if (TYPE_DECLARED_CLASS (parent_type))
{
- if (TYPE_NAME (parent_type) != NULL)
- return TYPE_NAME (parent_type);
+ if (parent_type->name () != NULL)
+ return parent_type->name ();
return "";
}
/* Fall through. */
{
if (name && cu->language == language_cplus)
{
- std::string canon_name = cp_canonicalize_string (name);
+ gdb::unique_xmalloc_ptr<char> canon_name
+ = cp_canonicalize_string (name);
- if (!canon_name.empty ())
- {
- if (canon_name != name)
- name = objfile->intern (canon_name);
- }
+ if (canon_name != nullptr)
+ name = objfile->intern (canon_name.get ());
}
return name;
dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
{
struct attribute *attr;
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
attr = dwarf2_attr (die, DW_AT_name, cu);
if ((!attr || !DW_STRING (attr))
{
dump_die_for_error (src_die);
error (_("Dwarf Error: Expected reference attribute [in module %s]"),
- objfile_name ((*ref_cu)->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name ((*ref_cu)->per_objfile->objfile));
}
return die;
{
struct die_info temp_die;
struct dwarf2_cu *target_cu, *cu = *ref_cu;
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
gdb_assert (cu->per_cu != NULL);
dwarf2_per_objfile);
/* If necessary, add it to the queue and load its DIEs. */
- if (maybe_queue_comp_unit (cu, per_cu, cu->language))
- load_full_comp_unit (per_cu, false, cu->language);
+ if (maybe_queue_comp_unit (cu, per_cu, dwarf2_per_objfile, cu->language))
+ load_full_comp_unit (per_cu, dwarf2_per_objfile, false, cu->language);
- target_cu = per_cu->cu;
+ target_cu = dwarf2_per_objfile->get_cu (per_cu);
}
else if (cu->dies == NULL)
{
/* We're loading full DIEs during partial symbol reading. */
- gdb_assert (dwarf2_per_objfile->reading_partial_symbols);
- load_full_comp_unit (cu->per_cu, false, language_minimal);
+ gdb_assert (dwarf2_per_objfile->per_bfd->reading_partial_symbols);
+ load_full_comp_unit (cu->per_cu, dwarf2_per_objfile, false,
+ language_minimal);
}
*ref_cu = target_cu;
error (_("Dwarf Error: Cannot find DIE at %s referenced from DIE "
"at %s [in module %s]"),
sect_offset_str (sect_off), sect_offset_str (src_die->sect_off),
- objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name (cu->per_objfile->objfile));
return die;
}
struct dwarf2_locexpr_baton
dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *dwarf2_per_objfile,
CORE_ADDR (*get_frame_pc) (void *baton),
void *baton, bool resolve_abstract_p)
{
- struct dwarf2_cu *cu;
struct die_info *die;
struct attribute *attr;
struct dwarf2_locexpr_baton retval;
- struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- if (per_cu->cu == NULL)
- load_cu (per_cu, false);
- cu = per_cu->cu;
- if (cu == NULL)
+ dwarf2_cu *cu = dwarf2_per_objfile->get_cu (per_cu);
+ if (cu == nullptr)
+ cu = load_cu (per_cu, dwarf2_per_objfile, false);
+
+ if (cu == nullptr)
{
/* We shouldn't get here for a dummy CU, but don't crash on the user.
Instead just throw an error, not much else we can do. */
attr = dwarf2_attr (die, DW_AT_location, cu);
if (!attr && resolve_abstract_p
- && (dwarf2_per_objfile->abstract_to_concrete.find (die->sect_off)
- != dwarf2_per_objfile->abstract_to_concrete.end ()))
+ && (dwarf2_per_objfile->per_bfd->abstract_to_concrete.find (die->sect_off)
+ != dwarf2_per_objfile->per_bfd->abstract_to_concrete.end ()))
{
CORE_ADDR pc = (*get_frame_pc) (baton);
CORE_ADDR baseaddr = objfile->text_section_offset ();
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct gdbarch *gdbarch = objfile->arch ();
for (const auto &cand_off
- : dwarf2_per_objfile->abstract_to_concrete[die->sect_off])
+ : dwarf2_per_objfile->per_bfd->abstract_to_concrete[die->sect_off])
{
struct dwarf2_cu *cand_cu = cu;
struct die_info *cand
retval.data = DW_BLOCK (attr)->data;
retval.size = DW_BLOCK (attr)->size;
}
+ retval.per_objfile = dwarf2_per_objfile;
retval.per_cu = cu->per_cu;
- age_cached_comp_units (dwarf2_per_objfile);
+ dwarf2_per_objfile->age_comp_units ();
return retval;
}
struct dwarf2_locexpr_baton
dwarf2_fetch_die_loc_cu_off (cu_offset offset_in_cu,
dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile,
CORE_ADDR (*get_frame_pc) (void *baton),
void *baton)
{
sect_offset sect_off = per_cu->sect_off + to_underlying (offset_in_cu);
- return dwarf2_fetch_die_loc_sect_off (sect_off, per_cu, get_frame_pc, baton);
+ return dwarf2_fetch_die_loc_sect_off (sect_off, per_cu, per_objfile,
+ get_frame_pc, baton);
}
/* Write a constant of a given type as target-ordered bytes into
const gdb_byte *
dwarf2_fetch_constant_bytes (sect_offset sect_off,
dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile,
obstack *obstack,
LONGEST *len)
{
- struct dwarf2_cu *cu;
struct die_info *die;
struct attribute *attr;
const gdb_byte *result = NULL;
struct type *type;
LONGEST value;
enum bfd_endian byte_order;
- struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = per_objfile->objfile;
+
+ dwarf2_cu *cu = per_objfile->get_cu (per_cu);
+ if (cu == nullptr)
+ cu = load_cu (per_cu, per_objfile, false);
- if (per_cu->cu == NULL)
- load_cu (per_cu, false);
- cu = per_cu->cu;
- if (cu == NULL)
+ if (cu == nullptr)
{
/* We shouldn't get here for a dummy CU, but don't crash on the user.
Instead just throw an error, not much else we can do. */
struct type *
dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
- dwarf2_per_cu_data *per_cu)
+ dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile)
{
- struct dwarf2_cu *cu;
struct die_info *die;
- if (per_cu->cu == NULL)
- load_cu (per_cu, false);
- cu = per_cu->cu;
- if (!cu)
- return NULL;
+ dwarf2_cu *cu = per_objfile->get_cu (per_cu);
+ if (cu == nullptr)
+ cu = load_cu (per_cu, per_objfile, false);
+
+ if (cu == nullptr)
+ return nullptr;
die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
if (!die)
struct type *
dwarf2_get_die_type (cu_offset die_offset,
- struct dwarf2_per_cu_data *per_cu)
+ dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile)
{
sect_offset die_offset_sect = per_cu->sect_off + to_underlying (die_offset);
- return get_die_type_at_offset (die_offset_sect, per_cu);
+ return get_die_type_at_offset (die_offset_sect, per_cu, per_objfile);
}
/* Follow type unit SIG_TYPE referenced by SRC_DIE.
struct die_info temp_die;
struct dwarf2_cu *sig_cu, *cu = *ref_cu;
struct die_info *die;
+ dwarf2_per_objfile *dwarf2_per_objfile = (*ref_cu)->per_objfile;
+
/* While it might be nice to assert sig_type->type == NULL here,
we can get here for DW_AT_imported_declaration where we need
/* If necessary, add it to the queue and load its DIEs. */
- if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu, language_minimal))
- read_signatured_type (sig_type);
+ if (maybe_queue_comp_unit (*ref_cu, &sig_type->per_cu, dwarf2_per_objfile,
+ language_minimal))
+ read_signatured_type (sig_type, dwarf2_per_objfile);
- sig_cu = sig_type->per_cu.cu;
+ sig_cu = dwarf2_per_objfile->get_cu (&sig_type->per_cu);
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;
to_underlying (temp_die.sect_off));
if (die)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = (*ref_cu)->per_cu->dwarf2_per_objfile;
-
/* For .gdb_index version 7 keep track of included TUs.
http://sourceware.org/bugzilla/show_bug.cgi?id=15021. */
- if (dwarf2_per_objfile->index_table != NULL
- && dwarf2_per_objfile->index_table->version <= 7)
+ if (dwarf2_per_objfile->per_bfd->index_table != NULL
+ && dwarf2_per_objfile->per_bfd->index_table->version <= 7)
{
(*ref_cu)->per_cu->imported_symtabs_push (sig_cu->per_cu);
}
error (_("Dwarf Error: Cannot find signatured DIE %s referenced"
" from DIE at %s [in module %s]"),
hex_string (signature), sect_offset_str (src_die->sect_off),
- objfile_name ((*ref_cu)->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name ((*ref_cu)->per_objfile->objfile));
}
die = follow_die_sig_1 (src_die, sig_type, ref_cu);
error (_("Dwarf Error: Problem reading signatured DIE %s referenced"
" from DIE at %s [in module %s]"),
hex_string (signature), sect_offset_str (src_die->sect_off),
- objfile_name ((*ref_cu)->per_cu->dwarf2_per_objfile->objfile));
+ objfile_name ((*ref_cu)->per_objfile->objfile));
}
return die;
get_signatured_type (struct die_info *die, ULONGEST signature,
struct dwarf2_cu *cu)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct signatured_type *sig_type;
struct dwarf2_cu *type_cu;
struct die_info *type_die;
}
/* If we already know the type we're done. */
- if (sig_type->type != NULL)
- return sig_type->type;
+ type = dwarf2_per_objfile->get_type_for_signatured_type (sig_type);
+ if (type != nullptr)
+ return type;
type_cu = cu;
type_die = follow_die_sig_1 (die, sig_type, &type_cu);
objfile_name (dwarf2_per_objfile->objfile));
type = build_error_marker_type (cu, die);
}
- sig_type->type = type;
+
+ dwarf2_per_objfile->set_type_for_signatured_type (sig_type, type);
return type;
}
}
else
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
complaint (_("Dwarf Error: DW_AT_signature has bad form %s in DIE"
" at %s [in module %s]"),
/* Load the DIEs associated with type unit PER_CU into memory. */
static void
-load_full_type_unit (struct dwarf2_per_cu_data *per_cu)
+load_full_type_unit (dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *per_objfile)
{
struct signatured_type *sig_type;
gdb_assert (per_cu->is_debug_types);
sig_type = (struct signatured_type *) per_cu;
- gdb_assert (per_cu->cu == NULL);
+ gdb_assert (per_objfile->get_cu (per_cu) == nullptr);
- read_signatured_type (sig_type);
+ read_signatured_type (sig_type, per_objfile);
- gdb_assert (per_cu->cu != NULL);
+ gdb_assert (per_objfile->get_cu (per_cu) != nullptr);
}
/* Read in a signatured type and build its CU and DIEs.
read in the real type from the DWO file as well. */
static void
-read_signatured_type (struct signatured_type *sig_type)
+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_cu->cu == NULL);
+ gdb_assert (per_objfile->get_cu (per_cu) == nullptr);
- cutu_reader reader (per_cu, NULL, 0, false);
+ cutu_reader reader (per_cu, per_objfile, nullptr, nullptr, false);
if (!reader.dummy_p)
{
/* Decode simple location descriptions.
Given a pointer to a dwarf block that defines a location, compute
- the location and return the value.
-
- NOTE drow/2003-11-18: This function is called in two situations
- now: for the address of static or global variables (partial symbols
- only) and for offsets into structures which are expected to be
- (more or less) constant. The partial symbol case should go away,
- and only the constant case should remain. That will let this
- function complain more accurately. A few special modes are allowed
- without complaint for global variables (for instance, global
- register values and thread-local values).
-
- A location description containing no operations indicates that the
- object is optimized out. The return value is 0 for that case.
- FIXME drow/2003-11-16: No callers check for this case any more; soon all
- callers will only want a very basic result and this can become a
- complaint.
-
- Note that stack[0] is unused except as a default error return. */
+ the location and return the value. If COMPUTED is non-null, it is
+ set to true to indicate that decoding was successful, and false
+ otherwise. If COMPUTED is null, then this function may emit a
+ complaint. */
static CORE_ADDR
-decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu)
+decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu, bool *computed)
{
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
+ struct objfile *objfile = cu->per_objfile->objfile;
size_t i;
size_t size = blk->size;
const gdb_byte *data = blk->data;
unsigned int bytes_read, unsnd;
gdb_byte op;
+ if (computed != nullptr)
+ *computed = false;
+
i = 0;
stacki = 0;
stack[stacki] = 0;
case DW_OP_reg31:
stack[++stacki] = op - DW_OP_reg0;
if (i < size)
- dwarf2_complex_location_expr_complaint ();
+ {
+ if (computed == nullptr)
+ dwarf2_complex_location_expr_complaint ();
+ else
+ return 0;
+ }
break;
case DW_OP_regx:
i += bytes_read;
stack[++stacki] = unsnd;
if (i < size)
- dwarf2_complex_location_expr_complaint ();
+ {
+ if (computed == nullptr)
+ dwarf2_complex_location_expr_complaint ();
+ else
+ return 0;
+ }
break;
case DW_OP_addr:
global symbols, although the variable's address will be bogus
in the psymtab. */
if (i < size)
- dwarf2_complex_location_expr_complaint ();
+ {
+ if (computed == nullptr)
+ dwarf2_complex_location_expr_complaint ();
+ else
+ return 0;
+ }
break;
case DW_OP_GNU_push_tls_address:
non-zero to not look as a variable garbage collected by linker
which have DW_OP_addr 0. */
if (i < size)
- dwarf2_complex_location_expr_complaint ();
+ {
+ if (computed == nullptr)
+ dwarf2_complex_location_expr_complaint ();
+ else
+ return 0;
+ }
stack[stacki]++;
break;
case DW_OP_GNU_uninit:
+ if (computed != nullptr)
+ return 0;
break;
case DW_OP_addrx:
break;
default:
- {
- const char *name = get_DW_OP_name (op);
+ if (computed == nullptr)
+ {
+ const char *name = get_DW_OP_name (op);
- if (name)
- complaint (_("unsupported stack op: '%s'"),
- name);
- else
- complaint (_("unsupported stack op: '%02x'"),
- op);
- }
+ if (name)
+ complaint (_("unsupported stack op: '%s'"),
+ name);
+ else
+ complaint (_("unsupported stack op: '%02x'"),
+ op);
+ }
return (stack[stacki]);
}
outside of the allocated space. Also enforce minimum>0. */
if (stacki >= ARRAY_SIZE (stack) - 1)
{
- complaint (_("location description stack overflow"));
+ if (computed == nullptr)
+ complaint (_("location description stack overflow"));
return 0;
}
if (stacki <= 0)
{
- complaint (_("location description stack underflow"));
+ if (computed == nullptr)
+ complaint (_("location description stack underflow"));
return 0;
}
}
+
+ if (computed != nullptr)
+ *computed = true;
return (stack[stacki]);
}
dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
int section_is_gnu)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
const struct line_header *lh = cu->line_header;
unsigned int offset_size = cu->header.offset_size;
{
if (section_is_gnu)
{
- section = &dwarf2_per_objfile->macro;
+ section = &dwarf2_per_objfile->per_bfd->macro;
section_name = ".debug_macro";
}
else
{
- section = &dwarf2_per_objfile->macinfo;
+ section = &dwarf2_per_objfile->per_bfd->macinfo;
section_name = ".debug_macinfo";
}
}
static struct dwarf2_section_info *
cu_debug_loc_section (struct dwarf2_cu *cu)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
if (cu->dwo_unit)
{
return cu->header.version >= 5 ? §ions->loclists : §ions->loc;
}
- return (cu->header.version >= 5 ? &dwarf2_per_objfile->loclists
- : &dwarf2_per_objfile->loc);
+ return (cu->header.version >= 5 ? &dwarf2_per_objfile->per_bfd->loclists
+ : &dwarf2_per_objfile->per_bfd->loc);
}
/* A helper function that fills in a dwarf2_loclist_baton. */
struct dwarf2_loclist_baton *baton,
const struct attribute *attr)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct dwarf2_section_info *section = cu_debug_loc_section (cu);
section->read (dwarf2_per_objfile->objfile);
+ baton->per_objfile = dwarf2_per_objfile;
baton->per_cu = cu->per_cu;
gdb_assert (baton->per_cu);
/* We don't know how long the location list is, but make sure we
dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
struct dwarf2_cu *cu, int is_block)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct dwarf2_section_info *section = cu_debug_loc_section (cu);
struct dwarf2_locexpr_baton *baton;
baton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton);
+ baton->per_objfile = dwarf2_per_objfile;
baton->per_cu = cu->per_cu;
gdb_assert (baton->per_cu);
/* See read.h. */
-struct objfile *
-dwarf2_per_cu_data::objfile () const
-{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
-
- /* Return the master objfile, so that we can report and look up the
- correct file containing this variable. */
- if (objfile->separate_debug_objfile_backlink)
- objfile = objfile->separate_debug_objfile_backlink;
-
- return objfile;
-}
-
-/* Return comp_unit_head for PER_CU, either already available in PER_CU->CU
- (CU_HEADERP is unused in such case) or prepare a temporary copy at
- CU_HEADERP first. */
-
-static const struct comp_unit_head *
-per_cu_header_read_in (struct comp_unit_head *cu_headerp,
- const struct dwarf2_per_cu_data *per_cu)
+const comp_unit_head *
+dwarf2_per_cu_data::get_header () const
{
- const gdb_byte *info_ptr;
-
- if (per_cu->cu)
- return &per_cu->cu->header;
+ if (!m_header_read_in)
+ {
+ const gdb_byte *info_ptr
+ = this->section->buffer + to_underlying (this->sect_off);
- info_ptr = per_cu->section->buffer + to_underlying (per_cu->sect_off);
+ memset (&m_header, 0, sizeof (m_header));
- memset (cu_headerp, 0, sizeof (*cu_headerp));
- read_comp_unit_head (cu_headerp, info_ptr, per_cu->section,
- rcuh_kind::COMPILE);
+ read_comp_unit_head (&m_header, info_ptr, this->section,
+ rcuh_kind::COMPILE);
+ }
- return cu_headerp;
+ return &m_header;
}
/* See read.h. */
int
dwarf2_per_cu_data::addr_size () const
{
- struct comp_unit_head cu_header_local;
- const struct comp_unit_head *cu_headerp;
-
- cu_headerp = per_cu_header_read_in (&cu_header_local, this);
-
- return cu_headerp->addr_size;
+ return this->get_header ()->addr_size;
}
/* See read.h. */
int
dwarf2_per_cu_data::offset_size () const
{
- struct comp_unit_head cu_header_local;
- const struct comp_unit_head *cu_headerp;
-
- cu_headerp = per_cu_header_read_in (&cu_header_local, this);
-
- return cu_headerp->offset_size;
+ return this->get_header ()->offset_size;
}
/* See read.h. */
int
dwarf2_per_cu_data::ref_addr_size () const
{
- struct comp_unit_head cu_header_local;
- const struct comp_unit_head *cu_headerp;
-
- cu_headerp = per_cu_header_read_in (&cu_header_local, this);
+ const comp_unit_head *header = this->get_header ();
- if (cu_headerp->version == 2)
- return cu_headerp->addr_size;
+ if (header->version == 2)
+ return header->addr_size;
else
- return cu_headerp->offset_size;
-}
-
-/* See read.h. */
-
-CORE_ADDR
-dwarf2_per_cu_data::text_offset () const
-{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
-
- return objfile->text_section_offset ();
+ return header->offset_size;
}
/* See read.h. */
struct type *
-dwarf2_per_cu_data::addr_type () const
+dwarf2_cu::addr_type () const
{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
+ 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->addr_size ();
+ int addr_size = this->per_cu->addr_size ();
if (TYPE_LENGTH (addr_type) == addr_size)
return addr_type;
{
int low
= dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
- dwarf2_per_objfile->all_comp_units);
+ dwarf2_per_objfile->per_bfd->all_comp_units);
struct dwarf2_per_cu_data *this_cu
- = dwarf2_per_objfile->all_comp_units[low];
+ = dwarf2_per_objfile->per_bfd->all_comp_units[low];
if (this_cu->is_dwz != offset_in_dwz || this_cu->sect_off > sect_off)
{
sect_offset_str (sect_off),
bfd_get_filename (dwarf2_per_objfile->objfile->obfd));
- gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->sect_off
+ gdb_assert (dwarf2_per_objfile->per_bfd->all_comp_units[low-1]->sect_off
<= sect_off);
- return dwarf2_per_objfile->all_comp_units[low-1];
+ return dwarf2_per_objfile->per_bfd->all_comp_units[low-1];
}
else
{
- if (low == dwarf2_per_objfile->all_comp_units.size () - 1
+ if (low == dwarf2_per_objfile->per_bfd->all_comp_units.size () - 1
&& sect_off >= this_cu->sect_off + this_cu->length)
error (_("invalid dwarf2 offset %s"), sect_offset_str (sect_off));
gdb_assert (sect_off < this_cu->sect_off + this_cu->length);
#endif /* GDB_SELF_TEST */
-/* Initialize dwarf2_cu CU, owned by PER_CU. */
+/* Initialize dwarf2_cu to read PER_CU, in the context of PER_OBJFILE. */
-dwarf2_cu::dwarf2_cu (struct dwarf2_per_cu_data *per_cu_)
- : per_cu (per_cu_),
+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_codewarrior (false),
processing_has_namespace_info (false)
{
- per_cu->cu = this;
-}
-
-/* Destroy a dwarf2_cu. */
-
-dwarf2_cu::~dwarf2_cu ()
-{
- per_cu->cu = NULL;
}
/* Initialize basic fields of dwarf_cu CU according to DIE COMP_UNIT_DIE. */
cu->producer = dwarf2_string_attr (comp_unit_die, DW_AT_producer, cu);
}
-/* Increase the age counter on each cached compilation unit, and free
- any that are too old. */
+/* See read.h. */
+
+dwarf2_cu *
+dwarf2_per_objfile::get_cu (dwarf2_per_cu_data *per_cu)
+{
+ auto it = m_dwarf2_cus.find (per_cu);
+ if (it == m_dwarf2_cus.end ())
+ return nullptr;
+
+ return it->second;
+}
+
+/* See read.h. */
-static void
-age_cached_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
+void
+dwarf2_per_objfile::set_cu (dwarf2_per_cu_data *per_cu, dwarf2_cu *cu)
+{
+ gdb_assert (this->get_cu (per_cu) == nullptr);
+
+ m_dwarf2_cus[per_cu] = cu;
+}
+
+/* See read.h. */
+
+void
+dwarf2_per_objfile::age_comp_units ()
{
- struct dwarf2_per_cu_data *per_cu, **last_chain;
+ /* Start by clearing all marks. */
+ for (auto pair : m_dwarf2_cus)
+ pair.second->mark = false;
- dwarf2_clear_marks (dwarf2_per_objfile->read_in_chain);
- per_cu = dwarf2_per_objfile->read_in_chain;
- while (per_cu != NULL)
+ /* Traverse all CUs, mark them and their dependencies if used recently
+ enough. */
+ for (auto pair : m_dwarf2_cus)
{
- per_cu->cu->last_used ++;
- if (per_cu->cu->last_used <= dwarf_max_cache_age)
- dwarf2_mark (per_cu->cu);
- per_cu = per_cu->cu->read_in_chain;
+ dwarf2_cu *cu = pair.second;
+
+ cu->last_used++;
+ if (cu->last_used <= dwarf_max_cache_age)
+ dwarf2_mark (cu);
}
- per_cu = dwarf2_per_objfile->read_in_chain;
- last_chain = &dwarf2_per_objfile->read_in_chain;
- while (per_cu != NULL)
+ /* Delete all CUs still not marked. */
+ for (auto it = m_dwarf2_cus.begin (); it != m_dwarf2_cus.end ();)
{
- struct dwarf2_per_cu_data *next_cu;
-
- next_cu = per_cu->cu->read_in_chain;
+ dwarf2_cu *cu = it->second;
- if (!per_cu->cu->mark)
+ if (!cu->mark)
{
- delete per_cu->cu;
- *last_chain = next_cu;
+ delete cu;
+ it = m_dwarf2_cus.erase (it);
}
else
- last_chain = &per_cu->cu->read_in_chain;
-
- per_cu = next_cu;
+ it++;
}
}
-/* Remove a single compilation unit from the cache. */
+/* See read.h. */
-static void
-free_one_cached_comp_unit (struct dwarf2_per_cu_data *target_per_cu)
+void
+dwarf2_per_objfile::remove_cu (dwarf2_per_cu_data *per_cu)
{
- struct dwarf2_per_cu_data *per_cu, **last_chain;
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = target_per_cu->dwarf2_per_objfile;
-
- per_cu = dwarf2_per_objfile->read_in_chain;
- last_chain = &dwarf2_per_objfile->read_in_chain;
- while (per_cu != NULL)
- {
- struct dwarf2_per_cu_data *next_cu;
+ auto it = m_dwarf2_cus.find (per_cu);
+ if (it == m_dwarf2_cus.end ())
+ return;
- next_cu = per_cu->cu->read_in_chain;
+ delete it->second;
- if (per_cu == target_per_cu)
- {
- delete per_cu->cu;
- per_cu->cu = NULL;
- *last_chain = next_cu;
- break;
- }
- else
- last_chain = &per_cu->cu->read_in_chain;
+ m_dwarf2_cus.erase (it);
+}
- per_cu = next_cu;
- }
+dwarf2_per_objfile::~dwarf2_per_objfile ()
+{
+ remove_all_cus ();
}
/* A set of CU "per_cu" pointer, DIE offset, and GDB type pointer.
static struct type *
set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu)
{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = cu->per_cu->dwarf2_per_objfile;
+ struct dwarf2_per_objfile *dwarf2_per_objfile = cu->per_objfile;
struct dwarf2_per_cu_offset_and_type **slot, ofs;
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct attribute *attr;
But this is not a problem, because the gnat-specific information
is actually not needed for these types. */
if (need_gnat_info (cu)
- && TYPE_CODE (type) != TYPE_CODE_FUNC
- && TYPE_CODE (type) != TYPE_CODE_FLT
- && TYPE_CODE (type) != TYPE_CODE_METHODPTR
- && TYPE_CODE (type) != TYPE_CODE_MEMBERPTR
- && TYPE_CODE (type) != TYPE_CODE_METHOD
+ && type->code () != TYPE_CODE_FUNC
+ && type->code () != TYPE_CODE_FLT
+ && type->code () != TYPE_CODE_METHODPTR
+ && type->code () != TYPE_CODE_MEMBERPTR
+ && type->code () != TYPE_CODE_METHOD
&& !HAVE_GNAT_AUX_INFO (type))
INIT_GNAT_SPECIFIC (type);
attr = dwarf2_attr (die, DW_AT_allocated, cu);
if (attr != NULL && attr->form_is_block ())
{
- struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
+ struct type *prop_type = cu->addr_sized_int_type (false);
if (attr_to_dynamic_prop (attr, die, cu, &prop, prop_type))
- add_dyn_prop (DYN_PROP_ALLOCATED, prop, type);
+ type->add_dyn_prop (DYN_PROP_ALLOCATED, prop);
}
else if (attr != NULL)
{
attr = dwarf2_attr (die, DW_AT_associated, cu);
if (attr != NULL && attr->form_is_block ())
{
- struct type *prop_type = cu->per_cu->addr_sized_int_type (false);
+ struct type *prop_type = cu->addr_sized_int_type (false);
if (attr_to_dynamic_prop (attr, die, cu, &prop, prop_type))
- add_dyn_prop (DYN_PROP_ASSOCIATED, prop, type);
+ type->add_dyn_prop (DYN_PROP_ASSOCIATED, prop);
}
else if (attr != NULL)
{
/* Read DW_AT_data_location and set in type. */
attr = dwarf2_attr (die, DW_AT_data_location, cu);
- if (attr_to_dynamic_prop (attr, die, cu, &prop,
- cu->per_cu->addr_type ()))
- add_dyn_prop (DYN_PROP_DATA_LOCATION, prop, type);
+ if (attr_to_dynamic_prop (attr, die, cu, &prop, cu->addr_type ()))
+ type->add_dyn_prop (DYN_PROP_DATA_LOCATION, prop);
if (dwarf2_per_objfile->die_type_hash == NULL)
dwarf2_per_objfile->die_type_hash
static struct type *
get_die_type_at_offset (sect_offset sect_off,
- struct dwarf2_per_cu_data *per_cu)
+ dwarf2_per_cu_data *per_cu,
+ dwarf2_per_objfile *dwarf2_per_objfile)
{
struct dwarf2_per_cu_offset_and_type *slot, ofs;
- struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
if (dwarf2_per_objfile->die_type_hash == NULL)
return NULL;
static struct type *
get_die_type (struct die_info *die, struct dwarf2_cu *cu)
{
- return get_die_type_at_offset (die->sect_off, cu->per_cu);
+ 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. */
/* 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. */
+ 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)
{
- struct dwarf2_per_cu_data *per_cu;
-
- per_cu = (struct dwarf2_per_cu_data *) *slot;
+ 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 (per_cu->cu == NULL)
+ if (cu == nullptr)
return 1;
- if (per_cu->cu->mark)
+ if (cu->mark)
return 1;
- per_cu->cu->mark = true;
- if (per_cu->cu->dependencies != NULL)
- htab_traverse (per_cu->cu->dependencies, dwarf2_mark_helper, NULL);
+ cu->mark = true;
+
+ if (cu->dependencies != nullptr)
+ htab_traverse (cu->dependencies, dwarf2_mark_helper, per_objfile);
return 1;
}
{
if (cu->mark)
return;
+
cu->mark = true;
- if (cu->dependencies != NULL)
- htab_traverse (cu->dependencies, dwarf2_mark_helper, NULL);
-}
-static void
-dwarf2_clear_marks (struct dwarf2_per_cu_data *per_cu)
-{
- while (per_cu)
- {
- per_cu->cu->mark = false;
- per_cu = per_cu->cu->read_in_chain;
- }
+ 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
struct cmd_list_element *set_dwarf_cmdlist;
struct cmd_list_element *show_dwarf_cmdlist;
-static void
-set_dwarf_cmd (const char *args, int from_tty)
-{
- help_list (set_dwarf_cmdlist, "maintenance set dwarf ", all_commands,
- gdb_stdout);
-}
-
-static void
-show_dwarf_cmd (const char *args, int from_tty)
-{
- cmd_show_list (show_dwarf_cmdlist, from_tty, "");
-}
-
static void
show_check_physname (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
void
_initialize_dwarf2_read ()
{
- add_prefix_cmd ("dwarf", class_maintenance, set_dwarf_cmd, _("\
+ 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 ",
- 0/*allow-unknown*/, &maintenance_set_cmdlist);
+ &set_dwarf_cmdlist, "maintenance set dwarf ",
+ 0/*allow-unknown*/, &maintenance_set_cmdlist);
- add_prefix_cmd ("dwarf", class_maintenance, show_dwarf_cmd, _("\
+ 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 ",
- 0/*allow-unknown*/, &maintenance_show_cmdlist);
+ &show_dwarf_cmdlist, "maintenance show dwarf ",
+ 0/*allow-unknown*/, &maintenance_show_cmdlist);
add_setshow_zinteger_cmd ("max-cache-age", class_obscure,
&dwarf_max_cache_age, _("\