aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/read.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dwarf2/read.c')
-rw-r--r--gdb/dwarf2/read.c6493
1 files changed, 2355 insertions, 4138 deletions
diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c
index 5214168..5e18e45 100644
--- a/gdb/dwarf2/read.c
+++ b/gdb/dwarf2/read.c
@@ -1,6 +1,6 @@
/* DWARF 2 debugging format support for GDB.
- Copyright (C) 1994-2024 Free Software Foundation, Inc.
+ Copyright (C) 1994-2025 Free Software Foundation, Inc.
Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
Inc. with support from Florida State University (under contract
@@ -31,7 +31,9 @@
#include "dwarf2/abbrev.h"
#include "dwarf2/aranges.h"
#include "dwarf2/attribute.h"
-#include "dwarf2/comp-unit-head.h"
+#include "dwarf2/unit-head.h"
+#include "dwarf2/cooked-index-worker.h"
+#include "dwarf2/cooked-indexer.h"
#include "dwarf2/cu.h"
#include "dwarf2/index-cache.h"
#include "dwarf2/leb.h"
@@ -43,11 +45,14 @@
#include "dwarf2/read-gdb-index.h"
#include "dwarf2/sect-names.h"
#include "dwarf2/stringify.h"
+#include "dwarf2/tag.h"
#include "dwarf2/public.h"
#include "bfd.h"
#include "elf-bfd.h"
#include "event-top.h"
+#include "exceptions.h"
#include "gdbsupport/task-group.h"
+#include "maint.h"
#include "symtab.h"
#include "gdbtypes.h"
#include "objfiles.h"
@@ -79,22 +84,18 @@
#include <optional>
#include "gdbsupport/underlying.h"
#include "filename-seen-cache.h"
-#include "producer.h"
#include <fcntl.h>
#include <algorithm>
-#include <unordered_map>
#include "gdbsupport/selftest.h"
#include "rust-lang.h"
#include "gdbsupport/pathstuff.h"
#include "count-one-bits.h"
-#include <unordered_set>
#include "dwarf2/abbrev-table-cache.h"
#include "cooked-index.h"
#include "gdbsupport/thread-pool.h"
#include "run-on-main-thread.h"
#include "dwarf2/parent-map.h"
#include "dwarf2/error.h"
-#include <variant>
#include "gdbsupport/unordered_set.h"
#include "extract-store-integer.h"
@@ -115,6 +116,12 @@ static unsigned int dwarf_read_debug = 0;
debug_prefixed_printf_cond (dwarf_read_debug >= 2, "dwarf-read", fmt, \
##__VA_ARGS__)
+/* Print "dwarf-read" start/end debug statements. */
+
+#define DWARF_READ_SCOPED_DEBUG_START_END(fmt, ...) \
+ scoped_debug_start_end ([] { return dwarf_read_debug >= 1; }, "dwarf-read", \
+ fmt, ##__VA_ARGS__)
+
/* When non-zero, dump DIEs after they are read in. */
static unsigned int dwarf_die_debug = 0;
@@ -149,9 +156,6 @@ static int dwarf2_locexpr_block_index;
static int dwarf2_loclist_block_index;
static int ada_block_index;
-static bool producer_is_gas_lt_2_38 (struct dwarf2_cu *cu);
-static bool producer_is_gas_ge_2_39 (struct dwarf2_cu *cu);
-
/* Size of .debug_loclists section header for 32-bit DWARF format. */
#define LOCLIST_HEADER_SIZE32 12
@@ -262,29 +266,6 @@ struct loclists_rnglists_header
unsigned int offset_entry_count;
};
-/* A struct that can be used as a hash key for tables based on DW_AT_stmt_list.
- This includes type_unit_group and quick_file_names. */
-
-struct stmt_list_hash
-{
- /* The DWO unit this table is from or NULL if there is none. */
- struct dwo_unit *dwo_unit;
-
- /* Offset in .debug_line or .debug_line.dwo. */
- sect_offset line_sect_off;
-};
-
-/* 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
-{
- /* The data used to construct the hash key. */
- struct stmt_list_hash hash {};
-};
-
/* These sections are what may appear in a (real or virtual) DWO file. */
struct dwo_sections
@@ -299,7 +280,7 @@ struct dwo_sections
struct dwarf2_section_info str;
struct dwarf2_section_info str_offsets;
/* In the case of a virtual DWO file, these two are unused. */
- struct dwarf2_section_info info;
+ std::vector<dwarf2_section_info> infos;
std::vector<dwarf2_section_info> types;
};
@@ -308,24 +289,63 @@ struct dwo_sections
struct dwo_unit
{
/* Backlink to the containing struct dwo_file. */
- struct dwo_file *dwo_file;
+ struct dwo_file *dwo_file = nullptr;
/* The "id" that distinguishes this CU/TU.
.debug_info calls this "dwo_id", .debug_types calls this "signature".
Since signatures came first, we stick with it for consistency. */
- ULONGEST signature;
+ ULONGEST signature = 0;
/* The section this CU/TU lives in, in the DWO file. */
- struct dwarf2_section_info *section;
+ dwarf2_section_info *section = nullptr;
- /* Same as dwarf2_per_cu_data:{sect_off,length} but in the DWO section. */
- sect_offset sect_off;
- unsigned int length;
+ /* This is set if SECTION is owned by this dwo_unit. */
+ dwarf2_section_info_up section_holder;
+
+ /* Same as dwarf2_per_cu::{sect_off,length} but in the DWO section. */
+ sect_offset sect_off {};
+ unsigned int length = 0;
/* For types, offset in the type's DIE of the type defined by this TU. */
cu_offset type_offset_in_tu;
};
+using dwo_unit_up = std::unique_ptr<dwo_unit>;
+
+/* Hash function for dwo_unit objects, based on the signature. */
+
+struct dwo_unit_hash
+{
+ using is_transparent = void;
+
+ std::size_t operator() (ULONGEST signature) const noexcept
+ { return signature; }
+
+ std::size_t operator() (const dwo_unit_up &unit) const noexcept
+ { return (*this) (unit->signature); }
+};
+
+/* Equal function for dwo_unit objects, based on the signature.
+
+ The signature is assumed to be unique within the DWO file. So while object
+ file CU dwo_id's always have the value zero, that's OK, assuming each object
+ file DWO file has only one CU, and that's the rule for now. */
+
+struct dwo_unit_eq
+{
+ using is_transparent = void;
+
+ bool operator() (ULONGEST sig, const dwo_unit_up &unit) const noexcept
+ { return sig == unit->signature; }
+
+ bool operator() (const dwo_unit_up &a, const dwo_unit_up &b) const noexcept
+ { return (*this) (a->signature, b); }
+};
+
+/* Set of dwo_unit object, using their signature as identity. */
+
+using dwo_unit_set = gdb::unordered_set<dwo_unit_up, dwo_unit_hash, dwo_unit_eq>;
+
/* include/dwarf2.h defines the DWP section codes.
It defines a max value but it doesn't define a min value, which we
use for error checking, so provide one. */
@@ -370,16 +390,59 @@ struct dwo_file
struct dwo_sections sections {};
/* The CUs in the file.
- Each element is a struct dwo_unit. Multiple CUs per DWO are supported as
- an extension to handle LLVM's Link Time Optimization output (where
- multiple source files may be compiled into a single object/dwo pair). */
- htab_up cus;
-
- /* Table of TUs in the file.
- Each element is a struct dwo_unit. */
- htab_up tus;
+
+ Multiple CUs per DWO are supported as an extension to handle LLVM's Link
+ Time Optimization output (where multiple source files may be compiled into
+ a single object/dwo pair). */
+ dwo_unit_set cus;
+
+ /* Table of TUs in the file. */
+ dwo_unit_set tus;
};
+/* See dwarf2/read.h. */
+
+std::size_t
+dwo_file_hash::operator() (const dwo_file_search &search) const noexcept
+{
+ hashval_t hash = htab_hash_string (search.dwo_name);
+
+ if (search.comp_dir != nullptr)
+ hash += htab_hash_string (search.comp_dir);
+
+ return hash;
+}
+
+/* See dwarf2/read.h. */
+
+std::size_t
+dwo_file_hash::operator() (const dwo_file_up &file) const noexcept
+{
+ return (*this) ({ file->dwo_name.c_str (), file->comp_dir });
+}
+
+/* See dwarf2/read.h. */
+
+bool
+dwo_file_eq::operator() (const dwo_file_search &search,
+ const dwo_file_up &dwo_file) const noexcept
+{
+ if (search.dwo_name != dwo_file->dwo_name)
+ return false;
+
+ if (search.comp_dir == nullptr || dwo_file->comp_dir == nullptr)
+ return search.comp_dir == dwo_file->comp_dir;
+
+ return std::strcmp (search.comp_dir, dwo_file->comp_dir) == 0;
+}
+
+/* See dwarf2/read.h. */
+
+bool
+dwo_file_eq::operator() (const dwo_file_up &a,
+ const dwo_file_up &b) const noexcept
+{ return (*this) ({ a->dwo_name.c_str (), a->comp_dir }, b); }
+
/* These sections are what may appear in a DWP file. */
struct dwp_sections
@@ -537,9 +600,14 @@ struct dwp_file
/* Table of TUs in the file. */
const struct dwp_hash_table *tus = nullptr;
- /* Tables of loaded CUs/TUs. Each entry is a struct dwo_unit *. */
- htab_up loaded_cus;
- htab_up loaded_tus;
+ /* Tables of loaded CUs/TUs. */
+ dwo_unit_set loaded_cus;
+ dwo_unit_set loaded_tus;
+
+#if CXX_STD_THREAD
+ /* Mutex to synchronize access to LOADED_CUS and LOADED_TUS. */
+ std::mutex loaded_cutus_lock;
+#endif
/* Table to map ELF section numbers to their sections.
This is only needed for the DWP V1 file format. */
@@ -547,89 +615,6 @@ struct dwp_file
asection **elf_sections = nullptr;
};
-/* Struct used to pass misc. parameters to read_die_and_children, et
- al. which are used for both .debug_info and .debug_types dies.
- All parameters here are unchanging for the life of the call. This
- struct exists to abstract away the constant parameters of die reading. */
-
-struct die_reader_specs
-{
- /* The bfd of die_section. */
- bfd *abfd;
-
- /* The CU of the DIE we are parsing. */
- struct dwarf2_cu *cu;
-
- /* Non-NULL if reading a DWO file (including one packaged into a DWP). */
- struct dwo_file *dwo_file;
-
- /* The section the die comes from.
- This is either .debug_info or .debug_types, or the .dwo variants. */
- struct dwarf2_section_info *die_section;
-
- /* die_section->buffer. */
- const gdb_byte *buffer;
-
- /* The end of the buffer. */
- const gdb_byte *buffer_end;
-
- /* The abbreviation table to use when reading the DIEs. */
- const struct abbrev_table *abbrev_table;
-};
-
-/* A subclass of die_reader_specs that holds storage and has complex
- constructor and destructor behavior. */
-
-class cutu_reader : public die_reader_specs
-{
-public:
-
- cutu_reader (dwarf2_per_cu_data *this_cu,
- dwarf2_per_objfile *per_objfile,
- const struct abbrev_table *abbrev_table,
- dwarf2_cu *existing_cu,
- bool skip_partial,
- const abbrev_table_cache *cache = nullptr);
-
- 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);
-
- DISABLE_COPY_AND_ASSIGN (cutu_reader);
-
- cutu_reader (cutu_reader &&) = default;
-
- const gdb_byte *info_ptr = nullptr;
- struct die_info *comp_unit_die = nullptr;
- bool dummy_p = false;
-
- /* Release the new CU, putting it on the chain. This cannot be done
- for dummy CUs. */
- void keep ();
-
- /* Release the abbrev table, transferring ownership to the
- caller. */
- abbrev_table_up release_abbrev_table ()
- {
- return std::move (m_abbrev_table_holder);
- }
-
-private:
- 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;
-
- /* The ordinary abbreviation table. */
- abbrev_table_up m_abbrev_table_holder;
-
- /* The DWO abbreviation table. */
- abbrev_table_up m_dwo_abbrev_table;
-};
-
/* FIXME: We might want to set this from BFD via bfd_arch_bits_per_byte,
but this would require a corresponding change in unpack_field_as_long
and friends. */
@@ -648,15 +633,21 @@ struct variant_field
/* 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 = false;
/* If we see a DW_AT_discr_value, then this will be the discriminant
- value. */
- ULONGEST discriminant_value = 0;
+ value. Just the attribute is stored here, because we have to
+ defer deciding whether the value is signed or unsigned until the
+ end. */
+ const attribute *discriminant_attr = nullptr;
/* If we see a DW_AT_discr_list, then this is a pointer to the list
data. */
struct dwarf_block *discr_list_data = nullptr;
+
+ /* If both DW_AT_discr_value and DW_AT_discr_list are absent, then
+ this is the default branch. */
+ bool is_default () const
+ {
+ return discriminant_attr == nullptr && discr_list_data == nullptr;
+ }
};
/* This represents a DW_TAG_variant_part. */
@@ -740,7 +731,7 @@ show_dwarf_max_cache_age (struct ui_file *file, int from_tty,
}
/* When true, wait for DWARF reading to be complete. */
-static bool dwarf_synchronous = true;
+static bool dwarf_synchronous = false;
/* "Show" callback for "maint set dwarf synchronous". */
static void
@@ -753,48 +744,26 @@ show_dwarf_synchronous (struct ui_file *file, int from_tty,
/* local function prototypes */
-static void dwarf2_find_base_address (struct die_info *die,
- struct dwarf2_cu *cu);
-
-static void build_type_psymtabs_reader (cutu_reader *reader,
- cooked_index_storage *storage);
-
static void var_decode_location (struct attribute *attr,
struct symbol *sym,
struct dwarf2_cu *cu);
static unsigned int peek_abbrev_code (bfd *, const gdb_byte *);
-static const gdb_byte *read_attribute (const struct die_reader_specs *,
- struct attribute *,
- const struct attr_abbrev *,
- const gdb_byte *,
- bool allow_reprocess = true);
-
-/* Note that the default for TAG is chosen because it only matters
- when reading the top-level DIE, and that function is careful to
- pass the correct tag. */
-static void read_attribute_reprocess (const struct die_reader_specs *reader,
- struct attribute *attr,
- dwarf_tag tag = DW_TAG_padding);
-
static unrelocated_addr read_addr_index (struct dwarf2_cu *cu,
unsigned int addr_index);
static sect_offset read_abbrev_offset (dwarf2_per_objfile *per_objfile,
dwarf2_section_info *, sect_offset);
-static const char *read_indirect_string
- (dwarf2_per_objfile *per_objfile, bfd *, const gdb_byte *,
- const struct comp_unit_head *, unsigned int *);
+static const char *read_indirect_string (dwarf2_per_objfile *per_objfile, bfd *,
+ const gdb_byte *, const unit_head *,
+ unsigned int *);
static unrelocated_addr read_addr_index_from_leb128 (struct dwarf2_cu *,
const gdb_byte *,
unsigned int *);
-static const char *read_dwo_str_index (const struct die_reader_specs *reader,
- ULONGEST str_index);
-
static const char *read_stub_str_index (struct dwarf2_cu *cu,
ULONGEST str_index);
@@ -888,31 +857,6 @@ static struct dwarf2_section_info *cu_debug_loc_section (struct dwarf2_cu *cu);
static struct dwarf2_section_info *cu_debug_rnglists_section
(struct dwarf2_cu *cu, dwarf_tag tag);
-/* How dwarf2_get_pc_bounds constructed its *LOWPC and *HIGHPC return
- values. Keep the items ordered with increasing constraints compliance. */
-enum pc_bounds_kind
-{
- /* No attribute DW_AT_low_pc, DW_AT_high_pc or DW_AT_ranges was found. */
- PC_BOUNDS_NOT_PRESENT,
-
- /* Some of the attributes DW_AT_low_pc, DW_AT_high_pc or DW_AT_ranges
- were present but they do not form a valid range of PC addresses. */
- PC_BOUNDS_INVALID,
-
- /* Discontiguous range was found - that is DW_AT_ranges was found. */
- PC_BOUNDS_RANGES,
-
- /* Contiguous range was found - DW_AT_low_pc and DW_AT_high_pc were found. */
- PC_BOUNDS_HIGH_LOW,
-};
-
-static enum pc_bounds_kind dwarf2_get_pc_bounds (struct die_info *,
- unrelocated_addr *,
- unrelocated_addr *,
- struct dwarf2_cu *,
- addrmap_mutable *,
- void *);
-
static void get_scope_pc_bounds (struct die_info *,
unrelocated_addr *, unrelocated_addr *,
struct dwarf2_cu *);
@@ -956,30 +900,9 @@ static const char *namespace_name (struct die_info *die,
static void process_enumeration_scope (struct die_info *, struct dwarf2_cu *);
-static bool decode_locdesc (struct dwarf_block *, struct dwarf2_cu *,
- CORE_ADDR *addr);
-
static enum dwarf_array_dim_ordering read_array_order (struct die_info *,
struct dwarf2_cu *);
-static struct die_info *read_die_and_siblings_1
- (const struct die_reader_specs *, const gdb_byte *, const gdb_byte **,
- struct die_info *);
-
-static struct die_info *read_die_and_siblings (const struct die_reader_specs *,
- const gdb_byte *info_ptr,
- const gdb_byte **new_info_ptr,
- struct die_info *parent);
-
-static const gdb_byte *read_full_die_1 (const struct die_reader_specs *,
- struct die_info **, const gdb_byte *,
- int, bool);
-
-static const gdb_byte *read_toplevel_die (const struct die_reader_specs *,
- struct die_info **,
- const gdb_byte *,
- gdb::array_view<attribute *> = {});
-
static void process_die (struct die_info *, struct dwarf2_cu *);
static const char *dwarf2_canonicalize_name (const char *, struct dwarf2_cu *,
@@ -1016,7 +939,7 @@ static struct type *get_DW_AT_signature_type (struct die_info *,
const struct attribute *,
struct dwarf2_cu *);
-static void load_full_type_unit (dwarf2_per_cu_data *per_cu,
+static void load_full_type_unit (dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile);
static void read_signatured_type (signatured_type *sig_type,
@@ -1041,43 +964,26 @@ static void dwarf2_symbol_mark_computed (const struct attribute *attr,
struct dwarf2_cu *cu,
int is_block);
-static const gdb_byte *skip_one_die (const struct die_reader_specs *reader,
- const gdb_byte *info_ptr,
- const struct abbrev_info *abbrev,
- bool do_skip_children = true);
-
-static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
- (sect_offset sect_off, unsigned int offset_in_dwz,
- dwarf2_per_bfd *per_bfd);
-
-static void prepare_one_comp_unit (struct dwarf2_cu *cu,
- struct die_info *comp_unit_die,
- enum language pretend_language);
-
static struct type *set_die_type (struct die_info *, struct type *,
struct dwarf2_cu *, bool = false);
-static void load_full_comp_unit (dwarf2_per_cu_data *per_cu,
+static void load_full_comp_unit (dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile,
- dwarf2_cu *existing_cu,
bool skip_partial,
enum language pretend_language);
-static void process_full_comp_unit (dwarf2_cu *cu,
- enum language pretend_language);
+static void process_full_comp_unit (dwarf2_cu *cu);
-static void process_full_type_unit (dwarf2_cu *cu,
- enum language pretend_language);
+static void process_full_type_unit (dwarf2_cu *cu);
static struct type *get_die_type_at_offset (sect_offset,
- dwarf2_per_cu_data *per_cu,
+ dwarf2_per_cu *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 (dwarf2_per_cu_data *per_cu,
- dwarf2_per_objfile *per_objfile,
- enum language pretend_language);
+static void queue_comp_unit (dwarf2_per_cu *per_cu,
+ dwarf2_per_objfile *per_objfile);
static void process_queue (dwarf2_per_objfile *per_objfile);
@@ -1129,7 +1035,7 @@ dwarf2_queue_item::~dwarf2_queue_item ()
/* See dwarf2/read.h. */
void
-dwarf2_per_cu_data_deleter::operator() (dwarf2_per_cu_data *data)
+dwarf2_per_cu_deleter::operator() (dwarf2_per_cu *data)
{
if (data->is_debug_types)
delete static_cast<signatured_type *> (data);
@@ -1137,39 +1043,22 @@ dwarf2_per_cu_data_deleter::operator() (dwarf2_per_cu_data *data)
delete data;
}
-static file_and_directory &find_file_and_directory
- (struct die_info *die, struct dwarf2_cu *cu);
-
static const char *compute_include_file_name
(const struct line_header *lh,
const file_entry &fe,
const file_and_directory &cu_info,
std::string &name_holder);
-static htab_up allocate_dwo_unit_table ();
-
static struct dwo_unit *lookup_dwo_unit_in_dwp
- (dwarf2_per_objfile *per_objfile, struct dwp_file *dwp_file,
+ (dwarf2_per_bfd *per_bfd, struct dwp_file *dwp_file,
const char *comp_dir, ULONGEST signature, int is_debug_types);
-static struct dwp_file *get_dwp_file (dwarf2_per_objfile *per_objfile);
-
-static struct dwo_unit *lookup_dwo_comp_unit
- (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
- ULONGEST signature);
-
-static struct dwo_unit *lookup_dwo_type_unit
- (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir);
+static void open_and_init_dwp_file (dwarf2_per_objfile *per_objfile);
static void queue_and_load_all_dwo_tus (dwarf2_cu *cu);
-/* A unique pointer to a dwo_file. */
-
-typedef std::unique_ptr<struct dwo_file> dwo_file_up;
-
static void process_cu_includes (dwarf2_per_objfile *per_objfile);
-static void check_producer (struct dwarf2_cu *cu);
/* Various complaints about symbol reading that don't abort the process. */
@@ -1260,7 +1149,7 @@ dwarf2_per_bfd::dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names,
names = &dwarf2_elf_names;
for (asection *sec = obfd->sections; sec != NULL; sec = sec->next)
- locate_sections (obfd, sec, *names);
+ this->locate_sections (sec, *names);
}
dwarf2_per_bfd::~dwarf2_per_bfd ()
@@ -1313,33 +1202,33 @@ private:
/* See read.h. */
bool
-dwarf2_per_objfile::symtab_set_p (const dwarf2_per_cu_data *per_cu) const
+dwarf2_per_objfile::symtab_set_p (const dwarf2_per_cu *per_cu) const
{
- if (per_cu->index < this->m_symtabs.size ())
- return this->m_symtabs[per_cu->index] != nullptr;
+ if (per_cu->index < m_symtabs.size ())
+ return m_symtabs[per_cu->index] != nullptr;
return false;
}
/* See read.h. */
compunit_symtab *
-dwarf2_per_objfile::get_symtab (const dwarf2_per_cu_data *per_cu) const
+dwarf2_per_objfile::get_symtab (const dwarf2_per_cu *per_cu) const
{
- if (per_cu->index < this->m_symtabs.size ())
- return this->m_symtabs[per_cu->index];
+ if (per_cu->index < m_symtabs.size ())
+ return m_symtabs[per_cu->index];
return nullptr;
}
/* See read.h. */
void
-dwarf2_per_objfile::set_symtab (const dwarf2_per_cu_data *per_cu,
+dwarf2_per_objfile::set_symtab (const dwarf2_per_cu *per_cu,
compunit_symtab *symtab)
{
- if (per_cu->index >= this->m_symtabs.size ())
- this->m_symtabs.resize (per_cu->index + 1);
- gdb_assert (this->m_symtabs[per_cu->index] == nullptr);
- this->m_symtabs[per_cu->index] = symtab;
+ if (per_cu->index >= m_symtabs.size ())
+ m_symtabs.resize (per_cu->index + 1);
+ gdb_assert (m_symtabs[per_cu->index] == nullptr);
+ m_symtabs[per_cu->index] = symtab;
}
/* Helper function for dwarf2_initialize_objfile that creates the
@@ -1407,7 +1296,16 @@ dwarf2_has_info (struct objfile *objfile,
BFD, to avoid races. */
try
{
- dwarf2_read_dwz_file (per_objfile);
+ dwz_file::read_dwz_file (per_objfile);
+ }
+ catch (const gdb_exception_error &err)
+ {
+ warning (_("%s"), err.what ());
+ }
+
+ try
+ {
+ open_and_init_dwp_file (per_objfile);
}
catch (const gdb_exception_error &err)
{
@@ -1421,7 +1319,7 @@ dwarf2_has_info (struct objfile *objfile,
/* See declaration. */
void
-dwarf2_per_bfd::locate_sections (bfd *abfd, asection *sectp,
+dwarf2_per_bfd::locate_sections (asection *sectp,
const dwarf2_debug_sections &names)
{
flagword aflag = bfd_section_flags (sectp);
@@ -1429,13 +1327,13 @@ dwarf2_per_bfd::locate_sections (bfd *abfd, asection *sectp,
if ((aflag & SEC_HAS_CONTENTS) == 0)
{
}
- else if (bfd_section_size_insane (abfd, sectp))
+ else if (bfd_section_size_insane (this->obfd, sectp))
{
bfd_size_type size = sectp->size;
warning (_("Discarding section %s which has an invalid size (%s) "
"[in module %s]"),
- bfd_section_name (sectp), phex_nz (size, sizeof (size)),
- bfd_get_filename (abfd));
+ bfd_section_name (sectp), phex_nz (size),
+ this->filename ());
}
else if (names.info.matches (sectp->name))
{
@@ -1608,6 +1506,16 @@ dwarf2_per_bfd::map_info_sections (struct objfile *objfile)
section.read (objfile);
}
+/* See dwarf2/read.h. */
+
+void
+dwarf2_per_bfd::start_reading (dwarf_scanner_base_up new_table)
+{
+ gdb_assert (index_table == nullptr);
+ index_table = std::move (new_table);
+ index_table->start_reading ();
+}
+
/* DWARF quick_symbol_functions support. */
@@ -1618,9 +1526,6 @@ dwarf2_per_bfd::map_info_sections (struct objfile *objfile)
line_header when we're done and don't need to record it here. */
struct quick_file_names
{
- /* The data used to construct the hash key. */
- struct stmt_list_hash hash;
-
/* The number of entries in file_names, real_names. */
unsigned int num_file_names;
@@ -1650,77 +1555,46 @@ struct readnow_functions : public dwarf2_base_index_functions
bool expand_symtabs_matching
(struct objfile *objfile,
- gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+ expand_symtabs_file_matcher file_matcher,
const lookup_name_info *lookup_name,
- gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
- gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+ expand_symtabs_symbol_matcher symbol_matcher,
+ expand_symtabs_expansion_listener expansion_notify,
block_search_flags search_flags,
domain_search_flags domain,
- gdb::function_view<expand_symtabs_lang_matcher_ftype> lang_matcher)
- override
+ expand_symtabs_lang_matcher lang_matcher) override
{
return true;
}
};
-/* Utility hash function for a stmt_list_hash. */
-
-static hashval_t
-hash_stmt_list_entry (const struct stmt_list_hash *stmt_list_hash)
-{
- hashval_t v = 0;
-
- if (stmt_list_hash->dwo_unit != NULL)
- v += (uintptr_t) stmt_list_hash->dwo_unit->dwo_file;
- v += to_underlying (stmt_list_hash->line_sect_off);
- return v;
-}
-
-/* Utility equality function for a stmt_list_hash. */
+/* See read.h. */
-static int
-eq_stmt_list_entry (const struct stmt_list_hash *lhs,
- const struct stmt_list_hash *rhs)
+std::uint64_t
+stmt_list_hash_hash::operator() (const stmt_list_hash &key) const noexcept
{
- if ((lhs->dwo_unit != NULL) != (rhs->dwo_unit != NULL))
- return 0;
- if (lhs->dwo_unit != NULL
- && lhs->dwo_unit->dwo_file != rhs->dwo_unit->dwo_file)
- return 0;
-
- return lhs->line_sect_off == rhs->line_sect_off;
-}
+ std::uint64_t v = 0;
-/* Hash function for a quick_file_names. */
-
-static hashval_t
-hash_file_name_entry (const void *e)
-{
- const struct quick_file_names *file_data
- = (const struct quick_file_names *) e;
+ if (key.dwo_unit != nullptr)
+ v += ankerl::unordered_dense::hash<dwo_file *> () (key.dwo_unit->dwo_file);
- return hash_stmt_list_entry (&file_data->hash);
+ v += (ankerl::unordered_dense::hash<std::uint64_t> ()
+ (to_underlying (key.line_sect_off)));
+ return v;
}
-/* Equality function for a quick_file_names. */
+/* See read.h. */
-static int
-eq_file_name_entry (const void *a, const void *b)
+bool
+stmt_list_hash::operator== (const stmt_list_hash &rhs) const noexcept
{
- const struct quick_file_names *ea = (const struct quick_file_names *) a;
- const struct quick_file_names *eb = (const struct quick_file_names *) b;
-
- return eq_stmt_list_entry (&ea->hash, &eb->hash);
-}
+ if ((this->dwo_unit != nullptr) != (rhs.dwo_unit != nullptr))
+ return false;
-/* See read.h. */
+ if (this->dwo_unit != nullptr
+ && this->dwo_unit->dwo_file != rhs.dwo_unit->dwo_file)
+ return false;
-htab_up
-create_quick_file_names_table (unsigned int nr_initial_entries)
-{
- return htab_up (htab_create_alloc (nr_initial_entries,
- hash_file_name_entry, eq_file_name_entry,
- nullptr, xcalloc, xfree));
+ return this->line_sect_off == rhs.line_sect_off;
}
/* Read in CU (dwarf2_cu object) for PER_CU in the context of PER_OBJFILE. This
@@ -1728,14 +1602,13 @@ create_quick_file_names_table (unsigned int nr_initial_entries)
You should call age_cached_comp_units after processing the CU. */
static dwarf2_cu *
-load_cu (dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
+load_cu (dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile,
bool skip_partial)
{
if (per_cu->is_debug_types)
load_full_type_unit (per_cu, per_objfile);
else
- load_full_comp_unit (per_cu, per_objfile, per_objfile->get_cu (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)
@@ -1749,7 +1622,7 @@ load_cu (dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
/* Read in the symbols for PER_CU in the context of PER_OBJFILE. */
static void
-dw2_do_instantiate_symtab (dwarf2_per_cu_data *per_cu,
+dw2_do_instantiate_symtab (dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile, bool skip_partial)
{
{
@@ -1760,8 +1633,11 @@ dw2_do_instantiate_symtab (dwarf2_per_cu_data *per_cu,
if (!per_objfile->symtab_set_p (per_cu))
{
- queue_comp_unit (per_cu, per_objfile, language_minimal);
- dwarf2_cu *cu = load_cu (per_cu, per_objfile, skip_partial);
+ queue_comp_unit (per_cu, per_objfile);
+ dwarf2_cu *cu = per_objfile->get_cu (per_cu);
+
+ if (cu == nullptr)
+ cu = load_cu (per_cu, 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.
@@ -1772,7 +1648,7 @@ dw2_do_instantiate_symtab (dwarf2_per_cu_data *per_cu,
&& per_objfile->per_bfd->index_table != NULL
&& !per_objfile->per_bfd->index_table->version_check ()
/* DWP files aren't supported yet. */
- && get_dwp_file (per_objfile) == NULL)
+ && per_objfile->per_bfd->dwp_file == nullptr)
queue_and_load_all_dwo_tus (cu);
}
@@ -1790,8 +1666,7 @@ dw2_do_instantiate_symtab (dwarf2_per_cu_data *per_cu,
Returns the resulting symbol table. */
static struct compunit_symtab *
-dw2_instantiate_symtab (dwarf2_per_cu_data *per_cu,
- dwarf2_per_objfile *per_objfile,
+dw2_instantiate_symtab (dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile,
bool skip_partial)
{
if (!per_objfile->symtab_set_p (per_cu))
@@ -1807,11 +1682,13 @@ dw2_instantiate_symtab (dwarf2_per_cu_data *per_cu,
/* See read.h. */
-dwarf2_per_cu_data_up
-dwarf2_per_bfd::allocate_per_cu ()
+dwarf2_per_cu_up
+dwarf2_per_bfd::allocate_per_cu (dwarf2_section_info *section,
+ sect_offset sect_off, unsigned int length,
+ bool is_dwz)
{
- dwarf2_per_cu_data_up result (new dwarf2_per_cu_data);
- result->per_bfd = this;
+ dwarf2_per_cu_up result (new dwarf2_per_cu (this, section, sect_off,
+ length, is_dwz));
result->index = all_units.size ();
return result;
}
@@ -1819,45 +1696,28 @@ dwarf2_per_bfd::allocate_per_cu ()
/* See read.h. */
signatured_type_up
-dwarf2_per_bfd::allocate_signatured_type (ULONGEST signature)
-{
- signatured_type_up result (new signatured_type (signature));
- result->per_bfd = this;
+dwarf2_per_bfd::allocate_signatured_type (dwarf2_section_info *section,
+ sect_offset sect_off,
+ unsigned int length,
+ bool is_dwz,
+ ULONGEST signature)
+{
+ auto result
+ = std::make_unique<signatured_type> (this, section, sect_off, length,
+ is_dwz, signature);
result->index = all_units.size ();
- result->is_debug_types = true;
tu_stats.nr_tus++;
return result;
}
-/* See read.h. */
-
-dwarf2_per_cu_data_up
-create_cu_from_index_list (dwarf2_per_bfd *per_bfd,
- struct dwarf2_section_info *section,
- int is_dwz,
- sect_offset sect_off, ULONGEST length)
-{
- dwarf2_per_cu_data_up the_cu = per_bfd->allocate_per_cu ();
- the_cu->sect_off = sect_off;
- the_cu->set_length (length);
- the_cu->section = section;
- the_cu->is_dwz = is_dwz;
- return the_cu;
-}
-
/* die_reader_func for dw2_get_file_names. */
static void
-dw2_get_file_names_reader (const struct die_reader_specs *reader,
- struct die_info *comp_unit_die)
+dw2_get_file_names_reader (dwarf2_cu *cu, die_info *comp_unit_die)
{
- struct dwarf2_cu *cu = reader->cu;
- struct dwarf2_per_cu_data *this_cu = cu->per_cu;
+ dwarf2_per_cu *this_cu = cu->per_cu;
dwarf2_per_objfile *per_objfile = cu->per_objfile;
- struct dwarf2_per_cu_data *lh_cu;
- struct attribute *attr;
- void **slot;
- struct quick_file_names *qfn;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
gdb_assert (! this_cu->is_debug_types);
@@ -1867,30 +1727,24 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
if (comp_unit_die->tag == DW_TAG_partial_unit)
return;
- lh_cu = this_cu;
- slot = NULL;
-
line_header_up lh;
- sect_offset line_offset {};
file_and_directory &fnd = find_file_and_directory (comp_unit_die, cu);
+ std::optional<stmt_list_hash> stmt_list_hash_key;
+ attribute *attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu);
- attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu);
if (attr != nullptr && attr->form_is_unsigned ())
{
- struct quick_file_names find_entry;
-
- line_offset = (sect_offset) attr->as_unsigned ();
+ sect_offset line_offset = (sect_offset) attr->as_unsigned ();
/* We may have already read in this line header (TU line header sharing).
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 (per_objfile->per_bfd->quick_file_names_table.get (),
- &find_entry, INSERT);
- if (*slot != NULL)
+ stmt_list_hash_key = {cu->dwo_unit, line_offset};
+
+ if (auto it = per_bfd->quick_file_names_table.find (*stmt_list_hash_key);
+ it != per_bfd->quick_file_names_table.end ())
{
- lh_cu->file_names = (struct quick_file_names *) *slot;
+ this_cu->file_names = it->second;
return;
}
@@ -1903,12 +1757,11 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
else if (lh == nullptr)
return;
- qfn = XOBNEW (&per_objfile->per_bfd->obstack, struct quick_file_names);
- qfn->hash.dwo_unit = cu->dwo_unit;
- qfn->hash.line_sect_off = line_offset;
+ auto *qfn = XOBNEW (&per_bfd->obstack, quick_file_names);
+
/* There may not be a DW_AT_stmt_list. */
- if (slot != nullptr)
- *slot = qfn;
+ if (stmt_list_hash_key.has_value ())
+ per_bfd->quick_file_names_table.emplace (*stmt_list_hash_key, qfn);
std::vector<const char *> include_names;
if (lh != nullptr)
@@ -1928,9 +1781,8 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
qfn->num_file_names = offset + include_names.size ();
qfn->comp_dir = fnd.intern_comp_dir (per_objfile->objfile);
- qfn->file_names =
- XOBNEWVEC (&per_objfile->per_bfd->obstack, const char *,
- qfn->num_file_names);
+ qfn->file_names
+ = XOBNEWVEC (&per_bfd->obstack, const char *, qfn->num_file_names);
if (offset != 0)
qfn->file_names[0] = per_objfile->objfile->intern (fnd.get_name ());
@@ -1940,15 +1792,14 @@ dw2_get_file_names_reader (const struct die_reader_specs *reader,
qfn->real_names = NULL;
- lh_cu->file_names = qfn;
+ this_cu->file_names = qfn;
}
/* A helper for the "quick" functions which attempts to read the line
table for THIS_CU. */
static struct quick_file_names *
-dw2_get_file_names (dwarf2_per_cu_data *this_cu,
- dwarf2_per_objfile *per_objfile)
+dw2_get_file_names (dwarf2_per_cu *this_cu, dwarf2_per_objfile *per_objfile)
{
/* This should never be called for TUs. */
gdb_assert (! this_cu->is_debug_types);
@@ -1956,9 +1807,11 @@ dw2_get_file_names (dwarf2_per_cu_data *this_cu,
if (this_cu->files_read)
return this_cu->file_names;
- cutu_reader reader (this_cu, per_objfile);
- if (!reader.dummy_p)
- dw2_get_file_names_reader (&reader, reader.comp_unit_die);
+ cutu_reader reader (*this_cu, *per_objfile, nullptr,
+ per_objfile->get_cu (this_cu), true, language_minimal,
+ nullptr);
+ if (!reader.is_dummy ())
+ dw2_get_file_names_reader (reader.cu (), reader.top_level_die ());
return this_cu->file_names;
}
@@ -1994,8 +1847,7 @@ struct symtab *
dwarf2_base_index_functions::find_last_source_symtab (struct objfile *objfile)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
- dwarf2_per_cu_data *dwarf_cu
- = per_objfile->per_bfd->all_units.back ().get ();
+ dwarf2_per_cu *dwarf_cu = per_objfile->per_bfd->all_units.back ().get ();
compunit_symtab *cust = dw2_instantiate_symtab (dwarf_cu, per_objfile, false);
if (cust == NULL)
@@ -2007,7 +1859,7 @@ dwarf2_base_index_functions::find_last_source_symtab (struct objfile *objfile)
/* See read.h. */
void
-dwarf2_per_cu_data::free_cached_file_names ()
+dwarf2_per_cu::free_cached_file_names ()
{
if (fnd != nullptr)
fnd->forget_fullname ();
@@ -2049,25 +1901,22 @@ dwarf2_base_index_functions::print_stats (struct objfile *objfile,
for (int i = 0; i < total; ++i)
{
- dwarf2_per_cu_data *per_cu = per_objfile->per_bfd->get_cu (i);
+ dwarf2_per_cu *per_cu = per_objfile->per_bfd->get_unit (i);
if (!per_objfile->symtab_set_p (per_cu))
++count;
}
- gdb_printf (_(" Number of read CUs: %d\n"), total - count);
- gdb_printf (_(" Number of unread CUs: %d\n"), count);
+ gdb_printf (_(" Number of read units: %d\n"), total - count);
+ gdb_printf (_(" Number of unread units: %d\n"), count);
}
void
dwarf2_base_index_functions::expand_all_symtabs (struct objfile *objfile)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
- int total_units = per_objfile->per_bfd->all_units.size ();
- for (int i = 0; i < total_units; ++i)
+ for (dwarf2_per_cu *per_cu : all_units_range (per_objfile->per_bfd))
{
- dwarf2_per_cu_data *per_cu = per_objfile->per_bfd->get_cu (i);
-
/* We don't want to directly expand a partial CU, because if we
read it with the wrong language, then assertion failures can
be triggered later on. See PR symtab/23010. So, tell
@@ -2081,11 +1930,11 @@ dwarf2_base_index_functions::expand_all_symtabs (struct objfile *objfile)
bool
dw2_expand_symtabs_matching_one
- (dwarf2_per_cu_data *per_cu,
+ (dwarf2_per_cu *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,
- gdb::function_view<expand_symtabs_lang_matcher_ftype> lang_matcher)
+ expand_symtabs_file_matcher file_matcher,
+ expand_symtabs_expansion_listener expansion_notify,
+ expand_symtabs_lang_matcher lang_matcher)
{
if (file_matcher != nullptr && !per_cu->mark)
return true;
@@ -2114,8 +1963,7 @@ dw2_expand_symtabs_matching_one
void
dw_expand_symtabs_matching_file_matcher
- (dwarf2_per_objfile *per_objfile,
- gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher)
+ (dwarf2_per_objfile *per_objfile, expand_symtabs_file_matcher file_matcher)
{
if (file_matcher == NULL)
return;
@@ -2250,7 +2098,7 @@ dwarf2_base_index_functions::find_pc_sect_compunit_symtab
return nullptr;
CORE_ADDR baseaddr = objfile->text_section_offset ();
- struct dwarf2_per_cu_data *data
+ dwarf2_per_cu *data
= per_bfd->index_table->lookup ((unrelocated_addr) (pc - baseaddr));
if (data == nullptr)
return nullptr;
@@ -2270,16 +2118,15 @@ dwarf2_base_index_functions::find_pc_sect_compunit_symtab
}
void
-dwarf2_base_index_functions::map_symbol_filenames
- (struct objfile *objfile,
- gdb::function_view<symbol_filename_ftype> fun,
- bool need_fullname)
+dwarf2_base_index_functions::map_symbol_filenames (objfile *objfile,
+ symbol_filename_listener fun,
+ bool need_fullname)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
/* Use caches to ensure we only call FUN once for each filename. */
filename_seen_cache filenames_cache;
- std::unordered_set<quick_file_names *> qfn_cache;
+ gdb::unordered_set<quick_file_names *> qfn_cache;
/* The rule is CUs specify all the files, including those used by any TU,
so there's no need to scan TUs here. We can ignore file names coming
@@ -2297,8 +2144,7 @@ dwarf2_base_index_functions::map_symbol_filenames
}
}
- for (dwarf2_per_cu_data *per_cu
- : all_units_range (per_objfile->per_bfd))
+ for (dwarf2_per_cu *per_cu : all_units_range (per_objfile->per_bfd))
{
/* We only need to look at symtabs not already expanded. */
if (per_cu->is_debug_types || per_objfile->symtab_set_p (per_cu))
@@ -2451,9 +2297,6 @@ dwarf2_initialize_objfile (struct objfile *objfile,
dwarf_read_debug_printf ("readnow requested");
create_all_units (per_objfile);
- per_bfd->quick_file_names_table
- = create_quick_file_names_table (per_bfd->all_units.size ());
-
objfile->qf.emplace_front (new readnow_functions);
}
/* Was a GDB index already read when we processed an objfile sharing
@@ -2490,15 +2333,9 @@ dwarf2_initialize_objfile (struct objfile *objfile,
return true;
}
-
-
-/* Find the base address of the compilation unit for range lists and
- location lists. It will normally be specified by DW_AT_low_pc.
- In DWARF-3 draft 4, the base address could be overridden by
- DW_AT_entry_pc. It's been removed, but GCC still uses this for
- compilation units with discontinuous ranges. */
+/* See read.h. */
-static void
+void
dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu)
{
struct attribute *attr;
@@ -2520,13 +2357,13 @@ dwarf2_find_base_address (struct die_info *die, struct dwarf2_cu *cu)
THIS_CU. */
static struct dwarf2_section_info *
-get_abbrev_section_for_cu (struct dwarf2_per_cu_data *this_cu)
+get_abbrev_section_for_cu (dwarf2_per_cu *this_cu)
{
struct dwarf2_section_info *abbrev;
dwarf2_per_bfd *per_bfd = this_cu->per_bfd;
if (this_cu->is_dwz)
- abbrev = &dwarf2_get_dwz_file (per_bfd, true)->abbrev;
+ abbrev = &per_bfd->get_dwz_file (true)->abbrev;
else
abbrev = &per_bfd->abbrev;
@@ -2562,179 +2399,29 @@ read_abbrev_offset (dwarf2_per_objfile *per_objfile,
return (sect_offset) read_offset (abfd, info_ptr, offset_size);
}
-static hashval_t
-hash_signatured_type (const void *item)
-{
- const struct signatured_type *sig_type
- = (const struct signatured_type *) item;
-
- /* This drops the top 32 bits of the signature, but is ok for a hash. */
- return sig_type->signature;
-}
-
-static int
-eq_signatured_type (const void *item_lhs, const void *item_rhs)
-{
- const struct signatured_type *lhs = (const struct signatured_type *) item_lhs;
- const struct signatured_type *rhs = (const struct signatured_type *) item_rhs;
-
- return lhs->signature == rhs->signature;
-}
-
-/* See read.h. */
+/* Add an entry for signature SIG to per_bfd->signatured_types. */
-htab_up
-allocate_signatured_type_table ()
+static signatured_type_set::iterator
+add_type_unit (dwarf2_per_bfd *per_bfd, dwarf2_section_info *section,
+ sect_offset sect_off, unsigned int length, ULONGEST sig)
{
- return htab_up (htab_create_alloc (41,
- hash_signatured_type,
- eq_signatured_type,
- NULL, xcalloc, xfree));
-}
-
-/* A helper for create_debug_types_hash_table. Read types from SECTION
- and fill them into TYPES_HTAB. It will process only type units,
- therefore DW_UT_type. */
-
-static void
-create_debug_type_hash_table (dwarf2_per_objfile *per_objfile,
- struct dwo_file *dwo_file,
- dwarf2_section_info *section, htab_up &types_htab,
- rcuh_kind section_kind)
-{
- struct objfile *objfile = per_objfile->objfile;
- struct dwarf2_section_info *abbrev_section;
- bfd *abfd;
- const gdb_byte *info_ptr, *end_ptr;
-
- abbrev_section = &dwo_file->sections.abbrev;
-
- dwarf_read_debug_printf ("Reading %s for %s",
- section->get_name (),
- abbrev_section->get_file_name ());
-
- section->read (objfile);
- info_ptr = section->buffer;
-
- if (info_ptr == NULL)
- return;
-
- /* We can't set abfd until now because the section may be empty or
- not present, in which case the bfd is unknown. */
- abfd = section->get_bfd_owner ();
-
- /* We don't use cutu_reader here because we don't need to read
- any dies: the signature is in the header. */
-
- end_ptr = info_ptr + section->size;
- while (info_ptr < end_ptr)
- {
- signatured_type_up sig_type;
- struct dwo_unit *dwo_tu;
- void **slot;
- const gdb_byte *ptr = info_ptr;
- struct comp_unit_head header;
- unsigned int length;
-
- sect_offset sect_off = (sect_offset) (ptr - section->buffer);
-
- /* Initialize it due to a false compiler warning. */
- header.signature = -1;
- header.type_cu_offset_in_tu = (cu_offset) -1;
-
- /* We need to read the type's signature in order to build the hash
- table, but we don't need anything else just yet. */
-
- ptr = read_and_check_comp_unit_head (per_objfile, &header, section,
- abbrev_section, ptr, section_kind);
-
- length = header.get_length_with_initial ();
-
- /* Skip dummy type units. */
- if (ptr >= info_ptr + length
- || peek_abbrev_code (abfd, ptr) == 0
- || (header.unit_type != DW_UT_type
- && header.unit_type != DW_UT_split_type))
- {
- info_ptr += length;
- continue;
- }
-
- if (types_htab == NULL)
- types_htab = allocate_dwo_unit_table ();
-
- dwo_tu = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack, dwo_unit);
- dwo_tu->dwo_file = dwo_file;
- dwo_tu->signature = header.signature;
- dwo_tu->type_offset_in_tu = header.type_cu_offset_in_tu;
- dwo_tu->section = section;
- dwo_tu->sect_off = sect_off;
- dwo_tu->length = length;
-
- slot = htab_find_slot (types_htab.get (), dwo_tu, INSERT);
- gdb_assert (slot != NULL);
- if (*slot != NULL)
- complaint (_("debug type entry at offset %s is duplicate to"
- " the entry at offset %s, signature %s"),
- sect_offset_str (sect_off),
- sect_offset_str (dwo_tu->sect_off),
- hex_string (header.signature));
- *slot = dwo_tu;
-
- dwarf_read_debug_printf_v (" offset %s, signature %s",
- sect_offset_str (sect_off),
- hex_string (header.signature));
-
- info_ptr += length;
- }
-}
-
-/* Create the hash table of all entries in the .debug_types
- (or .debug_types.dwo) section(s).
- DWO_FILE is a pointer to the DWO file object.
-
- The result is a pointer to the hash table or NULL if there are no types.
-
- Note: This function processes DWO files only, not DWP files. */
-
-static void
-create_debug_types_hash_table (dwarf2_per_objfile *per_objfile,
- struct dwo_file *dwo_file,
- gdb::array_view<dwarf2_section_info> type_sections,
- htab_up &types_htab)
-{
- for (dwarf2_section_info &section : type_sections)
- create_debug_type_hash_table (per_objfile, dwo_file, &section, types_htab,
- rcuh_kind::TYPE);
-}
-
-/* Add an entry for signature SIG to dwarf2_per_objfile->per_bfd->signatured_types.
- If SLOT is non-NULL, it is the entry to use in the hash table.
- Otherwise we find one. */
-
-static struct signatured_type *
-add_type_unit (dwarf2_per_objfile *per_objfile, ULONGEST sig, void **slot)
-{
- if (per_objfile->per_bfd->all_units.size ()
- == per_objfile->per_bfd->all_units.capacity ())
- ++per_objfile->per_bfd->tu_stats.nr_all_type_units_reallocs;
+ if (per_bfd->all_units.size () == per_bfd->all_units.capacity ())
+ ++per_bfd->tu_stats.nr_all_type_units_reallocs;
signatured_type_up sig_type_holder
- = per_objfile->per_bfd->allocate_signatured_type (sig);
+ = per_bfd->allocate_signatured_type (section, sect_off, length,
+ false /* is_dwz */, sig);
signatured_type *sig_type = sig_type_holder.get ();
- per_objfile->per_bfd->all_units.emplace_back
- (sig_type_holder.release ());
+ per_bfd->all_units.emplace_back (sig_type_holder.release ());
+ auto emplace_ret = per_bfd->signatured_types.emplace (sig_type);
+
+ /* Assert that an insertion took place - that there wasn't a type unit with
+ that signature already. */
+ gdb_assert (emplace_ret.second);
- if (slot == NULL)
- {
- slot = htab_find_slot (per_objfile->per_bfd->signatured_types.get (),
- sig_type, INSERT);
- }
- gdb_assert (*slot == NULL);
- *slot = sig_type;
/* The rest of sig_type must be filled in by the caller. */
- return sig_type;
+ return emplace_ret.first;
}
/* Subroutine of lookup_dwo_signatured_type and lookup_dwp_signatured_type.
@@ -2745,8 +2432,6 @@ fill_in_sig_entry_from_dwo_entry (dwarf2_per_objfile *per_objfile,
struct signatured_type *sig_entry,
struct dwo_unit *dwo_entry)
{
- dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
-
/* Make sure we're not clobbering something we don't expect to. */
gdb_assert (! sig_entry->queued);
gdb_assert (per_objfile->get_cu (sig_entry) == NULL);
@@ -2755,15 +2440,11 @@ fill_in_sig_entry_from_dwo_entry (dwarf2_per_objfile *per_objfile,
gdb_assert (to_underlying (sig_entry->type_offset_in_section) == 0
|| (to_underlying (sig_entry->type_offset_in_section)
== to_underlying (dwo_entry->type_offset_in_tu)));
- gdb_assert (sig_entry->type_unit_group == NULL);
+ gdb_assert (!sig_entry->type_unit_group_key.has_value ());
gdb_assert (sig_entry->dwo_unit == NULL
|| sig_entry->dwo_unit == dwo_entry);
- sig_entry->section = dwo_entry->section;
- sig_entry->sect_off = dwo_entry->sect_off;
- sig_entry->set_length (dwo_entry->length, false);
sig_entry->reading_dwo_directly = 1;
- sig_entry->per_bfd = per_bfd;
sig_entry->type_offset_in_tu = dwo_entry->type_offset_in_tu;
sig_entry->dwo_unit = dwo_entry;
}
@@ -2784,27 +2465,17 @@ static struct signatured_type *
lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
- struct dwo_file *dwo_file;
- struct dwo_unit find_dwo_entry, *dwo_entry;
- void **slot;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
gdb_assert (cu->dwo_unit);
- /* If TU skeletons have been removed then we may not have read in any
- TUs yet. */
- if (per_objfile->per_bfd->signatured_types == NULL)
- 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
of types. If this is the first time we're reading this TU, and
the TU has an entry in .gdb_index, replace the recorded data from
.gdb_index with this TU. */
- signatured_type find_sig_entry (sig);
- slot = htab_find_slot (per_objfile->per_bfd->signatured_types.get (),
- &find_sig_entry, INSERT);
- signatured_type *sig_entry = (struct signatured_type *) *slot;
+ auto sig_type_it = per_bfd->signatured_types.find (sig);
/* We can get here with the TU already read, *or* in the process of being
read. Don't reassign the global entry to point to this DWO if that's
@@ -2815,30 +2486,29 @@ lookup_dwo_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
/* Have we already tried to read this TU?
Note: sig_entry can be NULL if the skeleton TU was removed (thus it
needn't exist in the global table yet). */
- if (sig_entry != NULL && sig_entry->tu_read)
- return sig_entry;
+ if (sig_type_it != per_bfd->signatured_types.end ()
+ && (*sig_type_it)->tu_read)
+ return *sig_type_it;
/* Note: cu->dwo_unit is the dwo_unit that references this TU, not the
dwo_unit of the TU itself. */
- dwo_file = cu->dwo_unit->dwo_file;
+ dwo_file *dwo_file = cu->dwo_unit->dwo_file;
+ auto it = dwo_file->tus.find (sig);
+ if (it == dwo_file->tus.end ())
+ return nullptr;
- /* Ok, this is the first time we're reading this TU. */
- if (dwo_file->tus == NULL)
- return NULL;
- find_dwo_entry.signature = sig;
- dwo_entry = (struct dwo_unit *) htab_find (dwo_file->tus.get (),
- &find_dwo_entry);
- if (dwo_entry == NULL)
- return NULL;
+ dwo_unit *dwo_entry = it->get ();
/* If the global table doesn't have an entry for this TU, add one. */
- if (sig_entry == NULL)
- sig_entry = add_type_unit (per_objfile, sig, slot);
+ if (sig_type_it == per_bfd->signatured_types.end ())
+ sig_type_it = add_type_unit (per_bfd, dwo_entry->section,
+ dwo_entry->sect_off, dwo_entry->length, sig);
+
+ if ((*sig_type_it)->dwo_unit == nullptr)
+ fill_in_sig_entry_from_dwo_entry (per_objfile, *sig_type_it, dwo_entry);
- if (sig_entry->dwo_unit == nullptr)
- fill_in_sig_entry_from_dwo_entry (per_objfile, sig_entry, dwo_entry);
- sig_entry->tu_read = 1;
- return sig_entry;
+ (*sig_type_it)->tu_read = 1;
+ return *sig_type_it;
}
/* Subroutine of lookup_signatured_type.
@@ -2850,40 +2520,33 @@ static struct signatured_type *
lookup_dwp_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
- struct dwp_file *dwp_file = get_dwp_file (per_objfile);
- struct dwo_unit *dwo_entry;
- void **slot;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
+ dwp_file *dwp_file = per_objfile->per_bfd->dwp_file.get ();
gdb_assert (cu->dwo_unit);
gdb_assert (dwp_file != NULL);
- /* If TU skeletons have been removed then we may not have read in any
- TUs yet. */
- if (per_objfile->per_bfd->signatured_types == NULL)
- per_objfile->per_bfd->signatured_types = allocate_signatured_type_table ();
-
- signatured_type find_sig_entry (sig);
- slot = htab_find_slot (per_objfile->per_bfd->signatured_types.get (),
- &find_sig_entry, INSERT);
- signatured_type *sig_entry = (struct signatured_type *) *slot;
+ auto sig_type_it = per_bfd->signatured_types.find (sig);
/* Have we already tried to read this TU?
Note: sig_entry can be NULL if the skeleton TU was removed (thus it
needn't exist in the global table yet). */
- if (sig_entry != NULL)
- return sig_entry;
+ if (sig_type_it != per_bfd->signatured_types.end ())
+ return *sig_type_it;
if (dwp_file->tus == NULL)
return NULL;
- dwo_entry = lookup_dwo_unit_in_dwp (per_objfile, dwp_file, NULL, sig,
- 1 /* is_debug_types */);
+
+ auto dwo_entry = lookup_dwo_unit_in_dwp (per_bfd, dwp_file, NULL, sig,
+ 1 /* is_debug_types */);
if (dwo_entry == NULL)
return NULL;
- sig_entry = add_type_unit (per_objfile, sig, slot);
- fill_in_sig_entry_from_dwo_entry (per_objfile, sig_entry, dwo_entry);
+ sig_type_it = add_type_unit (per_bfd, dwo_entry->section,
+ dwo_entry->sect_off, dwo_entry->length, sig);
+ fill_in_sig_entry_from_dwo_entry (per_objfile, *sig_type_it, dwo_entry);
- return sig_entry;
+ return *sig_type_it;
}
/* Lookup a signature based type for DW_FORM_ref_sig8.
@@ -2894,46 +2557,45 @@ static struct signatured_type *
lookup_signatured_type (struct dwarf2_cu *cu, ULONGEST sig)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
if (cu->dwo_unit)
{
/* We're in a DWO/DWP file, and we're using .gdb_index.
These cases require special processing. */
- if (get_dwp_file (per_objfile) == NULL)
+ if (per_objfile->per_bfd->dwp_file == nullptr)
return lookup_dwo_signatured_type (cu, sig);
else
return lookup_dwp_signatured_type (cu, sig);
}
else
{
- if (per_objfile->per_bfd->signatured_types == NULL)
- return NULL;
- signatured_type find_entry (sig);
- return ((struct signatured_type *)
- htab_find (per_objfile->per_bfd->signatured_types.get (),
- &find_entry));
+ auto sig_type_it = per_bfd->signatured_types.find (sig);
+
+ if (sig_type_it != per_bfd->signatured_types.end ())
+ return *sig_type_it;
+
+ return nullptr;
}
}
/* Low level DIE reading support. */
-/* Initialize a die_reader_specs struct from a dwarf2_cu struct. */
+/* Initialize a cutu_reader from a dwarf2_cu. */
-static void
-init_cu_die_reader (struct die_reader_specs *reader,
- struct dwarf2_cu *cu,
- struct dwarf2_section_info *section,
- struct dwo_file *dwo_file,
- const abbrev_table *abbrev_table)
+void
+cutu_reader::init_cu_die_reader (dwarf2_cu *cu, dwarf2_section_info *section,
+ struct dwo_file *dwo_file,
+ const struct abbrev_table *abbrev_table)
{
gdb_assert (section->readin && section->buffer != NULL);
- reader->abfd = section->get_bfd_owner ();
- reader->cu = cu;
- reader->dwo_file = dwo_file;
- reader->die_section = section;
- reader->buffer = section->buffer;
- reader->buffer_end = section->buffer + section->size;
- reader->abbrev_table = abbrev_table;
+ m_abfd = section->get_bfd_owner ();
+ m_cu = cu;
+ m_dwo_file = dwo_file;
+ m_die_section = section;
+ m_buffer = section->buffer;
+ m_buffer_end = section->buffer + section->size;
+ m_abbrev_table = abbrev_table;
}
/* Subroutine of cutu_reader to simplify it.
@@ -2943,33 +2605,27 @@ init_cu_die_reader (struct die_reader_specs *reader,
STUB_COMP_UNIT_DIE is for the stub DIE, we copy over certain attributes
from it to the DIE in the DWO. If NULL we are skipping the stub.
+
STUB_COMP_DIR is similar to STUB_COMP_UNIT_DIE: When reading a TU directly
from the DWO file, bypassing the stub, it contains the DW_AT_comp_dir
attribute of the referencing CU. At most one of STUB_COMP_UNIT_DIE and
STUB_COMP_DIR may be non-NULL.
- *RESULT_READER,*RESULT_INFO_PTR,*RESULT_COMP_UNIT_DIE
- are filled in with the info of the DIE from the DWO file.
+
+ *RESULT_READER and *RESULT_TOP_LEVEL_DIE are filled in with the info of the
+ DIE from the DWO file.
+
*RESULT_DWO_ABBREV_TABLE will be filled in with the abbrev table allocated
from the dwo. Since *RESULT_READER references this abbrev table, it must be
- kept around for at least as long as *RESULT_READER.
+ kept around for at least as long as *RESULT_READER. */
- The result is non-zero if a valid (non-dummy) DIE was found. */
-
-static int
-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_reader_specs *result_reader,
- const gdb_byte **result_info_ptr,
- struct die_info **result_comp_unit_die,
- abbrev_table_up *result_dwo_abbrev_table)
+void
+cutu_reader::read_cutu_die_from_dwo (dwarf2_cu *cu, dwo_unit *dwo_unit,
+ die_info *stub_comp_unit_die,
+ const char *stub_comp_dir)
{
- dwarf2_per_objfile *per_objfile = cu->per_objfile;
- dwarf2_per_cu_data *per_cu = cu->per_cu;
- struct objfile *objfile = per_objfile->objfile;
+ dwarf2_per_cu *per_cu = cu->per_cu;
+ struct objfile *objfile = cu->per_objfile->objfile;
bfd *abfd;
- const gdb_byte *begin_info_ptr, *info_ptr;
struct dwarf2_section_info *dwo_abbrev_section;
/* At most one of these may be provided. */
@@ -3036,17 +2692,18 @@ read_cutu_die_from_dwo (dwarf2_cu *cu,
dwarf2_section_info *section = dwo_unit->section;
section->read (objfile);
abfd = section->get_bfd_owner ();
- begin_info_ptr = info_ptr = (section->buffer
- + to_underlying (dwo_unit->sect_off));
+ m_info_ptr = section->buffer + to_underlying (dwo_unit->sect_off);
+ const gdb_byte *begin_info_ptr = m_info_ptr;
dwo_abbrev_section = &dwo_unit->dwo_file->sections.abbrev;
if (per_cu->is_debug_types)
{
signatured_type *sig_type = (struct signatured_type *) per_cu;
- info_ptr = read_and_check_comp_unit_head (per_objfile, &cu->header,
- section, dwo_abbrev_section,
- info_ptr, rcuh_kind::TYPE);
+ m_info_ptr = read_and_check_unit_head (&cu->header, section,
+ dwo_abbrev_section, m_info_ptr,
+ ruh_kind::TYPE);
+
/* This is not an assert because it can be caused by bad debug info. */
if (sig_type->signature != cu->header.signature)
{
@@ -3062,7 +2719,7 @@ read_cutu_die_from_dwo (dwarf2_cu *cu,
/* For DWOs coming from DWP files, we don't know the CU length
nor the type's offset in the TU until now. */
dwo_unit->length = cu->header.get_length_with_initial ();
- dwo_unit->type_offset_in_tu = cu->header.type_cu_offset_in_tu;
+ dwo_unit->type_offset_in_tu = cu->header.type_offset_in_tu;
/* Establish the type offset that can be used to lookup the type.
For DWO files, we don't know it until now. */
@@ -3071,9 +2728,9 @@ read_cutu_die_from_dwo (dwarf2_cu *cu,
}
else
{
- info_ptr = read_and_check_comp_unit_head (per_objfile, &cu->header,
- section, dwo_abbrev_section,
- info_ptr, rcuh_kind::COMPILE);
+ m_info_ptr = read_and_check_unit_head (&cu->header, section,
+ dwo_abbrev_section, m_info_ptr,
+ ruh_kind::COMPILE);
gdb_assert (dwo_unit->sect_off == cu->header.sect_off);
/* For DWOs coming from DWP files, we don't know the CU length
until now. */
@@ -3081,26 +2738,26 @@ read_cutu_die_from_dwo (dwarf2_cu *cu,
}
dwo_abbrev_section->read (objfile);
- *result_dwo_abbrev_table
+ m_dwo_abbrev_table
= abbrev_table::read (dwo_abbrev_section, cu->header.abbrev_sect_off);
- init_cu_die_reader (result_reader, cu, section, dwo_unit->dwo_file,
- result_dwo_abbrev_table->get ());
+ this->init_cu_die_reader (cu, section, dwo_unit->dwo_file,
+ m_dwo_abbrev_table.get ());
+
+ /* Skip dummy compilation units. */
+ if (m_info_ptr >= begin_info_ptr + dwo_unit->length
+ || peek_abbrev_code (abfd, m_info_ptr) == 0)
+ {
+ m_dummy_p = true;
+ return;
+ }
/* Read in the die, filling in the attributes from the stub. This
has the benefit of simplifying the rest of the code - all the
work to maintain the illusion of a single
DW_TAG_{compile,type}_unit DIE is done here. */
- info_ptr = read_toplevel_die (result_reader, result_comp_unit_die, info_ptr,
- gdb::make_array_view (attributes,
- next_attr_idx));
-
- /* Skip dummy compilation units. */
- if (info_ptr >= begin_info_ptr + dwo_unit->length
- || peek_abbrev_code (abfd, info_ptr) == 0)
- return 0;
-
- *result_info_ptr = info_ptr;
- return 1;
+ m_top_level_die
+ = this->read_toplevel_die (gdb::make_array_view (attributes,
+ next_attr_idx));
}
/* Return the signature of the compile unit, if found. In DWARF 4 and before,
@@ -3119,27 +2776,23 @@ lookup_dwo_id (struct dwarf2_cu *cu, struct die_info* comp_unit_die)
}
/* Subroutine of cutu_reader to simplify it.
- Look up the DWO unit specified by COMP_UNIT_DIE of THIS_CU.
- Returns NULL if the specified DWO unit cannot be found. */
+ Look up the DWO unit specified by COMP_UNIT_DIE of CU.
-static struct dwo_unit *
-lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die, const char *dwo_name)
-{
-#if CXX_STD_THREAD
- /* We need a lock here to handle the DWO hash table. */
- static std::mutex dwo_lock;
+ DWO_NAME is the name (DW_AT_dwo_name) of the DWO unit already read from
+ COMP_UNIT_DIE.
- std::lock_guard<std::mutex> guard (dwo_lock);
-#endif
+ Returns nullptr if the specified DWO unit cannot be found. */
- dwarf2_per_cu_data *per_cu = cu->per_cu;
+dwo_unit *
+cutu_reader::lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die,
+ const char *dwo_name)
+{
+ dwarf2_per_cu *per_cu = cu->per_cu;
struct dwo_unit *dwo_unit;
const char *comp_dir;
gdb_assert (cu != NULL);
- /* Yeah, we look dwo_name up again, but it simplifies the code. */
- dwo_name = dwarf2_dwo_name (comp_unit_die, cu);
comp_dir = dwarf2_string_attr (comp_unit_die, DW_AT_comp_dir, cu);
if (per_cu->is_debug_types)
@@ -3152,7 +2805,7 @@ lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die, const char *dwo_name)
error (_(DWARF_ERROR_PREFIX
"missing dwo_id for dwo_name %s"
" [in module %s]"),
- dwo_name, bfd_get_filename (per_cu->per_bfd->obfd));
+ dwo_name, per_cu->per_bfd->filename ());
dwo_unit = lookup_dwo_comp_unit (cu, dwo_name, comp_dir, *signature);
}
@@ -3165,9 +2818,10 @@ lookup_dwo_unit (dwarf2_cu *cu, die_info *comp_unit_die, const char *dwo_name)
Read a TU directly from a DWO file, bypassing the stub. */
void
-cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
+cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu *this_cu,
dwarf2_per_objfile *per_objfile,
- dwarf2_cu *existing_cu)
+ dwarf2_cu *existing_cu,
+ enum language pretend_language)
{
struct signatured_type *sig_type;
@@ -3199,16 +2853,9 @@ cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
abbrev table. When reading DWOs with skeletonless TUs, all the TUs
could share abbrev tables. */
- 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,
- &comp_unit_die,
- &m_dwo_abbrev_table) == 0)
- {
- /* Dummy die. */
- dummy_p = true;
- }
+ read_cutu_die_from_dwo (cu, sig_type->dwo_unit, NULL /* stub_comp_unit_die */,
+ sig_type->dwo_unit->dwo_file->comp_dir);
+ prepare_one_comp_unit (cu, pretend_language);
}
/* Initialize a CU (or TU) and read its DIEs.
@@ -3221,17 +2868,16 @@ cutu_reader::init_tu_and_read_dwo_dies (dwarf2_per_cu_data *this_cu,
If EXISTING_CU is non-NULL, then use it. Otherwise, a new CU is
allocated. */
-cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
- dwarf2_per_objfile *per_objfile,
+cutu_reader::cutu_reader (dwarf2_per_cu &this_cu,
+ dwarf2_per_objfile &per_objfile,
const struct abbrev_table *abbrev_table,
dwarf2_cu *existing_cu,
bool skip_partial,
- const abbrev_table_cache *cache)
- : die_reader_specs {},
- m_this_cu (this_cu)
+ enum language pretend_language,
+ const abbrev_table_cache *abbrev_cache)
{
- struct objfile *objfile = per_objfile->objfile;
- struct dwarf2_section_info *section = this_cu->section;
+ struct objfile *objfile = per_objfile.objfile;
+ struct dwarf2_section_info *section = this_cu.section;
bfd *abfd = section->get_bfd_owner ();
const gdb_byte *begin_info_ptr;
struct signatured_type *sig_type = NULL;
@@ -3243,26 +2889,28 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
if (dwarf_die_debug)
gdb_printf (gdb_stdlog, "Reading %s unit at offset %s\n",
- this_cu->is_debug_types ? "type" : "comp",
- sect_offset_str (this_cu->sect_off));
+ this_cu.is_debug_types ? "type" : "comp",
+ sect_offset_str (this_cu.sect_off));
/* If we're reading a TU directly from a DWO file, including a virtual DWO
file (instead of going through the stub), short-circuit all of this. */
- if (this_cu->reading_dwo_directly)
+ if (this_cu.reading_dwo_directly)
{
/* Narrow down the scope of possibilities to have to understand. */
- gdb_assert (this_cu->is_debug_types);
+ gdb_assert (this_cu.is_debug_types);
gdb_assert (abbrev_table == NULL);
- init_tu_and_read_dwo_dies (this_cu, per_objfile, existing_cu);
+ init_tu_and_read_dwo_dies (&this_cu, &per_objfile, existing_cu,
+ pretend_language);
return;
}
/* This is cheap if the section is already read in. */
section->read (objfile);
- begin_info_ptr = info_ptr = section->buffer + to_underlying (this_cu->sect_off);
+ begin_info_ptr = m_info_ptr
+ = section->buffer + to_underlying (this_cu.sect_off);
- abbrev_section = get_abbrev_section_for_cu (this_cu);
+ abbrev_section = get_abbrev_section_for_cu (&this_cu);
dwarf2_cu *cu;
@@ -3286,229 +2934,207 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
indexer. This assert is avoided in this case because (1) it
is irrelevant, and (2) the get_cu method is not
thread-safe. */
- gdb_assert (cache != nullptr
- || per_objfile->get_cu (this_cu) == nullptr);
- m_new_cu = std::make_unique<dwarf2_cu> (this_cu, per_objfile);
+ gdb_assert (abbrev_cache != nullptr
+ || per_objfile.get_cu (&this_cu) == nullptr);
+ m_new_cu = std::make_unique<dwarf2_cu> (&this_cu, &per_objfile);
cu = m_new_cu.get ();
}
/* Get the header. */
- if (to_underlying (cu->header.first_die_cu_offset) != 0 && !rereading_dwo_cu)
+ if (to_underlying (cu->header.first_die_offset_in_unit) != 0
+ && !rereading_dwo_cu)
{
/* We already have the header, there's no need to read it in again. */
- info_ptr += to_underlying (cu->header.first_die_cu_offset);
+ m_info_ptr += to_underlying (cu->header.first_die_offset_in_unit);
}
else
{
- if (this_cu->is_debug_types)
+ if (this_cu.is_debug_types)
{
- info_ptr = read_and_check_comp_unit_head (per_objfile, &cu->header,
- section, abbrev_section,
- info_ptr, rcuh_kind::TYPE);
+ m_info_ptr = read_and_check_unit_head (&cu->header, section,
+ abbrev_section, m_info_ptr,
+ ruh_kind::TYPE);
/* Since per_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;
+ sig_type = (struct signatured_type *) &this_cu;
gdb_assert (sig_type->signature == cu->header.signature);
gdb_assert (sig_type->type_offset_in_tu
- == cu->header.type_cu_offset_in_tu);
- gdb_assert (this_cu->sect_off == cu->header.sect_off);
+ == cu->header.type_offset_in_tu);
+ gdb_assert (this_cu.sect_off == cu->header.sect_off);
/* LENGTH has not been set yet for type units if we're
using .gdb_index. */
- this_cu->set_length (cu->header.get_length_with_initial ());
+ this_cu.set_length (cu->header.get_length_with_initial ());
/* Establish the type offset that can be used to lookup the type. */
sig_type->type_offset_in_section =
- this_cu->sect_off + to_underlying (sig_type->type_offset_in_tu);
-
- this_cu->set_version (cu->header.version);
+ this_cu.sect_off + to_underlying (sig_type->type_offset_in_tu);
}
else
{
- info_ptr = read_and_check_comp_unit_head (per_objfile, &cu->header,
- section, abbrev_section,
- info_ptr,
- rcuh_kind::COMPILE);
-
- gdb_assert (this_cu->sect_off == cu->header.sect_off);
- this_cu->set_length (cu->header.get_length_with_initial ());
- this_cu->set_version (cu->header.version);
+ m_info_ptr = read_and_check_unit_head (&cu->header, section,
+ abbrev_section, m_info_ptr,
+ ruh_kind::COMPILE);
+
+ gdb_assert (this_cu.sect_off == cu->header.sect_off);
+ this_cu.set_length (cu->header.get_length_with_initial ());
}
}
/* Skip dummy compilation units. */
- if (info_ptr >= begin_info_ptr + this_cu->length ()
- || peek_abbrev_code (abfd, info_ptr) == 0)
- {
- dummy_p = true;
- return;
- }
-
- /* If we don't have them yet, read the abbrevs for this compilation unit.
- And if we need to read them now, make sure they're freed when we're
- done. */
- if (abbrev_table != NULL)
- gdb_assert (cu->header.abbrev_sect_off == abbrev_table->sect_off);
+ if (m_info_ptr >= begin_info_ptr + this_cu.length ()
+ || peek_abbrev_code (abfd, m_info_ptr) == 0)
+ m_dummy_p = true;
else
{
- if (cache != nullptr)
- abbrev_table = cache->find (abbrev_section,
- cu->header.abbrev_sect_off);
- if (abbrev_table == nullptr)
+ /* If we don't have them yet, read the abbrevs for this
+ compilation unit. And if we need to read them now, make sure
+ they're freed when we're done. */
+ if (abbrev_table != NULL)
+ gdb_assert (cu->header.abbrev_sect_off == abbrev_table->sect_off);
+ else
{
- abbrev_section->read (objfile);
- m_abbrev_table_holder
- = abbrev_table::read (abbrev_section, cu->header.abbrev_sect_off);
- abbrev_table = m_abbrev_table_holder.get ();
+ if (abbrev_cache != nullptr)
+ abbrev_table = abbrev_cache->find (abbrev_section,
+ cu->header.abbrev_sect_off);
+ if (abbrev_table == nullptr)
+ {
+ abbrev_section->read (objfile);
+ m_abbrev_table_holder
+ = abbrev_table::read (abbrev_section,
+ cu->header.abbrev_sect_off);
+ abbrev_table = m_abbrev_table_holder.get ();
+ }
}
- }
-
- /* Read the top level CU/TU die. */
- init_cu_die_reader (this, cu, section, NULL, abbrev_table);
- info_ptr = read_toplevel_die (this, &comp_unit_die, info_ptr);
-
- if (skip_partial && comp_unit_die->tag == DW_TAG_partial_unit)
- {
- dummy_p = true;
- return;
- }
-
- /* If we are in a DWO stub, process it and then read in the "real" CU/TU
- from the DWO file. read_cutu_die_from_dwo will allocate the abbreviation
- table from the DWO file and pass the ownership over to us. It will be
- referenced from READER, so we must make sure to free it after we're done
- with READER.
- Note that if USE_EXISTING_OK != 0, and THIS_CU->cu already contains a
- DWO CU, that this test will fail (the attribute will not be present). */
- const char *dwo_name = dwarf2_dwo_name (comp_unit_die, cu);
- if (dwo_name != nullptr)
- {
- struct dwo_unit *dwo_unit;
- struct die_info *dwo_comp_unit_die;
+ /* Read the top level CU/TU die. */
+ this->init_cu_die_reader (cu, section, NULL, abbrev_table);
+ m_top_level_die = this->read_toplevel_die ();
- if (comp_unit_die->has_children)
- {
- complaint (_("compilation unit with DW_AT_GNU_dwo_name"
- " has children (offset %s) [in module %s]"),
- sect_offset_str (this_cu->sect_off),
- bfd_get_filename (abfd));
- }
- dwo_unit = lookup_dwo_unit (cu, comp_unit_die, dwo_name);
- if (dwo_unit != NULL)
+ if (skip_partial && m_top_level_die->tag == DW_TAG_partial_unit)
+ m_dummy_p = true;
+ else
{
- if (read_cutu_die_from_dwo (cu, dwo_unit,
- comp_unit_die, NULL,
- this, &info_ptr,
- &dwo_comp_unit_die,
- &m_dwo_abbrev_table) == 0)
+ /* If we are in a DWO stub, process it and then read in the
+ "real" CU/TU from the DWO file. read_cutu_die_from_dwo
+ will allocate the abbreviation table from the DWO file
+ and pass the ownership over to us. It will be referenced
+ from READER, so we must make sure to free it after we're
+ done with READER.
+
+ Note that if USE_EXISTING_OK != 0, and THIS_CU->cu
+ already contains a DWO CU, that this test will fail (the
+ attribute will not be present). */
+ const char *dwo_name = dwarf2_dwo_name (m_top_level_die, cu);
+ if (dwo_name != nullptr)
{
- /* Dummy die. */
- dummy_p = true;
- return;
+ struct dwo_unit *dwo_unit;
+
+ if (m_top_level_die->has_children)
+ {
+ complaint (_("compilation unit with DW_AT_GNU_dwo_name"
+ " has children (offset %s) [in module %s]"),
+ sect_offset_str (this_cu.sect_off),
+ bfd_get_filename (abfd));
+ }
+
+ dwo_unit = lookup_dwo_unit (cu, m_top_level_die, dwo_name);
+ if (dwo_unit != NULL)
+ read_cutu_die_from_dwo (cu, dwo_unit, m_top_level_die, nullptr);
+ else
+ {
+ /* Yikes, we couldn't find the rest of the DIE, we only have
+ the stub. A complaint has already been logged. There's
+ not much more we can do except pass on the stub DIE to
+ die_reader_func. We don't want to throw an error on bad
+ debug info. */
+ }
}
- comp_unit_die = dwo_comp_unit_die;
- }
- else
- {
- /* Yikes, we couldn't find the rest of the DIE, we only have
- the stub. A complaint has already been logged. There's
- not much more we can do except pass on the stub DIE to
- die_reader_func. We don't want to throw an error on bad
- debug info. */
}
}
-}
-void
-cutu_reader::keep ()
-{
- /* Done, clean up. */
- gdb_assert (!dummy_p);
- if (m_new_cu != NULL)
- {
- /* 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, std::move (m_new_cu));
- }
+ /* Only a dummy unit can be missing the compunit DIE. */
+ gdb_assert (m_dummy_p || m_top_level_die != nullptr);
+ prepare_one_comp_unit (cu, pretend_language);
}
-/* Read CU/TU THIS_CU but do not follow DW_AT_GNU_dwo_name (DW_AT_dwo_name)
- if present. DWO_FILE, if non-NULL, is the DWO file to read (the caller is
- assumed to have already done the lookup to find the DWO file).
+/* See read.h. */
- The caller is required to fill in THIS_CU->section, THIS_CU->offset, and
- THIS_CU->is_debug_types, but nothing else.
+dwarf2_cu_up
+cutu_reader::release_cu ()
+{
+ gdb_assert (!m_dummy_p);
+ gdb_assert (m_new_cu != nullptr);
- We fill in THIS_CU->length.
+ return std::move (m_new_cu);
+}
+
+/* This constructor exists for the special case of reading many units in a row
+ from a given known DWO file.
- THIS_CU->cu is always freed when done.
- This is done in order to not leave THIS_CU->cu in a state where we have
- to care whether it refers to the "main" CU or the DWO CU.
+ THIS_CU is a special dwarf2_per_cu to represent where to read the unit from,
+ in the DWO file. The caller is required to fill THIS_CU::SECTION,
+ THIS_CU::SECT_OFF, and THIS_CU::IS_DEBUG_TYPES. This constructor will fill
+ in the length. THIS_CU::SECTION must point to a section from the DWO file,
+ which is normally not the case for regular dwarf2_per_cu uses.
- When parent_cu is passed, it is used to provide a default value for
- str_offsets_base and addr_base from the parent. */
+ PARENT_CU is the CU created when reading the skeleton unit, and is used to
+ provide a default value for str_offsets_base and addr_base. */
-cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
- dwarf2_per_objfile *per_objfile,
- struct dwarf2_cu *parent_cu,
- struct dwo_file *dwo_file)
- : die_reader_specs {},
- m_this_cu (this_cu)
+cutu_reader::cutu_reader (dwarf2_per_cu &this_cu,
+ dwarf2_per_objfile &per_objfile,
+ language pretend_language, dwarf2_cu &parent_cu,
+ dwo_file &dwo_file)
{
- struct objfile *objfile = per_objfile->objfile;
- struct dwarf2_section_info *section = this_cu->section;
+ struct objfile *objfile = per_objfile.objfile;
+ struct dwarf2_section_info *section = this_cu.section;
bfd *abfd = section->get_bfd_owner ();
- struct dwarf2_section_info *abbrev_section;
- const gdb_byte *begin_info_ptr, *info_ptr;
if (dwarf_die_debug)
gdb_printf (gdb_stdlog, "Reading %s unit at offset %s\n",
- this_cu->is_debug_types ? "type" : "comp",
- sect_offset_str (this_cu->sect_off));
+ this_cu.is_debug_types ? "type" : "comp",
+ sect_offset_str (this_cu.sect_off));
- gdb_assert (per_objfile->get_cu (this_cu) == nullptr);
+ gdb_assert (per_objfile.get_cu (&this_cu) == nullptr);
- abbrev_section = (dwo_file != NULL
- ? &dwo_file->sections.abbrev
- : get_abbrev_section_for_cu (this_cu));
+ dwarf2_section_info *abbrev_section = &dwo_file.sections.abbrev;
/* This is cheap if the section is already read in. */
section->read (objfile);
- m_new_cu = std::make_unique<dwarf2_cu> (this_cu, per_objfile);
+ m_new_cu = std::make_unique<dwarf2_cu> (&this_cu, &per_objfile);
- begin_info_ptr = info_ptr = section->buffer + to_underlying (this_cu->sect_off);
- info_ptr = read_and_check_comp_unit_head (per_objfile, &m_new_cu->header,
- section, abbrev_section, info_ptr,
- (this_cu->is_debug_types
- ? rcuh_kind::TYPE
- : rcuh_kind::COMPILE));
+ m_info_ptr = section->buffer + to_underlying (this_cu.sect_off);
+ const gdb_byte *begin_info_ptr = m_info_ptr;
+ m_info_ptr = read_and_check_unit_head (&m_new_cu->header, section,
+ abbrev_section, m_info_ptr,
+ (this_cu.is_debug_types
+ ? ruh_kind::TYPE
+ : ruh_kind::COMPILE));
- if (parent_cu != nullptr)
- {
- m_new_cu->str_offsets_base = parent_cu->str_offsets_base;
- m_new_cu->addr_base = parent_cu->addr_base;
- }
- this_cu->set_length (m_new_cu->header.get_length_with_initial ());
+ m_new_cu->str_offsets_base = parent_cu.str_offsets_base;
+ m_new_cu->addr_base = parent_cu.addr_base;
+
+ this_cu.set_length (m_new_cu->header.get_length_with_initial ());
/* Skip dummy compilation units. */
- if (info_ptr >= begin_info_ptr + this_cu->length ()
- || peek_abbrev_code (abfd, info_ptr) == 0)
+ if (m_info_ptr >= begin_info_ptr + this_cu.length ()
+ || peek_abbrev_code (abfd, m_info_ptr) == 0)
+ m_dummy_p = true;
+ else
{
- dummy_p = true;
- return;
- }
+ abbrev_section->read (objfile);
+ m_abbrev_table_holder
+ = abbrev_table::read (abbrev_section,
+ m_new_cu->header.abbrev_sect_off);
- abbrev_section->read (objfile);
- m_abbrev_table_holder
- = abbrev_table::read (abbrev_section, m_new_cu->header.abbrev_sect_off);
+ this->init_cu_die_reader (m_new_cu.get (), section, &dwo_file,
+ m_abbrev_table_holder.get ());
+ m_top_level_die = this->read_toplevel_die ();
+ }
- init_cu_die_reader (this, m_new_cu.get (), section, dwo_file,
- m_abbrev_table_holder.get ());
- info_ptr = read_toplevel_die (this, &comp_unit_die, info_ptr);
+ prepare_one_comp_unit (m_new_cu.get (), pretend_language);
}
@@ -3520,71 +3146,21 @@ cutu_reader::cutu_reader (dwarf2_per_cu_data *this_cu,
together. A future step could be to put the types in the same symtab as
the CU the types ultimately came from. */
-static hashval_t
-hash_type_unit_group (const void *item)
-{
- const struct type_unit_group *tu_group
- = (const struct type_unit_group *) item;
-
- return hash_stmt_list_entry (&tu_group->hash);
-}
-
-static int
-eq_type_unit_group (const void *item_lhs, const void *item_rhs)
-{
- const struct type_unit_group *lhs = (const struct type_unit_group *) item_lhs;
- const struct type_unit_group *rhs = (const struct type_unit_group *) item_rhs;
-
- return eq_stmt_list_entry (&lhs->hash, &rhs->hash);
-}
-
-/* Allocate a hash table for type unit groups. */
-
-static htab_up
-allocate_type_unit_groups_table ()
-{
- return htab_up (htab_create_alloc (3,
- hash_type_unit_group,
- eq_type_unit_group,
- htab_delete_entry<type_unit_group>,
- xcalloc, xfree));
-}
-
/* Type units that don't have DW_AT_stmt_list are grouped into their own
partial symtabs. We combine several TUs per psymtab to not let the size
of any one psymtab grow too big. */
#define NO_STMT_LIST_TYPE_UNIT_PSYMTAB (1 << 31)
#define NO_STMT_LIST_TYPE_UNIT_PSYMTAB_SIZE 10
-/* Helper routine for get_type_unit_group.
- Create the type_unit_group object used to hold one or more TUs. */
-
-static std::unique_ptr<type_unit_group>
-create_type_unit_group (struct dwarf2_cu *cu, sect_offset line_offset_struct)
-{
- auto tu_group = std::make_unique<type_unit_group> ();
-
- tu_group->hash.dwo_unit = cu->dwo_unit;
- tu_group->hash.line_sect_off = line_offset_struct;
+/* Get the type unit group key for type unit CU. STMT_LIST is a DW_AT_stmt_list
+ attribute. */
- return tu_group;
-}
-
-/* Look up the type_unit_group for type unit CU, and create it if necessary.
- STMT_LIST is a DW_AT_stmt_list attribute. */
-
-static struct type_unit_group *
-get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
+static stmt_list_hash
+get_type_unit_group_key (struct dwarf2_cu *cu, const struct attribute *stmt_list)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
struct tu_stats *tu_stats = &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 (per_objfile->per_bfd->type_unit_groups == NULL)
- 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? */
@@ -3606,291 +3182,158 @@ get_type_unit_group (struct dwarf2_cu *cu, const struct attribute *stmt_list)
++tu_stats->nr_stmt_less_type_units;
}
- 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 (per_objfile->per_bfd->type_unit_groups.get (),
- &type_unit_group_for_lookup, INSERT);
- if (*slot == nullptr)
- {
- sect_offset line_offset_struct = (sect_offset) line_offset;
- std::unique_ptr<type_unit_group> grp
- = create_type_unit_group (cu, line_offset_struct);
- *slot = grp.release ();
- ++tu_stats->nr_symtabs;
- }
-
- tu_group = (struct type_unit_group *) *slot;
- gdb_assert (tu_group != nullptr);
- return tu_group;
-}
-
-
-cooked_index_storage::cooked_index_storage ()
- : m_reader_hash (htab_create_alloc (10, hash_cutu_reader,
- eq_cutu_reader,
- htab_delete_entry<cutu_reader>,
- xcalloc, xfree)),
- m_index (new cooked_index_shard)
-{
-}
-
-cutu_reader *
-cooked_index_storage::get_reader (dwarf2_per_cu_data *per_cu)
-{
- int index = per_cu->index;
- return (cutu_reader *) htab_find_with_hash (m_reader_hash.get (),
- &index, index);
-}
-
-cutu_reader *
-cooked_index_storage::preserve (std::unique_ptr<cutu_reader> reader)
-{
- m_abbrev_table_cache.add (reader->release_abbrev_table ());
-
- int index = reader->cu->per_cu->index;
- void **slot = htab_find_slot_with_hash (m_reader_hash.get (), &index,
- index, INSERT);
- gdb_assert (*slot == nullptr);
- cutu_reader *result = reader.get ();
- *slot = reader.release ();
- return result;
+ return {cu->dwo_unit, static_cast<sect_offset> (line_offset)};
}
-/* Hash function for a cutu_reader. */
-hashval_t
-cooked_index_storage::hash_cutu_reader (const void *a)
-{
- const cutu_reader *reader = (const cutu_reader *) a;
- return reader->cu->per_cu->index;
-}
-
-/* Equality function for cutu_reader. */
-int
-cooked_index_storage::eq_cutu_reader (const void *a, const void *b)
-{
- const cutu_reader *ra = (const cutu_reader *) a;
- const int *rb = (const int *) b;
- return ra->cu->per_cu->index == *rb;
-}
-
-/* Dump MAP as parent_map. */
+/* A subclass of cooked_index_worker that handles scanning
+ .debug_info. */
-static void
-dump_parent_map (dwarf2_per_bfd *per_bfd, const struct addrmap *map)
+class cooked_index_worker_debug_info : public cooked_index_worker
{
- auto_obstack temp_storage;
-
- auto annotate_cooked_index_entry
- = [&] (struct ui_file *outfile, CORE_ADDR start_addr, const void *value)
- {
- const cooked_index_entry *parent_entry
- = (const cooked_index_entry *)value;
+public:
+ cooked_index_worker_debug_info (dwarf2_per_objfile *per_objfile)
+ : cooked_index_worker (per_objfile)
+ {
+ gdb_assert (is_main_thread ());
- gdb_printf (outfile, "\n\t");
+ struct objfile *objfile = per_objfile->objfile;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
- bool found = false;
- for (auto sections : {per_bfd->infos, per_bfd->types})
- for (auto section : sections)
- if ((CORE_ADDR)section.buffer <= start_addr
- && start_addr < (CORE_ADDR) (section.buffer + section.size))
- {
- gdb_printf (outfile, "(section: %s, offset: 0x%" PRIx64 ")",
- section.get_name (),
- start_addr - (CORE_ADDR)section.buffer);
- found = true;
- break;
- }
+ dwarf_read_debug_printf ("Building psymtabs of objfile %s ...",
+ objfile_name (objfile));
- if (!found)
- gdb_printf (outfile, "()");
+ per_bfd->map_info_sections (objfile);
+ }
- if (parent_entry == nullptr)
- {
- gdb_printf (outfile, " -> ()");
- return;
- }
+private:
+ void do_reading () override;
- gdb_printf (outfile, " -> (0x%" PRIx64 ": %s)",
- to_underlying (parent_entry->die_offset),
- parent_entry->full_name (&temp_storage, false));
- };
+ /* Print collected type unit statistics. */
- addrmap_dump (const_cast<addrmap *> (map), gdb_stdlog, nullptr,
- annotate_cooked_index_entry);
-}
+ void print_tu_stats (dwarf2_per_objfile *per_objfile)
+ {
+ struct tu_stats *tu_stats = &per_objfile->per_bfd->tu_stats;
+
+ dwarf_read_debug_printf ("Type unit statistics:");
+ dwarf_read_debug_printf (" %d TUs", tu_stats->nr_tus);
+ dwarf_read_debug_printf (" %d uniq abbrev tables",
+ tu_stats->nr_uniq_abbrev_tables);
+ dwarf_read_debug_printf (" %d symtabs from stmt_list entries",
+ tu_stats->nr_symtabs);
+ dwarf_read_debug_printf (" %d symtab sharers",
+ tu_stats->nr_symtab_sharers);
+ dwarf_read_debug_printf (" %d type units without a stmt_list",
+ tu_stats->nr_stmt_less_type_units);
+ dwarf_read_debug_printf (" %d all_type_units reallocs",
+ tu_stats->nr_all_type_units_reallocs);
+ }
-/* See parent-map.h. */
+ void print_stats () override
+ {
+ if (dwarf_read_debug > 0)
+ print_tu_stats (m_per_objfile);
-void
-parent_map::dump (dwarf2_per_bfd *per_bfd) const
-{
- dump_parent_map (per_bfd, &m_map);
-}
+ if (dwarf_read_debug > 1)
+ {
+ dwarf_read_debug_printf_v ("Final m_all_parents_map:");
+ m_all_parents_map.dump (m_per_objfile->per_bfd);
+ }
+ }
-/* See parent-map.h. */
+ /* After the last DWARF-reading task has finished, this function
+ does the remaining work to finish the scan. */
+ void done_reading () override;
-void
-parent_map_map::dump (dwarf2_per_bfd *per_bfd) const
-{
- for (const auto &iter : m_maps)
- {
- gdb_printf (gdb_stdlog, "map start:\n");
- dump_parent_map (per_bfd, iter);
- }
-}
+ /* An iterator for the comp units. */
+ using unit_iterator = std::vector<dwarf2_per_cu_up>::iterator;
-/* An instance of this is created to index a CU. */
+ /* Process a batch of CUs. This may be called multiple times in
+ separate threads. TASK_NUMBER indicates which task this is --
+ the result is stored in that slot of M_RESULTS. */
+ void process_units (size_t task_number, unit_iterator first,
+ unit_iterator end);
-class cooked_indexer
-{
-public:
+ /* Process unit THIS_CU. */
+ void process_unit (dwarf2_per_cu *this_cu, dwarf2_per_objfile *per_objfile,
+ cooked_index_worker_result *storage);
- cooked_indexer (cooked_index_storage *storage,
- dwarf2_per_cu_data *per_cu,
- enum language language)
- : m_index_storage (storage),
- m_per_cu (per_cu),
- m_language (language),
- m_die_range_map (storage->get_parent_map ())
- {
- }
+ /* Process all type units existing in PER_OBJFILE::PER_BFD::ALL_UNITS. */
+ void process_type_units (dwarf2_per_objfile *per_objfile,
+ cooked_index_worker_result *storage);
- DISABLE_COPY_AND_ASSIGN (cooked_indexer);
+ /* Process the type unit wrapped in READER. */
+ void process_type_unit (cutu_reader *reader,
+ cooked_index_worker_result *storage);
- /* Index the given CU. */
- void make_index (cutu_reader *reader);
+ /* Process all type units of all DWO files.
-private:
+ This is needed in case a TU was emitted without its skeleton.
+ Note: This can't be done until we know what all the DWO files are. */
+ void process_skeletonless_type_units (dwarf2_per_objfile *per_objfile,
+ cooked_index_worker_result *storage);
- /* A helper function to scan the PC bounds of READER and record them
- in the storage's addrmap. */
- void check_bounds (cutu_reader *reader);
+ /* Process the type unit represented by DWO_UNIT. */
+ void process_skeletonless_type_unit (dwo_unit *dwo_unit,
+ dwarf2_per_objfile *per_objfile,
+ cooked_index_worker_result *storage);
- /* Ensure that the indicated CU exists. The cutu_reader for it is
- returned. FOR_SCANNING is true if the caller intends to scan all
- the DIEs in the CU; when false, this use is assumed to be to look
- up just a single DIE. */
- cutu_reader *ensure_cu_exists (cutu_reader *reader,
- dwarf2_per_objfile *per_objfile,
- sect_offset sect_off,
- bool is_dwz,
- bool for_scanning);
-
- /* Index DIEs in the READER starting at INFO_PTR. PARENT is
- the entry for the enclosing scope (nullptr at top level). FULLY
- is true when a full scan must be done -- in some languages,
- function scopes must be fully explored in order to find nested
- functions. This returns a pointer to just after the spot where
- reading stopped. */
- const gdb_byte *index_dies (cutu_reader *reader,
- const gdb_byte *info_ptr,
- std::variant<const cooked_index_entry *,
- parent_map::addr_type> parent,
- bool fully);
-
- /* Scan the attributes for a given DIE and update the out
- parameters. Returns a pointer to the byte after the DIE. */
- const gdb_byte *scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
- cutu_reader *reader,
- const gdb_byte *watermark_ptr,
- const gdb_byte *info_ptr,
- const abbrev_info *abbrev,
- const char **name,
- const char **linkage_name,
- cooked_index_flag *flags,
- sect_offset *sibling_offset,
- const cooked_index_entry **parent_entry,
- parent_map::addr_type *maybe_defer,
- bool *is_enum_class,
- bool for_specification);
-
- /* Handle DW_TAG_imported_unit, by scanning the DIE to find
- DW_AT_import, and then scanning the referenced CU. Returns a
- pointer to the byte after the DIE. */
- const gdb_byte *index_imported_unit (cutu_reader *reader,
- const gdb_byte *info_ptr,
- const abbrev_info *abbrev);
-
- /* Recursively read DIEs, recording the section offsets in
- m_die_range_map and then calling index_dies. */
- const gdb_byte *recurse (cutu_reader *reader,
- const gdb_byte *info_ptr,
- std::variant<const cooked_index_entry *,
- parent_map::addr_type> parent_entry,
- bool fully);
-
- /* The storage object, where the results are kept. */
- cooked_index_storage *m_index_storage;
- /* The CU that we are reading on behalf of. This object might be
- asked to index one CU but to treat the results as if they come
- from some including CU; in this case the including CU would be
- recorded here. */
- dwarf2_per_cu_data *m_per_cu;
- /* The language that we're assuming when reading. */
- enum language m_language;
-
- /* Map from DIE ranges to newly-created entries. */
- parent_map *m_die_range_map;
+ /* A storage object for "leftovers" -- see the 'start' method, but
+ essentially things not parsed during the normal CU parsing
+ passes. */
+ cooked_index_worker_result m_index_storage;
};
-/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
- Process compilation unit THIS_CU for a psymtab. */
-
-static void
-process_psymtab_comp_unit (dwarf2_per_cu_data *this_cu,
- dwarf2_per_objfile *per_objfile,
- cooked_index_storage *storage)
+void
+cooked_index_worker_debug_info::process_unit
+ (dwarf2_per_cu *this_cu, dwarf2_per_objfile *per_objfile,
+ cooked_index_worker_result *storage)
{
cutu_reader *reader = storage->get_reader (this_cu);
if (reader == nullptr)
{
- cutu_reader new_reader (this_cu, per_objfile, nullptr, nullptr, false,
- &storage->get_abbrev_table_cache ());
+ const abbrev_table_cache &abbrev_table_cache
+ = storage->get_abbrev_table_cache ();
+ auto new_reader = std::make_unique<cutu_reader> (*this_cu, *per_objfile,
+ nullptr, nullptr, false,
+ language_minimal,
+ &abbrev_table_cache);
- if (new_reader.comp_unit_die == nullptr || new_reader.dummy_p)
+ if (new_reader->is_dummy ())
return;
- std::unique_ptr<cutu_reader> copy
- (new cutu_reader (std::move (new_reader)));
- reader = storage->preserve (std::move (copy));
+ reader = storage->preserve (std::move (new_reader));
}
- if (reader->comp_unit_die == nullptr || reader->dummy_p)
+ if (reader->is_dummy ())
return;
if (this_cu->is_debug_types)
- build_type_psymtabs_reader (reader, storage);
- else if (reader->comp_unit_die->tag != DW_TAG_partial_unit)
+ process_type_unit (reader, storage);
+ else if (reader->top_level_die ()->tag != DW_TAG_partial_unit)
{
bool nope = false;
if (this_cu->scanned.compare_exchange_strong (nope, true))
{
- prepare_one_comp_unit (reader->cu, reader->comp_unit_die,
- language_minimal);
gdb_assert (storage != nullptr);
- cooked_indexer indexer (storage, this_cu, reader->cu->lang ());
+ cooked_indexer indexer (storage, this_cu, reader->cu ()->lang ());
indexer.make_index (reader);
}
}
}
-/* Reader function for build_type_psymtabs. */
-
-static void
-build_type_psymtabs_reader (cutu_reader *reader,
- cooked_index_storage *storage)
+void
+cooked_index_worker_debug_info::process_type_unit
+ (cutu_reader *reader, cooked_index_worker_result *storage)
{
- struct dwarf2_cu *cu = reader->cu;
- struct dwarf2_per_cu_data *per_cu = cu->per_cu;
- struct die_info *type_unit_die = reader->comp_unit_die;
+ struct dwarf2_cu *cu = reader->cu ();
+ dwarf2_per_cu *per_cu = cu->per_cu;
+ die_info *type_unit_die = reader->top_level_die ();
gdb_assert (per_cu->is_debug_types);
if (! type_unit_die->has_children)
return;
- prepare_one_comp_unit (cu, type_unit_die, language_minimal);
-
gdb_assert (storage != nullptr);
cooked_indexer indexer (storage, per_cu, cu->lang ());
indexer.make_index (reader);
@@ -3914,34 +3357,14 @@ struct tu_abbrev_offset
sect_offset abbrev_offset;
};
-/* Efficiently read all the type units.
-
- The efficiency is because we sort TUs by the abbrev table they use and
- only read each abbrev table once. In one program there are 200K TUs
- sharing 8K abbrev tables.
-
- The main purpose of this function is to support building the
- 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
- share 8K stmt_list tables.
-
- 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->per_bfd->type_unit_groups. */
-
-static void
-build_type_psymtabs (dwarf2_per_objfile *per_objfile,
- cooked_index_storage *storage)
+void
+cooked_index_worker_debug_info::process_type_units
+ (dwarf2_per_objfile *per_objfile, cooked_index_worker_result *storage)
{
struct tu_stats *tu_stats = &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 (per_objfile->per_bfd->type_unit_groups == NULL);
-
if (per_objfile->per_bfd->all_type_units.size () == 0)
return;
@@ -3972,15 +3395,14 @@ build_type_psymtabs (dwarf2_per_objfile *per_objfile,
sorted_by_abbrev.reserve (per_objfile->per_bfd->all_type_units.size ());
for (const auto &cu : per_objfile->per_bfd->all_units)
- {
- if (cu->is_debug_types)
- {
- auto sig_type = static_cast<signatured_type *> (cu.get ());
- sorted_by_abbrev.emplace_back
- (sig_type, read_abbrev_offset (per_objfile, sig_type->section,
- sig_type->sect_off));
- }
- }
+ if (cu->is_debug_types)
+ {
+ auto sig_type = static_cast<signatured_type *> (cu.get ());
+ sorted_by_abbrev.emplace_back (sig_type,
+ read_abbrev_offset (per_objfile,
+ sig_type->section,
+ sig_type->sect_off));
+ }
std::sort (sorted_by_abbrev.begin (), sorted_by_abbrev.end ());
@@ -3999,169 +3421,65 @@ build_type_psymtabs (dwarf2_per_objfile *per_objfile,
++tu_stats->nr_uniq_abbrev_tables;
}
- cutu_reader reader (tu.sig_type, per_objfile,
- abbrev_table.get (), nullptr, false);
- if (!reader.dummy_p)
- build_type_psymtabs_reader (&reader, storage);
+ cutu_reader reader (*tu.sig_type, *per_objfile,
+ abbrev_table.get (), nullptr, false,
+ language_minimal);
+ if (!reader.is_dummy ())
+ storage->catch_error ([&] ()
+ {
+ process_type_unit (&reader, storage);
+ });
}
}
-/* Print collected type unit statistics. */
-
-static void
-print_tu_stats (dwarf2_per_objfile *per_objfile)
-{
- struct tu_stats *tu_stats = &per_objfile->per_bfd->tu_stats;
-
- dwarf_read_debug_printf ("Type unit statistics:");
- dwarf_read_debug_printf (" %d TUs", tu_stats->nr_tus);
- dwarf_read_debug_printf (" %d uniq abbrev tables",
- tu_stats->nr_uniq_abbrev_tables);
- dwarf_read_debug_printf (" %d symtabs from stmt_list entries",
- tu_stats->nr_symtabs);
- dwarf_read_debug_printf (" %d symtab sharers",
- tu_stats->nr_symtab_sharers);
- dwarf_read_debug_printf (" %d type units without a stmt_list",
- tu_stats->nr_stmt_less_type_units);
- dwarf_read_debug_printf (" %d all_type_units reallocs",
- tu_stats->nr_all_type_units_reallocs);
-}
-
-struct skeleton_data
-{
- dwarf2_per_objfile *per_objfile;
- cooked_index_storage *storage;
-};
-
-/* Traversal function for process_skeletonless_type_unit.
- Read a TU in a DWO file and build partial symbols for it. */
-
-static int
-process_skeletonless_type_unit (void **slot, void *info)
+void
+cooked_index_worker_debug_info::process_skeletonless_type_unit
+ (dwo_unit *dwo_unit, dwarf2_per_objfile *per_objfile,
+ cooked_index_worker_result *storage)
{
- struct dwo_unit *dwo_unit = (struct dwo_unit *) *slot;
- skeleton_data *data = (skeleton_data *) info;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
/* If this TU doesn't exist in the global table, add it and read it in. */
+ auto sig_type_it = per_bfd->signatured_types.find (dwo_unit->signature);
- if (data->per_objfile->per_bfd->signatured_types == NULL)
- data->per_objfile->per_bfd->signatured_types
- = allocate_signatured_type_table ();
-
- signatured_type find_entry (dwo_unit->signature);
- slot = htab_find_slot (data->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. */
- if (*slot != NULL)
- return 1;
+ if (sig_type_it != per_bfd->signatured_types.end ())
+ return;
/* This does the job that create_all_units would have done for
this TU. */
- signatured_type *entry
- = add_type_unit (data->per_objfile, dwo_unit->signature, slot);
- fill_in_sig_entry_from_dwo_entry (data->per_objfile, entry, dwo_unit);
- *slot = entry;
+ sig_type_it = add_type_unit (per_bfd, dwo_unit->section, dwo_unit->sect_off,
+ dwo_unit->length, dwo_unit->signature);
+ fill_in_sig_entry_from_dwo_entry (per_objfile, *sig_type_it, dwo_unit);
/* This does the job that build_type_psymtabs would have done. */
- cutu_reader reader (entry, data->per_objfile, nullptr, nullptr, false);
- if (!reader.dummy_p)
- build_type_psymtabs_reader (&reader, data->storage);
-
- return 1;
+ cutu_reader reader (**sig_type_it, *per_objfile, nullptr, nullptr, false,
+ language_minimal);
+ if (!reader.is_dummy ())
+ process_type_unit (&reader, storage);
}
-/* Traversal function for process_skeletonless_type_units. */
-
-static int
-process_dwo_file_for_skeletonless_type_units (void **slot, void *info)
-{
- struct dwo_file *dwo_file = (struct dwo_file *) *slot;
-
- if (dwo_file->tus != NULL)
- htab_traverse_noresize (dwo_file->tus.get (),
- process_skeletonless_type_unit, info);
-
- return 1;
-}
-
-/* Scan all TUs of DWO files, verifying we've processed them.
- This is needed in case a TU was emitted without its skeleton.
- Note: This can't be done until we know what all the DWO files are. */
-
-static void
-process_skeletonless_type_units (dwarf2_per_objfile *per_objfile,
- cooked_index_storage *storage)
+void
+cooked_index_worker_debug_info::process_skeletonless_type_units
+ (dwarf2_per_objfile *per_objfile, cooked_index_worker_result *storage)
{
- skeleton_data data { per_objfile, storage };
+ scoped_time_it time_it ("DWARF skeletonless type units", m_per_command_time);
/* Skeletonless TUs in DWP files without .gdb_index is not supported yet. */
- if (get_dwp_file (per_objfile) == NULL
- && per_objfile->per_bfd->dwo_files != NULL)
- {
- htab_traverse_noresize (per_objfile->per_bfd->dwo_files.get (),
- process_dwo_file_for_skeletonless_type_units,
- &data);
- }
+ if (per_objfile->per_bfd->dwp_file == nullptr)
+ for (const dwo_file_up &file : per_objfile->per_bfd->dwo_files)
+ for (const dwo_unit_up &unit : file->tus)
+ storage->catch_error ([&] ()
+ {
+ process_skeletonless_type_unit (unit.get (), per_objfile, storage);
+ });
}
-/* A subclass of cooked_index_worker that handles scanning
- .debug_info. */
-
-class cooked_index_debug_info : public cooked_index_worker
-{
-public:
- cooked_index_debug_info (dwarf2_per_objfile *per_objfile)
- : cooked_index_worker (per_objfile)
- {
- gdb_assert (is_main_thread ());
-
- struct objfile *objfile = per_objfile->objfile;
- dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
-
- dwarf_read_debug_printf ("Building psymtabs of objfile %s ...",
- objfile_name (objfile));
-
- per_bfd->map_info_sections (objfile);
- }
-
-private:
-
- void do_reading () override;
-
- void print_stats () override
- {
- if (dwarf_read_debug > 0)
- print_tu_stats (m_per_objfile);
- if (dwarf_read_debug > 1)
- {
- dwarf_read_debug_printf_v ("Final m_all_parents_map:");
- m_all_parents_map.dump (m_per_objfile->per_bfd);
- }
- }
-
- /* After the last DWARF-reading task has finished, this function
- does the remaining work to finish the scan. */
- void done_reading ();
-
- /* An iterator for the comp units. */
- typedef std::vector<dwarf2_per_cu_data_up>::iterator unit_iterator;
-
- /* Process a batch of CUs. This may be called multiple times in
- separate threads. TASK_NUMBER indicates which task this is --
- the result is stored in that slot of M_RESULTS. */
- void process_cus (size_t task_number, unit_iterator first,
- unit_iterator end);
-
- /* A storage object for "leftovers" -- see the 'start' method, but
- essentially things not parsed during the normal CU parsing
- passes. */
- cooked_index_storage m_index_storage;
-};
-
void
-cooked_index_debug_info::process_cus (size_t task_number, unit_iterator first,
- unit_iterator end)
+cooked_index_worker_debug_info::process_units (size_t task_number,
+ unit_iterator first,
+ unit_iterator end)
{
SCOPE_EXIT { bfd_thread_cleanup (); };
@@ -4169,64 +3487,41 @@ cooked_index_debug_info::process_cus (size_t task_number, unit_iterator first,
complaint_interceptor complaint_handler;
std::vector<gdb_exception> errors;
- cooked_index_storage thread_storage;
+ cooked_index_worker_result thread_storage;
for (auto inner = first; inner != end; ++inner)
{
- dwarf2_per_cu_data *per_cu = inner->get ();
- try
- {
- process_psymtab_comp_unit (per_cu, m_per_objfile, &thread_storage);
- }
- catch (gdb_exception &except)
+ dwarf2_per_cu *per_cu = inner->get ();
+
+ thread_storage.catch_error ([&] ()
{
- errors.push_back (std::move (except));
- }
+ process_unit (per_cu, m_per_objfile, &thread_storage);
+ });
}
- m_results[task_number] = result_type (thread_storage.release (),
- complaint_handler.release (),
- std::move (errors),
- thread_storage.release_parent_map ());
+ thread_storage.done_reading (complaint_handler.release ());
+ m_results[task_number] = std::move (thread_storage);
}
void
-cooked_index_debug_info::done_reading ()
+cooked_index_worker_debug_info::done_reading ()
{
- /* Only handle the scanning results here. Complaints and exceptions
- can only be dealt with on the main thread. */
- std::vector<std::unique_ptr<cooked_index_shard>> indexes;
- for (auto &one_result : m_results)
- {
- indexes.push_back (std::move (std::get<0> (one_result)));
- m_all_parents_map.add_map (std::get<3> (one_result));
- }
-
/* This has to wait until we read the CUs, we need the list of DWOs. */
process_skeletonless_type_units (m_per_objfile, &m_index_storage);
- indexes.push_back (m_index_storage.release ());
- indexes.shrink_to_fit ();
+ m_results.push_back (std::move (m_index_storage));
- m_all_parents_map.add_map (m_index_storage.release_parent_map ());
-
- dwarf2_per_bfd *per_bfd = m_per_objfile->per_bfd;
- cooked_index *table
- = (gdb::checked_static_cast<cooked_index *>
- (per_bfd->index_table.get ()));
- table->set_contents (std::move (indexes), &m_warnings,
- &m_all_parents_map);
+ /* Call into the base class. */
+ cooked_index_worker::done_reading ();
}
void
-cooked_index_debug_info::do_reading ()
+cooked_index_worker_debug_info::do_reading ()
{
dwarf2_per_bfd *per_bfd = m_per_objfile->per_bfd;
create_all_units (m_per_objfile);
- build_type_psymtabs (m_per_objfile, &m_index_storage);
+ process_type_units (m_per_objfile, &m_index_storage);
- per_bfd->quick_file_names_table
- = create_quick_file_names_table (per_bfd->all_units.size ());
if (!per_bfd->debug_aranges.empty ())
read_addrmap_from_aranges (m_per_objfile, &per_bfd->debug_aranges,
m_index_storage.get_addrmap (),
@@ -4278,7 +3573,8 @@ cooked_index_debug_info::do_reading ()
gdb_assert (iter != last);
workers.add_task ([this, task_count, iter, last] ()
{
- process_cus (task_count, iter, last);
+ scoped_time_it time_it ("DWARF indexing worker", m_per_command_time);
+ process_units (task_count, iter, last);
});
++task_count;
@@ -4294,11 +3590,12 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile,
struct dwarf2_section_info *section,
struct dwarf2_section_info *abbrev_section,
unsigned int is_dwz,
- htab_up &types_htab,
- rcuh_kind section_kind)
+ signatured_type_set &sig_types,
+ ruh_kind section_kind)
{
const gdb_byte *info_ptr;
struct objfile *objfile = per_objfile->objfile;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
dwarf_read_debug_printf ("Reading %s for %s",
section->get_name (),
@@ -4310,50 +3607,40 @@ read_comp_units_from_section (dwarf2_per_objfile *per_objfile,
while (info_ptr < section->buffer + section->size)
{
- dwarf2_per_cu_data_up this_cu;
+ dwarf2_per_cu_up this_cu;
sect_offset sect_off = (sect_offset) (info_ptr - section->buffer);
- comp_unit_head cu_header;
- read_and_check_comp_unit_head (per_objfile, &cu_header, section,
- abbrev_section, info_ptr,
- section_kind);
+ unit_head cu_header;
+ read_and_check_unit_head (&cu_header, section, abbrev_section, info_ptr,
+ section_kind);
+
+ unsigned int length = cu_header.get_length_with_initial ();
/* Save the compilation unit for later lookup. */
if (cu_header.unit_type != DW_UT_type)
- this_cu = per_objfile->per_bfd->allocate_per_cu ();
+ this_cu = per_bfd->allocate_per_cu (section, sect_off, length, is_dwz);
else
{
- if (types_htab == nullptr)
- types_htab = allocate_signatured_type_table ();
-
- auto sig_type = per_objfile->per_bfd->allocate_signatured_type
- (cu_header.signature);
+ auto sig_type
+ = per_bfd->allocate_signatured_type (section, sect_off, length,
+ is_dwz, cu_header.signature);
signatured_type *sig_ptr = sig_type.get ();
- sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
+ sig_type->type_offset_in_tu = cu_header.type_offset_in_tu;
this_cu.reset (sig_type.release ());
- void **slot = htab_find_slot (types_htab.get (), sig_ptr, INSERT);
- gdb_assert (slot != nullptr);
- if (*slot != nullptr)
+ auto inserted = sig_types.emplace (sig_ptr).second;
+
+ if (!inserted)
complaint (_("debug type entry at offset %s is duplicate to"
" the entry at offset %s, signature %s"),
sect_offset_str (sect_off),
sect_offset_str (sig_ptr->sect_off),
hex_string (sig_ptr->signature));
- *slot = sig_ptr;
}
- this_cu->sect_off = sect_off;
- this_cu->set_length (cu_header.get_length_with_initial ());
- this_cu->is_dwz = is_dwz;
- this_cu->section = section;
- /* Init this asap, to avoid a data race in the set_version in
- cutu_reader::cutu_reader (which may be run in parallel for the cooked
- index case). */
- this_cu->set_version (cu_header.version);
info_ptr = info_ptr + this_cu->length ();
- per_objfile->per_bfd->all_units.push_back (std::move (this_cu));
+ per_bfd->all_units.push_back (std::move (this_cu));
}
}
@@ -4364,7 +3651,7 @@ finalize_all_units (dwarf2_per_bfd *per_bfd)
{
size_t nr_tus = per_bfd->tu_stats.nr_tus;
size_t nr_cus = per_bfd->all_units.size () - nr_tus;
- gdb::array_view<dwarf2_per_cu_data_up> tmp = per_bfd->all_units;
+ gdb::array_view<dwarf2_per_cu_up> tmp = per_bfd->all_units;
per_bfd->all_comp_units = tmp.slice (0, nr_cus);
per_bfd->all_type_units = tmp.slice (nr_cus, nr_tus);
}
@@ -4374,23 +3661,24 @@ finalize_all_units (dwarf2_per_bfd *per_bfd)
void
create_all_units (dwarf2_per_objfile *per_objfile)
{
- htab_up types_htab;
gdb_assert (per_objfile->per_bfd->all_units.empty ());
+ signatured_type_set sig_types;
+
for (dwarf2_section_info &section : per_objfile->per_bfd->infos)
read_comp_units_from_section (per_objfile, &section,
- &per_objfile->per_bfd->abbrev, 0,
- types_htab, rcuh_kind::COMPILE);
+ &per_objfile->per_bfd->abbrev, 0, sig_types,
+ ruh_kind::COMPILE);
for (dwarf2_section_info &section : per_objfile->per_bfd->types)
read_comp_units_from_section (per_objfile, &section,
- &per_objfile->per_bfd->abbrev, 0,
- types_htab, rcuh_kind::TYPE);
+ &per_objfile->per_bfd->abbrev, 0, sig_types,
+ ruh_kind::TYPE);
- dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd);
+ dwz_file *dwz = per_objfile->per_bfd->get_dwz_file ();
if (dwz != NULL)
{
read_comp_units_from_section (per_objfile, &dwz->info, &dwz->abbrev, 1,
- types_htab, rcuh_kind::COMPILE);
+ sig_types, ruh_kind::COMPILE);
if (!dwz->types.empty ())
{
@@ -4402,7 +3690,7 @@ create_all_units (dwarf2_per_objfile *per_objfile)
}
}
- per_objfile->per_bfd->signatured_types = std::move (types_htab);
+ per_objfile->per_bfd->signatured_types = std::move (sig_types);
finalize_all_units (per_objfile->per_bfd);
}
@@ -4424,27 +3712,25 @@ peek_abbrev_code (bfd *abfd, const gdb_byte *info_ptr)
an empty DIE). In either case *BYTES_READ will be set to the length of
the initial number. */
-static const struct abbrev_info *
-peek_die_abbrev (const die_reader_specs &reader,
- const gdb_byte *info_ptr, unsigned int *bytes_read)
+const abbrev_info *
+cutu_reader::peek_die_abbrev (const gdb_byte *info_ptr,
+ unsigned int *bytes_read)
{
- dwarf2_cu *cu = reader.cu;
- bfd *abfd = reader.abfd;
unsigned int abbrev_number
- = read_unsigned_leb128 (abfd, info_ptr, bytes_read);
+ = read_unsigned_leb128 (m_abfd, info_ptr, bytes_read);
if (abbrev_number == 0)
return NULL;
- const abbrev_info *abbrev
- = reader.abbrev_table->lookup_abbrev (abbrev_number);
+ const abbrev_info *abbrev = m_abbrev_table->lookup_abbrev (abbrev_number);
if (!abbrev)
{
error (_(DWARF_ERROR_PREFIX
"Could not find abbrev number %d in %s at offset %s"
" [in module %s]"),
- abbrev_number, cu->per_cu->is_debug_types ? "TU" : "CU",
- sect_offset_str (cu->header.sect_off), bfd_get_filename (abfd));
+ abbrev_number, m_cu->per_cu->is_debug_types ? "TU" : "CU",
+ sect_offset_str (m_cu->header.sect_off),
+ bfd_get_filename (m_abfd));
}
return abbrev;
@@ -4454,19 +3740,121 @@ peek_die_abbrev (const die_reader_specs &reader,
Returns a pointer to the end of a series of DIEs, terminated by an empty
DIE. Any children of the skipped DIEs will also be skipped. */
-static const gdb_byte *
-skip_children (const struct die_reader_specs *reader, const gdb_byte *info_ptr)
+const gdb_byte *
+cutu_reader::skip_children (const gdb_byte *info_ptr)
{
while (1)
{
unsigned int bytes_read;
- const abbrev_info *abbrev = peek_die_abbrev (*reader, info_ptr,
- &bytes_read);
+ const abbrev_info *abbrev = this->peek_die_abbrev (info_ptr, &bytes_read);
if (abbrev == NULL)
return info_ptr + bytes_read;
else
- info_ptr = skip_one_die (reader, info_ptr + bytes_read, abbrev);
+ info_ptr = this->skip_one_die (info_ptr + bytes_read, abbrev);
+ }
+}
+
+/* See read.h. */
+
+const gdb_byte *
+cutu_reader::skip_one_attribute (dwarf_form form, const gdb_byte *info_ptr)
+{
+ unsigned int bytes_read;
+
+ switch (form)
+ {
+ case DW_FORM_ref_addr:
+ /* In DWARF 2, DW_FORM_ref_addr is address sized; in DWARF 3
+ and later it is offset sized. */
+ if (m_cu->header.version == 2)
+ return info_ptr + m_cu->header.addr_size;
+ else
+ return info_ptr + m_cu->header.offset_size;
+
+ case DW_FORM_GNU_ref_alt:
+ return info_ptr + m_cu->header.offset_size;
+
+ case DW_FORM_addr:
+ return info_ptr + m_cu->header.addr_size;
+
+ case DW_FORM_data1:
+ case DW_FORM_ref1:
+ case DW_FORM_flag:
+ case DW_FORM_strx1:
+ return info_ptr + 1;
+
+ case DW_FORM_flag_present:
+ case DW_FORM_implicit_const:
+ return info_ptr;
+
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ case DW_FORM_strx2:
+ return info_ptr + 2;
+
+ case DW_FORM_strx3:
+ return info_ptr + 3;
+
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ case DW_FORM_strx4:
+ case DW_FORM_ref_sup4:
+ return info_ptr + 4;
+
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ case DW_FORM_ref_sig8:
+ case DW_FORM_ref_sup8:
+ return info_ptr + 8;
+
+ case DW_FORM_data16:
+ return info_ptr + 16;
+
+ case DW_FORM_string:
+ read_direct_string (m_abfd, info_ptr, &bytes_read);
+ return info_ptr + bytes_read;
+
+ case DW_FORM_sec_offset:
+ case DW_FORM_strp:
+ case DW_FORM_GNU_strp_alt:
+ case DW_FORM_strp_sup:
+ return info_ptr + m_cu->header.offset_size;
+
+ case DW_FORM_exprloc:
+ case DW_FORM_block:
+ info_ptr += read_unsigned_leb128 (m_abfd, info_ptr, &bytes_read);
+ return info_ptr + bytes_read;
+
+ case DW_FORM_block1:
+ return info_ptr + 1 + read_1_byte (m_abfd, info_ptr);
+
+ case DW_FORM_block2:
+ return info_ptr + 2 + read_2_bytes (m_abfd, info_ptr);
+
+ case DW_FORM_block4:
+ return info_ptr + 4 + read_4_bytes (m_abfd, info_ptr);
+
+ case DW_FORM_addrx:
+ case DW_FORM_strx:
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_ref_udata:
+ case DW_FORM_GNU_addr_index:
+ case DW_FORM_GNU_str_index:
+ case DW_FORM_rnglistx:
+ case DW_FORM_loclistx:
+ return safe_skip_leb128 (info_ptr, m_buffer_end);
+
+ case DW_FORM_indirect:
+ form = static_cast<dwarf_form> (read_unsigned_leb128 (m_abfd, info_ptr,
+ &bytes_read));
+ return this->skip_one_attribute(form, info_ptr + bytes_read);
+
+ default:
+ error (_ (DWARF_ERROR_PREFIX
+ "Cannot handle %s in DWARF reader [in module %s]"),
+ dwarf_form_name (form), bfd_get_filename (m_abfd));
}
}
@@ -4479,26 +3867,18 @@ skip_children (const struct die_reader_specs *reader, const gdb_byte *info_ptr)
returns a pointer to this DIE's sibling, skipping any children.
Otherwise, returns a pointer to the DIE's first child. */
-static const gdb_byte *
-skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
- const struct abbrev_info *abbrev, bool do_skip_children)
+const gdb_byte *
+cutu_reader::skip_one_die (const gdb_byte *info_ptr, const abbrev_info *abbrev,
+ bool do_skip_children)
{
- unsigned int bytes_read;
- struct attribute attr;
- bfd *abfd = reader->abfd;
- struct dwarf2_cu *cu = reader->cu;
- const gdb_byte *buffer = reader->buffer;
- const gdb_byte *buffer_end = reader->buffer_end;
- unsigned int form, i;
-
if (do_skip_children && abbrev->sibling_offset != (unsigned short) -1)
{
/* We only handle DW_FORM_ref4 here. */
const gdb_byte *sibling_data = info_ptr + abbrev->sibling_offset;
- unsigned int offset = read_4_bytes (abfd, sibling_data);
+ unsigned int offset = read_4_bytes (m_abfd, sibling_data);
const gdb_byte *sibling_ptr
- = buffer + to_underlying (cu->header.sect_off) + offset;
- if (sibling_ptr >= info_ptr && sibling_ptr < reader->buffer_end)
+ = m_buffer + to_underlying (m_cu->header.sect_off) + offset;
+ if (sibling_ptr >= info_ptr && sibling_ptr < m_buffer_end)
return sibling_ptr;
/* Fall through to the slow way. */
}
@@ -4506,11 +3886,11 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
{
info_ptr += abbrev->size_if_constant;
if (do_skip_children && abbrev->has_children)
- return skip_children (reader, info_ptr);
+ return this->skip_children (info_ptr);
return info_ptr;
}
- for (i = 0; i < abbrev->num_attrs; i++)
+ for (unsigned int i = 0; i < abbrev->num_attrs; i++)
{
/* The only abbrev we care about is DW_AT_sibling. */
if (do_skip_children && abbrev->attrs[i].name == DW_AT_sibling)
@@ -4518,123 +3898,30 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
/* Note there is no need for the extra work of
"reprocessing" here, so we pass false for that
argument. */
- read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr, false);
+ attribute attr;
+ this->read_attribute (&attr, &abbrev->attrs[i], info_ptr, false);
if (attr.form == DW_FORM_ref_addr)
complaint (_("ignoring absolute DW_AT_sibling"));
else
{
sect_offset off = attr.get_ref_die_offset ();
- const gdb_byte *sibling_ptr = buffer + to_underlying (off);
+ const gdb_byte *sibling_ptr = m_buffer + to_underlying (off);
if (sibling_ptr < info_ptr)
complaint (_("DW_AT_sibling points backwards"));
- else if (sibling_ptr > reader->buffer_end)
- reader->die_section->overflow_complaint ();
+ else if (sibling_ptr > m_buffer_end)
+ m_die_section->overflow_complaint ();
else
return sibling_ptr;
}
}
/* If it isn't DW_AT_sibling, skip this attribute. */
- form = abbrev->attrs[i].form;
- skip_attribute:
- switch (form)
- {
- case DW_FORM_ref_addr:
- /* In DWARF 2, DW_FORM_ref_addr is address sized; in DWARF 3
- and later it is offset sized. */
- if (cu->header.version == 2)
- info_ptr += cu->header.addr_size;
- else
- info_ptr += cu->header.offset_size;
- break;
- case DW_FORM_GNU_ref_alt:
- info_ptr += cu->header.offset_size;
- break;
- case DW_FORM_addr:
- info_ptr += cu->header.addr_size;
- break;
- case DW_FORM_data1:
- case DW_FORM_ref1:
- case DW_FORM_flag:
- case DW_FORM_strx1:
- info_ptr += 1;
- break;
- case DW_FORM_flag_present:
- case DW_FORM_implicit_const:
- break;
- case DW_FORM_data2:
- case DW_FORM_ref2:
- case DW_FORM_strx2:
- info_ptr += 2;
- break;
- case DW_FORM_strx3:
- info_ptr += 3;
- break;
- case DW_FORM_data4:
- case DW_FORM_ref4:
- case DW_FORM_strx4:
- info_ptr += 4;
- break;
- case DW_FORM_data8:
- case DW_FORM_ref8:
- case DW_FORM_ref_sig8:
- info_ptr += 8;
- break;
- case DW_FORM_data16:
- info_ptr += 16;
- break;
- case DW_FORM_string:
- read_direct_string (abfd, info_ptr, &bytes_read);
- info_ptr += bytes_read;
- break;
- case DW_FORM_sec_offset:
- case DW_FORM_strp:
- case DW_FORM_GNU_strp_alt:
- info_ptr += cu->header.offset_size;
- break;
- case DW_FORM_exprloc:
- case DW_FORM_block:
- info_ptr += read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
- info_ptr += bytes_read;
- break;
- case DW_FORM_block1:
- info_ptr += 1 + read_1_byte (abfd, info_ptr);
- break;
- case DW_FORM_block2:
- info_ptr += 2 + read_2_bytes (abfd, info_ptr);
- break;
- case DW_FORM_block4:
- info_ptr += 4 + read_4_bytes (abfd, info_ptr);
- break;
- case DW_FORM_addrx:
- case DW_FORM_strx:
- case DW_FORM_sdata:
- case DW_FORM_udata:
- case DW_FORM_ref_udata:
- 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:
- form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
- info_ptr += bytes_read;
- /* We need to continue parsing from here, so just go back to
- the top. */
- goto skip_attribute;
-
- default:
- error (_(DWARF_ERROR_PREFIX
- "Cannot handle %s in DWARF reader [in module %s]"),
- dwarf_form_name (form),
- bfd_get_filename (abfd));
- }
+ info_ptr = this->skip_one_attribute (abbrev->attrs[i].form, info_ptr);
}
if (do_skip_children && abbrev->has_children)
- return skip_children (reader, info_ptr);
+ return this->skip_children (info_ptr);
else
return info_ptr;
}
@@ -4644,14 +3931,12 @@ skip_one_die (const struct die_reader_specs *reader, const gdb_byte *info_ptr,
/* Add PER_CU to the queue. */
static void
-queue_comp_unit (dwarf2_per_cu_data *per_cu,
- dwarf2_per_objfile *per_objfile,
- enum language pretend_language)
+queue_comp_unit (dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile)
{
per_cu->queued = 1;
gdb_assert (per_objfile->queue.has_value ());
- per_objfile->queue->emplace (per_cu, per_objfile, pretend_language);
+ per_objfile->queue->emplace (per_cu, per_objfile);
}
/* If PER_CU is not yet expanded of queued for expansion, add it to the queue.
@@ -4679,11 +3964,9 @@ queue_comp_unit (dwarf2_per_cu_data *per_cu,
indicator of whether the CU's DIEs are loaded right now, it should check
that by calling `dwarf2_per_objfile::get_cu` instead. */
-static int
-maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
- dwarf2_per_cu_data *per_cu,
- dwarf2_per_objfile *per_objfile,
- enum language pretend_language)
+static bool
+maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu, dwarf2_per_cu *per_cu,
+ dwarf2_per_objfile *per_objfile)
{
/* Mark the dependence relation so that we don't flush PER_CU
too early. */
@@ -4702,15 +3985,21 @@ maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
gdb_assert (!per_objfile->symtab_set_p (per_cu));
/* The DIEs are already loaded, the caller doesn't need to do it. */
- return 0;
+ return false;
}
bool queued = false;
if (!per_objfile->symtab_set_p (per_cu))
{
/* Add it to the queue. */
- queue_comp_unit (per_cu, per_objfile, pretend_language);
+ queue_comp_unit (per_cu, per_objfile);
queued = true;
+
+ dwarf_read_debug_printf ("Queuing CU for expansion: "
+ "section offset = 0x%" PRIx64 ", "
+ "queue size = %zu",
+ to_underlying (per_cu->sect_off),
+ per_objfile->queue->size ());
}
/* If the compilation unit is already loaded, just mark it as
@@ -4729,15 +4018,18 @@ maybe_queue_comp_unit (struct dwarf2_cu *dependent_cu,
static void
process_queue (dwarf2_per_objfile *per_objfile)
{
- dwarf_read_debug_printf ("Expanding one or more symtabs of objfile %s ...",
- objfile_name (per_objfile->objfile));
+ DWARF_READ_SCOPED_DEBUG_START_END
+ ("Expanding one or more symtabs of objfile %s ...",
+ objfile_name (per_objfile->objfile));
+
+ unsigned int expanded_count = 0;
/* 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 (!per_objfile->queue->empty ())
{
dwarf2_queue_item &item = per_objfile->queue->front ();
- dwarf2_per_cu_data *per_cu = item.per_cu;
+ dwarf2_per_cu *per_cu = item.per_cu;
if (!per_objfile->symtab_set_p (per_cu))
{
@@ -4746,8 +4038,11 @@ process_queue (dwarf2_per_objfile *per_objfile)
/* Skip dummy CUs. */
if (cu != nullptr)
{
+ namespace chr = std::chrono;
+
unsigned int debug_print_threshold;
char buf[100];
+ std::optional<chr::time_point<chr::steady_clock>> start_time;
if (per_cu->is_debug_types)
{
@@ -4769,15 +4064,28 @@ process_queue (dwarf2_per_objfile *per_objfile)
}
if (dwarf_read_debug >= debug_print_threshold)
- dwarf_read_debug_printf ("Expanding symtab of %s", buf);
+ {
+ dwarf_read_debug_printf ("Expanding symtab of %s", buf);
+ start_time = chr::steady_clock::now ();
+ }
+
+ ++expanded_count;
if (per_cu->is_debug_types)
- process_full_type_unit (cu, item.pretend_language);
+ process_full_type_unit (cu);
else
- process_full_comp_unit (cu, item.pretend_language);
+ process_full_comp_unit (cu);
if (dwarf_read_debug >= debug_print_threshold)
- dwarf_read_debug_printf ("Done expanding %s", buf);
+ {
+ const auto end_time = chr::steady_clock::now ();
+ const auto time_spent = end_time - *start_time;
+ const auto ms
+ = chr::duration_cast<chr::milliseconds> (time_spent);
+
+ dwarf_read_debug_printf ("Done expanding %s, took %.3fs", buf,
+ ms.count () / 1000.0);
+ }
}
}
@@ -4785,52 +4093,28 @@ process_queue (dwarf2_per_objfile *per_objfile)
per_objfile->queue->pop ();
}
- dwarf_read_debug_printf ("Done expanding symtabs of %s.",
- objfile_name (per_objfile->objfile));
+ dwarf_read_debug_printf ("Done expanding %u symtabs.", expanded_count);
}
-/* Load the DIEs associated with PER_CU into memory.
-
- In some cases, the caller, while reading partial symbols, will need to load
- the full symbols for the CU for some reason. It will already have a
- dwarf2_cu object for THIS_CU and pass it as EXISTING_CU, so it can be re-used
- rather than creating a new one. */
+/* Load the DIEs associated with PER_CU into memory. */
static void
-load_full_comp_unit (dwarf2_per_cu_data *this_cu,
- dwarf2_per_objfile *per_objfile,
- dwarf2_cu *existing_cu,
- bool skip_partial,
- enum language pretend_language)
+load_full_comp_unit (dwarf2_per_cu *this_cu, dwarf2_per_objfile *per_objfile,
+ bool skip_partial, enum language pretend_language)
{
gdb_assert (! this_cu->is_debug_types);
+ gdb_assert (per_objfile->get_cu (this_cu) == nullptr);
- cutu_reader reader (this_cu, per_objfile, NULL, existing_cu, skip_partial);
- if (reader.dummy_p)
+ cutu_reader reader (*this_cu, *per_objfile, nullptr, nullptr, skip_partial,
+ pretend_language);
+ if (reader.is_dummy ())
return;
- struct dwarf2_cu *cu = reader.cu;
- const gdb_byte *info_ptr = reader.info_ptr;
-
- gdb_assert (cu->die_hash.empty ());
- cu->die_hash.reserve (cu->header.get_length_without_initial () / 12);
-
- if (reader.comp_unit_die->has_children)
- reader.comp_unit_die->child
- = read_die_and_siblings (&reader, reader.info_ptr,
- &info_ptr, reader.comp_unit_die);
- cu->dies = reader.comp_unit_die;
- /* comp_unit_die is not stored in die_hash, no need. */
-
- /* We try not to read any attributes in this function, because not
- all CUs needed for references have been loaded yet, and symbol
- table processing isn't initialized. But we have to set the CU language,
- or we won't be able to build types correctly.
- Similarly, if we do not read the producer, we can not apply
- producer-specific interpretation. */
- prepare_one_comp_unit (cu, cu->dies, pretend_language);
+ reader.read_all_dies ();
- reader.keep ();
+ /* Save this dwarf2_cu in the per_objfile. The per_objfile owns it
+ now. */
+ per_objfile->set_cu (this_cu, reader.release_cu ());
}
/* Add a DIE to the delayed physname list. */
@@ -5242,7 +4526,7 @@ quirk_rust_enum (struct type *type, struct objfile *objfile)
/* We need a way to find the correct discriminant given a
variant name. For convenience we build a map here. */
struct type *enum_type = disr_field->type ();
- std::unordered_map<std::string_view, ULONGEST> discriminant_map;
+ gdb::unordered_map<std::string_view, ULONGEST> discriminant_map;
for (int i = 0; i < enum_type->num_fields (); ++i)
{
if (enum_type->field (i).loc_kind () == FIELD_LOC_KIND_ENUMVAL)
@@ -5315,24 +4599,23 @@ rust_union_quirks (struct dwarf2_cu *cu)
/* See read.h. */
type_unit_group_unshareable *
-dwarf2_per_objfile::get_type_unit_group_unshareable (type_unit_group *tu_group)
+dwarf2_per_objfile::get_type_unit_group_unshareable
+ (stmt_list_hash tu_group_key)
{
- auto iter = this->m_type_units.find (tu_group);
- if (iter != this->m_type_units.end ())
- return iter->second.get ();
+ auto [it, inserted] = m_type_units.emplace (tu_group_key, nullptr);
- 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;
+ if (inserted)
+ it->second = std::make_unique<type_unit_group_unshareable> ();
+
+ return it->second.get ();
}
struct type *
dwarf2_per_objfile::get_type_for_signatured_type
(signatured_type *sig_type) const
{
- auto iter = this->m_type_map.find (sig_type);
- if (iter == this->m_type_map.end ())
+ auto iter = m_type_map.find (sig_type);
+ if (iter == m_type_map.end ())
return nullptr;
return iter->second;
@@ -5341,9 +4624,9 @@ dwarf2_per_objfile::get_type_for_signatured_type
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 ());
+ gdb_assert (m_type_map.find (sig_type) == m_type_map.end ());
- this->m_type_map[sig_type] = type;
+ m_type_map[sig_type] = type;
}
/* A helper function for computing the list of all symbol tables
@@ -5352,9 +4635,9 @@ void dwarf2_per_objfile::set_type_for_signatured_type
static void
recursively_compute_inclusions
(std::vector<compunit_symtab *> *result,
- gdb::unordered_set<dwarf2_per_cu_data *> &all_children,
+ gdb::unordered_set<dwarf2_per_cu *> &all_children,
gdb::unordered_set<compunit_symtab *> &all_type_symtabs,
- dwarf2_per_cu_data *per_cu,
+ dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile,
struct compunit_symtab *immediate_parent)
{
@@ -5389,7 +4672,7 @@ recursively_compute_inclusions
}
}
- for (dwarf2_per_cu_data *ptr : per_cu->imported_symtabs)
+ for (dwarf2_per_cu *ptr : per_cu->imported_symtabs)
recursively_compute_inclusions (result, all_children,
all_type_symtabs, ptr, per_objfile,
cust);
@@ -5399,7 +4682,7 @@ recursively_compute_inclusions
PER_CU. */
static void
-compute_compunit_symtab_includes (dwarf2_per_cu_data *per_cu,
+compute_compunit_symtab_includes (dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile)
{
gdb_assert (! per_cu->is_debug_types);
@@ -5414,10 +4697,10 @@ compute_compunit_symtab_includes (dwarf2_per_cu_data *per_cu,
if (cust == NULL)
return;
- gdb::unordered_set<dwarf2_per_cu_data *> all_children;
+ gdb::unordered_set<dwarf2_per_cu *> all_children;
gdb::unordered_set<compunit_symtab *> all_type_symtabs;
- for (dwarf2_per_cu_data *ptr : per_cu->imported_symtabs)
+ for (dwarf2_per_cu *ptr : per_cu->imported_symtabs)
recursively_compute_inclusions (&result_symtabs, all_children,
all_type_symtabs, ptr,
per_objfile, cust);
@@ -5439,7 +4722,7 @@ compute_compunit_symtab_includes (dwarf2_per_cu_data *per_cu,
static void
process_cu_includes (dwarf2_per_objfile *per_objfile)
{
- for (dwarf2_per_cu_data *iter : per_objfile->per_bfd->just_read_cus)
+ for (dwarf2_per_cu *iter : per_objfile->per_bfd->just_read_cus)
{
if (! iter->is_debug_types)
compute_compunit_symtab_includes (iter, per_objfile);
@@ -5452,7 +4735,7 @@ process_cu_includes (dwarf2_per_objfile *per_objfile)
already been loaded into memory. */
static void
-process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
+process_full_comp_unit (dwarf2_cu *cu)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
unrelocated_addr lowpc, highpc;
@@ -5517,8 +4800,6 @@ process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
if (cust != NULL)
{
- int gcc_4_minor = producer_is_gcc_ge_4 (cu->producer);
-
/* Set symtab language to language from DW_AT_language. If the
compilation is from a C file generated by language preprocessors, do
not set the language if it was already deduced by start_subfile. */
@@ -5538,13 +4819,13 @@ process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
Still one can confuse GDB by using non-standard GCC compilation
options - this waits on GCC PR other/32998 (-frecord-gcc-switches).
*/
- if (cu->has_loclist && gcc_4_minor >= 5)
+ /* Note that this code traditionally did not accept non-GCC
+ compilers; that is preserved but seems potentially wrong. */
+ if (cu->has_loclist && cu->producer_is_gcc ()
+ && !cu->producer_is_gcc_lt_4_5 ())
cust->set_locations_valid (true);
- int major, minor;
- if (cu->producer != nullptr
- && producer_is_gcc (cu->producer, &major, &minor)
- && (major < 4 || (major == 4 && minor < 5)))
+ if (cu->producer_is_gcc_lt_4_5 ())
/* Don't trust gcc < 4.5.x. */
cust->set_epilogue_unwind_valid (false);
else
@@ -5566,8 +4847,7 @@ process_full_comp_unit (dwarf2_cu *cu, enum language pretend_language)
already been loaded into memory. */
static void
-process_full_type_unit (dwarf2_cu *cu,
- enum language pretend_language)
+process_full_type_unit (dwarf2_cu *cu)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
struct compunit_symtab *cust;
@@ -5599,7 +4879,7 @@ process_full_type_unit (dwarf2_cu *cu,
of it with end_expandable_symtab. Otherwise, complete the addition of
this TU's symbols to the existing symtab. */
type_unit_group_unshareable *tug_unshare =
- per_objfile->get_type_unit_group_unshareable (sig_type->type_unit_group);
+ per_objfile->get_type_unit_group_unshareable (*sig_type->type_unit_group_key);
if (tug_unshare->compunit_symtab == NULL)
{
buildsym_compunit *builder = cu->get_builder ();
@@ -5649,9 +4929,9 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
if (attr != NULL)
{
sect_offset sect_off = attr->get_ref_die_offset ();
- bool is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
+ bool is_dwz = attr->form_is_alt () || cu->per_cu->is_dwz;
dwarf2_per_objfile *per_objfile = cu->per_objfile;
- dwarf2_per_cu_data *per_cu
+ dwarf2_per_cu *per_cu
= dwarf2_find_containing_comp_unit (sect_off, is_dwz,
per_objfile->per_bfd);
@@ -5665,10 +4945,8 @@ process_imported_unit_die (struct die_info *die, struct dwarf2_cu *cu)
return;
/* If necessary, add it to the queue and load its DIEs. */
- if (maybe_queue_comp_unit (cu, per_cu, per_objfile,
- cu->lang ()))
- load_full_comp_unit (per_cu, per_objfile, per_objfile->get_cu (per_cu),
- false, cu->lang ());
+ if (maybe_queue_comp_unit (cu, per_cu, per_objfile))
+ load_full_comp_unit (per_cu, per_objfile, false, cu->lang ());
cu->per_cu->imported_symtabs.push_back (per_cu);
}
@@ -5838,15 +5116,39 @@ die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu)
{
struct attribute *attr;
+ if (tag_is_type (die->tag) && die->tag != DW_TAG_template_type_param)
+ {
+ /* Historically GNAT emitted some types in funny scopes. For
+ example, in one test case, where the first use of Natural was
+ as the type of a field in a record, GNAT emitted:
+
+ <2>: DW_TAG_structure_type
+ ... variant parts and whatnot
+ <5>: DW_TAG_subrange_type
+ . DW_AT_name: natural
+
+ To detect this, we look up the DIE tree for a node that has
+ a name; and if that name is fully qualified, we return 0
+ here. */
+ if (cu->lang () == language_ada)
+ {
+ for (die_info *iter = die->parent;
+ iter != nullptr;
+ iter = iter->parent)
+ {
+ if (tag_is_type (iter->tag))
+ {
+ const char *name = dwarf2_name (iter, cu);
+ if (name != nullptr)
+ return strstr (name, "__") == nullptr;
+ }
+ }
+ }
+ return 1;
+ }
+
switch (die->tag)
{
- case DW_TAG_namespace:
- case DW_TAG_typedef:
- case DW_TAG_class_type:
- case DW_TAG_interface_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- case DW_TAG_enumeration_type:
case DW_TAG_enumerator:
case DW_TAG_subprogram:
case DW_TAG_inlined_subroutine:
@@ -5855,6 +5157,11 @@ die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu)
case DW_TAG_imported_declaration:
return 1;
+ case DW_TAG_module:
+ /* We don't need the namespace for Fortran modules, but we do
+ for Ada packages. */
+ return cu->lang () == language_ada;
+
case DW_TAG_variable:
case DW_TAG_constant:
/* We only need to prefix "globally" visible variables. These include
@@ -5961,8 +5268,7 @@ dwarf2_compute_name (const char *name,
Fortran names because there is no mangling standard. So new_symbol
will set the demangled name to the result of dwarf2_full_name, and it is
the demangled name that GDB uses if it exists. */
- if (lang == language_ada
- || (lang == language_fortran && physname))
+ if ((lang == language_ada || lang == language_fortran) && physname)
{
/* For Ada unit, we prefer the linkage name over the name, as
the former contains the exported name, which the user expects
@@ -5975,11 +5281,21 @@ dwarf2_compute_name (const char *name,
return linkage_name;
}
+ /* Some versions of GNAT emit fully-qualified names already. These
+ have "__" separating the components -- something ordinary names
+ will never have. */
+ if (lang == language_ada
+ && name != nullptr
+ && strstr (name, "__") != nullptr)
+ return name;
+
/* These are the only languages we know how to qualify names in. */
if (name != NULL
&& (lang == language_cplus
- || lang == language_fortran || lang == language_d
- || lang == language_rust))
+ || lang == language_fortran
+ || lang == language_d
+ || lang == language_rust
+ || lang == language_ada))
{
if (die_needs_namespace (die, cu))
{
@@ -6022,12 +5338,11 @@ dwarf2_compute_name (const char *name,
if (lang == language_cplus && strchr (name, '<') == NULL)
{
struct attribute *attr;
- struct die_info *child;
int first = 1;
die->building_fullname = 1;
- for (child = die->child; child != NULL; child = child->sibling)
+ for (die_info *child : die->children ())
{
struct type *type;
LONGEST value;
@@ -6373,17 +5688,14 @@ read_decl_line (struct die_info *die, struct dwarf2_cu *cu)
struct attribute *decl_line = dwarf2_attr (die, DW_AT_decl_line, cu);
if (decl_line == nullptr)
return 0;
- if (decl_line->form_is_constant ())
- {
- LONGEST val = decl_line->constant_value (0);
- if (0 <= val && val <= UINT_MAX)
- return (unsigned int) val;
+ std::optional<ULONGEST> val = decl_line->unsigned_constant ();
+ if (val.has_value ())
+ {
+ if (*val <= UINT_MAX)
+ return (unsigned int) *val;
complaint (_("Declared line for using directive is too large"));
- return 0;
}
-
- complaint (_("Declared line for using directive is of incorrect format"));
return 0;
}
@@ -6394,7 +5706,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->per_objfile->objfile;
struct attribute *import_attr;
- struct die_info *imported_die, *child_die;
+ struct die_info *imported_die;
struct dwarf2_cu *imported_cu;
const char *imported_name;
const char *imported_name_prefix;
@@ -6469,19 +5781,16 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
canonical_name = imported_name_prefix;
}
else if (strlen (imported_name_prefix) > 0)
- canonical_name = obconcat (&objfile->objfile_obstack,
- imported_name_prefix,
- (cu->lang () == language_d
- ? "."
- : "::"),
- imported_name, (char *) NULL);
+ {
+ gdb::unique_xmalloc_ptr<char> temp;
+ temp = typename_concat (imported_name_prefix, imported_name, 0, cu);
+ canonical_name = obstack_strdup (&objfile->objfile_obstack, temp.get ());
+ }
else
canonical_name = imported_name;
- if (die->tag == DW_TAG_imported_module
- && cu->lang () == language_fortran)
- for (child_die = die->child; child_die && child_die->tag;
- child_die = child_die->sibling)
+ if (die->tag == DW_TAG_imported_module && cu->lang () == language_fortran)
+ for (die_info *child_die : die->children ())
{
/* DWARF-4: A Fortran use statement with a “rename list” may be
represented by an imported module entry with an import attribute
@@ -6533,56 +5842,7 @@ read_import_statement (struct die_info *die, struct dwarf2_cu *cu)
&objfile->objfile_obstack);
}
-/* ICC<14 does not output the required DW_AT_declaration on incomplete
- types, but gives them a size of zero. Starting with version 14,
- ICC is compatible with GCC. */
-
-static bool
-producer_is_icc_lt_14 (struct dwarf2_cu *cu)
-{
- if (!cu->checked_producer)
- check_producer (cu);
-
- return cu->producer_is_icc_lt_14;
-}
-
-/* ICC generates a DW_AT_type for C void functions. This was observed on
- ICC 14.0.5.212, and appears to be against the DWARF spec (V5 3.3.2)
- which says that void functions should not have a DW_AT_type. */
-
-static bool
-producer_is_icc (struct dwarf2_cu *cu)
-{
- if (!cu->checked_producer)
- check_producer (cu);
-
- return cu->producer_is_icc;
-}
-
-/* Check for possibly missing DW_AT_comp_dir with relative .debug_line
- directory paths. GCC SVN r127613 (new option -fdebug-prefix-map) fixed
- this, it was first present in GCC release 4.3.0. */
-
-static bool
-producer_is_gcc_lt_4_3 (struct dwarf2_cu *cu)
-{
- if (!cu->checked_producer)
- check_producer (cu);
-
- return cu->producer_is_gcc_lt_4_3;
-}
-
-/* See dwarf2/read.h. */
-bool
-producer_is_clang (struct dwarf2_cu *cu)
-{
- if (!cu->checked_producer)
- check_producer (cu);
-
- return cu->producer_is_clang;
-}
-
-static file_and_directory &
+file_and_directory &
find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu)
{
if (cu->per_cu->fnd != nullptr)
@@ -6594,11 +5854,11 @@ find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu)
dwarf2_string_attr (die, DW_AT_comp_dir, cu));
if (res.get_comp_dir () == nullptr
- && producer_is_gcc_lt_4_3 (cu)
+ && cu->producer_is_gcc_lt_4_3 ()
&& res.get_name () != nullptr
&& IS_ABSOLUTE_PATH (res.get_name ()))
{
- res.set_comp_dir (ldirname (res.get_name ()));
+ res.set_comp_dir (gdb_ldirname (res.get_name ()));
res.set_name (make_unique_xstrdup (lbasename (res.get_name ())));
}
@@ -6717,9 +5977,6 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
struct objfile *objfile = per_objfile->objfile;
CORE_ADDR lowpc;
struct attribute *attr;
- struct die_info *child_die;
-
- prepare_one_comp_unit (cu, die, cu->lang ());
unrelocated_addr unrel_low, unrel_high;
get_scope_pc_bounds (die, &unrel_low, &unrel_high, cu);
@@ -6737,7 +5994,7 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
implicitly prefixing it with the compilation dir. Work around this by
prefixing it with the source dir instead. */
if (cu->header.version == 5 && !IS_ABSOLUTE_PATH (fnd.get_name ())
- && producer_is_gas_lt_2_38 (cu))
+ && cu->producer_is_gas_lt_2_38 ())
{
attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
if (attr != nullptr && attr->form_is_unsigned ())
@@ -6766,15 +6023,9 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
handle_DW_AT_stmt_list (die, cu, fnd, unrel_low, unrel_low != unrel_high);
/* Process all dies in compilation unit. */
- if (die->child != NULL)
- {
- child_die = die->child;
- while (child_die && child_die->tag)
- {
- process_die (child_die, cu);
- child_die = child_die->sibling;
- }
- }
+ for (die_info *child_die : die->children ())
+ process_die (child_die, cu);
+
per_objfile->sym_cu = nullptr;
/* Decode macro information, if present. Dwarf 2 macro information
@@ -6806,7 +6057,6 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu)
void
dwarf2_cu::setup_type_unit_groups (struct die_info *die)
{
- struct type_unit_group *tu_group;
int first_time;
struct attribute *attr;
unsigned int i;
@@ -6819,16 +6069,15 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
/* If we're using .gdb_index (includes -readnow) then
per_cu->type_unit_group may not have been set up yet. */
- if (sig_type->type_unit_group == NULL)
- sig_type->type_unit_group = get_type_unit_group (this, attr);
- tu_group = sig_type->type_unit_group;
+ if (!sig_type->type_unit_group_key.has_value ())
+ sig_type->type_unit_group_key = get_type_unit_group_key (this, attr);
/* If we've already processed this stmt_list there's no real need to
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. */
type_unit_group_unshareable *tug_unshare
- = per_objfile->get_type_unit_group_unshareable (tu_group);
+ = per_objfile->get_type_unit_group_unshareable (*sig_type->type_unit_group_key);
first_time = tug_unshare->compunit_symtab == NULL;
/* We have to handle the case of both a missing DW_AT_stmt_list or bad
@@ -6932,24 +6181,13 @@ dwarf2_cu::setup_type_unit_groups (struct die_info *die)
static void
read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu)
{
- struct die_info *child_die;
-
- prepare_one_comp_unit (cu, die, language_minimal);
-
/* Initialize (or reinitialize) the machinery for building symtabs.
We do this before processing child DIEs, so that the line header table
is available for DW_AT_decl_file. */
cu->setup_type_unit_groups (die);
- if (die->child != NULL)
- {
- child_die = die->child;
- while (child_die && child_die->tag)
- {
- process_die (child_die, cu);
- child_die = child_die->sibling;
- }
- }
+ for (die_info *child_die : die->children ())
+ process_die (child_die, cu);
}
/* DWO/DWP files.
@@ -6961,225 +6199,164 @@ read_type_unit_scope (struct die_info *die, struct dwarf2_cu *cu)
and DWP files (a file with the DWOs packaged up into one file), we treat
DWP files as having a collection of virtual DWO files. */
-/* A helper function to hash two file names. This is a separate
- function because the hash table uses a search with a different
- type. The second file may be NULL. */
-
-static hashval_t
-hash_two_files (const char *one, const char *two)
-{
- hashval_t hash = htab_hash_string (one);
- if (two != nullptr)
- hash += htab_hash_string (two);
- return hash;
-}
-
-static hashval_t
-hash_dwo_file (const void *item)
-{
- const struct dwo_file *dwo_file = (const struct dwo_file *) item;
- return hash_two_files (dwo_file->dwo_name.c_str (), dwo_file->comp_dir);
-}
-
-/* This is used when looking up entries in the DWO hash table. */
-
-struct dwo_file_search
-{
- /* Name of the DWO to look for. */
- const char *dwo_name;
- /* Compilation directory to look for. */
- const char *comp_dir;
-
- /* Return a hash value compatible with the table. */
- hashval_t hash () const
- {
- return hash_two_files (dwo_name, comp_dir);
- }
-};
+/* Lookup DWO file DWO_NAME. */
-static int
-eq_dwo_file (const void *item_lhs, const void *item_rhs)
+static dwo_file *
+lookup_dwo_file (dwarf2_per_bfd *per_bfd, const char *dwo_name,
+ const char *comp_dir)
{
- const struct dwo_file *lhs = (const struct dwo_file *) item_lhs;
- const struct dwo_file_search *rhs
- = (const struct dwo_file_search *) item_rhs;
-
- if (lhs->dwo_name != rhs->dwo_name)
- return 0;
- if (lhs->comp_dir == NULL || rhs->comp_dir == NULL)
- return lhs->comp_dir == rhs->comp_dir;
- return strcmp (lhs->comp_dir, rhs->comp_dir) == 0;
-}
+#if CXX_STD_THREAD
+ std::lock_guard<std::mutex> guard (per_bfd->dwo_files_lock);
+#endif
-/* Allocate a hash table for DWO files. */
+ auto it = per_bfd->dwo_files.find (dwo_file_search {dwo_name, comp_dir});
-static htab_up
-allocate_dwo_file_hash_table ()
-{
- return htab_up (htab_create_alloc (41,
- hash_dwo_file,
- eq_dwo_file,
- htab_delete_entry<dwo_file>,
- xcalloc, xfree));
+ return it != per_bfd->dwo_files.end () ? it->get() : nullptr;
}
-/* Lookup DWO file DWO_NAME. */
+/* Add DWO_FILE to the per-BFD DWO file hash table.
-static void **
-lookup_dwo_file_slot (dwarf2_per_objfile *per_objfile,
- const char *dwo_name,
- const char *comp_dir)
-{
- struct dwo_file_search find_entry;
- void **slot;
+ Return the dwo_file actually kept in the hash table.
- if (per_objfile->per_bfd->dwo_files == NULL)
- per_objfile->per_bfd->dwo_files = allocate_dwo_file_hash_table ();
+ If another thread raced with this one, opening the exact same DWO file and
+ inserting it first in the hash table, then keep that other thread's copy
+ and DWO_FILE gets freed. */
- find_entry.dwo_name = dwo_name;
- find_entry.comp_dir = comp_dir;
- slot = htab_find_slot_with_hash (per_objfile->per_bfd->dwo_files.get (),
- &find_entry, find_entry.hash (),
- INSERT);
-
- return slot;
-}
-
-static hashval_t
-hash_dwo_unit (const void *item)
+static dwo_file *
+add_dwo_file (dwarf2_per_bfd *per_bfd, dwo_file_up dwo_file)
{
- const struct dwo_unit *dwo_unit = (const struct dwo_unit *) item;
+#if CXX_STD_THREAD
+ std::lock_guard<std::mutex> lock (per_bfd->dwo_files_lock);
+#endif
- /* This drops the top 32 bits of the id, but is ok for a hash. */
- return dwo_unit->signature;
+ return per_bfd->dwo_files.emplace (std::move (dwo_file)).first->get ();
}
-static int
-eq_dwo_unit (const void *item_lhs, const void *item_rhs)
+void
+cutu_reader::create_dwo_unit_hash_tables (dwo_file &dwo_file,
+ dwarf2_cu &skeleton_cu,
+ dwarf2_section_info &section,
+ ruh_kind section_kind)
{
- const struct dwo_unit *lhs = (const struct dwo_unit *) item_lhs;
- const struct dwo_unit *rhs = (const struct dwo_unit *) item_rhs;
-
- /* The signature is assumed to be unique within the DWO file.
- So while object file CU dwo_id's always have the value zero,
- that's OK, assuming each object file DWO file has only one CU,
- and that's the rule for now. */
- return lhs->signature == rhs->signature;
-}
+ dwarf2_per_objfile &per_objfile = *skeleton_cu.per_objfile;
+ dwarf2_per_bfd &per_bfd = *per_objfile.per_bfd;
-/* Allocate a hash table for DWO CUs,TUs.
- There is one of these tables for each of CUs,TUs for each DWO file. */
+ const gdb_byte *info_ptr = section.buffer;
-static htab_up
-allocate_dwo_unit_table ()
-{
- /* Start out with a pretty small number.
- Generally DWO files contain only one CU and maybe some TUs. */
- return htab_up (htab_create_alloc (3,
- hash_dwo_unit,
- eq_dwo_unit,
- NULL, xcalloc, xfree));
-}
+ if (info_ptr == NULL)
+ return;
-/* die_reader_func for create_dwo_cu. */
+ dwarf_read_debug_printf ("Reading %s for %s:", section.get_name (),
+ section.get_file_name ());
-static void
-create_dwo_cu_reader (const struct die_reader_specs *reader,
- const gdb_byte *info_ptr,
- struct die_info *comp_unit_die,
- struct dwo_file *dwo_file,
- struct dwo_unit *dwo_unit)
-{
- struct dwarf2_cu *cu = reader->cu;
- sect_offset sect_off = cu->per_cu->sect_off;
- struct dwarf2_section_info *section = cu->per_cu->section;
+ const gdb_byte *end_ptr = info_ptr + section.size;
- std::optional<ULONGEST> signature = lookup_dwo_id (cu, comp_unit_die);
- if (!signature.has_value ())
+ while (info_ptr < end_ptr)
{
- complaint (_(DWARF_ERROR_PREFIX
- "debug entry at offset %s is missing its dwo_id"
- " [in module %s]"),
- sect_offset_str (sect_off), dwo_file->dwo_name.c_str ());
- return;
- }
+ sect_offset sect_off = (sect_offset) (info_ptr - section.buffer);
+ unit_head header;
+ dwarf2_section_info *abbrev_section = &dwo_file.sections.abbrev;
+ const gdb_byte *info_ptr_post_header
+ = read_and_check_unit_head (&header, &section, abbrev_section,
+ info_ptr, section_kind);
- dwo_unit->dwo_file = dwo_file;
- dwo_unit->signature = *signature;
- dwo_unit->section = section;
- dwo_unit->sect_off = sect_off;
- dwo_unit->length = cu->per_cu->length ();
+ unsigned int length = header.get_length_with_initial ();
+ info_ptr += length;
- dwarf_read_debug_printf (" offset %s, dwo_id %s",
- sect_offset_str (sect_off),
- hex_string (dwo_unit->signature));
-}
+ /* Skip dummy units. */
+ if (info_ptr_post_header >= info_ptr
+ || peek_abbrev_code (section.get_bfd_owner (),
+ info_ptr_post_header) == 0)
+ continue;
-/* Create the dwo_units for the CUs in a DWO_FILE.
- Note: This function processes DWO files only, not DWP files. */
+ if (header.unit_type != DW_UT_compile
+ && header.unit_type != DW_UT_split_compile
+ && header.unit_type != DW_UT_type
+ && header.unit_type != DW_UT_split_type)
+ continue;
-static void
-create_cus_hash_table (dwarf2_per_objfile *per_objfile,
- dwarf2_cu *cu, struct dwo_file &dwo_file,
- dwarf2_section_info &section, htab_up &cus_htab)
-{
- struct objfile *objfile = per_objfile->objfile;
- dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
- const gdb_byte *info_ptr, *end_ptr;
+ ULONGEST signature;
- section.read (objfile);
- info_ptr = section.buffer;
+ /* For type units (all DWARF versions) and DWARF 5 compile units, the
+ signature/DWO ID is already available in the header. For compile
+ units in DWARF < 5, we need to read the DW_AT_GNU_dwo_id attribute
+ from the top-level DIE.
- if (info_ptr == NULL)
- return;
+ For DWARF < 5 compile units, the unit type will be set to DW_UT_compile
+ by read_and_check_comp_unit_head. */
+ if (header.version < 5 && header.unit_type == DW_UT_compile)
+ {
+ /* The length of the CU is not necessary. */
+ dwarf2_per_cu per_cu (&per_bfd, &section, sect_off, length,
+ false /* is_dwz */);
+ cutu_reader reader (per_cu, per_objfile, language_minimal,
+ skeleton_cu, dwo_file);
- dwarf_read_debug_printf ("Reading %s for %s:",
- section.get_name (),
- section.get_file_name ());
+ std::optional<ULONGEST> opt_signature
+ = lookup_dwo_id (reader.cu (), reader.top_level_die ());
- end_ptr = info_ptr + section.size;
- while (info_ptr < end_ptr)
- {
- struct dwarf2_per_cu_data per_cu;
- struct dwo_unit read_unit {};
- struct dwo_unit *dwo_unit;
- void **slot;
- sect_offset sect_off = (sect_offset) (info_ptr - section.buffer);
+ if (!opt_signature.has_value ())
+ {
+ complaint (_ (DWARF_ERROR_PREFIX
+ "debug entry at offset %s is missing its dwo_id"
+ " [in module %s]"),
+ sect_offset_str (sect_off),
+ dwo_file.dwo_name.c_str ());
+ continue;
+ }
- 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 = &section;
+ signature = *opt_signature;
+ }
+ else
+ signature = header.signature;
- cutu_reader reader (&per_cu, 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);
- info_ptr += per_cu.length ();
+ auto dwo_unit = std::make_unique<struct dwo_unit> ();
- // If the unit could not be parsed, skip it.
- if (read_unit.dwo_file == NULL)
- continue;
+ /* Set the fields common to compile and type units. */
+ dwo_unit->dwo_file = &dwo_file;
+ dwo_unit->signature = signature;
+ dwo_unit->section = &section;
+ dwo_unit->sect_off = sect_off;
+ dwo_unit->length = length;
+
+ switch (header.unit_type)
+ {
+ case DW_UT_compile:
+ case DW_UT_split_compile:
+ {
+ dwarf_read_debug_printf (" compile unit at offset %s, dwo_id %s",
+ sect_offset_str (sect_off),
+ hex_string (dwo_unit->signature));
- if (cus_htab == NULL)
- cus_htab = allocate_dwo_unit_table ();
+ auto [it, inserted] = dwo_file.cus.emplace (std::move (dwo_unit));
+ if (!inserted)
+ complaint (_("debug cu entry at offset %s is duplicate to"
+ " the entry at offset %s, signature %s"),
+ sect_offset_str (sect_off),
+ sect_offset_str ((*it)->sect_off),
+ hex_string (dwo_unit->signature));
+ break;
+ }
- 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);
- if (*slot != NULL)
+ case DW_UT_type:
+ case DW_UT_split_type:
{
- const struct dwo_unit *dup_cu = (const struct dwo_unit *)*slot;
- sect_offset dup_sect_off = dup_cu->sect_off;
+ dwo_unit->type_offset_in_tu = header.type_offset_in_tu;
- complaint (_("debug cu entry at offset %s is duplicate to"
- " the entry at offset %s, signature %s"),
- sect_offset_str (sect_off), sect_offset_str (dup_sect_off),
- hex_string (dwo_unit->signature));
+ dwarf_read_debug_printf (" type unit at offset %s, signature %s",
+ sect_offset_str (sect_off),
+ hex_string (dwo_unit->signature));
+
+ auto [it, inserted] = dwo_file.tus.emplace (std::move (dwo_unit));
+ if (!inserted)
+ complaint (_("debug type entry at offset %s is duplicate to"
+ " the entry at offset %s, signature %s"),
+ sect_offset_str (sect_off),
+ sect_offset_str ((*it)->sect_off),
+ hex_string (header.signature));
+ break;
+ }
}
- *slot = (void *)dwo_unit;
}
}
@@ -7337,27 +6514,18 @@ create_cus_hash_table (dwarf2_per_objfile *per_objfile,
Note: This function processes DWP files only, not DWO files. */
static struct dwp_hash_table *
-create_dwp_hash_table (dwarf2_per_objfile *per_objfile,
- struct dwp_file *dwp_file, int is_debug_types)
+create_dwp_hash_table (dwarf2_per_bfd *per_bfd, struct dwp_file *dwp_file,
+ dwarf2_section_info &index)
{
- struct objfile *objfile = per_objfile->objfile;
bfd *dbfd = dwp_file->dbfd.get ();
- const gdb_byte *index_ptr, *index_end;
- struct dwarf2_section_info *index;
uint32_t version, nr_columns, nr_units, nr_slots;
struct dwp_hash_table *htab;
- if (is_debug_types)
- index = &dwp_file->sections.tu_index;
- else
- index = &dwp_file->sections.cu_index;
-
- if (index->empty ())
+ if (index.empty ())
return NULL;
- index->read (objfile);
- index_ptr = index->buffer;
- index_end = index_ptr + index->size;
+ const gdb_byte *index_ptr = index.buffer;
+ const gdb_byte *index_end = index_ptr + index.size;
/* For Version 5, the version is really 2 bytes of data & 2 bytes of padding.
For now it's safe to just read 4 bytes (particularly as it's difficult to
@@ -7388,7 +6556,7 @@ create_dwp_hash_table (dwarf2_per_objfile *per_objfile,
pulongest (nr_slots), dwp_file->name);
}
- htab = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack, struct dwp_hash_table);
+ htab = OBSTACK_ZALLOC (&per_bfd->obstack, struct dwp_hash_table);
htab->version = version;
htab->nr_columns = nr_columns;
htab->nr_units = nr_units;
@@ -7660,8 +6828,8 @@ locate_v1_virtual_dwo_sections (asection *sectp,
COMP_DIR is the DW_AT_comp_dir attribute of the referencing CU.
This is for DWP version 1 files. */
-static struct dwo_unit *
-create_dwo_unit_in_dwp_v1 (dwarf2_per_objfile *per_objfile,
+static dwo_unit_up
+create_dwo_unit_in_dwp_v1 (dwarf2_per_bfd *per_bfd,
struct dwp_file *dwp_file,
uint32_t unit_index,
const char *comp_dir,
@@ -7671,10 +6839,7 @@ create_dwo_unit_in_dwp_v1 (dwarf2_per_objfile *per_objfile,
is_debug_types ? dwp_file->tus : dwp_file->cus;
bfd *dbfd = dwp_file->dbfd.get ();
const char *kind = is_debug_types ? "TU" : "CU";
- struct dwo_file *dwo_file;
- struct dwo_unit *dwo_unit;
struct virtual_v1_dwo_sections sections;
- void **dwo_file_slot;
int i;
gdb_assert (dwp_file->version == 1);
@@ -7755,26 +6920,30 @@ create_dwo_unit_in_dwp_v1 (dwarf2_per_objfile *per_objfile,
sections.line.get_id (),
sections.loc.get_id (),
sections.str_offsets.get_id ());
+
/* Can we use an existing virtual DWO file? */
- dwo_file_slot = lookup_dwo_file_slot (per_objfile, virtual_dwo_name.c_str (),
- comp_dir);
+ dwo_file *dwo_file
+ = lookup_dwo_file (per_bfd, virtual_dwo_name.c_str (), comp_dir);
+
/* Create one if necessary. */
- if (*dwo_file_slot == NULL)
+ if (dwo_file == nullptr)
{
dwarf_read_debug_printf ("Creating virtual DWO: %s",
virtual_dwo_name.c_str ());
- dwo_file = new struct dwo_file;
- dwo_file->dwo_name = std::move (virtual_dwo_name);
- dwo_file->comp_dir = comp_dir;
- dwo_file->sections.abbrev = sections.abbrev;
- dwo_file->sections.line = sections.line;
- dwo_file->sections.loc = sections.loc;
- dwo_file->sections.macinfo = sections.macinfo;
- dwo_file->sections.macro = sections.macro;
- dwo_file->sections.str_offsets = sections.str_offsets;
+ dwo_file_up new_dwo_file = std::make_unique<struct dwo_file> ();
+ new_dwo_file->dwo_name = std::move (virtual_dwo_name);
+ new_dwo_file->comp_dir = comp_dir;
+ new_dwo_file->sections.abbrev = sections.abbrev;
+ new_dwo_file->sections.line = sections.line;
+ new_dwo_file->sections.loc = sections.loc;
+ new_dwo_file->sections.macinfo = sections.macinfo;
+ new_dwo_file->sections.macro = sections.macro;
+ new_dwo_file->sections.str_offsets = sections.str_offsets;
+
/* The "str" section is global to the entire DWP file. */
- dwo_file->sections.str = dwp_file->sections.str;
+ new_dwo_file->sections.str = dwp_file->sections.str;
+
/* The info or types section is assigned below to dwo_unit,
there's no need to record it in dwo_file.
Also, we can't simply record type sections in dwo_file because
@@ -7782,21 +6951,17 @@ create_dwo_unit_in_dwp_v1 (dwarf2_per_objfile *per_objfile,
types we'll grow the vector and eventually have to reallocate space
for it, invalidating all copies of pointers into the previous
contents. */
- *dwo_file_slot = dwo_file;
+ dwo_file = add_dwo_file (per_bfd, std::move (new_dwo_file));
}
else
- {
- dwarf_read_debug_printf ("Using existing virtual DWO: %s",
- virtual_dwo_name.c_str ());
-
- dwo_file = (struct dwo_file *) *dwo_file_slot;
- }
+ dwarf_read_debug_printf ("Using existing virtual DWO: %s",
+ virtual_dwo_name.c_str ());
- dwo_unit = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack, struct dwo_unit);
+ auto dwo_unit = std::make_unique<struct dwo_unit> ();
dwo_unit->dwo_file = dwo_file;
dwo_unit->signature = signature;
- dwo_unit->section =
- XOBNEW (&per_objfile->per_bfd->obstack, struct dwarf2_section_info);
+ dwo_unit->section_holder = std::make_unique<dwarf2_section_info> ();
+ dwo_unit->section = dwo_unit->section_holder.get ();
*dwo_unit->section = sections.info_or_types;
/* dwo_unit->{offset,length,type_offset_in_tu} are set later. */
@@ -7809,7 +6974,7 @@ create_dwo_unit_in_dwp_v1 (dwarf2_per_objfile *per_objfile,
virtual section of just that piece. */
static struct dwarf2_section_info
-create_dwp_v2_or_v5_section (dwarf2_per_objfile *per_objfile,
+create_dwp_v2_or_v5_section (dwarf2_per_bfd *per_bfd,
struct dwarf2_section_info *section,
bfd_size_type offset, bfd_size_type size)
{
@@ -7838,7 +7003,7 @@ create_dwp_v2_or_v5_section (dwarf2_per_objfile *per_objfile,
"Bad DWP V2 or V5 section info, doesn't fit in section %s"
" [in module %s]"),
sectp ? bfd_section_name (sectp) : "<unknown>",
- objfile_name (per_objfile->objfile));
+ per_bfd->filename ());
}
result.virtual_offset = offset;
@@ -7854,8 +7019,8 @@ create_dwp_v2_or_v5_section (dwarf2_per_objfile *per_objfile,
COMP_DIR is the DW_AT_comp_dir attribute of the referencing CU.
This is for DWP version 2 files. */
-static struct dwo_unit *
-create_dwo_unit_in_dwp_v2 (dwarf2_per_objfile *per_objfile,
+static dwo_unit_up
+create_dwo_unit_in_dwp_v2 (dwarf2_per_bfd *per_bfd,
struct dwp_file *dwp_file,
uint32_t unit_index,
const char *comp_dir,
@@ -7865,10 +7030,7 @@ create_dwo_unit_in_dwp_v2 (dwarf2_per_objfile *per_objfile,
is_debug_types ? dwp_file->tus : dwp_file->cus;
bfd *dbfd = dwp_file->dbfd.get ();
const char *kind = is_debug_types ? "TU" : "CU";
- struct dwo_file *dwo_file;
- struct dwo_unit *dwo_unit;
struct virtual_v2_or_v5_dwo_sections sections;
- void **dwo_file_slot;
int i;
gdb_assert (dwp_file->version == 2);
@@ -7944,44 +7106,47 @@ create_dwo_unit_in_dwp_v2 (dwarf2_per_objfile *per_objfile,
(long) (sections.loc_size ? sections.loc_offset : 0),
(long) (sections.str_offsets_size
? sections.str_offsets_offset : 0));
+
/* Can we use an existing virtual DWO file? */
- dwo_file_slot = lookup_dwo_file_slot (per_objfile, virtual_dwo_name.c_str (),
- comp_dir);
+ dwo_file *dwo_file
+ = lookup_dwo_file (per_bfd, virtual_dwo_name.c_str (), comp_dir);
+
/* Create one if necessary. */
- if (*dwo_file_slot == NULL)
+ if (dwo_file == nullptr)
{
dwarf_read_debug_printf ("Creating virtual DWO: %s",
virtual_dwo_name.c_str ());
- dwo_file = new struct dwo_file;
- dwo_file->dwo_name = std::move (virtual_dwo_name);
- dwo_file->comp_dir = comp_dir;
- dwo_file->sections.abbrev =
- create_dwp_v2_or_v5_section (per_objfile, &dwp_file->sections.abbrev,
- sections.abbrev_offset,
- sections.abbrev_size);
- dwo_file->sections.line =
- create_dwp_v2_or_v5_section (per_objfile, &dwp_file->sections.line,
- sections.line_offset,
- sections.line_size);
- dwo_file->sections.loc =
- create_dwp_v2_or_v5_section (per_objfile, &dwp_file->sections.loc,
- sections.loc_offset, sections.loc_size);
- dwo_file->sections.macinfo =
- create_dwp_v2_or_v5_section (per_objfile, &dwp_file->sections.macinfo,
- sections.macinfo_offset,
- sections.macinfo_size);
- dwo_file->sections.macro =
- create_dwp_v2_or_v5_section (per_objfile, &dwp_file->sections.macro,
- sections.macro_offset,
- sections.macro_size);
- dwo_file->sections.str_offsets =
- create_dwp_v2_or_v5_section (per_objfile,
- &dwp_file->sections.str_offsets,
- sections.str_offsets_offset,
- sections.str_offsets_size);
+ dwo_file_up new_dwo_file = std::make_unique<struct dwo_file> ();
+ new_dwo_file->dwo_name = std::move (virtual_dwo_name);
+ new_dwo_file->comp_dir = comp_dir;
+ new_dwo_file->sections.abbrev
+ = create_dwp_v2_or_v5_section (per_bfd, &dwp_file->sections.abbrev,
+ sections.abbrev_offset,
+ sections.abbrev_size);
+ new_dwo_file->sections.line
+ = create_dwp_v2_or_v5_section (per_bfd, &dwp_file->sections.line,
+ sections.line_offset,
+ sections.line_size);
+ new_dwo_file->sections.loc
+ = create_dwp_v2_or_v5_section (per_bfd, &dwp_file->sections.loc,
+ sections.loc_offset, sections.loc_size);
+ new_dwo_file->sections.macinfo
+ = create_dwp_v2_or_v5_section (per_bfd, &dwp_file->sections.macinfo,
+ sections.macinfo_offset,
+ sections.macinfo_size);
+ new_dwo_file->sections.macro
+ = create_dwp_v2_or_v5_section (per_bfd, &dwp_file->sections.macro,
+ sections.macro_offset,
+ sections.macro_size);
+ new_dwo_file->sections.str_offsets
+ = create_dwp_v2_or_v5_section (per_bfd, &dwp_file->sections.str_offsets,
+ sections.str_offsets_offset,
+ sections.str_offsets_size);
+
/* The "str" section is global to the entire DWP file. */
- dwo_file->sections.str = dwp_file->sections.str;
+ new_dwo_file->sections.str = dwp_file->sections.str;
+
/* The info or types section is assigned below to dwo_unit,
there's no need to record it in dwo_file.
Also, we can't simply record type sections in dwo_file because
@@ -7989,23 +7154,19 @@ create_dwo_unit_in_dwp_v2 (dwarf2_per_objfile *per_objfile,
types we'll grow the vector and eventually have to reallocate space
for it, invalidating all copies of pointers into the previous
contents. */
- *dwo_file_slot = dwo_file;
+ dwo_file = add_dwo_file (per_bfd, std::move (new_dwo_file));
}
else
- {
- dwarf_read_debug_printf ("Using existing virtual DWO: %s",
- virtual_dwo_name.c_str ());
+ dwarf_read_debug_printf ("Using existing virtual DWO: %s",
+ virtual_dwo_name.c_str ());
- dwo_file = (struct dwo_file *) *dwo_file_slot;
- }
-
- dwo_unit = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack, struct dwo_unit);
+ auto dwo_unit = std::make_unique<struct dwo_unit> ();
dwo_unit->dwo_file = dwo_file;
dwo_unit->signature = signature;
- dwo_unit->section =
- XOBNEW (&per_objfile->per_bfd->obstack, struct dwarf2_section_info);
+ dwo_unit->section_holder = std::make_unique<dwarf2_section_info> ();
+ dwo_unit->section = dwo_unit->section_holder.get ();
*dwo_unit->section = create_dwp_v2_or_v5_section
- (per_objfile,
+ (per_bfd,
is_debug_types
? &dwp_file->sections.types
: &dwp_file->sections.info,
@@ -8021,8 +7182,8 @@ create_dwo_unit_in_dwp_v2 (dwarf2_per_objfile *per_objfile,
COMP_DIR is the DW_AT_comp_dir attribute of the referencing CU.
This is for DWP version 5 files. */
-static struct dwo_unit *
-create_dwo_unit_in_dwp_v5 (dwarf2_per_objfile *per_objfile,
+static dwo_unit_up
+create_dwo_unit_in_dwp_v5 (dwarf2_per_bfd *per_bfd,
struct dwp_file *dwp_file,
uint32_t unit_index,
const char *comp_dir,
@@ -8032,10 +7193,7 @@ create_dwo_unit_in_dwp_v5 (dwarf2_per_objfile *per_objfile,
= is_debug_types ? dwp_file->tus : dwp_file->cus;
bfd *dbfd = dwp_file->dbfd.get ();
const char *kind = is_debug_types ? "TU" : "CU";
- struct dwo_file *dwo_file;
- struct dwo_unit *dwo_unit;
struct virtual_v2_or_v5_dwo_sections sections {};
- void **dwo_file_slot;
gdb_assert (dwp_file->version == 5);
@@ -8115,50 +7273,48 @@ create_dwo_unit_in_dwp_v5 (dwarf2_per_objfile *per_objfile,
? sections.str_offsets_offset : 0),
(long) (sections.macro_size ? sections.macro_offset : 0),
(long) (sections.rnglists_size ? sections.rnglists_offset: 0));
+
/* Can we use an existing virtual DWO file? */
- dwo_file_slot = lookup_dwo_file_slot (per_objfile,
- virtual_dwo_name.c_str (),
- comp_dir);
+ dwo_file *dwo_file
+ = lookup_dwo_file (per_bfd, virtual_dwo_name.c_str (), comp_dir);
+
/* Create one if necessary. */
- if (*dwo_file_slot == NULL)
+ if (dwo_file == nullptr)
{
dwarf_read_debug_printf ("Creating virtual DWO: %s",
virtual_dwo_name.c_str ());
- dwo_file = new struct dwo_file;
- dwo_file->dwo_name = std::move (virtual_dwo_name);
- dwo_file->comp_dir = comp_dir;
- dwo_file->sections.abbrev =
- create_dwp_v2_or_v5_section (per_objfile,
- &dwp_file->sections.abbrev,
- sections.abbrev_offset,
- sections.abbrev_size);
- dwo_file->sections.line =
- create_dwp_v2_or_v5_section (per_objfile,
- &dwp_file->sections.line,
- sections.line_offset, sections.line_size);
- dwo_file->sections.macro =
- create_dwp_v2_or_v5_section (per_objfile,
- &dwp_file->sections.macro,
- sections.macro_offset,
- sections.macro_size);
- dwo_file->sections.loclists =
- create_dwp_v2_or_v5_section (per_objfile,
- &dwp_file->sections.loclists,
- sections.loclists_offset,
- sections.loclists_size);
- dwo_file->sections.rnglists =
- create_dwp_v2_or_v5_section (per_objfile,
- &dwp_file->sections.rnglists,
- sections.rnglists_offset,
- sections.rnglists_size);
- dwo_file->sections.str_offsets =
- create_dwp_v2_or_v5_section (per_objfile,
- &dwp_file->sections.str_offsets,
- sections.str_offsets_offset,
- sections.str_offsets_size);
+ dwo_file_up new_dwo_file = std::make_unique<struct dwo_file> ();
+ new_dwo_file->dwo_name = std::move (virtual_dwo_name);
+ new_dwo_file->comp_dir = comp_dir;
+ new_dwo_file->sections.abbrev
+ = create_dwp_v2_or_v5_section (per_bfd, &dwp_file->sections.abbrev,
+ sections.abbrev_offset,
+ sections.abbrev_size);
+ new_dwo_file->sections.line
+ = create_dwp_v2_or_v5_section (per_bfd, &dwp_file->sections.line,
+ sections.line_offset,
+ sections.line_size);
+ new_dwo_file->sections.macro
+ = create_dwp_v2_or_v5_section (per_bfd, &dwp_file->sections.macro,
+ sections.macro_offset,
+ sections.macro_size);
+ new_dwo_file->sections.loclists
+ = create_dwp_v2_or_v5_section (per_bfd, &dwp_file->sections.loclists,
+ sections.loclists_offset,
+ sections.loclists_size);
+ new_dwo_file->sections.rnglists
+ = create_dwp_v2_or_v5_section (per_bfd, &dwp_file->sections.rnglists,
+ sections.rnglists_offset,
+ sections.rnglists_size);
+ new_dwo_file->sections.str_offsets
+ = create_dwp_v2_or_v5_section (per_bfd, &dwp_file->sections.str_offsets,
+ sections.str_offsets_offset,
+ sections.str_offsets_size);
+
/* The "str" section is global to the entire DWP file. */
- dwo_file->sections.str = dwp_file->sections.str;
+ new_dwo_file->sections.str = dwp_file->sections.str;
+
/* The info or types section is assigned below to dwo_unit,
there's no need to record it in dwo_file.
Also, we can't simply record type sections in dwo_file because
@@ -8166,25 +7322,21 @@ create_dwo_unit_in_dwp_v5 (dwarf2_per_objfile *per_objfile,
types we'll grow the vector and eventually have to reallocate space
for it, invalidating all copies of pointers into the previous
contents. */
- *dwo_file_slot = dwo_file;
+ dwo_file = add_dwo_file (per_bfd, std::move (new_dwo_file));
}
else
- {
- dwarf_read_debug_printf ("Using existing virtual DWO: %s",
- virtual_dwo_name.c_str ());
-
- dwo_file = (struct dwo_file *) *dwo_file_slot;
- }
+ dwarf_read_debug_printf ("Using existing virtual DWO: %s",
+ virtual_dwo_name.c_str ());
- dwo_unit = OBSTACK_ZALLOC (&per_objfile->per_bfd->obstack, struct dwo_unit);
+ auto dwo_unit = std::make_unique<struct dwo_unit> ();
dwo_unit->dwo_file = dwo_file;
dwo_unit->signature = signature;
dwo_unit->section
- = XOBNEW (&per_objfile->per_bfd->obstack, struct dwarf2_section_info);
- *dwo_unit->section = create_dwp_v2_or_v5_section (per_objfile,
- &dwp_file->sections.info,
- sections.info_or_types_offset,
- sections.info_or_types_size);
+ = XOBNEW (&per_bfd->obstack, struct dwarf2_section_info);
+ *dwo_unit->section
+ = create_dwp_v2_or_v5_section (per_bfd, &dwp_file->sections.info,
+ sections.info_or_types_offset,
+ sections.info_or_types_size);
/* dwo_unit->{offset,length,type_offset_in_tu} are set later. */
return dwo_unit;
@@ -8194,7 +7346,7 @@ create_dwo_unit_in_dwp_v5 (dwarf2_per_objfile *per_objfile,
Returns NULL if the signature isn't found. */
static struct dwo_unit *
-lookup_dwo_unit_in_dwp (dwarf2_per_objfile *per_objfile,
+lookup_dwo_unit_in_dwp (dwarf2_per_bfd *per_bfd,
struct dwp_file *dwp_file, const char *comp_dir,
ULONGEST signature, int is_debug_types)
{
@@ -8204,22 +7356,21 @@ lookup_dwo_unit_in_dwp (dwarf2_per_objfile *per_objfile,
uint32_t mask = dwp_htab->nr_slots - 1;
uint32_t hash = signature & mask;
uint32_t hash2 = ((signature >> 32) & mask) | 1;
- unsigned int i;
- void **slot;
- struct dwo_unit find_dwo_cu;
+ auto &dwo_unit_set
+ = is_debug_types ? dwp_file->loaded_tus : dwp_file->loaded_cus;
- memset (&find_dwo_cu, 0, sizeof (find_dwo_cu));
- find_dwo_cu.signature = signature;
- slot = htab_find_slot (is_debug_types
- ? dwp_file->loaded_tus.get ()
- : dwp_file->loaded_cus.get (),
- &find_dwo_cu, INSERT);
+ {
+#if CXX_STD_THREAD
+ std::lock_guard<std::mutex> guard (dwp_file->loaded_cutus_lock);
+#endif
- if (*slot != NULL)
- return (struct dwo_unit *) *slot;
+ if (auto it = dwo_unit_set.find (signature);
+ it != dwo_unit_set.end ())
+ return it->get ();
+ }
/* Use a for loop so that we don't loop forever on bad debug info. */
- for (i = 0; i < dwp_htab->nr_slots; ++i)
+ for (unsigned int i = 0; i < dwp_htab->nr_slots; ++i)
{
ULONGEST signature_in_table;
@@ -8230,29 +7381,34 @@ lookup_dwo_unit_in_dwp (dwarf2_per_objfile *per_objfile,
uint32_t unit_index =
read_4_bytes (dbfd,
dwp_htab->unit_table + hash * sizeof (uint32_t));
+ dwo_unit_up dwo_unit;
if (dwp_file->version == 1)
- {
- *slot = create_dwo_unit_in_dwp_v1 (per_objfile, dwp_file,
- unit_index, comp_dir,
- signature, is_debug_types);
- }
+ dwo_unit
+ = create_dwo_unit_in_dwp_v1 (per_bfd, dwp_file, unit_index,
+ comp_dir, signature, is_debug_types);
else if (dwp_file->version == 2)
- {
- *slot = create_dwo_unit_in_dwp_v2 (per_objfile, dwp_file,
- unit_index, comp_dir,
- signature, is_debug_types);
- }
+ dwo_unit
+ = create_dwo_unit_in_dwp_v2 (per_bfd, dwp_file, unit_index,
+ comp_dir, signature, is_debug_types);
else /* version == 5 */
- {
- *slot = create_dwo_unit_in_dwp_v5 (per_objfile, dwp_file,
- unit_index, comp_dir,
- signature, is_debug_types);
- }
- return (struct dwo_unit *) *slot;
+ dwo_unit
+ = create_dwo_unit_in_dwp_v5 (per_bfd, dwp_file, unit_index,
+ comp_dir, signature, is_debug_types);
+
+ /* If another thread raced with this one, opening the exact same
+ DWO unit, then we'll keep that other thread's copy. */
+#if CXX_STD_THREAD
+ std::lock_guard<std::mutex> guard (dwp_file->loaded_cutus_lock);
+#endif
+
+ auto it = dwo_unit_set.emplace (std::move (dwo_unit)).first;
+ return it->get ();
}
+
if (signature_in_table == 0)
return NULL;
+
hash = (hash + hash2) & mask;
}
@@ -8274,8 +7430,8 @@ lookup_dwo_unit_in_dwp (dwarf2_per_objfile *per_objfile,
NOTE: This function is derived from symfile_bfd_open. */
static gdb_bfd_ref_ptr
-try_open_dwop_file (dwarf2_per_objfile *per_objfile,
- const char *file_name, int is_dwp, int search_cwd)
+try_open_dwop_file (dwarf2_per_bfd *per_bfd, const char *file_name, int is_dwp,
+ int search_cwd)
{
int desc;
/* Blech. OPF_TRY_CWD_FIRST also disables searching the path list if
@@ -8287,7 +7443,7 @@ try_open_dwop_file (dwarf2_per_objfile *per_objfile,
gdb::unique_xmalloc_ptr<char> search_path_holder;
if (search_cwd)
{
- const std::string &debug_dir = per_objfile->per_bfd->captured_debug_dir;
+ const std::string &debug_dir = per_bfd->captured_debug_dir;
if (!debug_dir.empty ())
{
@@ -8300,10 +7456,10 @@ try_open_dwop_file (dwarf2_per_objfile *per_objfile,
search_path = ".";
}
else
- search_path = per_objfile->per_bfd->captured_debug_dir.c_str ();
+ search_path = per_bfd->captured_debug_dir.c_str ();
/* Add the path for the executable binary to the list of search paths. */
- std::string objfile_dir = ldirname (objfile_name (per_objfile->objfile));
+ std::string objfile_dir = gdb_ldirname (per_bfd->filename ());
search_path_holder.reset (concat (objfile_dir.c_str (),
dirname_separator_string,
search_path, nullptr));
@@ -8314,9 +7470,8 @@ try_open_dwop_file (dwarf2_per_objfile *per_objfile,
flags |= OPF_SEARCH_IN_PATH;
gdb::unique_xmalloc_ptr<char> absolute_name;
- desc = openp (search_path, flags, file_name,
- O_RDONLY | O_BINARY, &absolute_name,
- per_objfile->per_bfd->captured_cwd.c_str ());
+ desc = openp (search_path, flags, file_name, O_RDONLY | O_BINARY,
+ &absolute_name, per_bfd->captured_cwd.c_str ());
if (desc < 0)
return NULL;
@@ -8325,14 +7480,23 @@ try_open_dwop_file (dwarf2_per_objfile *per_objfile,
if (sym_bfd == NULL)
return NULL;
- if (!bfd_check_format (sym_bfd.get (), bfd_object))
- return NULL;
+ {
+#if CXX_STD_THREAD
+ /* The operations below are not thread-safe, use a lock to synchronize
+ concurrent accesses. */
+ static std::mutex mutex;
+ std::lock_guard<std::mutex> lock (mutex);
+#endif
+
+ if (!bfd_check_format (sym_bfd.get (), bfd_object))
+ return NULL;
- /* Success. Record the bfd as having been included by the objfile's bfd.
+ /* Success. Record the bfd as having been included by the objfile's bfd.
This is important because things like demangled_names_hash lives in the
objfile's per_bfd space and may have references to things like symbol
names that live in the DWO/DWP file's per_bfd space. PR 16426. */
- gdb_bfd_record_inclusion (per_objfile->objfile->obfd.get (), sym_bfd.get ());
+ gdb_bfd_record_inclusion (per_bfd->obfd, sym_bfd.get ());
+ }
return sym_bfd;
}
@@ -8344,12 +7508,12 @@ try_open_dwop_file (dwarf2_per_objfile *per_objfile,
Upon success, the canonicalized path of the file is stored in the bfd,
same as symfile_bfd_open. */
-static gdb_bfd_ref_ptr
-open_dwo_file (dwarf2_per_objfile *per_objfile,
- const char *file_name, const char *comp_dir)
+gdb_bfd_ref_ptr
+cutu_reader::open_dwo_file (dwarf2_per_bfd *per_bfd, const char *file_name,
+ const char *comp_dir)
{
if (IS_ABSOLUTE_PATH (file_name))
- return try_open_dwop_file (per_objfile, file_name,
+ return try_open_dwop_file (per_bfd, file_name,
0 /*is_dwp*/, 0 /*search_cwd*/);
/* Before trying the search path, try DWO_NAME in COMP_DIR. */
@@ -8360,8 +7524,9 @@ open_dwo_file (dwarf2_per_objfile *per_objfile,
/* NOTE: If comp_dir is a relative path, this will also try the
search path, which seems useful. */
- gdb_bfd_ref_ptr abfd (try_open_dwop_file
- (per_objfile, path_to_try.c_str (), 0 /*is_dwp*/, 1 /*search_cwd*/));
+ gdb_bfd_ref_ptr abfd
+ = try_open_dwop_file (per_bfd, path_to_try.c_str (), 0 /* is_dwp */,
+ 1 /* search_cwd */);
if (abfd != NULL)
return abfd;
@@ -8370,58 +7535,77 @@ open_dwo_file (dwarf2_per_objfile *per_objfile,
/* That didn't work, try debug-file-directory, which, despite its name,
is a list of paths. */
- if (per_objfile->per_bfd->captured_debug_dir.empty ())
+ if (per_bfd->captured_debug_dir.empty ())
return NULL;
- return try_open_dwop_file (per_objfile, file_name,
- 0 /*is_dwp*/, 1 /*search_cwd*/);
+ return try_open_dwop_file (per_bfd, file_name, 0 /* is_dwp */,
+ 1 /* search_cwd */);
}
/* This function is mapped across the sections and remembers the offset and
size of each of the DWO debugging sections we are interested in. */
-static void
-dwarf2_locate_dwo_sections (struct objfile *objfile, bfd *abfd,
- asection *sectp, dwo_sections *dwo_sections)
+void
+cutu_reader::locate_dwo_sections (objfile *objfile, dwo_file &dwo_file)
{
const struct dwop_section_names *names = &dwop_section_names;
+ dwo_sections &dwo_sections = dwo_file.sections;
+ bool complained_about_macro_already = false;
+
+ for (asection *sec : gdb_bfd_sections (dwo_file.dbfd))
+ {
+ struct dwarf2_section_info *dw_sect = nullptr;
+
+ if (names->abbrev_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.abbrev;
+ else if (names->info_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.infos.emplace_back (dwarf2_section_info {});
+ else if (names->line_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.line;
+ else if (names->loc_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.loc;
+ else if (names->loclists_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.loclists;
+ else if (names->macinfo_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.macinfo;
+ else if (names->macro_dwo.matches (sec->name))
+ {
+ /* gcc versions <= 13 generate multiple .debug_macro.dwo sections with
+ some unresolved links between them. It's not usable, so do as if
+ there were not there. */
+ if (!complained_about_macro_already)
+ {
+ if (dwo_sections.macro.s.section == nullptr)
+ dw_sect = &dwo_sections.macro;
+ else
+ {
+ warning (_("Multiple .debug_macro.dwo sections found in "
+ "%s, ignoring them."), dwo_file.dbfd->filename);
- struct dwarf2_section_info *dw_sect = nullptr;
-
- if (names->abbrev_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->abbrev;
- else if (names->info_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->info;
- else if (names->line_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->line;
- else if (names->loc_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->loc;
- else if (names->loclists_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->loclists;
- else if (names->macinfo_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->macinfo;
- else if (names->macro_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->macro;
- else if (names->rnglists_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->rnglists;
- else if (names->str_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->str;
- else if (names->str_offsets_dwo.matches (sectp->name))
- dw_sect = &dwo_sections->str_offsets;
- else if (names->types_dwo.matches (sectp->name))
- {
- struct dwarf2_section_info type_section;
-
- memset (&type_section, 0, sizeof (type_section));
- dwo_sections->types.push_back (type_section);
- dw_sect = &dwo_sections->types.back ();
- }
+ dwo_sections.macro = dwarf2_section_info {};
+ complained_about_macro_already = true;
+ }
+ }
+ }
+ else if (names->rnglists_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.rnglists;
+ else if (names->str_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.str;
+ else if (names->str_offsets_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.str_offsets;
+ else if (names->types_dwo.matches (sec->name))
+ dw_sect = &dwo_sections.types.emplace_back (dwarf2_section_info {});
+
+ if (dw_sect != nullptr)
+ {
+ /* Make sure we don't overwrite a section info that has been filled in
+ already. */
+ gdb_assert (!dw_sect->readin);
- if (dw_sect != nullptr)
- {
- dw_sect->s.section = sectp;
- dw_sect->size = bfd_section_size (sectp);
- dw_sect->read (objfile);
+ dw_sect->s.section = sec;
+ dw_sect->size = bfd_section_size (sec);
+ dw_sect->read (objfile);
+ }
}
}
@@ -8429,13 +7613,14 @@ dwarf2_locate_dwo_sections (struct objfile *objfile, bfd *abfd,
by PER_CU. This is for the non-DWP case.
The result is NULL if DWO_NAME can't be found. */
-static struct dwo_file *
-open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
- const char *comp_dir)
+dwo_file_up
+cutu_reader::open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
- gdb_bfd_ref_ptr dbfd = open_dwo_file (per_objfile, dwo_name, comp_dir);
+ gdb_bfd_ref_ptr dbfd
+ = open_dwo_file (per_objfile->per_bfd, dwo_name, comp_dir);
if (dbfd == NULL)
{
dwarf_read_debug_printf ("DWO file not found: %s", dwo_name);
@@ -8443,35 +7628,24 @@ open_and_init_dwo_file (dwarf2_cu *cu, const char *dwo_name,
return NULL;
}
- dwo_file_up dwo_file (new struct dwo_file);
+ dwo_file_up dwo_file = std::make_unique<struct dwo_file> ();
dwo_file->dwo_name = dwo_name;
dwo_file->comp_dir = comp_dir;
dwo_file->dbfd = std::move (dbfd);
- for (asection *sec : gdb_bfd_sections (dwo_file->dbfd))
- dwarf2_locate_dwo_sections (per_objfile->objfile, dwo_file->dbfd.get (),
- sec, &dwo_file->sections);
+ this->locate_dwo_sections (per_objfile->objfile, *dwo_file);
- create_cus_hash_table (per_objfile, cu, *dwo_file, dwo_file->sections.info,
- dwo_file->cus);
+ for (dwarf2_section_info &section : dwo_file->sections.infos)
+ create_dwo_unit_hash_tables (*dwo_file, *cu, section, ruh_kind::COMPILE);
- if (cu->per_cu->version () < 5)
- {
- create_debug_types_hash_table (per_objfile, dwo_file.get (),
- dwo_file->sections.types, dwo_file->tus);
- }
- else
- {
- create_debug_type_hash_table (per_objfile, dwo_file.get (),
- &dwo_file->sections.info, dwo_file->tus,
- rcuh_kind::COMPILE);
- }
+ for (dwarf2_section_info &section : dwo_file->sections.types)
+ create_dwo_unit_hash_tables (*dwo_file, *cu, section, ruh_kind::TYPE);
dwarf_read_debug_printf ("DWO file found: %s", dwo_name);
bfd_cache_close (dwo_file->dbfd.get ());
- return dwo_file.release ();
+ return dwo_file;
}
/* This function is mapped across the sections and remembers the offset and
@@ -8501,6 +7675,10 @@ dwarf2_locate_common_dwp_sections (struct objfile *objfile, bfd *abfd,
if (dw_sect != nullptr)
{
+ /* Make sure we don't overwrite a section info that has been filled in
+ already. */
+ gdb_assert (!dw_sect->readin);
+
dw_sect->s.section = sectp;
dw_sect->size = bfd_section_size (sectp);
dw_sect->read (objfile);
@@ -8546,6 +7724,10 @@ dwarf2_locate_v2_dwp_sections (struct objfile *objfile, bfd *abfd,
if (dw_sect != nullptr)
{
+ /* Make sure we don't overwrite a section info that has been filled in
+ already. */
+ gdb_assert (!dw_sect->readin);
+
dw_sect->s.section = sectp;
dw_sect->size = bfd_section_size (sectp);
dw_sect->read (objfile);
@@ -8589,45 +7771,16 @@ dwarf2_locate_v5_dwp_sections (struct objfile *objfile, bfd *abfd,
if (dw_sect != nullptr)
{
+ /* Make sure we don't overwrite a section info that has been filled in
+ already. */
+ gdb_assert (!dw_sect->readin);
+
dw_sect->s.section = sectp;
dw_sect->size = bfd_section_size (sectp);
dw_sect->read (objfile);
}
}
-/* Hash function for dwp_file loaded CUs/TUs. */
-
-static hashval_t
-hash_dwp_loaded_cutus (const void *item)
-{
- const struct dwo_unit *dwo_unit = (const struct dwo_unit *) item;
-
- /* This drops the top 32 bits of the signature, but is ok for a hash. */
- return dwo_unit->signature;
-}
-
-/* Equality function for dwp_file loaded CUs/TUs. */
-
-static int
-eq_dwp_loaded_cutus (const void *a, const void *b)
-{
- const struct dwo_unit *dua = (const struct dwo_unit *) a;
- const struct dwo_unit *dub = (const struct dwo_unit *) b;
-
- return dua->signature == dub->signature;
-}
-
-/* Allocate a hash table for dwp_file loaded CUs/TUs. */
-
-static htab_up
-allocate_dwp_loaded_cutus_table ()
-{
- return htab_up (htab_create_alloc (3,
- hash_dwp_loaded_cutus,
- eq_dwp_loaded_cutus,
- NULL, xcalloc, xfree));
-}
-
/* Try to open DWP file FILE_NAME.
The result is the bfd handle of the file.
If there is a problem finding or opening the file, return NULL.
@@ -8635,11 +7788,11 @@ allocate_dwp_loaded_cutus_table ()
same as symfile_bfd_open. */
static gdb_bfd_ref_ptr
-open_dwp_file (dwarf2_per_objfile *per_objfile, const char *file_name)
+open_dwp_file (dwarf2_per_bfd *per_bfd, const char *file_name)
{
- gdb_bfd_ref_ptr abfd (try_open_dwop_file (per_objfile, file_name,
- 1 /*is_dwp*/,
- 1 /*search_cwd*/));
+ gdb_bfd_ref_ptr abfd
+ = try_open_dwop_file (per_bfd, file_name, 1 /* is_dwp */,
+ 1 /* search_cwd */);
if (abfd != NULL)
return abfd;
@@ -8651,27 +7804,26 @@ open_dwp_file (dwarf2_per_objfile *per_objfile, const char *file_name)
[IWBN if the dwp file name was recorded in the executable, akin to
.gnu_debuglink, but that doesn't exist yet.]
Strip the directory from FILE_NAME and search again. */
- if (!per_objfile->per_bfd->captured_debug_dir.empty ())
+ if (!per_bfd->captured_debug_dir.empty ())
{
/* Don't implicitly search the current directory here.
If the user wants to search "." to handle this case,
it must be added to debug-file-directory. */
- return try_open_dwop_file (per_objfile, lbasename (file_name),
- 1 /*is_dwp*/,
- 0 /*search_cwd*/);
+ return try_open_dwop_file (per_bfd, lbasename (file_name),
+ 1 /* is_dwp */, 0 /* search_cwd */);
}
return NULL;
}
/* Initialize the use of the DWP file for the current objfile.
- By convention the name of the DWP file is ${objfile}.dwp.
- The result is NULL if it can't be found. */
+ By convention the name of the DWP file is ${objfile}.dwp. */
-static std::unique_ptr<struct dwp_file>
+static void
open_and_init_dwp_file (dwarf2_per_objfile *per_objfile)
{
struct objfile *objfile = per_objfile->objfile;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
/* Try to find first .dwp for the binary file before any symbolic links
resolving. */
@@ -8684,46 +7836,45 @@ open_and_init_dwp_file (dwarf2_per_objfile *per_objfile)
struct objfile *backlink = objfile->separate_debug_objfile_backlink;
const char *backlink_basename = lbasename (backlink->original_name);
- dwp_name = ldirname (objfile->original_name) + SLASH_STRING + backlink_basename;
+ dwp_name = gdb_ldirname (objfile->original_name) + SLASH_STRING + backlink_basename;
}
else
dwp_name = objfile->original_name;
dwp_name += ".dwp";
- gdb_bfd_ref_ptr dbfd (open_dwp_file (per_objfile, dwp_name.c_str ()));
+ gdb_bfd_ref_ptr dbfd (open_dwp_file (per_bfd, dwp_name.c_str ()));
if (dbfd == NULL
&& strcmp (objfile->original_name, objfile_name (objfile)) != 0)
{
/* Try to find .dwp for the binary file after gdb_realpath resolving. */
dwp_name = objfile_name (objfile);
dwp_name += ".dwp";
- dbfd = open_dwp_file (per_objfile, dwp_name.c_str ());
+ dbfd = open_dwp_file (per_bfd, dwp_name.c_str ());
}
if (dbfd == NULL)
{
dwarf_read_debug_printf ("DWP file not found: %s", dwp_name.c_str ());
- return std::unique_ptr<dwp_file> ();
+ return;
}
const char *name = bfd_get_filename (dbfd.get ());
- std::unique_ptr<struct dwp_file> dwp_file
- (new struct dwp_file (name, std::move (dbfd)));
+ auto dwp_file = std::make_unique<struct dwp_file> (name, std::move (dbfd));
dwp_file->num_sections = elf_numsections (dwp_file->dbfd);
- dwp_file->elf_sections =
- OBSTACK_CALLOC (&per_objfile->per_bfd->obstack,
- dwp_file->num_sections, asection *);
+ dwp_file->elf_sections
+ = OBSTACK_CALLOC (&per_bfd->obstack, dwp_file->num_sections, asection *);
for (asection *sec : gdb_bfd_sections (dwp_file->dbfd))
dwarf2_locate_common_dwp_sections (objfile, dwp_file->dbfd.get (), sec,
dwp_file.get ());
- dwp_file->cus = create_dwp_hash_table (per_objfile, dwp_file.get (), 0);
-
- dwp_file->tus = create_dwp_hash_table (per_objfile, dwp_file.get (), 1);
+ dwp_file->cus = create_dwp_hash_table (per_bfd, dwp_file.get (),
+ dwp_file->sections.cu_index);
+ dwp_file->tus = create_dwp_hash_table (per_bfd, dwp_file.get (),
+ dwp_file->sections.tu_index);
/* The DWP file version is stored in the hash table. Oh well. */
if (dwp_file->cus && dwp_file->tus
@@ -8756,9 +7907,6 @@ open_and_init_dwp_file (dwarf2_per_objfile *per_objfile)
dwp_file.get ());
}
- dwp_file->loaded_cus = allocate_dwp_loaded_cutus_table ();
- dwp_file->loaded_tus = allocate_dwp_loaded_cutus_table ();
-
dwarf_read_debug_printf ("DWP file found: %s", dwp_file->name);
dwarf_read_debug_printf (" %s CUs, %s TUs",
pulongest (dwp_file->cus ? dwp_file->cus->nr_units : 0),
@@ -8766,20 +7914,8 @@ open_and_init_dwp_file (dwarf2_per_objfile *per_objfile)
bfd_cache_close (dwp_file->dbfd.get ());
- return dwp_file;
-}
-
-/* Wrapper around open_and_init_dwp_file, only open it once. */
-
-static struct dwp_file *
-get_dwp_file (dwarf2_per_objfile *per_objfile)
-{
- if (!per_objfile->per_bfd->dwp_checked)
- {
- per_objfile->per_bfd->dwp_file = open_and_init_dwp_file (per_objfile);
- per_objfile->per_bfd->dwp_checked = 1;
- }
- return per_objfile->per_bfd->dwp_file.get ();
+ /* Everything worked, install this dwp_file in the per_bfd. */
+ per_objfile->per_bfd->dwp_file = std::move (dwp_file);
}
/* Subroutine of lookup_dwo_comp_unit, lookup_dwo_type_unit.
@@ -8798,23 +7934,23 @@ get_dwp_file (dwarf2_per_objfile *per_objfile)
The result is a pointer to the dwo_unit object or NULL if we didn't find it
(dwo_id mismatch or couldn't find the DWO/DWP file). */
-static struct dwo_unit *
-lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
- ULONGEST signature, int is_debug_types)
+dwo_unit *
+cutu_reader::lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir, ULONGEST signature,
+ int is_debug_types)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
struct objfile *objfile = per_objfile->objfile;
const char *kind = is_debug_types ? "TU" : "CU";
- void **dwo_file_slot;
- struct dwo_file *dwo_file;
- struct dwp_file *dwp_file;
/* First see if there's a DWP file.
If we have a DWP file but didn't find the DWO inside it, don't
look for the original DWO file. It makes gdb behave differently
depending on whether one is debugging in the build tree. */
- dwp_file = get_dwp_file (per_objfile);
+ dwp_file *dwp_file = per_objfile->per_bfd->dwp_file.get ();
+
if (dwp_file != NULL)
{
const struct dwp_hash_table *dwp_htab =
@@ -8823,7 +7959,7 @@ lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
if (dwp_htab != NULL)
{
struct dwo_unit *dwo_cutu =
- lookup_dwo_unit_in_dwp (per_objfile, dwp_file, comp_dir, signature,
+ lookup_dwo_unit_in_dwp (per_bfd, dwp_file, comp_dir, signature,
is_debug_types);
if (dwo_cutu != NULL)
@@ -8839,38 +7975,35 @@ lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
else
{
/* No DWP file, look for the DWO file. */
+ dwo_file *dwo_file = lookup_dwo_file (per_bfd, dwo_name, comp_dir);
- dwo_file_slot = lookup_dwo_file_slot (per_objfile, dwo_name, comp_dir);
- if (*dwo_file_slot == NULL)
+ if (dwo_file == nullptr)
{
- /* Read in the file and build a table of the CUs/TUs it contains. */
- *dwo_file_slot = open_and_init_dwo_file (cu, dwo_name, comp_dir);
+ /* Read in the file and build a table of the CUs/TUs it contains.
+
+ NOTE: This will be nullptr if unable to open the file. */
+ dwo_file_up new_dwo_file
+ = open_and_init_dwo_file (cu, dwo_name, comp_dir);
+
+ if (new_dwo_file != nullptr)
+ dwo_file = add_dwo_file (per_bfd, std::move (new_dwo_file));
}
- /* NOTE: This will be NULL if unable to open the file. */
- dwo_file = (struct dwo_file *) *dwo_file_slot;
if (dwo_file != NULL)
{
struct dwo_unit *dwo_cutu = NULL;
- if (is_debug_types && dwo_file->tus)
+ if (is_debug_types && !dwo_file->tus.empty ())
{
- struct dwo_unit find_dwo_cutu;
-
- memset (&find_dwo_cutu, 0, sizeof (find_dwo_cutu));
- find_dwo_cutu.signature = signature;
- dwo_cutu
- = (struct dwo_unit *) htab_find (dwo_file->tus.get (),
- &find_dwo_cutu);
+ if (auto it = dwo_file->tus.find (signature);
+ it != dwo_file->tus.end ())
+ dwo_cutu = it->get ();
}
- else if (!is_debug_types && dwo_file->cus)
+ else if (!is_debug_types && !dwo_file->cus.empty ())
{
- struct dwo_unit find_dwo_cutu;
-
- memset (&find_dwo_cutu, 0, sizeof (find_dwo_cutu));
- find_dwo_cutu.signature = signature;
- dwo_cutu = (struct dwo_unit *)htab_find (dwo_file->cus.get (),
- &find_dwo_cutu);
+ if (auto it = dwo_file->cus.find (signature);
+ it != dwo_file->cus.end ())
+ dwo_cutu = it->get ();
}
if (dwo_cutu != NULL)
@@ -8913,9 +8046,9 @@ lookup_dwo_cutu (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
/* Lookup the DWO CU DWO_NAME/SIGNATURE referenced from THIS_CU.
See lookup_dwo_cutu_unit for details. */
-static struct dwo_unit *
-lookup_dwo_comp_unit (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
- ULONGEST signature)
+dwo_unit *
+cutu_reader::lookup_dwo_comp_unit (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir, ULONGEST signature)
{
gdb_assert (!cu->per_cu->is_debug_types);
@@ -8925,8 +8058,9 @@ lookup_dwo_comp_unit (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir,
/* 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 (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir)
+dwo_unit *
+cutu_reader::lookup_dwo_type_unit (dwarf2_cu *cu, const char *dwo_name,
+ const char *comp_dir)
{
gdb_assert (cu->per_cu->is_debug_types);
@@ -8938,10 +8072,8 @@ lookup_dwo_type_unit (dwarf2_cu *cu, const char *dwo_name, const char *comp_dir)
/* Traversal function for queue_and_load_all_dwo_tus. */
static int
-queue_and_load_dwo_tu (void **slot, void *info)
+queue_and_load_dwo_tu (dwo_unit *dwo_unit, dwarf2_cu *cu)
{
- struct dwo_unit *dwo_unit = (struct dwo_unit *) *slot;
- dwarf2_cu *cu = (dwarf2_cu *) info;
ULONGEST signature = dwo_unit->signature;
signatured_type *sig_type = lookup_dwo_signatured_type (cu, signature);
@@ -8950,8 +8082,7 @@ queue_and_load_dwo_tu (void **slot, void *info)
/* 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_type, cu->per_objfile,
- cu->lang ()))
+ if (maybe_queue_comp_unit (NULL, sig_type, cu->per_objfile))
load_full_type_unit (sig_type, cu->per_objfile);
cu->per_cu->imported_symtabs.push_back (sig_type);
}
@@ -8972,14 +8103,15 @@ queue_and_load_all_dwo_tus (dwarf2_cu *cu)
gdb_assert (cu != nullptr);
gdb_assert (!cu->per_cu->is_debug_types);
- gdb_assert (get_dwp_file (cu->per_objfile) == nullptr);
+ gdb_assert (cu->per_objfile->per_bfd->dwp_file == nullptr);
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, cu);
+
+ for (const dwo_unit_up &unit : dwo_file->tus)
+ queue_and_load_dwo_tu (unit.get (), cu);
}
/* Read in various DIEs. */
@@ -9034,8 +8166,8 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
break;
}
- concrete_child = concrete_child->sibling;
- abstract_child = abstract_child->sibling;
+ concrete_child = concrete_child->next;
+ abstract_child = abstract_child->next;
}
/* Walk the origin's children in parallel to the concrete children.
@@ -9048,9 +8180,7 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
std::vector<sect_offset> offsets;
- for (die_info *child_die = die->child;
- child_die && child_die->tag;
- child_die = child_die->sibling)
+ for (die_info *child_die : die->children ())
{
/* We are trying to process concrete instance entries:
DW_TAG_call_site DIEs indeed have a DW_AT_abstract_origin tag, but
@@ -9062,7 +8192,7 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
{
if (are_isomorphic)
corresponding_abstract_child
- = corresponding_abstract_child->sibling;
+ = corresponding_abstract_child->next;
continue;
}
@@ -9120,7 +8250,7 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
}
if (are_isomorphic)
- corresponding_abstract_child = corresponding_abstract_child->sibling;
+ corresponding_abstract_child = corresponding_abstract_child->next;
}
if (!offsets.empty ())
@@ -9138,8 +8268,7 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
}
auto offsets_it = offsets.begin ();
- die_info *origin_child_die = origin_die->child;
- while (origin_child_die != nullptr && origin_child_die->tag != 0)
+ for (die_info *origin_child_die : origin_die->children ())
{
/* Is ORIGIN_CHILD_DIE referenced by any of the DIE children? */
while (offsets_it < offsets.end ()
@@ -9156,8 +8285,6 @@ inherit_abstract_dies (struct die_info *die, struct dwarf2_cu *cu)
if (!origin_child_die->in_process)
process_die (origin_child_die, origin_cu);
}
-
- origin_child_die = origin_child_die->sibling;
}
origin_cu->list_in_scope = origin_previous_list_in_scope;
@@ -9178,8 +8305,10 @@ dwarf2_func_is_main_p (struct die_info *die, struct dwarf2_cu *cu)
if (dwarf2_flag_true_p (die, DW_AT_main_subprogram, cu))
return true;
struct attribute *attr = dwarf2_attr (die, DW_AT_calling_convention, cu);
- return (attr != nullptr
- && attr->constant_value (DW_CC_normal) == DW_CC_program);
+ if (attr == nullptr)
+ return false;
+ std::optional<ULONGEST> value = attr->unsigned_constant ();
+ return value.has_value () && *value == DW_CC_program;
}
/* A helper to handle Ada's "Pragma Import" feature when it is applied
@@ -9188,8 +8317,14 @@ dwarf2_func_is_main_p (struct die_info *die, struct dwarf2_cu *cu)
static bool
check_ada_pragma_import (struct die_info *die, struct dwarf2_cu *cu)
{
- /* A Pragma Import will have both a name and a linkage name. */
- const char *name = dwarf2_name (die, cu);
+ if (cu->lang () != language_ada)
+ return false;
+
+ /* A Pragma Import will have both a name and a linkage name. With a
+ newer version of GNAT, we have to examine the full name, because
+ the compiler might decide to emit a linkage name matching the
+ full name in some scenario. */
+ const char *name = dwarf2_full_name (nullptr, die, cu);
if (name == nullptr)
return false;
@@ -9221,7 +8356,7 @@ fixup_low_high_pc (struct dwarf2_cu *cu, struct die_info *die, CORE_ADDR *low_pc
struct gdbarch *gdbarch = objfile->arch ();
if (gdbarch_bfd_arch_info (gdbarch)->arch == bfd_arch_arm
- && producer_is_gas_ge_2_39 (cu))
+ && cu->producer_is_gas_ge_2_39 ())
{
/* Gas version 2.39 produces DWARF for a Thumb subprogram with a low_pc
attribute with the thumb bit set (PR gas/31115). Work around this. */
@@ -9240,7 +8375,6 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
struct context_stack *newobj;
CORE_ADDR lowpc;
CORE_ADDR highpc;
- struct die_info *child_die;
struct attribute *attr, *call_line, *call_file;
const char *name;
struct block *block;
@@ -9293,11 +8427,14 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf2_attr (die, DW_AT_external, cu);
bool external_p = attr != nullptr && attr->as_boolean ();
attr = dwarf2_attr (die, DW_AT_inline, cu);
- bool inlined_p
- = (attr != nullptr
- && attr->is_nonnegative ()
- && (attr->as_nonnegative () == DW_INL_inlined
- || attr->as_nonnegative () == DW_INL_declared_inlined));
+ bool inlined_p = false;
+ if (attr != nullptr)
+ {
+ std::optional<ULONGEST> value = attr->unsigned_constant ();
+ inlined_p = (value.has_value ()
+ && (*value == DW_INL_inlined
+ || *value == DW_INL_declared_inlined));
+ }
attr = dwarf2_attr (die, DW_AT_declaration, cu);
bool decl_p = attr != nullptr && attr->as_boolean ();
if (!external_p && !inlined_p && !decl_p)
@@ -9314,7 +8451,7 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
/* If we have any template arguments, then we must allocate a
different sort of symbol. */
- for (child_die = die->child; child_die; child_die = child_die->sibling)
+ for (die_info *child_die : die->children ())
{
if (child_die->tag == DW_TAG_template_type_param
|| child_die->tag == DW_TAG_template_value_param)
@@ -9352,23 +8489,18 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
cu->list_in_scope = cu->get_builder ()->get_local_symbols ();
- if (die->child != NULL)
+ for (die_info *child_die : die->children ())
{
- child_die = die->child;
- while (child_die && child_die->tag)
+ if (child_die->tag == DW_TAG_template_type_param
+ || child_die->tag == DW_TAG_template_value_param)
{
- if (child_die->tag == DW_TAG_template_type_param
- || child_die->tag == DW_TAG_template_value_param)
- {
- struct symbol *arg = new_symbol (child_die, NULL, cu);
+ struct symbol *arg = new_symbol (child_die, NULL, cu);
- if (arg != NULL)
- template_args.push_back (arg);
- }
- else
- process_die (child_die, cu);
- child_die = child_die->sibling;
+ if (arg != NULL)
+ template_args.push_back (arg);
}
+ else
+ process_die (child_die, cu);
}
inherit_abstract_dies (die, cu);
@@ -9384,13 +8516,9 @@ read_func_scope (struct die_info *die, struct dwarf2_cu *cu)
while (spec_die)
{
- child_die = spec_die->child;
- while (child_die && child_die->tag)
- {
- if (child_die->tag == DW_TAG_imported_module)
- process_die (child_die, spec_cu);
- child_die = child_die->sibling;
- }
+ for (die_info *child_die : spec_die->children ())
+ if (child_die->tag == DW_TAG_imported_module)
+ process_die (child_die, spec_cu);
/* In some cases, GCC generates specification DIEs that
themselves contain DW_AT_specification attributes. */
@@ -9459,7 +8587,6 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
CORE_ADDR lowpc, highpc;
- struct die_info *child_die;
/* Ignore blocks with missing or invalid low and high pc attributes. */
/* ??? Perhaps consider discontiguous blocks defined by DW_AT_ranges
@@ -9474,9 +8601,7 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
/* DW_TAG_lexical_block has no attributes, process its children as if
there was no wrapping by that DW_TAG_lexical_block.
GCC does no longer produces such DWARF since GCC r224161. */
- for (child_die = die->child;
- child_die != NULL && child_die->tag;
- child_die = child_die->sibling)
+ for (die_info *child_die : die->children ())
{
/* We might already be processing this DIE. This can happen
in an unusual circumstance -- where a subroutine A
@@ -9495,15 +8620,9 @@ read_lexical_block_scope (struct die_info *die, struct dwarf2_cu *cu)
highpc = per_objfile->relocate (unrel_high);
cu->get_builder ()->push_context (0, lowpc);
- if (die->child != NULL)
- {
- child_die = die->child;
- while (child_die && child_die->tag)
- {
- process_die (child_die, cu);
- child_die = child_die->sibling;
- }
- }
+ for (die_info *child_die : die->children ())
+ process_die (child_die, cu);
+
inherit_abstract_dies (die, cu);
struct context_stack cstk = cu->get_builder ()->pop_context ();
@@ -9546,7 +8665,6 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
struct gdbarch *gdbarch = objfile->arch ();
struct attribute *attr;
int nparams;
- struct die_info *child_die;
attr = dwarf2_attr (die, DW_AT_call_return_pc, cu);
if (attr == NULL)
@@ -9567,8 +8685,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
/* Count parameters at the caller. */
nparams = 0;
- for (child_die = die->child; child_die && child_die->tag;
- child_die = child_die->sibling)
+ for (die_info *child_die : die->children ())
{
if (child_die->tag != DW_TAG_call_site_parameter
&& child_die->tag != DW_TAG_GNU_call_site_parameter)
@@ -9670,7 +8787,8 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
struct dwarf2_locexpr_baton *dlbaton;
struct dwarf_block *block = attr->as_block ();
- dlbaton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton);
+ dlbaton = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct dwarf2_locexpr_baton);
dlbaton->data = block->data;
dlbaton->size = block->size;
dlbaton->per_objfile = per_objfile;
@@ -9737,9 +8855,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
"block nor reference, for DIE %s [in module %s]"),
sect_offset_str (die->sect_off), objfile_name (objfile));
- for (child_die = die->child;
- child_die && child_die->tag;
- child_die = child_die->sibling)
+ for (die_info *child_die : die->children ())
{
struct call_site_parameter *parameter;
struct attribute *loc, *origin;
@@ -9771,7 +8887,7 @@ read_call_site_scope (struct die_info *die, struct dwarf2_cu *cu)
parameter->kind = CALL_SITE_PARAMETER_PARAM_OFFSET;
sect_offset sect_off = origin->get_ref_die_offset ();
- if (!cu->header.offset_in_cu_p (sect_off))
+ if (!cu->header.offset_in_unit_p (sect_off))
{
/* As DW_OP_GNU_parameter_ref uses CU-relative offset this
binding can be done only inside one CU. Such referenced DIE
@@ -10139,7 +9255,7 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
struct objfile *objfile = per_objfile->objfile;
- struct comp_unit_head *cu_header = &cu->header;
+ unit_head *cu_header = &cu->header;
bfd *obfd = objfile->obfd.get ();
unsigned int addr_size = cu_header->addr_size;
CORE_ADDR mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
@@ -10229,12 +9345,9 @@ dwarf2_ranges_process (unsigned offset, struct dwarf2_cu *cu, dwarf_tag tag,
return 1;
}
-/* Get low and high pc attributes from DW_AT_ranges attribute value OFFSET.
- Return 1 if the attributes are present and valid, otherwise, return 0.
- TAG is passed to dwarf2_ranges_process. If MAP is not NULL, then
- ranges in MAP are set, using DATUM as the value. */
+/* See read.h. */
-static int
+int
dwarf2_ranges_read (unsigned offset, unrelocated_addr *low_return,
unrelocated_addr *high_return, struct dwarf2_cu *cu,
addrmap_mutable *map, void *datum, dwarf_tag tag)
@@ -10405,11 +9518,9 @@ dwarf_get_pc_bounds_ranges_or_highlow_pc (die_info *die, unrelocated_addr *low,
return ret;
}
-/* Get low and high pc attributes from a die. See enum pc_bounds_kind
- definition for the return value. *LOWPC and *HIGHPC are set iff
- neither PC_BOUNDS_NOT_PRESENT nor PC_BOUNDS_INVALID are returned. */
+/* See read.h. */
-static enum pc_bounds_kind
+pc_bounds_kind
dwarf2_get_pc_bounds (struct die_info *die, unrelocated_addr *lowpc,
unrelocated_addr *highpc, struct dwarf2_cu *cu,
addrmap_mutable *map, void *datum)
@@ -10464,7 +9575,6 @@ dwarf2_get_subprogram_pc_bounds (struct die_info *die,
struct dwarf2_cu *cu)
{
unrelocated_addr low, high;
- struct die_info *child = die->child;
if (dwarf2_get_pc_bounds (die, &low, &high, cu, nullptr, nullptr)
>= PC_BOUNDS_RANGES)
@@ -10482,12 +9592,11 @@ dwarf2_get_subprogram_pc_bounds (struct die_info *die,
subprograms, then check their pc bounds. Likewise, we need to
check lexical blocks as well, as they may also contain subprogram
definitions. */
- while (child && child->tag)
+ for (die_info *child : die->children ())
{
if (child->tag == DW_TAG_subprogram
|| child->tag == DW_TAG_lexical_block)
dwarf2_get_subprogram_pc_bounds (child, lowpc, highpc, cu);
- child = child->sibling;
}
}
@@ -10513,9 +9622,7 @@ get_scope_pc_bounds (struct die_info *die,
}
else
{
- struct die_info *child = die->child;
-
- while (child && child->tag)
+ for (die_info *child : die->children ())
{
switch (child->tag) {
case DW_TAG_subprogram:
@@ -10543,8 +9650,6 @@ get_scope_pc_bounds (struct die_info *die,
/* Ignore. */
break;
}
-
- child = child->sibling;
}
}
@@ -10640,8 +9745,8 @@ dwarf2_record_block_entry_pc (struct die_info *die, struct block *block,
{
/* We could possibly handle signed constants, but this is out
of spec, so for now, just complain and ignore it. */
- complaint (_("Unhandled constant for DW_AT_entry_pc, value (%s)"),
- plongest (attr->as_nonnegative ()));
+ complaint (_("Invalid form for DW_AT_entry_pc: %s"),
+ dwarf_form_name (attr->form));
}
}
else
@@ -10761,110 +9866,6 @@ dwarf2_record_block_ranges (struct die_info *die, struct block *block,
dwarf2_record_block_entry_pc (die, block, cu);
}
-/* Check whether the producer field indicates either of GCC < 4.6, or the
- Intel C/C++ compiler, and cache the result in CU. */
-
-static void
-check_producer (struct dwarf2_cu *cu)
-{
- int major, minor;
-
- if (cu->producer == NULL)
- {
- /* For unknown compilers expect their behavior is DWARF version
- compliant.
-
- GCC started to support .debug_types sections by -gdwarf-4 since
- gcc-4.5.x. As the .debug_types sections are missing DW_AT_producer
- for their space efficiency GDB cannot workaround gcc-4.5.x -gdwarf-4
- combination. gcc-4.5.x -gdwarf-4 binaries have DW_AT_accessibility
- interpreted incorrectly by GDB now - GCC PR debug/48229. */
- }
- else if (producer_is_gcc (cu->producer, &major, &minor))
- {
- cu->producer_is_gxx_lt_4_6 = major < 4 || (major == 4 && minor < 6);
- cu->producer_is_gcc_lt_4_3 = major < 4 || (major == 4 && minor < 3);
- cu->producer_is_gcc_11 = major == 11;
- }
- else if (producer_is_icc (cu->producer, &major, &minor))
- {
- cu->producer_is_icc = true;
- cu->producer_is_icc_lt_14 = major < 14;
- }
- else if (startswith (cu->producer, "CodeWarrior S12/L-ISA"))
- cu->producer_is_codewarrior = true;
- else if (producer_is_clang (cu->producer, &major, &minor))
- cu->producer_is_clang = true;
- else if (producer_is_gas (cu->producer, &major, &minor))
- {
- cu->producer_is_gas_lt_2_38 = major < 2 || (major == 2 && minor < 38);
- cu->producer_is_gas_2_39 = major == 2 && minor == 39;
- cu->producer_is_gas_ge_2_40 = major > 2 || (major == 2 && minor >= 40);
- }
- else
- {
- /* For other non-GCC compilers, expect their behavior is DWARF version
- compliant. */
- }
-
- cu->checked_producer = true;
-}
-
-/* Check for GCC PR debug/45124 fix which is not present in any G++ version up
- to 4.5.any while it is present already in G++ 4.6.0 - the PR has been fixed
- during 4.6.0 experimental. */
-
-static bool
-producer_is_gxx_lt_4_6 (struct dwarf2_cu *cu)
-{
- if (!cu->checked_producer)
- check_producer (cu);
-
- return cu->producer_is_gxx_lt_4_6;
-}
-
-
-/* Codewarrior (at least as of version 5.0.40) generates dwarf line information
- with incorrect is_stmt attributes. */
-
-static bool
-producer_is_codewarrior (struct dwarf2_cu *cu)
-{
- if (!cu->checked_producer)
- check_producer (cu);
-
- return cu->producer_is_codewarrior;
-}
-
-static bool
-producer_is_gas_lt_2_38 (struct dwarf2_cu *cu)
-{
- if (!cu->checked_producer)
- check_producer (cu);
-
- return cu->producer_is_gas_lt_2_38;
-}
-
-static bool
-producer_is_gas_2_39 (struct dwarf2_cu *cu)
-{
- if (!cu->checked_producer)
- check_producer (cu);
-
- return cu->producer_is_gas_2_39;
-}
-
-/* Return true if CU is produced by GAS 2.39 or later. */
-
-static bool
-producer_is_gas_ge_2_39 (struct dwarf2_cu *cu)
-{
- if (!cu->checked_producer)
- check_producer (cu);
-
- return cu->producer_is_gas_2_39 || cu->producer_is_gas_ge_2_40;
-}
-
/* Return the accessibility of DIE, as given by DW_AT_accessibility.
If that attribute is not available, return the appropriate
default. */
@@ -10875,16 +9876,19 @@ dwarf2_access_attribute (struct die_info *die, struct dwarf2_cu *cu)
attribute *attr = dwarf2_attr (die, DW_AT_accessibility, cu);
if (attr != nullptr)
{
- LONGEST value = attr->constant_value (-1);
- if (value == DW_ACCESS_public
- || value == DW_ACCESS_protected
- || value == DW_ACCESS_private)
- return (dwarf_access_attribute) value;
- complaint (_("Unhandled DW_AT_accessibility value (%s)"),
- plongest (value));
+ std::optional<ULONGEST> value = attr->unsigned_constant ();
+ if (value.has_value ())
+ {
+ if (*value == DW_ACCESS_public
+ || *value == DW_ACCESS_protected
+ || *value == DW_ACCESS_private)
+ return (dwarf_access_attribute) *value;
+ complaint (_("Unhandled DW_AT_accessibility value (%s)"),
+ pulongest (*value));
+ }
}
- if (cu->header.version < 3 || producer_is_gxx_lt_4_6 (cu))
+ if (cu->header.version < 3 || cu->producer_is_gxx_lt_4_6 ())
{
/* The default DWARF 2 accessibility for members is public, the default
accessibility for inheritance is private. */
@@ -10907,54 +9911,6 @@ dwarf2_access_attribute (struct die_info *die, struct dwarf2_cu *cu)
}
}
-/* Look for DW_AT_data_member_location or DW_AT_data_bit_offset. Set
- *OFFSET to the byte offset. If the attribute was not found return
- 0, otherwise return 1. If it was found but could not properly be
- handled, set *OFFSET to 0. */
-
-static int
-handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
- LONGEST *offset)
-{
- struct attribute *attr;
-
- attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
- if (attr != NULL)
- {
- *offset = 0;
- CORE_ADDR temp;
-
- /* Note that we do not check for a section offset first here.
- This is because DW_AT_data_member_location is new in DWARF 4,
- so if we see it, we can assume that a constant form is really
- a constant and not a section offset. */
- if (attr->form_is_constant ())
- *offset = attr->constant_value (0);
- else if (attr->form_is_section_offset ())
- dwarf2_complex_location_expr_complaint ();
- else if (attr->form_is_block ()
- && decode_locdesc (attr->as_block (), cu, &temp))
- {
- *offset = temp;
- }
- else
- dwarf2_complex_location_expr_complaint ();
-
- return 1;
- }
- else
- {
- attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
- if (attr != nullptr)
- {
- *offset = attr->constant_value (0);
- return 1;
- }
- }
-
- return 0;
-}
-
/* Look for DW_AT_data_member_location or DW_AT_data_bit_offset and
store the results in FIELD. */
@@ -10967,9 +9923,28 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
attr = dwarf2_attr (die, DW_AT_data_member_location, cu);
if (attr != NULL)
{
+ bool has_bit_offset = false;
+ LONGEST bit_offset = 0;
+ LONGEST anonymous_size = 0;
+
+ attribute *attr2 = dwarf2_attr (die, DW_AT_bit_offset, cu);
+ if (attr2 != nullptr && attr2->form_is_constant ())
+ {
+ has_bit_offset = true;
+ bit_offset = attr2->confused_constant ().value_or (0);
+ attr2 = dwarf2_attr (die, DW_AT_byte_size, cu);
+ if (attr2 != nullptr && attr2->form_is_constant ())
+ {
+ /* The size of the anonymous object containing
+ the bit field is explicit, so use the
+ indicated size (in bytes). */
+ anonymous_size = attr2->unsigned_constant ().value_or (0);
+ }
+ }
+
if (attr->form_is_constant ())
{
- LONGEST offset = attr->constant_value (0);
+ LONGEST offset = attr->confused_constant ().value_or (0);
/* Work around this GCC 11 bug, where it would erroneously use -1
data member locations, instead of 0:
@@ -10977,16 +9952,16 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
Negative DW_AT_data_member_location
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101378
*/
- if (offset == -1 && cu->producer_is_gcc_11)
+ if (offset == -1 && cu->producer_is_gcc_11 ())
{
complaint (_("DW_AT_data_member_location value of -1, assuming 0"));
offset = 0;
}
field->set_loc_bitpos (offset * bits_per_byte);
+ if (has_bit_offset)
+ apply_bit_offset_to_field (*field, bit_offset, anonymous_size);
}
- else if (attr->form_is_section_offset ())
- dwarf2_complex_location_expr_complaint ();
else if (attr->form_is_block ())
{
CORE_ADDR offset;
@@ -10996,9 +9971,20 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
{
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);
+ struct dwarf2_locexpr_baton *dlbaton;
+ if (has_bit_offset)
+ {
+ dwarf2_field_location_baton *flbaton
+ = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ dwarf2_field_location_baton);
+ flbaton->is_field_location = true;
+ flbaton->bit_offset = bit_offset;
+ flbaton->explicit_byte_size = anonymous_size;
+ dlbaton = flbaton;
+ }
+ else
+ dlbaton = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct dwarf2_locexpr_baton);
dlbaton->data = attr->as_block ()->data;
dlbaton->size = attr->as_block ()->size;
/* When using this baton, we want to compute the address
@@ -11008,28 +9994,71 @@ handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
dlbaton->per_objfile = per_objfile;
dlbaton->per_cu = cu->per_cu;
- field->set_loc_dwarf_block (dlbaton);
+ field->set_loc_dwarf_block_addr (dlbaton);
}
}
else
- dwarf2_complex_location_expr_complaint ();
+ complaint (_("Unsupported form %s for DW_AT_data_member_location"),
+ dwarf_form_name (attr->form));
}
else
{
attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
if (attr != nullptr)
- field->set_loc_bitpos (attr->constant_value (0));
+ {
+ if (attr->form_is_constant ())
+ field->set_loc_bitpos (attr->unsigned_constant ().value_or (0));
+ else if (attr->form_is_block ())
+ {
+ /* This is a DWARF extension. See
+ https://dwarfstd.org/issues/250501.1.html. */
+ dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ dwarf2_locexpr_baton *dlbaton
+ = OBSTACK_ZALLOC (&per_objfile->objfile->objfile_obstack,
+ dwarf2_locexpr_baton);
+ dlbaton->data = attr->as_block ()->data;
+ dlbaton->size = attr->as_block ()->size;
+ dlbaton->per_objfile = per_objfile;
+ dlbaton->per_cu = cu->per_cu;
+
+ field->set_loc_dwarf_block_bitpos (dlbaton);
+ }
+ else
+ complaint (_("Unsupported form %s for DW_AT_data_bit_offset"),
+ dwarf_form_name (attr->form));
+ }
}
}
+/* A helper that computes the location of a field. The CU and the
+ DW_TAG_member DIE are passed in. The results are stored in
+ *FP. */
+
+static void
+compute_field_location (dwarf2_cu *cu, die_info *die, field *fp)
+{
+ /* Get type of field. */
+ fp->set_type (die_type (die, cu));
+
+ fp->set_loc_bitpos (0);
+
+ /* Get bit size of field (zero if none). */
+ attribute *attr = dwarf2_attr (die, DW_AT_bit_size, cu);
+ if (attr != nullptr)
+ fp->set_bitsize (attr->unsigned_constant ().value_or (0));
+ else
+ fp->set_bitsize (0);
+
+ /* Get bit offset of field. */
+ handle_member_location (die, cu, fp);
+}
+
/* 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_objfile->objfile;
- struct gdbarch *gdbarch = objfile->arch ();
struct nextfield *new_field;
struct attribute *attr;
struct field *fp;
@@ -11079,64 +10108,7 @@ dwarf2_add_field (struct field_info *fip, struct die_info *die,
}
/* Data member other than a C++ static data member. */
- /* Get type of field. */
- fp->set_type (die_type (die, cu));
-
- fp->set_loc_bitpos (0);
-
- /* Get bit size of field (zero if none). */
- attr = dwarf2_attr (die, DW_AT_bit_size, cu);
- if (attr != nullptr)
- fp->set_bitsize (attr->constant_value (0));
- else
- fp->set_bitsize (0);
-
- /* Get bit offset of field. */
- handle_member_location (die, cu, fp);
- attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
- if (attr != nullptr && attr->form_is_constant ())
- {
- if (gdbarch_byte_order (gdbarch) == BFD_ENDIAN_BIG)
- {
- /* For big endian bits, the DW_AT_bit_offset gives the
- additional bit offset from the MSB of the containing
- anonymous object to the MSB of the field. We don't
- have to do anything special since we don't need to
- know the size of the anonymous object. */
- fp->set_loc_bitpos (fp->loc_bitpos () + attr->constant_value (0));
- }
- else
- {
- /* For little endian bits, compute the bit offset to the
- MSB of the anonymous object, subtract off the number of
- bits from the MSB of the field to the MSB of the
- object, and then subtract off the number of bits of
- the field itself. The result is the bit offset of
- the LSB of the field. */
- int anonymous_size;
- int bit_offset = attr->constant_value (0);
-
- attr = dwarf2_attr (die, DW_AT_byte_size, cu);
- if (attr != nullptr && attr->form_is_constant ())
- {
- /* The size of the anonymous object containing
- the bit field is explicit, so use the
- indicated size (in bytes). */
- anonymous_size = attr->constant_value (0);
- }
- else
- {
- /* The size of the anonymous object containing
- the bit field must be inferred from the type
- attribute of the data member containing the
- bit field. */
- anonymous_size = fp->type ()->length ();
- }
- fp->set_loc_bitpos (fp->loc_bitpos ()
- + anonymous_size * bits_per_byte
- - bit_offset - fp->bitsize ());
- }
- }
+ compute_field_location (cu, die, fp);
/* Get name of field. */
fieldname = dwarf2_name (die, cu);
@@ -11262,7 +10234,7 @@ dwarf2_add_type_defn (struct field_info *fip, struct die_info *die,
/* A convenience typedef that's used when finding the discriminant
field for a variant part. */
-typedef std::unordered_map<sect_offset, int> offset_map_type;
+using offset_map_type = gdb::unordered_map<sect_offset, int>;
/* Compute the discriminant range for a given variant. OBSTACK is
where the results will be stored. VARIANT is the variant to
@@ -11275,13 +10247,19 @@ convert_variant_range (struct obstack *obstack, const variant_field &variant,
{
std::vector<discriminant_range> ranges;
- if (variant.default_branch)
+ if (variant.is_default ())
return {};
if (variant.discr_list_data == nullptr)
{
- discriminant_range r
- = {variant.discriminant_value, variant.discriminant_value};
+ ULONGEST value;
+
+ if (is_unsigned)
+ value = variant.discriminant_attr->unsigned_constant ().value_or (0);
+ else
+ value = variant.discriminant_attr->signed_constant ().value_or (0);
+
+ discriminant_range r = { value, value };
ranges.push_back (r);
}
else
@@ -11908,16 +10886,11 @@ get_alignment (struct dwarf2_cu *cu, struct die_info *die)
return 0;
}
- LONGEST val = attr->constant_value (0);
- if (val < 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_objfile->objfile));
- return 0;
- }
- ULONGEST align = val;
+ std::optional<ULONGEST> val = attr->unsigned_constant ();
+ if (!val.has_value ())
+ return 0;
+
+ ULONGEST align = *val;
if (align == 0)
{
@@ -12040,7 +11013,8 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
{
if (cu->lang () == language_cplus
|| cu->lang () == language_d
- || cu->lang () == language_rust)
+ || cu->lang () == language_rust
+ || cu->lang () == language_ada)
{
const char *full_name = dwarf2_full_name (name, die, cu);
@@ -12083,19 +11057,23 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
the die. Otherwise the calling convention remains set to
the default value DW_CC_normal. */
attr = dwarf2_attr (die, DW_AT_calling_convention, cu);
- if (attr != nullptr
- && is_valid_DW_AT_calling_convention_for_type (attr->constant_value (0)))
+ if (attr != nullptr)
{
- ALLOCATE_CPLUS_STRUCT_TYPE (type);
- TYPE_CPLUS_CALLING_CONVENTION (type)
- = (enum dwarf_calling_convention) (attr->constant_value (0));
+ std::optional<ULONGEST> value = attr->unsigned_constant ();
+ if (value.has_value ()
+ && is_valid_DW_AT_calling_convention_for_type (*value))
+ {
+ ALLOCATE_CPLUS_STRUCT_TYPE (type);
+ TYPE_CPLUS_CALLING_CONVENTION (type)
+ = (enum dwarf_calling_convention) *value;
+ }
}
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr != nullptr)
{
if (attr->form_is_constant ())
- type->set_length (attr->constant_value (0));
+ type->set_length (attr->unsigned_constant ().value_or (0));
else
{
struct dynamic_prop prop;
@@ -12110,7 +11088,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
maybe_set_alignment (cu, die, type);
- if (producer_is_icc_lt_14 (cu) && (type->length () == 0))
+ if (cu->producer_is_icc_lt_14 () && type->length () == 0)
{
/* ICC<14 does not output the required DW_AT_declaration on
incomplete types, but gives them a size of zero. */
@@ -12122,7 +11100,7 @@ read_structure_type (struct die_info *die, struct dwarf2_cu *cu)
if (die_is_declaration (die, cu))
type->set_is_stub (true);
else if (attr == NULL && die->child == NULL
- && producer_is_realview (cu->producer))
+ && cu->producer_is_realview ())
/* RealView does not output the required DW_AT_declaration
on incomplete types. */
type->set_is_stub (true);
@@ -12196,9 +11174,7 @@ handle_variant_part (struct die_info *die, struct type *type,
objfile_name (cu->per_objfile->objfile));
}
- for (die_info *child_die = die->child;
- child_die != NULL;
- child_die = child_die->sibling)
+ for (die_info *child_die : die->children ())
handle_struct_member_die (child_die, type, fi, template_args, cu);
}
@@ -12242,16 +11218,16 @@ handle_variant (struct die_info *die, struct type *type,
{
discr = dwarf2_attr (die, DW_AT_discr_list, cu);
if (discr == nullptr || discr->as_block ()->size == 0)
- variant.default_branch = true;
+ {
+ /* Nothing to do here -- default branch. */
+ }
else
variant.discr_list_data = discr->as_block ();
}
else
- variant.discriminant_value = discr->constant_value (0);
+ variant.discriminant_attr = discr;
- for (die_info *variant_child = die->child;
- variant_child != NULL;
- variant_child = variant_child->sibling)
+ for (die_info *variant_child : die->children ())
handle_struct_member_die (variant_child, type, fi, template_args, cu);
variant.last_field = fi->fields.size ();
@@ -12311,6 +11287,21 @@ handle_struct_member_die (struct die_info *child_die, struct type *type,
handle_variant (child_die, type, fi, template_args, cu);
}
+/* Create a property baton for a field. DIE is the field's DIE. The
+ baton's "field" member is filled in, but the other members of the
+ baton are not. The new property baton is returned. */
+
+static dwarf2_property_baton *
+find_field_create_baton (dwarf2_cu *cu, die_info *die)
+{
+ dwarf2_property_baton *result
+ = XOBNEW (&cu->per_objfile->objfile->objfile_obstack,
+ struct dwarf2_property_baton);
+ memset (&result->field, 0, sizeof (result->field));
+ compute_field_location (cu, die, &result->field);
+ return result;
+}
+
/* Finish creating a structure or union type, including filling in its
members and creating a symbol for it. This function also handles Fortran
namelist variables, their items or members and creating a symbol for
@@ -12320,7 +11311,6 @@ static void
process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->per_objfile->objfile;
- struct die_info *child_die;
struct type *type;
type = get_die_type (die, cu);
@@ -12333,13 +11323,8 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
struct field_info fi;
std::vector<struct symbol *> template_args;
- child_die = die->child;
-
- while (child_die && child_die->tag)
- {
- handle_struct_member_die (child_die, type, &fi, &template_args, cu);
- child_die = child_die->sibling;
- }
+ for (die_info *child_die : die->children ())
+ handle_struct_member_die (child_die, type, &fi, &template_args, cu);
/* Attach template arguments to type. */
if (!template_args.empty ())
@@ -12403,8 +11388,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
set_type_vptr_fieldno (type, TYPE_VPTR_FIELDNO (t));
}
}
- else if (cu->producer
- && startswith (cu->producer, "IBM(R) XL C/C++ Advanced Edition"))
+ else if (cu->producer_is_xlc ())
{
/* The IBM XLC compiler does not provide direct indication
of the containing type, but the vtable pointer is
@@ -12478,9 +11462,7 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
current die is a declaration. Normally, of course, a declaration
won't have any children at all. */
- child_die = die->child;
-
- while (child_die != NULL && child_die->tag)
+ for (die_info *child_die : die->children ())
{
if (child_die->tag == DW_TAG_member
|| child_die->tag == DW_TAG_variable
@@ -12492,8 +11474,6 @@ process_structure_scope (struct die_info *die, struct dwarf2_cu *cu)
}
else
process_die (child_die, cu);
-
- child_die = child_die->sibling;
}
/* Do not consider external references. According to the DWARF standard,
@@ -12555,19 +11535,26 @@ die_byte_order (die_info *die, dwarf2_cu *cu, enum bfd_endian *byte_order)
attribute *attr = dwarf2_attr (die, DW_AT_endianity, cu);
if (attr != nullptr && attr->form_is_constant ())
{
- int endianity = attr->constant_value (0);
+ std::optional<ULONGEST> endianity = attr->unsigned_constant ();
- switch (endianity)
+ if (endianity.has_value ())
{
- case DW_END_big:
- new_order = BFD_ENDIAN_BIG;
- break;
- case DW_END_little:
- new_order = BFD_ENDIAN_LITTLE;
- break;
- default:
- complaint (_("DW_AT_endianity has unrecognized value %d"), endianity);
- break;
+ switch (*endianity)
+ {
+ case DW_END_default:
+ /* Nothing. */
+ break;
+ case DW_END_big:
+ new_order = BFD_ENDIAN_BIG;
+ break;
+ case DW_END_little:
+ new_order = BFD_ENDIAN_LITTLE;
+ break;
+ default:
+ complaint (_("DW_AT_endianity has unrecognized value %s"),
+ pulongest (*endianity));
+ break;
+ }
}
}
@@ -12579,28 +11566,30 @@ die_byte_order (die_info *die, dwarf2_cu *cu, enum bfd_endian *byte_order)
/* 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. */
+ children. In particular, the fields are computed. If IS_UNSIGNED
+ is set, the enumeration type's sign is already known (a true value
+ means unsigned), and so examining the constants to determine the
+ sign isn't needed; when this is unset, the enumerator constants are
+ read as signed values. */
static void
update_enumeration_type_from_children (struct die_info *die,
struct type *type,
- struct dwarf2_cu *cu)
+ struct dwarf2_cu *cu,
+ std::optional<bool> is_unsigned)
{
- struct die_info *child_die;
- int unsigned_enum = 1;
- int flag_enum = 1;
+ /* This is used to check whether the enum is signed or unsigned; for
+ simplicity, it is always correct regardless of whether
+ IS_UNSIGNED is set. */
+ bool unsigned_enum = is_unsigned.value_or (true);
+ bool flag_enum = true;
- auto_obstack obstack;
std::vector<struct field> fields;
- for (child_die = die->child;
- child_die != NULL && child_die->tag;
- child_die = child_die->sibling)
+ for (die_info *child_die : die->children ())
{
struct attribute *attr;
LONGEST value;
- const gdb_byte *bytes;
- struct dwarf2_locexpr_baton *baton;
const char *name;
if (child_die->tag != DW_TAG_enumerator)
@@ -12614,19 +11603,26 @@ update_enumeration_type_from_children (struct die_info *die,
if (name == NULL)
name = "<anonymous enumerator>";
- dwarf2_const_value_attr (attr, type, name, &obstack, cu,
- &value, &bytes, &baton);
- if (value < 0)
- {
- unsigned_enum = 0;
- flag_enum = 0;
- }
+ /* Can't check UNSIGNED_ENUM here because that is
+ optimistic. */
+ if (is_unsigned.has_value () && *is_unsigned)
+ value = attr->unsigned_constant ().value_or (0);
else
{
- if (count_one_bits_ll (value) >= 2)
- flag_enum = 0;
+ /* Read as signed, either because we don't know the sign or
+ because we know it is definitely signed. */
+ value = attr->signed_constant ().value_or (0);
+
+ if (value < 0)
+ {
+ unsigned_enum = false;
+ flag_enum = false;
+ }
}
+ if (flag_enum && count_one_bits_ll (value) >= 2)
+ flag_enum = false;
+
struct field &field = fields.emplace_back ();
field.set_name (dwarf2_physname (name, child_die, cu));
field.set_loc_enumval (value);
@@ -12635,13 +11631,10 @@ update_enumeration_type_from_children (struct die_info *die,
if (!fields.empty ())
type->copy_fields (fields);
else
- flag_enum = 0;
+ flag_enum = false;
- if (unsigned_enum)
- type->set_is_unsigned (true);
-
- if (flag_enum)
- type->set_is_flag_enum (true);
+ type->set_is_unsigned (unsigned_enum);
+ type->set_is_flag_enum (flag_enum);
}
/* Given a DW_AT_enumeration_type die, set its type. We do not
@@ -12685,7 +11678,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr != nullptr)
- type->set_length (attr->constant_value (0));
+ type->set_length (attr->unsigned_constant ().value_or (0));
else
type->set_length (0);
@@ -12699,6 +11692,11 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
if (die_is_declaration (die, cu))
type->set_is_stub (true);
+ /* If the underlying type is known, and is unsigned, then we'll
+ assume the enumerator constants are unsigned. Otherwise we have
+ to assume they are signed. */
+ std::optional<bool> is_unsigned;
+
/* 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
@@ -12711,7 +11709,8 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
struct type *underlying_type = type->target_type ();
underlying_type = check_typedef (underlying_type);
- type->set_is_unsigned (underlying_type->is_unsigned ());
+ is_unsigned = underlying_type->is_unsigned ();
+ type->set_is_unsigned (*is_unsigned);
if (type->length () == 0)
type->set_length (underlying_type->length ());
@@ -12731,7 +11730,7 @@ read_enumeration_type (struct die_info *die, struct dwarf2_cu *cu)
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);
+ update_enumeration_type_from_children (die, type, cu, is_unsigned);
return type;
}
@@ -12753,10 +11752,7 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
if (die->child != NULL)
{
- struct die_info *child_die;
-
- child_die = die->child;
- while (child_die && child_die->tag)
+ for (die_info *child_die : die->children ())
{
if (child_die->tag != DW_TAG_enumerator)
{
@@ -12764,8 +11760,6 @@ process_enumeration_scope (struct die_info *die, struct dwarf2_cu *cu)
}
else
new_symbol (child_die, this_type, cu);
-
- child_die = child_die->sibling;
}
}
@@ -12946,9 +11940,7 @@ quirk_ada_thick_pointer (struct die_info *die, struct dwarf2_cu *cu,
int bounds_offset = -1;
int max_align = -1;
std::vector<struct field> range_fields;
- for (struct die_info *child_die = die->child;
- child_die;
- child_die = child_die->sibling)
+ for (die_info *child_die : die->children ())
{
if (child_die->tag == DW_TAG_subrange_type)
{
@@ -13049,7 +12041,6 @@ static struct type *
read_array_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->per_objfile->objfile;
- struct die_info *child_die;
struct type *type;
struct type *element_type, *range_type, *index_type;
struct attribute *attr;
@@ -13089,7 +12080,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
attr = dwarf2_attr (die, DW_AT_bit_stride, cu);
if (attr != NULL)
- bit_stride = attr->constant_value (0);
+ bit_stride = attr->unsigned_constant ().value_or (0);
/* Irix 6.2 native cc creates array types without children for
arrays with unspecified length. */
@@ -13104,8 +12095,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
}
std::vector<struct type *> range_types;
- child_die = die->child;
- while (child_die && child_die->tag)
+ for (die_info *child_die : die->children ())
{
if (child_die->tag == DW_TAG_subrange_type
|| child_die->tag == DW_TAG_generic_subrange)
@@ -13119,7 +12109,6 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
range_types.push_back (child_type);
}
}
- child_die = child_die->sibling;
}
if (range_types.empty ())
@@ -13189,7 +12178,7 @@ read_array_type (struct die_info *die, struct dwarf2_cu *cu)
"than the total size of elements"));
}
- name = dwarf2_name (die, cu);
+ name = dwarf2_full_name (nullptr, die, cu);
if (name)
type->set_name (name);
@@ -13221,9 +12210,10 @@ read_array_order (struct die_info *die, struct dwarf2_cu *cu)
if (attr != nullptr)
{
- LONGEST val = attr->constant_value (-1);
- if (val == DW_ORD_row_major || val == DW_ORD_col_major)
- return (enum dwarf_array_dim_ordering) val;
+ std::optional<ULONGEST> val = attr->unsigned_constant ();
+ if (val.has_value () &&
+ (*val == DW_ORD_row_major || *val == DW_ORD_col_major))
+ return (enum dwarf_array_dim_ordering) *val;
}
/* GNU F77 is a special case, as at 08/2004 array type info is the
@@ -13233,8 +12223,7 @@ read_array_order (struct die_info *die, struct dwarf2_cu *cu)
FIXME: dsl/2004-8-20: If G77 is ever fixed, this will also need
version checking. */
- if (cu->lang () == language_fortran
- && cu->producer && strstr (cu->producer, "GNU F77"))
+ if (cu->lang () == language_fortran && cu->producer_is_gf77 ())
{
return DW_ORD_row_major;
}
@@ -13306,7 +12295,8 @@ mark_common_block_symbol_computed (struct symbol *sym,
gdb_assert (member_loc->form_is_block ()
|| member_loc->form_is_constant ());
- baton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton);
+ baton = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct dwarf2_locexpr_baton);
baton->per_objfile = per_objfile;
baton->per_cu = cu->per_cu;
gdb_assert (baton->per_cu);
@@ -13315,7 +12305,7 @@ mark_common_block_symbol_computed (struct symbol *sym,
if (member_loc->form_is_constant ())
{
- offset = member_loc->constant_value (0);
+ offset = member_loc->unsigned_constant ().value_or (0);
baton->size += 1 /* DW_OP_addr */ + cu->header.addr_size;
}
else
@@ -13386,15 +12376,12 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
if (die->child != NULL)
{
struct objfile *objfile = cu->per_objfile->objfile;
- struct die_info *child_die;
- size_t n_entries = 0, size;
+ size_t size;
struct common_block *common_block;
struct symbol *sym;
- for (child_die = die->child;
- child_die && child_die->tag;
- child_die = child_die->sibling)
- ++n_entries;
+ auto range = die->children ();
+ size_t n_entries = std::distance (range.begin (), range.end ());
size = (sizeof (struct common_block)
+ (n_entries - 1) * sizeof (struct symbol *));
@@ -13404,9 +12391,7 @@ read_common_block (struct die_info *die, struct dwarf2_cu *cu)
memset (common_block->contents, 0, n_entries * sizeof (struct symbol *));
common_block->n_entries = 0;
- for (child_die = die->child;
- child_die && child_die->tag;
- child_die = child_die->sibling)
+ for (die_info *child_die : die->children ())
{
/* Create the symbol in the DW_TAG_common_block block in the current
symbol scope. */
@@ -13529,50 +12514,52 @@ read_namespace (struct die_info *die, struct dwarf2_cu *cu)
if (die->child != NULL)
{
- struct die_info *child_die = die->child;
-
- while (child_die && child_die->tag)
- {
- process_die (child_die, cu);
- child_die = child_die->sibling;
- }
+ for (die_info *child_die : die->children ())
+ process_die (child_die, cu);
}
}
-/* Read a Fortran module as type. This DIE can be only a declaration used for
- imported module. Still we need that type as local Fortran "use ... only"
- declaration imports depend on the created type in determine_prefix. */
+/* Read a Fortran module or Ada package as type. For Fortran, This
+ DIE can be only a declaration used for imported module. Still we
+ need that type as local Fortran "use ... only" declaration imports
+ depend on the created type in determine_prefix. */
static struct type *
read_module_type (struct die_info *die, struct dwarf2_cu *cu)
{
+ enum language lang = cu->lang ();
struct objfile *objfile = cu->per_objfile->objfile;
- const char *module_name;
struct type *type;
- module_name = dwarf2_name (die, cu);
- type = type_allocator (objfile, cu->lang ()).new_type (TYPE_CODE_MODULE,
- 0, module_name);
+ if (lang == language_ada)
+ {
+ const char *pkg_name = dwarf2_full_name (nullptr, die, cu);
+ type = type_allocator (objfile, lang).new_type (TYPE_CODE_NAMESPACE,
+ 0, pkg_name);
+ }
+ else
+ {
+ const char *module_name = dwarf2_name (die, cu);
+ type = type_allocator (objfile, lang).new_type (TYPE_CODE_MODULE,
+ 0, module_name);
+ }
return set_die_type (die, type, cu);
}
-/* Read a Fortran module. */
+/* Read a module. This tag is used by Fortran (for modules), but also
+ by Ada (for packages). */
static void
read_module (struct die_info *die, struct dwarf2_cu *cu)
{
- struct die_info *child_die = die->child;
struct type *type;
type = read_type_die (die, cu);
new_symbol (die, type, cu);
- while (child_die && child_die->tag)
- {
- process_die (child_die, cu);
- child_die = child_die->sibling;
- }
+ for (die_info *child_die : die->children ())
+ process_die (child_die, cu);
}
/* Return the name of the namespace represented by DIE. Set
@@ -13615,11 +12602,11 @@ static struct type *
read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
{
struct gdbarch *gdbarch = cu->per_objfile->objfile->arch ();
- struct comp_unit_head *cu_header = &cu->header;
+ unit_head *cu_header = &cu->header;
struct type *type;
struct attribute *attr_byte_size;
struct attribute *attr_address_class;
- int byte_size, addr_class;
+ int byte_size;
struct type *target_type;
target_type = die_type (die, cu);
@@ -13633,13 +12620,16 @@ read_tag_pointer_type (struct die_info *die, struct dwarf2_cu *cu)
attr_byte_size = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr_byte_size)
- byte_size = attr_byte_size->constant_value (cu_header->addr_size);
+ byte_size = (attr_byte_size->unsigned_constant ()
+ .value_or (cu_header->addr_size));
else
byte_size = cu_header->addr_size;
attr_address_class = dwarf2_attr (die, DW_AT_address_class, cu);
+ ULONGEST addr_class;
if (attr_address_class)
- addr_class = attr_address_class->constant_value (DW_ADDR_none);
+ addr_class = (attr_address_class->unsigned_constant ()
+ .value_or (DW_ADDR_none));
else
addr_class = DW_ADDR_none;
@@ -13727,7 +12717,7 @@ static struct type *
read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu,
enum type_code refcode)
{
- struct comp_unit_head *cu_header = &cu->header;
+ unit_head *cu_header = &cu->header;
struct type *type, *target_type;
struct attribute *attr;
@@ -13743,7 +12733,8 @@ read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu,
type = lookup_reference_type (target_type, refcode);
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr != nullptr)
- type->set_length (attr->constant_value (cu_header->addr_size));
+ type->set_length (attr->unsigned_constant ()
+ .value_or (cu_header->addr_size));
else
type->set_length (cu_header->addr_size);
@@ -13907,9 +12898,7 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
len = dwarf2_attr (die, DW_AT_byte_size, cu);
if (len != nullptr && len->form_is_constant ())
{
- /* 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);
+ LONGEST sz = len->unsigned_constant ().value_or (0);
prop_type = objfile_int_type (objfile, sz, true);
}
else
@@ -13928,15 +12917,14 @@ read_tag_string_type (struct die_info *die, struct dwarf2_cu *cu)
else if (attr != nullptr)
{
/* This DW_AT_string_length just contains the length with no
- indirection. There's no need to create a dynamic property in this
- case. Pass 0 for the default value as we know it will not be
- returned in this case. */
- length = attr->constant_value (0);
+ indirection. There's no need to create a dynamic property in
+ this case. */
+ length = attr->unsigned_constant ().value_or (0);
}
else if ((attr = dwarf2_attr (die, DW_AT_byte_size, cu)) != nullptr)
{
/* We don't currently support non-constant byte sizes for strings. */
- length = attr->constant_value (1);
+ length = attr->unsigned_constant ().value_or (1);
}
else
{
@@ -13987,7 +12975,7 @@ prototyped_function_p (struct die_info *die, struct dwarf2_cu *cu)
prototyped and unprototyped functions; default to prototyped,
since that is more common in modern code (and RealView warns
about unprototyped functions). */
- if (producer_is_realview (cu->producer))
+ if (cu->producer_is_realview ())
return 1;
return 0;
@@ -14018,8 +13006,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
if (type->code () == TYPE_CODE_VOID
&& !type->is_stub ()
&& die->child == nullptr
- && (cu->per_cu->version () == 2
- || producer_is_gas_2_39 (cu)))
+ && (cu->header.version == 2 || cu->producer_is_gas_2_39 ()))
{
/* Work around PR gas/29517, pretend we have an DW_TAG_unspecified_type
return type. */
@@ -14042,11 +13029,15 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
the subroutine die. Otherwise set the calling convention to
the default value DW_CC_normal. */
attr = dwarf2_attr (die, DW_AT_calling_convention, cu);
- if (attr != nullptr
- && is_valid_DW_AT_calling_convention_for_subroutine (attr->constant_value (0)))
- TYPE_CALLING_CONVENTION (ftype)
- = (enum dwarf_calling_convention) attr->constant_value (0);
- else if (cu->producer && strstr (cu->producer, "IBM XL C for OpenCL"))
+ if (attr != nullptr)
+ {
+ std::optional<ULONGEST> value = attr->unsigned_constant ();
+ if (value.has_value ()
+ && is_valid_DW_AT_calling_convention_for_subroutine (*value))
+ TYPE_CALLING_CONVENTION (ftype)
+ = (enum dwarf_calling_convention) *value;
+ }
+ else if (cu->producer_is_xlc_opencl ())
TYPE_CALLING_CONVENTION (ftype) = DW_CC_GDB_IBM_OpenCL;
else
TYPE_CALLING_CONVENTION (ftype) = DW_CC_normal;
@@ -14065,22 +13056,18 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
if (die->child != NULL)
{
struct type *void_type = builtin_type (objfile)->builtin_void;
- struct die_info *child_die;
int nparams, iparams;
/* Count the number of parameters.
FIXME: GDB currently ignores vararg functions, but knows about
vararg member functions. */
nparams = 0;
- child_die = die->child;
- while (child_die && child_die->tag)
+ for (die_info *child_die : die->children ())
{
if (child_die->tag == DW_TAG_formal_parameter)
nparams++;
else if (child_die->tag == DW_TAG_unspecified_parameters)
ftype->set_has_varargs (true);
-
- child_die = child_die->sibling;
}
/* Allocate storage for parameters and fill them in. */
@@ -14092,8 +13079,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
ftype->field (iparams).set_type (void_type);
iparams = 0;
- child_die = die->child;
- while (child_die && child_die->tag)
+ for (die_info *child_die : die->children ())
{
if (child_die->tag == DW_TAG_formal_parameter)
{
@@ -14150,7 +13136,6 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
ftype->field (iparams).set_type (arg_type);
iparams++;
}
- child_die = child_die->sibling;
}
}
@@ -14166,7 +13151,8 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
struct gdbarch *gdbarch = objfile->arch ();
struct type *target_type = die_type (die, cu);
- if (gdbarch_dwarf2_omit_typedef_p (gdbarch, target_type, cu->producer, name))
+ if (gdbarch_dwarf2_omit_typedef_p (gdbarch, target_type,
+ cu->get_producer (), name))
{
/* The long double is defined as a base type in C. GCC creates a long
double typedef with target-type _Float128 for the long double to
@@ -14213,7 +13199,7 @@ read_typedef (struct die_info *die, struct dwarf2_cu *cu)
a given gmp_mpz given an attribute. */
static void
-get_mpz (struct dwarf2_cu *cu, gdb_mpz *value, struct attribute *attr)
+get_mpz_for_rational (dwarf2_cu *cu, gdb_mpz *value, attribute *attr)
{
/* GCC will sometimes emit a 16-byte constant value as a DWARF
location expression that pushes an implicit value. */
@@ -14247,10 +13233,11 @@ get_mpz (struct dwarf2_cu *cu, gdb_mpz *value, struct attribute *attr)
? BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE,
true);
}
- else if (attr->form_is_unsigned ())
- *value = gdb_mpz (attr->as_unsigned ());
else
- *value = gdb_mpz (attr->constant_value (1));
+ {
+ /* Rational constants for Ada are always unsigned. */
+ *value = gdb_mpz (attr->unsigned_constant ().value_or (1));
+ }
}
/* Assuming DIE is a rational DW_TAG_constant, read the DIE's
@@ -14279,8 +13266,8 @@ get_dwarf2_rational_constant (struct die_info *die, struct dwarf2_cu *cu,
if (num_attr == nullptr || denom_attr == nullptr)
return;
- get_mpz (cu, numerator, num_attr);
- get_mpz (cu, denominator, denom_attr);
+ get_mpz_for_rational (cu, numerator, num_attr);
+ get_mpz_for_rational (cu, denominator, denom_attr);
}
/* Same as get_dwarf2_rational_constant, but extracting an unsigned
@@ -14429,14 +13416,14 @@ finish_fixed_point_type (struct type *type, const char *suffix,
}
else if (attr->name == DW_AT_binary_scale)
{
- LONGEST scale_exp = attr->constant_value (0);
+ LONGEST scale_exp = attr->signed_constant ().value_or (0);
gdb_mpz &num_or_denom = scale_exp > 0 ? scale_num : scale_denom;
num_or_denom <<= std::abs (scale_exp);
}
else if (attr->name == DW_AT_decimal_scale)
{
- LONGEST scale_exp = attr->constant_value (0);
+ LONGEST scale_exp = attr->signed_constant ().value_or (0);
gdb_mpz &num_or_denom = scale_exp > 0 ? scale_num : scale_denom;
num_or_denom = gdb_mpz::pow (10, std::abs (scale_exp));
@@ -14515,7 +13502,7 @@ dwarf2_init_integer_type (struct dwarf2_cu *cu, int bits, int unsigned_p,
/* Versions of Intel's C Compiler generate an integer type called "void"
instead of using DW_TAG_unspecified_type. This has been seen on
at least versions 14, 17, and 18. */
- if (bits == 0 && producer_is_icc (cu) && name != nullptr
+ if (bits == 0 && cu->producer_is_icc () && name != nullptr
&& strcmp (name, "void") == 0)
type = builtin_type (objfile)->builtin_void;
else
@@ -14635,16 +13622,44 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
struct objfile *objfile = cu->per_objfile->objfile;
struct type *type;
struct attribute *attr;
- int encoding = 0, bits = 0;
+ ULONGEST encoding = 0;
const char *name;
attr = dwarf2_attr (die, DW_AT_encoding, cu);
- if (attr != nullptr && attr->form_is_constant ())
- encoding = attr->constant_value (0);
+ if (attr != nullptr)
+ {
+ std::optional<ULONGEST> value = attr->unsigned_constant ();
+ if (value.has_value ())
+ encoding = *value;
+ }
+
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
+ std::optional<ULONGEST> byte_size;
if (attr != nullptr)
- bits = attr->constant_value (0) * TARGET_CHAR_BIT;
- name = dwarf2_name (die, cu);
+ byte_size = attr->unsigned_constant ();
+ attr = dwarf2_attr (die, DW_AT_bit_size, cu);
+ std::optional<ULONGEST> bit_size;
+ if (attr != nullptr)
+ bit_size = attr->unsigned_constant ();
+
+ attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
+ std::optional<ULONGEST> bit_offset;
+ if (attr != nullptr)
+ bit_offset = attr->unsigned_constant ();
+
+ int bits = 0;
+ if (byte_size.has_value ())
+ bits = TARGET_CHAR_BIT * *byte_size;
+ else if (bit_size.has_value ())
+ bits = align_up (*bit_size, 8);
+ else
+ {
+ /* No size, so arrange for an error type. */
+ complaint (_("DW_TAG_base_type has neither bit- nor byte-size"));
+ encoding = (ULONGEST) -1;
+ }
+
+ name = dwarf2_full_name (nullptr, die, cu);
if (!name)
complaint (_("DW_AT_name missing from DW_TAG_base_type"));
@@ -14789,29 +13804,21 @@ read_base_type (struct die_info *die, struct dwarf2_cu *cu)
type->set_endianity_is_not_default (not_default);
- if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_INT)
+ /* If both a byte size and bit size were provided, then that means
+ that not every bit in the object contributes to the value. */
+ if (TYPE_SPECIFIC_FIELD (type) == TYPE_SPECIFIC_INT
+ && byte_size.has_value ()
+ && bit_size.has_value ())
{
- attr = dwarf2_attr (die, DW_AT_bit_size, cu);
- if (attr != nullptr && attr->form_is_constant ())
+ /* DWARF says: If this attribute is omitted a default data bit
+ offset of zero is assumed. */
+ ULONGEST offset = bit_offset.value_or (0);
+
+ /* Only use the attributes if they make sense together. */
+ if (*bit_size + offset <= 8 * type->length ())
{
- unsigned real_bit_size = attr->constant_value (0);
- if (real_bit_size >= 0 && real_bit_size <= 8 * type->length ())
- {
- attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
- /* Only use the attributes if they make sense together. */
- if (attr == nullptr
- || (attr->form_is_constant ()
- && attr->constant_value (0) >= 0
- && (attr->constant_value (0) + real_bit_size
- <= 8 * type->length ())))
- {
- TYPE_MAIN_TYPE (type)->type_specific.int_stuff.bit_size
- = real_bit_size;
- if (attr != nullptr)
- TYPE_MAIN_TYPE (type)->type_specific.int_stuff.bit_offset
- = attr->constant_value (0);
- }
- }
+ TYPE_MAIN_TYPE (type)->type_specific.int_stuff.bit_size = *bit_size;
+ TYPE_MAIN_TYPE (type)->type_specific.int_stuff.bit_offset = offset;
}
}
@@ -14952,17 +13959,13 @@ attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
case DW_AT_data_member_location:
case DW_AT_data_bit_offset:
{
- LONGEST offset;
-
- if (!handle_member_location (target_die, target_cu, &offset))
+ baton = find_field_create_baton (cu, target_die);
+ if (baton == nullptr)
return 0;
- baton = XOBNEW (obstack, struct dwarf2_property_baton);
baton->property_type = read_type_die (target_die->parent,
- target_cu);
- baton->offset_info.offset = offset;
- baton->offset_info.type = die_type (target_die, target_cu);
- prop->set_addr_offset (baton);
+ target_cu);
+ prop->set_field (baton);
break;
}
}
@@ -15122,8 +14125,13 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
LONGEST bias = 0;
struct attribute *bias_attr = dwarf2_attr (die, DW_AT_GNU_bias, cu);
- if (bias_attr != nullptr && bias_attr->form_is_constant ())
- bias = bias_attr->constant_value (0);
+ if (bias_attr != nullptr)
+ {
+ if (base_type->is_unsigned ())
+ bias = (LONGEST) bias_attr->unsigned_constant ().value_or (0);
+ else
+ bias = bias_attr->signed_constant ().value_or (0);
+ }
/* Normally, the DWARF producers are expected to use a signed
constant form (Eg. DW_FORM_sdata) to express negative bounds.
@@ -15204,13 +14212,13 @@ read_subrange_type (struct die_info *die, struct dwarf2_cu *cu)
if (attr == NULL && cu->lang () != language_ada)
range_type->bounds ()->high.set_undefined ();
- name = dwarf2_name (die, cu);
+ name = dwarf2_full_name (nullptr, die, cu);
if (name)
range_type->set_name (name);
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr != nullptr)
- range_type->set_length (attr->constant_value (0));
+ range_type->set_length (attr->unsigned_constant ().value_or (0));
maybe_set_alignment (cu, die, range_type);
@@ -15241,40 +14249,28 @@ read_unspecified_type (struct die_info *die, struct dwarf2_cu *cu)
return set_die_type (die, type, cu);
}
-/* Read a single die and all its descendents. Set the die's sibling
+/* Read a single die and all its descendents. Set the die's next
field to NULL; set other fields in the die correctly, and set all
- of the descendents' fields correctly. Set *NEW_INFO_PTR to the
- location of the info_ptr after reading all of those dies. PARENT
- is the parent of the die in question. */
+ of the descendents' fields correctly. PARENT is the parent of the
+ die in question. */
-static struct die_info *
-read_die_and_children (const struct die_reader_specs *reader,
- const gdb_byte *info_ptr,
- const gdb_byte **new_info_ptr,
- struct die_info *parent)
+die_info *
+cutu_reader::read_die_and_children (die_info *parent)
{
- struct die_info *die;
- const gdb_byte *cur_ptr;
+ die_info *die = this->read_full_die (0, true);
- cur_ptr = read_full_die_1 (reader, &die, info_ptr, 0, true);
- if (die == NULL)
- {
- *new_info_ptr = cur_ptr;
- return NULL;
- }
+ if (die == nullptr)
+ return nullptr;
- bool inserted = reader->cu->die_hash.emplace (die).second;
+ bool inserted = m_cu->die_hash.emplace (die).second;
gdb_assert (inserted);
if (die->has_children)
- die->child = read_die_and_siblings_1 (reader, cur_ptr, new_info_ptr, die);
+ die->child = this->read_die_and_siblings (die);
else
- {
- die->child = NULL;
- *new_info_ptr = cur_ptr;
- }
+ die->child = nullptr;
- die->sibling = NULL;
+ die->next = nullptr;
die->parent = parent;
return die;
}
@@ -15283,101 +14279,85 @@ read_die_and_children (const struct die_reader_specs *reader,
all of the fields of all of the dies correctly. Arguments are as
in read_die_and_children. */
-static struct die_info *
-read_die_and_siblings_1 (const struct die_reader_specs *reader,
- const gdb_byte *info_ptr,
- const gdb_byte **new_info_ptr,
- struct die_info *parent)
+die_info *
+cutu_reader::read_die_and_siblings (die_info *parent)
{
- struct die_info *first_die, *last_sibling;
- const gdb_byte *cur_ptr;
-
- cur_ptr = info_ptr;
- first_die = last_sibling = NULL;
+ die_info *first_die = nullptr;
+ die_info *last_sibling = nullptr;
- while (1)
+ while (true)
{
- struct die_info *die
- = read_die_and_children (reader, cur_ptr, &cur_ptr, parent);
+ die_info *die = this->read_die_and_children (parent);
- if (die == NULL)
- {
- *new_info_ptr = cur_ptr;
- return first_die;
- }
+ if (die == nullptr)
+ return first_die;
- if (!first_die)
+ if (first_die == nullptr)
first_die = die;
else
- last_sibling->sibling = die;
+ last_sibling->next = die;
last_sibling = die;
}
}
-/* Read a die, all of its descendents, and all of its siblings; set
- all of the fields of all of the dies correctly. Arguments are as
- in read_die_and_children.
- This the main entry point for reading a DIE and all its children. */
+/* See read.h. */
-static struct die_info *
-read_die_and_siblings (const struct die_reader_specs *reader,
- const gdb_byte *info_ptr,
- const gdb_byte **new_info_ptr,
- struct die_info *parent)
+void
+cutu_reader::read_all_dies ()
{
- struct die_info *die = read_die_and_siblings_1 (reader, info_ptr,
- new_info_ptr, parent);
+ const gdb_byte *begin_info_ptr = m_info_ptr;
- if (dwarf_die_debug)
+ if (m_top_level_die->has_children)
{
- gdb_printf (gdb_stdlog,
- "Read die from %s@0x%x of %s:\n",
- reader->die_section->get_name (),
- (unsigned) (info_ptr - reader->die_section->buffer),
- bfd_get_filename (reader->abfd));
- die->dump (dwarf_die_debug);
+ gdb_assert (m_cu->die_hash.empty ());
+ m_cu->die_hash.reserve (m_cu->header.get_length_without_initial () / 12);
+ m_top_level_die->child = this->read_die_and_siblings (m_top_level_die);
}
- return die;
+ m_cu->dies = m_top_level_die;
+
+ if (dwarf_die_debug)
+ {
+ gdb_printf (gdb_stdlog, "Read die from %s@0x%tx of %s:\n",
+ m_die_section->get_name (),
+ begin_info_ptr - m_die_section->buffer,
+ bfd_get_filename (m_abfd));
+ m_top_level_die->child->dump (dwarf_die_debug);
+ }
}
/* Read a die and all its attributes, leave space for NUM_EXTRA_ATTRS
attributes.
+
The caller is responsible for filling in the extra attributes
- and updating (*DIEP)->num_attrs.
- Set DIEP to point to a newly allocated die with its information,
- except for its child, sibling, and parent fields. */
+ and updating die_info::num_attrs.
-static const gdb_byte *
-read_full_die_1 (const struct die_reader_specs *reader,
- struct die_info **diep, const gdb_byte *info_ptr,
- int num_extra_attrs, bool allow_reprocess)
+ Return a newly allocated die with its information, except for its
+ child, next, and parent fields. */
+
+die_info *
+cutu_reader::read_full_die (int num_extra_attrs, bool allow_reprocess)
{
- unsigned int abbrev_number, bytes_read, i;
+ unsigned int bytes_read, i;
const struct abbrev_info *abbrev;
- struct die_info *die;
- struct dwarf2_cu *cu = reader->cu;
- bfd *abfd = reader->abfd;
- sect_offset sect_off = (sect_offset) (info_ptr - reader->buffer);
- abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
- info_ptr += bytes_read;
- if (!abbrev_number)
- {
- *diep = NULL;
- return info_ptr;
- }
+ sect_offset sect_off = static_cast<sect_offset> (m_info_ptr - m_buffer);
+ unsigned int abbrev_number
+ = read_unsigned_leb128 (m_abfd, m_info_ptr, &bytes_read);
+ m_info_ptr += bytes_read;
- abbrev = reader->abbrev_table->lookup_abbrev (abbrev_number);
+ if (abbrev_number == 0)
+ return nullptr;
+
+ abbrev = m_abbrev_table->lookup_abbrev (abbrev_number);
if (!abbrev)
error (_(DWARF_ERROR_PREFIX
"could not find abbrev number %d [in module %s]"),
- abbrev_number,
- bfd_get_filename (abfd));
+ abbrev_number, bfd_get_filename (m_abfd));
- die = die_info::allocate (&cu->comp_unit_obstack,
- abbrev->num_attrs + num_extra_attrs);
+ die_info *die = die_info::allocate (&m_cu->comp_unit_obstack,
+ abbrev->num_attrs + num_extra_attrs);
die->sect_off = sect_off;
die->tag = abbrev->tag;
die->abbrev = abbrev_number;
@@ -15389,722 +14369,62 @@ read_full_die_1 (const struct die_reader_specs *reader,
die->num_attrs = abbrev->num_attrs;
for (i = 0; i < abbrev->num_attrs; ++i)
- info_ptr = read_attribute (reader, &die->attrs[i], &abbrev->attrs[i],
- info_ptr, allow_reprocess);
+ m_info_ptr = this->read_attribute (&die->attrs[i], &abbrev->attrs[i],
+ m_info_ptr, allow_reprocess);
- *diep = die;
- return info_ptr;
+ return die;
}
/* Read a die and all its attributes.
- Set DIEP to point to a newly allocated die with its information,
- except for its child, sibling, and parent fields. */
-static const gdb_byte *
-read_toplevel_die (const struct die_reader_specs *reader,
- struct die_info **diep, const gdb_byte *info_ptr,
- gdb::array_view<attribute *> extra_attrs)
-{
- const gdb_byte *result;
- struct dwarf2_cu *cu = reader->cu;
+ Return a newly allocated die with its information, except for its
+ child, next, and parent fields. */
- result = read_full_die_1 (reader, diep, info_ptr, extra_attrs.size (),
- false);
+die_info *
+cutu_reader::read_toplevel_die (gdb::array_view<attribute *> extra_attrs)
+{
+ const gdb_byte *begin_info_ptr = m_info_ptr;
+ die_info *die = this->read_full_die (extra_attrs.size (), false);
/* Copy in the extra attributes, if any. */
- attribute *next = &(*diep)->attrs[(*diep)->num_attrs];
+ attribute *next = &die->attrs[die->num_attrs];
for (attribute *extra : extra_attrs)
*next++ = *extra;
- struct attribute *attr = (*diep)->attr (DW_AT_str_offsets_base);
+ struct attribute *attr = die->attr (DW_AT_str_offsets_base);
if (attr != nullptr && attr->form_is_unsigned ())
- cu->str_offsets_base = attr->as_unsigned ();
+ m_cu->str_offsets_base = attr->as_unsigned ();
- attr = (*diep)->attr (DW_AT_loclists_base);
+ attr = die->attr (DW_AT_loclists_base);
if (attr != nullptr)
- cu->loclist_base = attr->as_unsigned ();
+ m_cu->loclist_base = attr->as_unsigned ();
- auto maybe_addr_base = (*diep)->addr_base ();
+ auto maybe_addr_base = die->addr_base ();
if (maybe_addr_base.has_value ())
- cu->addr_base = *maybe_addr_base;
+ m_cu->addr_base = *maybe_addr_base;
- attr = (*diep)->attr (DW_AT_rnglists_base);
+ attr = die->attr (DW_AT_rnglists_base);
if (attr != nullptr)
- cu->rnglists_base = attr->as_unsigned ();
+ m_cu->rnglists_base = attr->as_unsigned ();
- for (int i = 0; i < (*diep)->num_attrs; ++i)
+ for (int i = 0; i < die->num_attrs; ++i)
{
- if ((*diep)->attrs[i].form_requires_reprocessing ())
- read_attribute_reprocess (reader, &(*diep)->attrs[i], (*diep)->tag);
+ if (die->attrs[i].form_requires_reprocessing ())
+ this->read_attribute_reprocess (&die->attrs[i], die->tag);
}
- (*diep)->num_attrs += extra_attrs.size ();
+ die->num_attrs += extra_attrs.size ();
if (dwarf_die_debug)
{
- gdb_printf (gdb_stdlog,
- "Read die from %s@0x%x of %s:\n",
- reader->die_section->get_name (),
- (unsigned) (info_ptr - reader->die_section->buffer),
- bfd_get_filename (reader->abfd));
- (*diep)->dump (dwarf_die_debug);
- }
-
- return result;
-}
-
-
-void
-cooked_indexer::check_bounds (cutu_reader *reader)
-{
- if (reader->cu->per_cu->addresses_seen)
- return;
-
- dwarf2_cu *cu = reader->cu;
-
- unrelocated_addr best_lowpc = {}, best_highpc = {};
- /* Possibly set the default values of LOWPC and HIGHPC from
- `DW_AT_ranges'. */
- dwarf2_find_base_address (reader->comp_unit_die, cu);
- enum pc_bounds_kind cu_bounds_kind
- = dwarf2_get_pc_bounds (reader->comp_unit_die, &best_lowpc, &best_highpc,
- cu, m_index_storage->get_addrmap (), cu->per_cu);
- if (cu_bounds_kind == PC_BOUNDS_HIGH_LOW && best_lowpc < best_highpc)
- {
- /* Store the contiguous range if it is not empty; it can be
- empty for CUs with no code. addrmap requires CORE_ADDR, so
- we cast here. */
- m_index_storage->get_addrmap ()->set_empty ((CORE_ADDR) best_lowpc,
- (CORE_ADDR) best_highpc - 1,
- cu->per_cu);
-
- cu->per_cu->addresses_seen = true;
- }
-}
-
-/* Helper function that returns true if TAG can have a linkage
- name. */
-
-static bool
-tag_can_have_linkage_name (enum dwarf_tag tag)
-{
- switch (tag)
- {
- case DW_TAG_variable:
- case DW_TAG_subprogram:
- return true;
-
- default:
- return false;
- }
-}
-
-cutu_reader *
-cooked_indexer::ensure_cu_exists (cutu_reader *reader,
- dwarf2_per_objfile *per_objfile,
- sect_offset sect_off, bool is_dwz,
- bool for_scanning)
-{
- /* Lookups for type unit references are always in the CU, and
- cross-CU references will crash. */
- if (reader->cu->per_cu->is_dwz == is_dwz
- && reader->cu->header.offset_in_cu_p (sect_off))
- return reader;
-
- dwarf2_per_cu_data *per_cu
- = dwarf2_find_containing_comp_unit (sect_off, is_dwz,
- per_objfile->per_bfd);
-
- /* When scanning, we only want to visit a given CU a single time.
- Doing this check here avoids self-imports as well. */
- if (for_scanning)
- {
- bool nope = false;
- if (!per_cu->scanned.compare_exchange_strong (nope, true))
- return nullptr;
- }
-
- cutu_reader *result = m_index_storage->get_reader (per_cu);
- if (result == nullptr)
- {
- cutu_reader new_reader (per_cu, per_objfile, nullptr, nullptr, false,
- &m_index_storage->get_abbrev_table_cache ());
-
- if (new_reader.dummy_p || new_reader.comp_unit_die == nullptr
- || !new_reader.comp_unit_die->has_children)
- return nullptr;
-
- prepare_one_comp_unit (new_reader.cu, new_reader.comp_unit_die,
- language_minimal);
- std::unique_ptr<cutu_reader> copy
- (new cutu_reader (std::move (new_reader)));
- result = m_index_storage->preserve (std::move (copy));
- }
-
- if (result->dummy_p || result->comp_unit_die == nullptr
- || !result->comp_unit_die->has_children)
- return nullptr;
-
- if (for_scanning)
- check_bounds (result);
-
- return result;
-}
-
-const gdb_byte *
-cooked_indexer::scan_attributes (dwarf2_per_cu_data *scanning_per_cu,
- cutu_reader *reader,
- const gdb_byte *watermark_ptr,
- const gdb_byte *info_ptr,
- const abbrev_info *abbrev,
- const char **name,
- const char **linkage_name,
- cooked_index_flag *flags,
- sect_offset *sibling_offset,
- const cooked_index_entry **parent_entry,
- parent_map::addr_type *maybe_defer,
- bool *is_enum_class,
- bool for_specification)
-{
- bool origin_is_dwz = false;
- bool is_declaration = false;
- sect_offset origin_offset {};
-
- std::optional<unrelocated_addr> low_pc;
- std::optional<unrelocated_addr> high_pc;
- bool high_pc_relative = false;
-
- for (int i = 0; i < abbrev->num_attrs; ++i)
- {
- attribute attr;
- info_ptr = read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr);
-
- /* Store the data if it is of an attribute we want to keep in a
- partial symbol table. */
- switch (attr.name)
- {
- case DW_AT_name:
- switch (abbrev->tag)
- {
- case DW_TAG_compile_unit:
- case DW_TAG_partial_unit:
- case DW_TAG_type_unit:
- /* Compilation units have a DW_AT_name that is a filename, not
- a source language identifier. */
- break;
-
- default:
- if (*name == nullptr)
- *name = attr.as_string ();
- break;
- }
- break;
-
- case DW_AT_linkage_name:
- case DW_AT_MIPS_linkage_name:
- /* 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. */
- if (*linkage_name == nullptr)
- *linkage_name = attr.as_string ();
- break;
-
- /* DWARF 4 has defined a dedicated DW_AT_main_subprogram
- attribute to indicate the starting function of the program... */
- case DW_AT_main_subprogram:
- if (attr.as_boolean ())
- *flags |= IS_MAIN;
- break;
-
- /* ... however with older versions the DW_CC_program value of
- the DW_AT_calling_convention attribute was used instead as
- the only means available. We handle both variants then. */
- case DW_AT_calling_convention:
- if (attr.constant_value (DW_CC_normal) == DW_CC_program)
- *flags |= IS_MAIN;
- break;
-
- case DW_AT_declaration:
- is_declaration = attr.as_boolean ();
- break;
-
- case DW_AT_sibling:
- if (sibling_offset != nullptr)
- *sibling_offset = attr.get_ref_die_offset ();
- break;
-
- case DW_AT_specification:
- case DW_AT_abstract_origin:
- case DW_AT_extension:
- origin_offset = attr.get_ref_die_offset ();
- origin_is_dwz = attr.form == DW_FORM_GNU_ref_alt;
- break;
-
- case DW_AT_external:
- if (attr.as_boolean ())
- *flags &= ~IS_STATIC;
- break;
-
- case DW_AT_enum_class:
- if (attr.as_boolean ())
- *is_enum_class = true;
- break;
-
- case DW_AT_low_pc:
- low_pc = attr.as_address ();
- break;
-
- case DW_AT_high_pc:
- high_pc = attr.as_address ();
- if (reader->cu->header.version >= 4 && attr.form_is_constant ())
- high_pc_relative = true;
- break;
-
- case DW_AT_location:
- if (!scanning_per_cu->addresses_seen && attr.form_is_block ())
- {
- struct dwarf_block *locdesc = attr.as_block ();
- CORE_ADDR addr;
- if (decode_locdesc (locdesc, reader->cu, &addr)
- && (addr != 0
- || reader->cu->per_objfile->per_bfd->has_section_at_zero))
- {
- low_pc = (unrelocated_addr) addr;
- /* For variables, we don't want to try decoding the
- type just to find the size -- for gdb's purposes
- we only need the address of a variable. */
- high_pc = (unrelocated_addr) (addr + 1);
- high_pc_relative = false;
- }
- }
- break;
-
- case DW_AT_ranges:
- if (!scanning_per_cu->addresses_seen)
- {
- /* Offset in the .debug_ranges or .debug_rnglist section
- (depending on DWARF version). */
- ULONGEST ranges_offset = attr.as_unsigned ();
-
- /* See dwarf2_cu::gnu_ranges_base's doc for why we might
- want to add this value. */
- ranges_offset += reader->cu->gnu_ranges_base;
-
- unrelocated_addr lowpc, highpc;
- dwarf2_ranges_read (ranges_offset, &lowpc, &highpc, reader->cu,
- m_index_storage->get_addrmap (),
- scanning_per_cu, abbrev->tag);
- }
- break;
- }
- }
-
- /* We don't want to examine declarations, but if we found a
- declaration when handling DW_AT_specification or the like, then
- that is ok. Similarly, we allow an external variable without a
- location; those are resolved via minimal symbols. */
- if (is_declaration && !for_specification
- && !(abbrev->tag == DW_TAG_variable && (*flags & IS_STATIC) == 0))
- {
- /* We always want to recurse into some types, but we may not
- want to treat them as definitions. */
- if ((abbrev->tag == DW_TAG_class_type
- || abbrev->tag == DW_TAG_structure_type
- || abbrev->tag == DW_TAG_union_type
- || abbrev->tag == DW_TAG_namespace)
- && abbrev->has_children)
- *flags |= IS_TYPE_DECLARATION;
- else
- {
- *linkage_name = nullptr;
- *name = nullptr;
- }
- }
- else if ((*name == nullptr
- || (*linkage_name == nullptr
- && tag_can_have_linkage_name (abbrev->tag))
- || (*parent_entry == nullptr && m_language != language_c))
- && origin_offset != sect_offset (0))
- {
- cutu_reader *new_reader
- = ensure_cu_exists (reader, reader->cu->per_objfile, origin_offset,
- origin_is_dwz, false);
- if (new_reader == nullptr)
- error (_(DWARF_ERROR_PREFIX
- "cannot follow reference to DIE at %s"
- " [in module %s]"),
- sect_offset_str (origin_offset),
- bfd_get_filename (reader->abfd));
-
- const gdb_byte *new_info_ptr = (new_reader->buffer
- + to_underlying (origin_offset));
-
- if (*parent_entry == nullptr)
- {
- /* We only perform immediate lookups of parents for DIEs
- from earlier in this CU. This avoids any problem
- with a NULL result when when we see a reference to a
- DIE in another CU that we may or may not have
- imported locally. */
- parent_map::addr_type addr = parent_map::form_addr (new_info_ptr);
- if (new_reader->cu != reader->cu || new_info_ptr > watermark_ptr)
- *maybe_defer = addr;
- else
- *parent_entry = m_die_range_map->find (addr);
- }
-
- unsigned int bytes_read;
- const abbrev_info *new_abbrev = peek_die_abbrev (*new_reader,
- new_info_ptr,
- &bytes_read);
-
- if (new_abbrev == nullptr)
- error (_(DWARF_ERROR_PREFIX
- "Unexpected null DIE at offset %s [in module %s]"),
- sect_offset_str (origin_offset),
- bfd_get_filename (new_reader->abfd));
-
- new_info_ptr += bytes_read;
-
- if (new_reader->cu == reader->cu && new_info_ptr == watermark_ptr)
- {
- /* Self-reference, we're done. */
- }
- else
- scan_attributes (scanning_per_cu, new_reader, new_info_ptr,
- new_info_ptr, new_abbrev, name, linkage_name,
- flags, nullptr, parent_entry, maybe_defer,
- is_enum_class, true);
- }
-
- if (!for_specification)
- {
- if (m_language == language_ada
- && *linkage_name == nullptr)
- *linkage_name = *name;
-
- if (!scanning_per_cu->addresses_seen
- && low_pc.has_value ()
- && (reader->cu->per_objfile->per_bfd->has_section_at_zero
- || *low_pc != (unrelocated_addr) 0)
- && high_pc.has_value ())
- {
- if (high_pc_relative)
- high_pc = (unrelocated_addr) ((ULONGEST) *high_pc
- + (ULONGEST) *low_pc);
-
- if (*high_pc > *low_pc)
- {
- /* Need CORE_ADDR casts for addrmap. */
- m_index_storage->get_addrmap ()->set_empty
- ((CORE_ADDR) *low_pc, (CORE_ADDR) *high_pc - 1,
- scanning_per_cu);
- }
- }
-
- if (abbrev->tag == DW_TAG_module || abbrev->tag == DW_TAG_namespace)
- *flags &= ~IS_STATIC;
-
- if (abbrev->tag == DW_TAG_namespace && *name == nullptr)
- *name = "(anonymous namespace)";
-
- if (m_language == language_cplus
- && (abbrev->tag == DW_TAG_class_type
- || abbrev->tag == DW_TAG_interface_type
- || abbrev->tag == DW_TAG_structure_type
- || abbrev->tag == DW_TAG_union_type
- || abbrev->tag == DW_TAG_enumeration_type
- || abbrev->tag == DW_TAG_enumerator))
- *flags &= ~IS_STATIC;
-
- /* Keep in sync with new_symbol. */
- if (abbrev->tag == DW_TAG_subprogram
- && (m_language == language_ada
- || m_language == language_fortran))
- *flags &= ~IS_STATIC;
- }
-
- return info_ptr;
-}
-
-const gdb_byte *
-cooked_indexer::index_imported_unit (cutu_reader *reader,
- const gdb_byte *info_ptr,
- const abbrev_info *abbrev)
-{
- sect_offset sect_off {};
- bool is_dwz = false;
-
- for (int i = 0; i < abbrev->num_attrs; ++i)
- {
- /* Note that we never need to reprocess attributes here. */
- attribute attr;
- info_ptr = read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr);
-
- if (attr.name == DW_AT_import)
- {
- sect_off = attr.get_ref_die_offset ();
- is_dwz = (attr.form == DW_FORM_GNU_ref_alt
- || reader->cu->per_cu->is_dwz);
- }
- }
-
- /* Did not find DW_AT_import. */
- if (sect_off == sect_offset (0))
- return info_ptr;
-
- dwarf2_per_objfile *per_objfile = reader->cu->per_objfile;
- cutu_reader *new_reader = ensure_cu_exists (reader, per_objfile, sect_off,
- is_dwz, true);
- if (new_reader != nullptr)
- {
- index_dies (new_reader, new_reader->info_ptr, nullptr, false);
-
- reader->cu->add_dependence (new_reader->cu->per_cu);
- }
-
- return info_ptr;
-}
-
-const gdb_byte *
-cooked_indexer::recurse (cutu_reader *reader,
- const gdb_byte *info_ptr,
- std::variant<const cooked_index_entry *,
- parent_map::addr_type> parent,
- bool fully)
-{
- info_ptr = index_dies (reader, info_ptr, parent, fully);
-
- if (!std::holds_alternative<const cooked_index_entry *> (parent))
- return info_ptr;
- const cooked_index_entry *parent_entry
- = std::get<const cooked_index_entry *> (parent);
-
- if (parent_entry != nullptr)
- {
- /* Both start and end are inclusive, so use both "+ 1" and "- 1" to
- limit the range to the children of parent_entry. */
- parent_map::addr_type start
- = parent_map::form_addr (reader->buffer
- + to_underlying (parent_entry->die_offset)
- + 1);
- parent_map::addr_type end = parent_map::form_addr (info_ptr - 1);
- m_die_range_map->add_entry (start, end, parent_entry);
- }
-
- return info_ptr;
-}
-
-const gdb_byte *
-cooked_indexer::index_dies (cutu_reader *reader,
- const gdb_byte *info_ptr,
- std::variant<const cooked_index_entry *,
- parent_map::addr_type> parent,
- bool fully)
-{
- const gdb_byte *end_ptr = (reader->buffer
- + to_underlying (reader->cu->header.sect_off)
- + reader->cu->header.get_length_with_initial ());
-
- while (info_ptr < end_ptr)
- {
- sect_offset this_die = (sect_offset) (info_ptr - reader->buffer);
- unsigned int bytes_read;
- const abbrev_info *abbrev = peek_die_abbrev (*reader, info_ptr,
- &bytes_read);
- info_ptr += bytes_read;
- if (abbrev == nullptr)
- break;
-
- if (abbrev->tag == DW_TAG_imported_unit)
- {
- info_ptr = index_imported_unit (reader, info_ptr, abbrev);
- continue;
- }
-
- parent_map::addr_type defer {};
- if (std::holds_alternative<parent_map::addr_type> (parent))
- defer = std::get<parent_map::addr_type> (parent);
- const cooked_index_entry *parent_entry = nullptr;
- if (std::holds_alternative<const cooked_index_entry *> (parent))
- parent_entry = std::get<const cooked_index_entry *> (parent);
-
- /* If a DIE parent is a DW_TAG_subprogram, then the DIE is only
- interesting if it's a DW_TAG_subprogram or a DW_TAG_entry_point. */
- bool die_interesting
- = (abbrev->interesting
- && (parent_entry == nullptr
- || parent_entry->tag != DW_TAG_subprogram
- || abbrev->tag == DW_TAG_subprogram
- || abbrev->tag == DW_TAG_entry_point));
-
- if (!die_interesting)
- {
- info_ptr = skip_one_die (reader, info_ptr, abbrev, !fully);
- if (fully && abbrev->has_children)
- info_ptr = index_dies (reader, info_ptr, parent, fully);
- continue;
- }
-
- const char *name = nullptr;
- const char *linkage_name = nullptr;
- cooked_index_flag flags = IS_STATIC;
- sect_offset sibling {};
- const cooked_index_entry *this_parent_entry = parent_entry;
- bool is_enum_class = false;
-
- /* The scope of a DW_TAG_entry_point cooked_index_entry is the one of
- its surrounding subroutine. */
- if (abbrev->tag == DW_TAG_entry_point)
- this_parent_entry = parent_entry->get_parent ();
- info_ptr = scan_attributes (reader->cu->per_cu, reader, info_ptr,
- info_ptr, abbrev, &name, &linkage_name,
- &flags, &sibling, &this_parent_entry,
- &defer, &is_enum_class, false);
- /* A DW_TAG_entry_point inherits its static/extern property from
- the enclosing subroutine. */
- if (abbrev->tag == DW_TAG_entry_point)
- {
- flags &= ~IS_STATIC;
- flags |= parent_entry->flags & IS_STATIC;
- }
-
- if (abbrev->tag == DW_TAG_namespace
- && m_language == language_cplus
- && strcmp (name, "::") == 0)
- {
- /* GCC 4.0 and 4.1 had a bug (PR c++/28460) where they
- generated bogus DW_TAG_namespace DIEs with a name of "::"
- for the global namespace. Work around this problem
- here. */
- name = nullptr;
- }
-
- cooked_index_entry *this_entry = nullptr;
- if (name != nullptr)
- {
- if (defer != 0)
- this_entry
- = m_index_storage->add (this_die, abbrev->tag,
- flags | IS_PARENT_DEFERRED, name,
- defer, m_per_cu);
- else
- this_entry
- = m_index_storage->add (this_die, abbrev->tag, flags, name,
- this_parent_entry, m_per_cu);
- }
-
- if (linkage_name != nullptr)
- {
- /* We only want this to be "main" if it has a linkage name
- but not an ordinary name. */
- if (name != nullptr)
- flags = flags & ~IS_MAIN;
- /* Set the IS_LINKAGE on for everything except when functions
- have linkage name present but name is absent. */
- if (name != nullptr
- || (abbrev->tag != DW_TAG_subprogram
- && abbrev->tag != DW_TAG_inlined_subroutine
- && abbrev->tag != DW_TAG_entry_point))
- flags = flags | IS_LINKAGE;
- m_index_storage->add (this_die, abbrev->tag, flags,
- linkage_name, nullptr, m_per_cu);
- }
-
- if (abbrev->has_children)
- {
- switch (abbrev->tag)
- {
- case DW_TAG_class_type:
- case DW_TAG_interface_type:
- case DW_TAG_structure_type:
- case DW_TAG_union_type:
- if (m_language != language_c && this_entry != nullptr)
- {
- info_ptr = recurse (reader, info_ptr, this_entry, fully);
- continue;
- }
- break;
-
- case DW_TAG_enumeration_type:
- /* Some versions of gdc could emit an "enum class"
- without a name, which is nonsensical. These are
- skipped. */
- if (is_enum_class && this_entry == nullptr)
- continue;
-
- /* We need to recurse even for an anonymous enumeration.
- Which scope we record as the parent scope depends on
- whether we're reading an "enum class". If so, we use
- the enum itself as the parent, yielding names like
- "enum_class::enumerator"; otherwise we inject the
- names into our own parent scope. */
- {
- std::variant<const cooked_index_entry *,
- parent_map::addr_type> recurse_parent;
- if (is_enum_class)
- {
- gdb_assert (this_entry != nullptr);
- recurse_parent = this_entry;
- }
- else if (defer != 0)
- recurse_parent = defer;
- else
- recurse_parent = this_parent_entry;
-
- info_ptr = recurse (reader, info_ptr, recurse_parent, fully);
- }
- continue;
-
- case DW_TAG_module:
- if (this_entry == nullptr)
- break;
- [[fallthrough]];
- case DW_TAG_namespace:
- /* We don't check THIS_ENTRY for a namespace, to handle
- the ancient G++ workaround pointed out above. */
- info_ptr = recurse (reader, info_ptr, this_entry, fully);
- continue;
-
- case DW_TAG_subprogram:
- if ((m_language == language_fortran
- || m_language == language_ada)
- && this_entry != nullptr)
- {
- info_ptr = recurse (reader, info_ptr, this_entry, true);
- continue;
- }
- break;
- }
-
- if (sibling != sect_offset (0))
- {
- const gdb_byte *sibling_ptr
- = reader->buffer + to_underlying (sibling);
-
- if (sibling_ptr < info_ptr)
- complaint (_("DW_AT_sibling points backwards"));
- else if (sibling_ptr > reader->buffer_end)
- reader->die_section->overflow_complaint ();
- else
- info_ptr = sibling_ptr;
- }
- else
- info_ptr = skip_children (reader, info_ptr);
- }
+ gdb_printf (gdb_stdlog, "Read die from %s@0x%tx of %s:\n",
+ m_die_section->get_name (),
+ (begin_info_ptr - m_die_section->buffer),
+ bfd_get_filename (m_abfd));
+ die->dump (dwarf_die_debug);
}
- return info_ptr;
-}
-
-void
-cooked_indexer::make_index (cutu_reader *reader)
-{
- check_bounds (reader);
- find_file_and_directory (reader->comp_unit_die, reader->cu);
- if (!reader->comp_unit_die->has_children)
- return;
- index_dies (reader, reader->info_ptr, nullptr, false);
+ return die;
}
struct compunit_symtab *
@@ -16118,7 +14438,7 @@ cooked_index_functions::find_compunit_symtab_by_address
cooked_index *table = wait (objfile, true);
CORE_ADDR baseaddr = objfile->data_section_offset ();
- dwarf2_per_cu_data *per_cu
+ dwarf2_per_cu *per_cu
= table->lookup ((unrelocated_addr) (address - baseaddr));
if (per_cu == nullptr)
return nullptr;
@@ -16128,14 +14448,14 @@ cooked_index_functions::find_compunit_symtab_by_address
bool
cooked_index_functions::expand_symtabs_matching
- (struct objfile *objfile,
- gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
- const lookup_name_info *lookup_name,
- gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
- gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
- block_search_flags search_flags,
- domain_search_flags domain,
- gdb::function_view<expand_symtabs_lang_matcher_ftype> lang_matcher)
+ (objfile *objfile,
+ expand_symtabs_file_matcher file_matcher,
+ const lookup_name_info *lookup_name,
+ expand_symtabs_symbol_matcher symbol_matcher,
+ expand_symtabs_expansion_listener expansion_notify,
+ block_search_flags search_flags,
+ domain_search_flags domain,
+ expand_symtabs_lang_matcher lang_matcher)
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
@@ -16147,8 +14467,7 @@ cooked_index_functions::expand_symtabs_matching
gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);
if (lookup_name == nullptr)
{
- for (dwarf2_per_cu_data *per_cu
- : all_units_range (per_objfile->per_bfd))
+ for (dwarf2_per_cu *per_cu : all_units_range (per_objfile->per_bfd))
{
QUIT;
@@ -16222,10 +14541,8 @@ cooked_index_functions::expand_symtabs_matching
std::vector<lookup_name_info> segment_lookup_names;
segment_lookup_names.reserve (name_vec.size ());
for (auto &segment_name : name_str_vec)
- {
- segment_lookup_names.emplace_back (segment_name,
- symbol_name_match_type::FULL, completing, true);
- }
+ segment_lookup_names.emplace_back (segment_name, match_type,
+ completing, true);
for (const cooked_index_entry *entry : table->find (name_str_vec.back (),
completing))
@@ -16261,6 +14578,7 @@ cooked_index_functions::expand_symtabs_matching
bool found = true;
const cooked_index_entry *parent = entry->get_parent ();
+ const language_defn *lang_def = language_def (entry->lang);
for (int i = name_vec.size () - 1; i > 0; --i)
{
/* If we ran out of entries, or if this segment doesn't
@@ -16272,7 +14590,6 @@ cooked_index_functions::expand_symtabs_matching
}
if (parent->lang != language_unknown)
{
- const language_defn *lang_def = language_def (parent->lang);
symbol_name_matcher_ftype *name_matcher
= lang_def->get_symbol_name_matcher
(segment_lookup_names[i-1]);
@@ -16292,32 +14609,33 @@ cooked_index_functions::expand_symtabs_matching
/* Might have been looking for "a::b" and found
"x::a::b". */
- if (symbol_matcher == nullptr)
- {
- if ((match_type == symbol_name_match_type::FULL
- || (lang != language_ada
- && match_type == symbol_name_match_type::EXPRESSION)))
- {
- if (parent != nullptr)
- continue;
+ if (((match_type == symbol_name_match_type::FULL
+ || (lang != language_ada
+ && match_type == symbol_name_match_type::EXPRESSION)))
+ && parent != nullptr)
+ continue;
- if (entry->lang != language_unknown)
- {
- const language_defn *lang_def = language_def (entry->lang);
- symbol_name_matcher_ftype *name_matcher
- = lang_def->get_symbol_name_matcher
- (segment_lookup_names.back ());
- if (!name_matcher (entry->canonical,
- segment_lookup_names.back (), nullptr))
- continue;
- }
- }
- }
- else
+ /* Check that the full name matches -- either by matching
+ the lookup name ourselves, or by passing the full name to
+ the symbol matcher. The former is a bit of a hack: it
+ seems like the loop above could just examine every
+ element of the name, avoiding the need to check here; but
+ this is hard. See PR symtab/32733. */
+ if (symbol_matcher != nullptr || entry->lang != language_unknown)
{
auto_obstack temp_storage;
- const char *full_name = entry->full_name (&temp_storage);
- if (!symbol_matcher (full_name))
+ const char *full_name = entry->full_name (&temp_storage,
+ FOR_ADA_LINKAGE_NAME);
+ if (symbol_matcher == nullptr)
+ {
+ symbol_name_matcher_ftype *name_matcher
+ = (lang_def->get_symbol_name_matcher
+ (lookup_name_without_params));
+ if (!name_matcher (full_name, lookup_name_without_params,
+ nullptr))
+ continue;
+ }
+ else if (!symbol_matcher (full_name))
continue;
}
@@ -16339,13 +14657,8 @@ start_debug_info_reader (dwarf2_per_objfile *per_objfile)
/* Set the index table early so that sharing works even while
scanning; and then start the scanning. */
dwarf2_per_bfd *per_bfd = per_objfile->per_bfd;
- std::unique_ptr<cooked_index_worker> worker
- (new cooked_index_debug_info (per_objfile));
- cooked_index *idx = new cooked_index (per_objfile, std::move (worker));
- per_bfd->index_table.reset (idx);
- /* Don't start reading until after 'index_table' is set. This
- avoids races. */
- idx->start_reading ();
+ auto worker = std::make_unique<cooked_index_worker_debug_info> (per_objfile);
+ per_bfd->start_reading (std::make_unique<cooked_index> (std::move (worker)));
}
@@ -16527,22 +14840,21 @@ read_rnglist_index (struct dwarf2_cu *cu, ULONGEST rnglist_index,
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
the values of str_offsets_base or addr_base may not have been known. */
-static void
-read_attribute_reprocess (const struct die_reader_specs *reader,
- struct attribute *attr, dwarf_tag tag)
+
+void
+cutu_reader::read_attribute_reprocess (attribute *attr, dwarf_tag tag)
{
- struct dwarf2_cu *cu = reader->cu;
switch (attr->form)
{
case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
- attr->set_address (read_addr_index (cu,
+ attr->set_address (read_addr_index (m_cu,
attr->as_unsigned_reprocess ()));
break;
case DW_FORM_loclistx:
{
sect_offset loclists_sect_off
- = read_loclist_index (cu, attr->as_unsigned_reprocess ());
+ = read_loclist_index (m_cu, attr->as_unsigned_reprocess ());
attr->set_unsigned (to_underlying (loclists_sect_off));
}
@@ -16550,7 +14862,7 @@ read_attribute_reprocess (const struct die_reader_specs *reader,
case DW_FORM_rnglistx:
{
sect_offset rnglists_sect_off
- = read_rnglist_index (cu, attr->as_unsigned_reprocess (), tag);
+ = read_rnglist_index (m_cu, attr->as_unsigned_reprocess (), tag);
attr->set_unsigned (to_underlying (rnglists_sect_off));
}
@@ -16564,11 +14876,11 @@ read_attribute_reprocess (const struct die_reader_specs *reader,
{
unsigned int str_index = attr->as_unsigned_reprocess ();
gdb_assert (!attr->canonical_string_p ());
- if (reader->dwo_file != NULL)
- attr->set_string_noncanonical (read_dwo_str_index (reader,
- str_index));
+ if (m_dwo_file != NULL)
+ attr->set_string_noncanonical
+ (this->read_dwo_str_index (str_index));
else
- attr->set_string_noncanonical (read_stub_str_index (cu,
+ attr->set_string_noncanonical (read_stub_str_index (m_cu,
str_index));
break;
}
@@ -16579,17 +14891,15 @@ read_attribute_reprocess (const struct die_reader_specs *reader,
/* Read an attribute value described by an attribute form. */
-static const gdb_byte *
-read_attribute_value (const struct die_reader_specs *reader,
- struct attribute *attr, unsigned form,
- LONGEST implicit_const, const gdb_byte *info_ptr,
- bool allow_reprocess)
+const gdb_byte *
+cutu_reader::read_attribute_value (attribute *attr, unsigned form,
+ LONGEST implicit_const,
+ const gdb_byte *info_ptr,
+ bool allow_reprocess)
{
- struct dwarf2_cu *cu = reader->cu;
- dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ dwarf2_per_objfile *per_objfile = m_cu->per_objfile;
struct objfile *objfile = per_objfile->objfile;
- bfd *abfd = reader->abfd;
- struct comp_unit_head *cu_header = &cu->header;
+ unit_head *cu_header = &m_cu->header;
unsigned int bytes_read;
struct dwarf_block *blk;
@@ -16598,93 +14908,96 @@ read_attribute_value (const struct die_reader_specs *reader,
{
case DW_FORM_ref_addr:
if (cu_header->version == 2)
- attr->set_unsigned ((ULONGEST) cu_header->read_address (abfd, info_ptr,
+ attr->set_unsigned ((ULONGEST) cu_header->read_address (m_abfd,
+ info_ptr,
&bytes_read));
else
- attr->set_unsigned (cu_header->read_offset (abfd, info_ptr,
+ attr->set_unsigned (cu_header->read_offset (m_abfd, info_ptr,
&bytes_read));
info_ptr += bytes_read;
break;
case DW_FORM_GNU_ref_alt:
- attr->set_unsigned (cu_header->read_offset (abfd, info_ptr,
+ attr->set_unsigned (cu_header->read_offset (m_abfd, info_ptr,
&bytes_read));
info_ptr += bytes_read;
break;
case DW_FORM_addr:
{
- unrelocated_addr addr = cu_header->read_address (abfd, info_ptr,
- &bytes_read);
+ unrelocated_addr addr
+ = cu_header->read_address (m_abfd, info_ptr, &bytes_read);
attr->set_address (addr);
info_ptr += bytes_read;
}
break;
case DW_FORM_block2:
- blk = dwarf_alloc_block (cu);
- blk->size = read_2_bytes (abfd, info_ptr);
+ blk = dwarf_alloc_block (m_cu);
+ blk->size = read_2_bytes (m_abfd, info_ptr);
info_ptr += 2;
- blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ blk->data = read_n_bytes (m_abfd, info_ptr, blk->size);
info_ptr += blk->size;
attr->set_block (blk);
break;
case DW_FORM_block4:
- blk = dwarf_alloc_block (cu);
- blk->size = read_4_bytes (abfd, info_ptr);
+ blk = dwarf_alloc_block (m_cu);
+ blk->size = read_4_bytes (m_abfd, info_ptr);
info_ptr += 4;
- blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ blk->data = read_n_bytes (m_abfd, info_ptr, blk->size);
info_ptr += blk->size;
attr->set_block (blk);
break;
case DW_FORM_data2:
- attr->set_unsigned (read_2_bytes (abfd, info_ptr));
+ attr->set_unsigned (read_2_bytes (m_abfd, info_ptr));
info_ptr += 2;
break;
case DW_FORM_data4:
- attr->set_unsigned (read_4_bytes (abfd, info_ptr));
+ case DW_FORM_ref_sup4:
+ attr->set_unsigned (read_4_bytes (m_abfd, info_ptr));
info_ptr += 4;
break;
case DW_FORM_data8:
- attr->set_unsigned (read_8_bytes (abfd, info_ptr));
+ case DW_FORM_ref_sup8:
+ attr->set_unsigned (read_8_bytes (m_abfd, info_ptr));
info_ptr += 8;
break;
case DW_FORM_data16:
- blk = dwarf_alloc_block (cu);
+ blk = dwarf_alloc_block (m_cu);
blk->size = 16;
- blk->data = read_n_bytes (abfd, info_ptr, 16);
+ blk->data = read_n_bytes (m_abfd, info_ptr, 16);
info_ptr += 16;
attr->set_block (blk);
break;
case DW_FORM_sec_offset:
- attr->set_unsigned (cu_header->read_offset (abfd, info_ptr,
+ attr->set_unsigned (cu_header->read_offset (m_abfd, info_ptr,
&bytes_read));
info_ptr += bytes_read;
break;
case DW_FORM_loclistx:
{
- attr->set_unsigned_reprocess (read_unsigned_leb128 (abfd, info_ptr,
+ attr->set_unsigned_reprocess (read_unsigned_leb128 (m_abfd, info_ptr,
&bytes_read));
info_ptr += bytes_read;
if (allow_reprocess)
- read_attribute_reprocess (reader, attr);
+ this->read_attribute_reprocess (attr);
}
break;
case DW_FORM_string:
- attr->set_string_noncanonical (read_direct_string (abfd, info_ptr,
+ attr->set_string_noncanonical (read_direct_string (m_abfd, info_ptr,
&bytes_read));
info_ptr += bytes_read;
break;
case DW_FORM_strp:
- if (!cu->per_cu->is_dwz)
+ if (!m_cu->per_cu->is_dwz)
{
- attr->set_string_noncanonical
- (read_indirect_string (per_objfile,
- abfd, info_ptr, cu_header,
- &bytes_read));
+ attr->set_string_noncanonical (read_indirect_string (per_objfile,
+ m_abfd, info_ptr,
+ cu_header,
+ &bytes_read));
info_ptr += bytes_read;
break;
}
[[fallthrough]];
case DW_FORM_line_strp:
- if (!cu->per_cu->is_dwz)
+ if (!m_cu->per_cu->is_dwz)
{
attr->set_string_noncanonical
(per_objfile->read_line_string (info_ptr, cu_header,
@@ -16694,10 +15007,11 @@ read_attribute_value (const struct die_reader_specs *reader,
}
[[fallthrough]];
case DW_FORM_GNU_strp_alt:
+ case DW_FORM_strp_sup:
{
- dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd, true);
- LONGEST str_offset = cu_header->read_offset (abfd, info_ptr,
- &bytes_read);
+ dwz_file *dwz = per_objfile->per_bfd->get_dwz_file (true);
+ LONGEST str_offset
+ = cu_header->read_offset (m_abfd, info_ptr, &bytes_read);
attr->set_string_noncanonical
(dwz->read_string (objfile, str_offset));
@@ -16706,97 +15020,97 @@ read_attribute_value (const struct die_reader_specs *reader,
break;
case DW_FORM_exprloc:
case DW_FORM_block:
- blk = dwarf_alloc_block (cu);
- blk->size = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ blk = dwarf_alloc_block (m_cu);
+ blk->size = read_unsigned_leb128 (m_abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
- blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ blk->data = read_n_bytes (m_abfd, info_ptr, blk->size);
info_ptr += blk->size;
attr->set_block (blk);
break;
case DW_FORM_block1:
- blk = dwarf_alloc_block (cu);
- blk->size = read_1_byte (abfd, info_ptr);
+ blk = dwarf_alloc_block (m_cu);
+ blk->size = read_1_byte (m_abfd, info_ptr);
info_ptr += 1;
- blk->data = read_n_bytes (abfd, info_ptr, blk->size);
+ blk->data = read_n_bytes (m_abfd, info_ptr, blk->size);
info_ptr += blk->size;
attr->set_block (blk);
break;
case DW_FORM_data1:
case DW_FORM_flag:
- attr->set_unsigned (read_1_byte (abfd, info_ptr));
+ attr->set_unsigned (read_1_byte (m_abfd, info_ptr));
info_ptr += 1;
break;
case DW_FORM_flag_present:
attr->set_unsigned (1);
break;
case DW_FORM_sdata:
- attr->set_signed (read_signed_leb128 (abfd, info_ptr, &bytes_read));
+ attr->set_signed (read_signed_leb128 (m_abfd, info_ptr, &bytes_read));
info_ptr += bytes_read;
break;
case DW_FORM_rnglistx:
{
- attr->set_unsigned_reprocess (read_unsigned_leb128 (abfd, info_ptr,
+ attr->set_unsigned_reprocess (read_unsigned_leb128 (m_abfd, info_ptr,
&bytes_read));
info_ptr += bytes_read;
if (allow_reprocess)
- read_attribute_reprocess (reader, attr);
+ this->read_attribute_reprocess (attr);
}
break;
case DW_FORM_udata:
- attr->set_unsigned (read_unsigned_leb128 (abfd, info_ptr, &bytes_read));
+ attr->set_unsigned (read_unsigned_leb128 (m_abfd, info_ptr, &bytes_read));
info_ptr += bytes_read;
break;
case DW_FORM_ref1:
attr->set_unsigned ((to_underlying (cu_header->sect_off)
- + read_1_byte (abfd, info_ptr)));
+ + read_1_byte (m_abfd, info_ptr)));
info_ptr += 1;
break;
case DW_FORM_ref2:
attr->set_unsigned ((to_underlying (cu_header->sect_off)
- + read_2_bytes (abfd, info_ptr)));
+ + read_2_bytes (m_abfd, info_ptr)));
info_ptr += 2;
break;
case DW_FORM_ref4:
attr->set_unsigned ((to_underlying (cu_header->sect_off)
- + read_4_bytes (abfd, info_ptr)));
+ + read_4_bytes (m_abfd, info_ptr)));
info_ptr += 4;
break;
case DW_FORM_ref8:
attr->set_unsigned ((to_underlying (cu_header->sect_off)
- + read_8_bytes (abfd, info_ptr)));
+ + read_8_bytes (m_abfd, info_ptr)));
info_ptr += 8;
break;
case DW_FORM_ref_sig8:
- attr->set_signature (read_8_bytes (abfd, info_ptr));
+ attr->set_signature (read_8_bytes (m_abfd, info_ptr));
info_ptr += 8;
break;
case DW_FORM_ref_udata:
attr->set_unsigned ((to_underlying (cu_header->sect_off)
- + read_unsigned_leb128 (abfd, info_ptr,
+ + read_unsigned_leb128 (m_abfd, info_ptr,
&bytes_read)));
info_ptr += bytes_read;
break;
case DW_FORM_indirect:
- form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ form = read_unsigned_leb128 (m_abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
if (form == DW_FORM_implicit_const)
{
- implicit_const = read_signed_leb128 (abfd, info_ptr, &bytes_read);
+ implicit_const = read_signed_leb128 (m_abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
}
- info_ptr = read_attribute_value (reader, attr, form, implicit_const,
- info_ptr, allow_reprocess);
+ info_ptr = this->read_attribute_value (attr, form, implicit_const,
+ info_ptr, allow_reprocess);
break;
case DW_FORM_implicit_const:
attr->set_signed (implicit_const);
break;
case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
- attr->set_unsigned_reprocess (read_unsigned_leb128 (abfd, info_ptr,
+ attr->set_unsigned_reprocess (read_unsigned_leb128 (m_abfd, info_ptr,
&bytes_read));
info_ptr += bytes_read;
if (allow_reprocess)
- read_attribute_reprocess (reader, attr);
+ this->read_attribute_reprocess (attr);
break;
case DW_FORM_strx:
case DW_FORM_strx1:
@@ -16808,43 +15122,42 @@ read_attribute_value (const struct die_reader_specs *reader,
ULONGEST str_index;
if (form == DW_FORM_strx1)
{
- str_index = read_1_byte (abfd, info_ptr);
+ str_index = read_1_byte (m_abfd, info_ptr);
info_ptr += 1;
}
else if (form == DW_FORM_strx2)
{
- str_index = read_2_bytes (abfd, info_ptr);
+ str_index = read_2_bytes (m_abfd, info_ptr);
info_ptr += 2;
}
else if (form == DW_FORM_strx3)
{
- str_index = read_3_bytes (abfd, info_ptr);
+ str_index = read_3_bytes (m_abfd, info_ptr);
info_ptr += 3;
}
else if (form == DW_FORM_strx4)
{
- str_index = read_4_bytes (abfd, info_ptr);
+ str_index = read_4_bytes (m_abfd, info_ptr);
info_ptr += 4;
}
else
{
- str_index = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ str_index = read_unsigned_leb128 (m_abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
}
attr->set_unsigned_reprocess (str_index);
if (allow_reprocess)
- read_attribute_reprocess (reader, attr);
+ this->read_attribute_reprocess (attr);
}
break;
default:
error (_(DWARF_ERROR_PREFIX
"Cannot handle %s in DWARF reader [in module %s]"),
- dwarf_form_name (form),
- bfd_get_filename (abfd));
+ dwarf_form_name (form), bfd_get_filename (m_abfd));
}
/* Super hack. */
- if (cu->per_cu->is_dwz && attr->form_is_ref ())
+ if (m_cu->per_cu->is_dwz && attr->form_is_ref ())
attr->form = DW_FORM_GNU_ref_alt;
/* We have seen instances where the compiler tried to emit a byte
@@ -16868,17 +15181,14 @@ read_attribute_value (const struct die_reader_specs *reader,
/* Read an attribute described by an abbreviated attribute. */
-static const gdb_byte *
-read_attribute (const struct die_reader_specs *reader,
- struct attribute *attr, const struct attr_abbrev *abbrev,
- const gdb_byte *info_ptr,
- bool allow_reprocess)
+const gdb_byte *
+cutu_reader::read_attribute (attribute *attr, const attr_abbrev *abbrev,
+ const gdb_byte *info_ptr, bool allow_reprocess)
{
attr->name = abbrev->name;
attr->string_is_canonical = 0;
- return read_attribute_value (reader, attr, abbrev->form,
- abbrev->implicit_const, info_ptr,
- allow_reprocess);
+ return this->read_attribute_value (attr, abbrev->form, abbrev->implicit_const,
+ info_ptr, allow_reprocess);
}
/* See read.h. */
@@ -16897,8 +15207,7 @@ read_indirect_string_at_offset (dwarf2_per_objfile *per_objfile,
static const char *
read_indirect_string (dwarf2_per_objfile *per_objfile, bfd *abfd,
- const gdb_byte *buf,
- const struct comp_unit_head *cu_header,
+ const gdb_byte *buf, const unit_head *cu_header,
unsigned int *bytes_read_ptr)
{
LONGEST str_offset = cu_header->read_offset (abfd, buf, bytes_read_ptr);
@@ -16922,7 +15231,7 @@ dwarf2_per_objfile::read_line_string (const gdb_byte *buf,
const char *
dwarf2_per_objfile::read_line_string (const gdb_byte *buf,
- const struct comp_unit_head *cu_header,
+ const unit_head *cu_header,
unsigned int *bytes_read_ptr)
{
bfd *abfd = objfile->obfd.get ();
@@ -16985,8 +15294,7 @@ read_addr_index_from_leb128 (struct dwarf2_cu *cu, const gdb_byte *info_ptr,
/* See read.h. */
unrelocated_addr
-dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu,
- dwarf2_per_objfile *per_objfile,
+dwarf2_read_addr_index (dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile,
unsigned int addr_index)
{
struct dwarf2_cu *cu = per_objfile->get_cu (per_cu);
@@ -17016,9 +15324,10 @@ dwarf2_read_addr_index (dwarf2_per_cu_data *per_cu,
}
else
{
- cutu_reader reader (per_cu, per_objfile, nullptr, nullptr, false);
- addr_base = reader.cu->addr_base;
- addr_size = reader.cu->header.addr_size;
+ cutu_reader reader (*per_cu, *per_objfile, nullptr, nullptr, false,
+ language_minimal);
+ addr_base = reader.cu ()->addr_base;
+ addr_size = reader.cu ()->header.addr_size;
}
return read_addr_index_1 (per_objfile, addr_index, addr_base, addr_size);
@@ -17055,9 +15364,16 @@ read_str_index (struct dwarf2_cu *cu,
" in CU at offset %s [in module %s]"),
form_name, str_section->get_name (),
sect_offset_str (cu->header.sect_off), objf_name);
- info_ptr = (str_offsets_section->buffer
- + str_offsets_base
- + str_index * offset_size);
+
+ ULONGEST str_offsets_offset = str_offsets_base + str_index * offset_size;
+ if (str_offsets_offset >= str_offsets_section->size)
+ error (_(DWARF_ERROR_PREFIX
+ "Offset from %s pointing outside of %s section in CU at offset %s"
+ " [in module %s]"),
+ form_name, str_offsets_section->get_name (),
+ sect_offset_str (cu->header.sect_off), objf_name);
+ info_ptr = str_offsets_section->buffer + str_offsets_offset;
+
if (offset_size == 4)
str_offset = bfd_get_32 (abfd, info_ptr);
else
@@ -17072,19 +15388,19 @@ read_str_index (struct dwarf2_cu *cu,
/* Given a DW_FORM_GNU_str_index from a DWO file, fetch the string. */
-static const char *
-read_dwo_str_index (const struct die_reader_specs *reader, ULONGEST str_index)
+const char *
+cutu_reader::read_dwo_str_index (ULONGEST str_index)
{
unsigned offset_size;
ULONGEST str_offsets_base;
- if (reader->cu->header.version >= 5)
+ if (m_cu->header.version >= 5)
{
/* We have a DWARF5 CU with a reference to a .debug_str_offsets section,
so assume the .debug_str_offsets section is DWARF5 as well, and
parse the header. FIXME: Parse the header only once. */
unsigned int bytes_read = 0;
- bfd *abfd = reader->dwo_file->sections.str_offsets.get_bfd_owner ();
- const gdb_byte *p = reader->dwo_file->sections.str_offsets.buffer;
+ bfd *abfd = m_dwo_file->sections.str_offsets.get_bfd_owner ();
+ const gdb_byte *p = m_dwo_file->sections.str_offsets.buffer;
/* Header: Initial length. */
read_initial_length (abfd, p + bytes_read, &bytes_read);
@@ -17105,7 +15421,7 @@ read_dwo_str_index (const struct die_reader_specs *reader, ULONGEST str_index)
least has a limit. */
complaint (_("Section .debug_str_offsets in %s has unsupported"
" version %d, use empty string."),
- reader->dwo_file->dwo_name.c_str (), version);
+ m_dwo_file->dwo_name.c_str (), version);
return "";
}
@@ -17122,13 +15438,12 @@ read_dwo_str_index (const struct die_reader_specs *reader, ULONGEST str_index)
str_offsets_base = 0;
/* Determine offset_size based on the .debug_info header. */
- offset_size = reader->cu->header.offset_size;
+ offset_size = m_cu->header.offset_size;
}
- return read_str_index (reader->cu,
- &reader->dwo_file->sections.str,
- &reader->dwo_file->sections.str_offsets,
- str_offsets_base, str_index, offset_size);
+ return read_str_index (m_cu, &m_dwo_file->sections.str,
+ &m_dwo_file->sections.str_offsets, str_offsets_base,
+ str_index, offset_size);
}
/* Given a DW_FORM_GNU_str_index from a Fission stub, fetch the string. */
@@ -17173,7 +15488,7 @@ leb128_size (const gdb_byte *buf)
/* Converts DWARF language names to GDB language names. */
enum language
-dwarf_lang_to_enum_language (unsigned int lang)
+dwarf_lang_to_enum_language (ULONGEST lang)
{
enum language language;
@@ -17384,11 +15699,7 @@ get_debug_line_section (struct dwarf2_cu *cu)
if (cu->dwo_unit && cu->per_cu->is_debug_types)
section = &cu->dwo_unit->dwo_file->sections.line;
else if (cu->per_cu->is_dwz)
- {
- dwz_file *dwz = dwarf2_get_dwz_file (per_objfile->per_bfd, true);
-
- section = &dwz->line;
- }
+ section = &per_objfile->per_bfd->get_dwz_file (true)->line;
else
section = &per_objfile->per_bfd->line;
@@ -17631,9 +15942,6 @@ private:
/* Additional bits of state we need to track. */
- /* The last file that we called dwarf2_start_subfile for.
- This is only used for TLLs. */
- unsigned int m_last_file = 0;
/* The last file a line number was recorded for. */
struct subfile *m_last_subfile = NULL;
@@ -17700,7 +16008,6 @@ lnp_state_machine::handle_set_file (file_name_index file)
dwarf2_debug_line_missing_file_complaint ();
else
{
- m_last_subfile = m_cu->get_builder ()->get_current_subfile ();
m_line_has_non_zero_discriminator = m_discriminator != 0;
dwarf2_start_subfile (m_cu, *fe, *m_line_header);
}
@@ -17877,7 +16184,7 @@ lnp_state_machine::record_line (bool end_sequence)
if (!end_sequence && !ignore_this_line)
{
linetable_entry_flags lte_flags = m_flags;
- if (producer_is_codewarrior (m_cu))
+ if (m_cu->producer_is_codewarrior ())
lte_flags |= LEF_IS_STMT;
if (dwarf_record_line_p (m_cu, m_line, m_last_line,
@@ -17889,9 +16196,10 @@ lnp_state_machine::record_line (bool end_sequence)
builder->get_current_subfile (),
m_line, m_address, lte_flags,
m_currently_recording_lines ? m_cu : nullptr);
+
+ m_last_subfile = m_cu->get_builder ()->get_current_subfile ();
+ m_last_line = m_line;
}
- m_last_subfile = m_cu->get_builder ()->get_current_subfile ();
- m_last_line = m_line;
}
}
@@ -18262,7 +16570,7 @@ var_decode_location (struct attribute *attr, struct symbol *sym,
struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->per_objfile->objfile;
- struct comp_unit_head *cu_header = &cu->header;
+ unit_head *cu_header = &cu->header;
/* NOTE drow/2003-01-30: There used to be a comment and some special
code here to turn a symbol with DW_AT_external and a
@@ -18418,13 +16726,15 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
/* Fortran does not have mangling standard and the mangling does differ
between gfortran, iFort etc. */
const char *physname
- = (cu->lang () == language_fortran
+ = ((cu->lang () == language_fortran || cu->lang () == language_ada)
? dwarf2_full_name (name, die, cu)
: dwarf2_physname (name, die, cu));
const char *linkagename = dw2_linkage_name (die, cu);
- if (linkagename == nullptr || cu->lang () == language_ada)
+ if (linkagename == nullptr)
sym->set_linkage_name (physname);
+ else if (cu->lang () == language_ada)
+ sym->set_linkage_name (linkagename);
else
{
if (physname == linkagename)
@@ -18452,33 +16762,36 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
inlined_func ? DW_AT_call_line : DW_AT_decl_line,
cu);
if (attr != nullptr)
- sym->set_line (attr->constant_value (0));
+ sym->set_line (attr->unsigned_constant ().value_or (0));
struct dwarf2_cu *file_cu = cu;
attr = dwarf2_attr (die,
inlined_func ? DW_AT_call_file : DW_AT_decl_file,
&file_cu);
- if (attr != nullptr && attr->is_nonnegative ())
+ if (attr != nullptr)
{
- file_name_index file_index
- = (file_name_index) attr->as_nonnegative ();
- struct file_entry *fe;
-
- if (file_cu->line_header == nullptr)
+ std::optional<ULONGEST> index_cst = attr->unsigned_constant ();
+ if (index_cst.has_value ())
{
- file_and_directory fnd (nullptr, nullptr);
- handle_DW_AT_stmt_list (file_cu->dies, file_cu, fnd, {}, false);
- }
+ file_name_index file_index = (file_name_index) *index_cst;
+ struct file_entry *fe;
- if (file_cu->line_header != nullptr)
- fe = file_cu->line_header->file_name_at (file_index);
- else
- fe = NULL;
+ if (file_cu->line_header == nullptr)
+ {
+ file_and_directory fnd (nullptr, nullptr);
+ handle_DW_AT_stmt_list (file_cu->dies, file_cu, fnd, {}, false);
+ }
- if (fe == NULL)
- complaint (_("file index out of range"));
- else
- sym->set_symtab (fe->symtab);
+ if (file_cu->line_header != nullptr)
+ fe = file_cu->line_header->file_name_at (file_index);
+ else
+ fe = NULL;
+
+ if (fe == NULL)
+ complaint (_("file index out of range"));
+ else
+ sym->set_symtab (fe->symtab);
+ }
}
switch (die->tag)
@@ -18536,11 +16849,11 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
list_to_add = cu->list_in_scope;
}
- if (is_ada_import_or_export (cu, name, linkagename))
+ if (is_ada_import_or_export (cu, physname, linkagename))
{
/* This is either a Pragma Import or Export. They can
be distinguished by the declaration flag. */
- sym->set_linkage_name (name);
+ sym->set_linkage_name (physname);
if (die_is_declaration (die, cu))
{
/* For Import, create a symbol using the source
@@ -18553,7 +16866,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
/* For Export, create a symbol using the source
name, then create a second symbol that refers
back to it. */
- add_ada_export_symbol (sym, linkagename, name, cu,
+ add_ada_export_symbol (sym, linkagename, physname, cu,
list_to_add);
}
}
@@ -18653,12 +16966,12 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
list_to_add = cu->list_in_scope;
if (list_to_add != nullptr
- && is_ada_import_or_export (cu, name, linkagename))
+ && is_ada_import_or_export (cu, physname, linkagename))
{
/* This is a Pragma Export. A Pragma Import won't
be seen here, because it will not have a location
and so will be handled below. */
- add_ada_export_symbol (sym, name, linkagename, cu,
+ add_ada_export_symbol (sym, physname, linkagename, cu,
list_to_add);
}
}
@@ -18682,12 +16995,12 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
if (!suppress_add)
list_to_add = cu->list_in_scope;
}
- else if (is_ada_import_or_export (cu, name, linkagename))
+ else if (is_ada_import_or_export (cu, physname, linkagename))
{
/* This is a Pragma Import. A Pragma Export won't
be seen here, because it will have a location and
so will be handled above. */
- sym->set_linkage_name (name);
+ sym->set_linkage_name (physname);
list_to_add
= ((cu->list_in_scope
== cu->get_builder ()->get_file_symbols ())
@@ -18758,17 +17071,11 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
case DW_TAG_union_type:
case DW_TAG_set_type:
case DW_TAG_enumeration_type:
- case DW_TAG_namelist:
- if (die->tag == DW_TAG_namelist)
- {
- sym->set_aclass_index (LOC_STATIC);
- sym->set_domain (VAR_DOMAIN);
- }
- else if (cu->lang () == language_c
- || cu->lang () == language_cplus
- || cu->lang () == language_objc
- || cu->lang () == language_opencl
- || cu->lang () == language_minimal)
+ if (cu->lang () == language_c
+ || cu->lang () == language_cplus
+ || cu->lang () == language_objc
+ || cu->lang () == language_opencl
+ || cu->lang () == language_minimal)
{
/* These languages have a tag namespace. Note that
there's a special hack for C++ in the matching code,
@@ -18862,6 +17169,11 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
sym->set_domain (COMMON_BLOCK_DOMAIN);
list_to_add = cu->list_in_scope;
break;
+ case DW_TAG_namelist:
+ sym->set_aclass_index (LOC_STATIC);
+ sym->set_domain (VAR_DOMAIN);
+ list_to_add = cu->list_in_scope;
+ break;
default:
/* Not a tag we recognize. Hopefully we aren't processing
trash data, but since we must specifically ignore things
@@ -18891,40 +17203,6 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
return (sym);
}
-/* Given an attr with a DW_FORM_dataN value in host byte order,
- zero-extend it as appropriate for the symbol's type. The DWARF
- standard (v4) is not entirely clear about the meaning of using
- DW_FORM_dataN for a constant with a signed type, where the type is
- wider than the data. The conclusion of a discussion on the DWARF
- list was that this is unspecified. We choose to always zero-extend
- because that is the interpretation long in use by GCC. */
-
-static gdb_byte *
-dwarf2_const_value_data (const struct attribute *attr, struct obstack *obstack,
- struct dwarf2_cu *cu, LONGEST *value, int bits)
-{
- struct objfile *objfile = cu->per_objfile->objfile;
- enum bfd_endian byte_order = bfd_big_endian (objfile->obfd.get ()) ?
- BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE;
- LONGEST l = attr->constant_value (0);
-
- if (bits < sizeof (*value) * 8)
- {
- l &= ((LONGEST) 1 << bits) - 1;
- *value = l;
- }
- else if (bits == sizeof (*value) * 8)
- *value = l;
- else
- {
- gdb_byte *bytes = (gdb_byte *) obstack_alloc (obstack, bits / 8);
- store_unsigned_integer (bytes, bits / 8, byte_order, l);
- return bytes;
- }
-
- return NULL;
-}
-
/* Read a constant value from an attribute. Either set *VALUE, or if
the value does not fit in *VALUE, set *BYTES - either already
allocated on the objfile obstack, or newly allocated on OBSTACK,
@@ -18940,7 +17218,7 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
struct objfile *objfile = per_objfile->objfile;
- struct comp_unit_head *cu_header = &cu->header;
+ unit_head *cu_header = &cu->header;
struct dwarf_block *blk;
enum bfd_endian byte_order = (bfd_big_endian (objfile->obfd.get ()) ?
BFD_ENDIAN_BIG : BFD_ENDIAN_LITTLE);
@@ -18964,7 +17242,7 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
/* Symbols of this form are reasonably rare, so we just
piggyback on the existing location code rather than writing
a new implementation of symbol_computed_ops. */
- *baton = XOBNEW (obstack, struct dwarf2_locexpr_baton);
+ *baton = OBSTACK_ZALLOC (obstack, struct dwarf2_locexpr_baton);
(*baton)->per_objfile = per_objfile;
(*baton)->per_cu = cu->per_cu;
gdb_assert ((*baton)->per_cu);
@@ -18984,6 +17262,7 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
case DW_FORM_strx:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_strp_alt:
+ case DW_FORM_strp_sup:
/* The string is already allocated on the objfile obstack, point
directly to it. */
*bytes = (const gdb_byte *) attr->as_string ();
@@ -19007,25 +17286,13 @@ dwarf2_const_value_attr (const struct attribute *attr, struct type *type,
converted to host endianness, so we just need to sign- or
zero-extend it as appropriate. */
case DW_FORM_data1:
- *bytes = dwarf2_const_value_data (attr, obstack, cu, value, 8);
- break;
case DW_FORM_data2:
- *bytes = dwarf2_const_value_data (attr, obstack, cu, value, 16);
- break;
case DW_FORM_data4:
- *bytes = dwarf2_const_value_data (attr, obstack, cu, value, 32);
- break;
case DW_FORM_data8:
- *bytes = dwarf2_const_value_data (attr, obstack, cu, value, 64);
- break;
-
case DW_FORM_sdata:
case DW_FORM_implicit_const:
- *value = attr->as_signed ();
- break;
-
case DW_FORM_udata:
- *value = attr->as_unsigned ();
+ *value = attr->confused_constant ().value_or (0);
break;
default:
@@ -19190,13 +17457,12 @@ lookup_die_type (struct die_info *die, const struct attribute *attr,
/* First see if we have it cached. */
- if (attr->form == DW_FORM_GNU_ref_alt)
+ if (attr->form_is_alt ())
{
- struct dwarf2_per_cu_data *per_cu;
sect_offset sect_off = attr->get_ref_die_offset ();
+ dwarf2_per_cu *per_cu
+ = dwarf2_find_containing_comp_unit (sect_off, 1, per_objfile->per_bfd);
- per_cu = dwarf2_find_containing_comp_unit (sect_off, 1,
- per_objfile->per_bfd);
this_type = get_die_type_at_offset (sect_off, per_cu, per_objfile);
}
else if (attr->form_is_ref ())
@@ -19364,7 +17630,6 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu)
{
struct die_info *spec_die;
struct dwarf2_cu *spec_cu;
- struct die_info *child;
struct objfile *objfile = cu->per_objfile->objfile;
spec_cu = cu;
@@ -19375,9 +17640,7 @@ guess_full_die_structure_name (struct die_info *die, struct dwarf2_cu *cu)
cu = spec_cu;
}
- for (child = die->child;
- child != NULL;
- child = child->sibling)
+ for (die_info *child : die->children ())
{
if (child->tag == DW_TAG_subprogram)
{
@@ -19481,7 +17744,8 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
if (cu->lang () != language_cplus
&& cu->lang () != language_fortran
&& cu->lang () != language_d
- && cu->lang () != language_rust)
+ && cu->lang () != language_rust
+ && cu->lang () != language_ada)
return "";
retval = anonymous_struct_prefix (die, cu);
@@ -19614,6 +17878,11 @@ determine_prefix (struct die_info *die, struct dwarf2_cu *cu)
else if (die->tag == DW_TAG_entry_point)
return determine_prefix (parent, cu);
}
+ else if (cu->lang () == language_ada
+ && (die->tag == DW_TAG_subprogram
+ || die->tag == DW_TAG_inlined_subroutine
+ || die->tag == DW_TAG_lexical_block))
+ return dwarf2_full_name (nullptr, parent, cu);
return "";
case DW_TAG_enumeration_type:
parent_type = read_type_die (parent, cu);
@@ -19665,6 +17934,8 @@ typename_concat (const char *prefix, const char *suffix, int physname,
lead = "__";
sep = "_MOD_";
}
+ else if (cu->lang () == language_ada)
+ sep = "__";
else
sep = "::";
@@ -19695,18 +17966,19 @@ unnamed_template_tag_name (die_info *die, dwarf2_cu *cu)
arrive at our entry. */
size_t nth_unnamed = 0;
- die_info *child = die->parent->child;
- while (child != die)
- {
- gdb_assert (child != nullptr);
- if (child->tag == DW_TAG_template_type_param
- || child->tag == DW_TAG_template_value_param)
- {
- if (dwarf2_attr (child, DW_AT_name, cu) == nullptr)
- ++nth_unnamed;
- }
- child = child->sibling;
- }
+ for (die_info *child : die->parent->children ())
+ {
+ if (child == die)
+ break;
+
+ gdb_assert (child != nullptr);
+ if (child->tag == DW_TAG_template_type_param
+ || child->tag == DW_TAG_template_value_param)
+ {
+ if (dwarf2_attr (child, DW_AT_name, cu) == nullptr)
+ ++nth_unnamed;
+ }
+ }
const std::string name_str = "<unnamed" + std::to_string (nth_unnamed) + ">";
return cu->per_objfile->objfile->intern (name_str.c_str ());
@@ -19760,7 +18032,8 @@ dwarf2_name (struct die_info *die, struct dwarf2_cu *cu)
&& die->tag != DW_TAG_namelist
&& die->tag != DW_TAG_union_type
&& die->tag != DW_TAG_template_type_param
- && die->tag != DW_TAG_template_value_param)
+ && die->tag != DW_TAG_template_value_param
+ && die->tag != DW_TAG_module)
return NULL;
switch (die->tag)
@@ -19898,51 +18171,50 @@ static struct die_info *
follow_die_offset (sect_offset sect_off, int offset_in_dwz,
struct dwarf2_cu **ref_cu)
{
- struct dwarf2_cu *target_cu, *cu = *ref_cu;
- dwarf2_per_objfile *per_objfile = cu->per_objfile;
+ dwarf2_cu *source_cu = *ref_cu;
+ dwarf2_cu *target_cu = source_cu;
+ dwarf2_per_objfile *per_objfile = source_cu->per_objfile;
- gdb_assert (cu->per_cu != NULL);
-
- target_cu = cu;
+ gdb_assert (source_cu->per_cu != nullptr);
+ gdb_assert (source_cu->dies != nullptr);
dwarf_read_debug_printf_v ("source CU offset: %s, target offset: %s, "
"source CU contains target offset: %d",
- sect_offset_str (cu->per_cu->sect_off),
+ sect_offset_str (source_cu->per_cu->sect_off),
sect_offset_str (sect_off),
- cu->header.offset_in_cu_p (sect_off));
+ source_cu->header.offset_in_unit_p (sect_off));
- if (cu->per_cu->is_debug_types)
+ if (source_cu->per_cu->is_debug_types)
{
/* .debug_types CUs cannot reference anything outside their CU.
If they need to, they have to reference a signatured type via
DW_FORM_ref_sig8. */
- if (!cu->header.offset_in_cu_p (sect_off))
+ if (!source_cu->header.offset_in_unit_p (sect_off))
return NULL;
}
- else if (offset_in_dwz != cu->per_cu->is_dwz
- || !cu->header.offset_in_cu_p (sect_off))
+ else if (offset_in_dwz != source_cu->per_cu->is_dwz
+ || !source_cu->header.offset_in_unit_p (sect_off))
{
- struct dwarf2_per_cu_data *per_cu;
-
- per_cu = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
- per_objfile->per_bfd);
+ dwarf2_per_cu *target_per_cu
+ = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
+ per_objfile->per_bfd);
dwarf_read_debug_printf_v ("target CU offset: %s, "
"target CU DIEs loaded: %d",
- sect_offset_str (per_cu->sect_off),
- per_objfile->get_cu (per_cu) != nullptr);
+ sect_offset_str (target_per_cu->sect_off),
+ per_objfile->get_cu (target_per_cu) != nullptr);
/* If necessary, add it to the queue and load its DIEs.
Even if maybe_queue_comp_unit doesn't require us to load the CU's DIEs,
it doesn't mean they are currently loaded. Since we require them
to be loaded, we must check for ourselves. */
- if (maybe_queue_comp_unit (cu, per_cu, per_objfile, cu->lang ())
- || per_objfile->get_cu (per_cu) == nullptr)
- load_full_comp_unit (per_cu, per_objfile, per_objfile->get_cu (per_cu),
- false, cu->lang ());
+ if (maybe_queue_comp_unit (source_cu, target_per_cu, per_objfile)
+ || per_objfile->get_cu (target_per_cu) == nullptr)
+ load_full_comp_unit (target_per_cu, per_objfile, false,
+ source_cu->lang ());
- target_cu = per_objfile->get_cu (per_cu);
+ target_cu = per_objfile->get_cu (target_per_cu);
if (target_cu == nullptr)
error (_(DWARF_ERROR_PREFIX
"cannot follow reference to DIE at %s"
@@ -19950,17 +18222,10 @@ follow_die_offset (sect_offset sect_off, int offset_in_dwz,
sect_offset_str (sect_off),
objfile_name (per_objfile->objfile));
}
- else if (cu->dies == NULL)
- {
- /* We're loading full DIEs during partial symbol reading. */
- load_full_comp_unit (cu->per_cu, per_objfile, cu, false,
- language_minimal);
- }
*ref_cu = target_cu;
- auto it = target_cu->die_hash.find (sect_off);
- return it != target_cu->die_hash.end () ? *it : nullptr;
+ return target_cu->find_die (sect_off);
}
/* Follow reference attribute ATTR of SRC_DIE.
@@ -19975,15 +18240,14 @@ follow_die_ref (struct die_info *src_die, const struct attribute *attr,
struct dwarf2_cu *cu = *ref_cu;
struct die_info *die;
- if (attr->form != DW_FORM_GNU_ref_alt && src_die->sect_off == sect_off)
+ if (!attr->form_is_alt () && src_die->sect_off == sect_off)
{
/* Self-reference, we're done. */
return src_die;
}
die = follow_die_offset (sect_off,
- (attr->form == DW_FORM_GNU_ref_alt
- || cu->per_cu->is_dwz),
+ attr->form_is_alt () || cu->per_cu->is_dwz,
ref_cu);
if (!die)
error (_(DWARF_ERROR_PREFIX
@@ -19997,8 +18261,7 @@ follow_die_ref (struct die_info *src_die, const struct attribute *attr,
/* See read.h. */
struct dwarf2_locexpr_baton
-dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
- dwarf2_per_cu_data *per_cu,
+dwarf2_fetch_die_loc_sect_off (sect_offset sect_off, dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile,
gdb::function_view<CORE_ADDR ()> get_frame_pc,
bool resolve_abstract_p)
@@ -20103,8 +18366,7 @@ dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
/* See read.h. */
struct dwarf2_locexpr_baton
-dwarf2_fetch_die_loc_cu_off (cu_offset offset_in_cu,
- dwarf2_per_cu_data *per_cu,
+dwarf2_fetch_die_loc_cu_off (cu_offset offset_in_cu, dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile,
gdb::function_view<CORE_ADDR ()> get_frame_pc)
{
@@ -20137,7 +18399,7 @@ write_constant_as_bytes (struct obstack *obstack,
const gdb_byte *
dwarf2_fetch_constant_bytes (sect_offset sect_off,
- dwarf2_per_cu_data *per_cu,
+ dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile,
obstack *obstack,
LONGEST *len)
@@ -20196,6 +18458,7 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
case DW_FORM_strx:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_strp_alt:
+ case DW_FORM_strp_sup:
/* The string is already allocated on the objfile obstack, point
directly to it. */
{
@@ -20221,47 +18484,19 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
symbol's value "represented as it would be on the target
architecture." By the time we get here, it's already been
converted to host endianness, so we just need to sign- or
- zero-extend it as appropriate. */
+ zero-extend it as appropriate.
+
+ Both GCC and LLVM agree that these are always signed, though. */
case DW_FORM_data1:
- type = die_type (die, cu);
- result = dwarf2_const_value_data (attr, obstack, cu, &value, 8);
- if (result == NULL)
- result = write_constant_as_bytes (obstack, byte_order,
- type, value, len);
- break;
case DW_FORM_data2:
- type = die_type (die, cu);
- result = dwarf2_const_value_data (attr, obstack, cu, &value, 16);
- if (result == NULL)
- result = write_constant_as_bytes (obstack, byte_order,
- type, value, len);
- break;
case DW_FORM_data4:
- type = die_type (die, cu);
- result = dwarf2_const_value_data (attr, obstack, cu, &value, 32);
- if (result == NULL)
- result = write_constant_as_bytes (obstack, byte_order,
- type, value, len);
- break;
case DW_FORM_data8:
- type = die_type (die, cu);
- result = dwarf2_const_value_data (attr, obstack, cu, &value, 64);
- if (result == NULL)
- result = write_constant_as_bytes (obstack, byte_order,
- type, value, len);
- break;
-
case DW_FORM_sdata:
case DW_FORM_implicit_const:
- type = die_type (die, cu);
- result = write_constant_as_bytes (obstack, byte_order,
- type, attr->as_signed (), len);
- break;
-
case DW_FORM_udata:
type = die_type (die, cu);
- result = write_constant_as_bytes (obstack, byte_order,
- type, attr->as_unsigned (), len);
+ value = attr->confused_constant ().value_or (0);
+ result = write_constant_as_bytes (obstack, byte_order, type, value, len);
break;
default:
@@ -20276,8 +18511,7 @@ dwarf2_fetch_constant_bytes (sect_offset sect_off,
/* See read.h. */
struct type *
-dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
- dwarf2_per_cu_data *per_cu,
+dwarf2_fetch_die_type_sect_off (sect_offset sect_off, dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile,
const char **var_name)
{
@@ -20302,8 +18536,7 @@ dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
/* See read.h. */
struct type *
-dwarf2_get_die_type (cu_offset die_offset,
- dwarf2_per_cu_data *per_cu,
+dwarf2_get_die_type (cu_offset die_offset, dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile)
{
sect_offset die_offset_sect = per_cu->sect_off + to_underlying (die_offset);
@@ -20332,8 +18565,7 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
Even if maybe_queue_comp_unit doesn't require us to load the CU's DIEs,
it doesn't mean they are currently loaded. Since we require them
to be loaded, we must check for ourselves. */
- if (maybe_queue_comp_unit (*ref_cu, sig_type, per_objfile,
- language_minimal)
+ if (maybe_queue_comp_unit (*ref_cu, sig_type, per_objfile)
|| per_objfile->get_cu (sig_type) == nullptr)
read_signatured_type (sig_type, per_objfile);
@@ -20341,8 +18573,8 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
gdb_assert (sig_cu != NULL);
gdb_assert (to_underlying (sig_type->type_offset_in_section) != 0);
- if (auto die_it = sig_cu->die_hash.find (sig_type->type_offset_in_section);
- die_it != sig_cu->die_hash.end ())
+ if (die_info *die = sig_cu->find_die (sig_type->type_offset_in_section);
+ die != nullptr)
{
/* For .gdb_index version 7 keep track of included TUs.
http://sourceware.org/bugzilla/show_bug.cgi?id=15021. */
@@ -20351,7 +18583,7 @@ follow_die_sig_1 (struct die_info *src_die, struct signatured_type *sig_type,
(*ref_cu)->per_cu->imported_symtabs.push_back (sig_cu->per_cu);
*ref_cu = sig_cu;
- return *die_it;
+ return die;
}
return NULL;
@@ -20498,8 +18730,7 @@ get_DW_AT_signature_type (struct die_info *die, const struct attribute *attr,
/* Load the DIEs associated with type unit PER_CU into memory. */
static void
-load_full_type_unit (dwarf2_per_cu_data *per_cu,
- dwarf2_per_objfile *per_objfile)
+load_full_type_unit (dwarf2_per_cu *per_cu, dwarf2_per_objfile *per_objfile)
{
struct signatured_type *sig_type;
@@ -20526,64 +18757,24 @@ read_signatured_type (signatured_type *sig_type,
gdb_assert (sig_type->is_debug_types);
gdb_assert (per_objfile->get_cu (sig_type) == nullptr);
- cutu_reader reader (sig_type, per_objfile, nullptr, nullptr, false);
+ cutu_reader reader (*sig_type, *per_objfile, nullptr, nullptr, false,
+ language_minimal);
- if (!reader.dummy_p)
+ if (!reader.is_dummy ())
{
- struct dwarf2_cu *cu = reader.cu;
- const gdb_byte *info_ptr = reader.info_ptr;
-
- gdb_assert (cu->die_hash.empty ());
- cu->die_hash.reserve (cu->header.get_length_without_initial () / 12);
-
- if (reader.comp_unit_die->has_children)
- reader.comp_unit_die->child
- = read_die_and_siblings (&reader, info_ptr, &info_ptr,
- reader.comp_unit_die);
- cu->dies = reader.comp_unit_die;
- /* comp_unit_die is not stored in die_hash, no need. */
+ reader.read_all_dies ();
- /* We try not to read any attributes in this function, because
- not all CUs needed for references have been loaded yet, and
- symbol table processing isn't initialized. But we have to
- set the CU language, or we won't be able to build types
- correctly. Similarly, if we do not read the producer, we can
- not apply producer-specific interpretation. */
- prepare_one_comp_unit (cu, cu->dies, language_minimal);
-
- reader.keep ();
+ /* Save this dwarf2_cu in the per_objfile. The per_objfile owns it
+ now. */
+ per_objfile->set_cu (sig_type, reader.release_cu ());
}
sig_type->tu_read = 1;
}
-/* Decode simple location descriptions.
-
- Given a pointer to a DWARF block that defines a location, compute
- the location. Returns true if the expression was computable by
- this function, false otherwise. On a true return, *RESULT is set.
-
- Note that this function does not implement a full DWARF expression
- evaluator. Instead, it is used for a few limited purposes:
-
- - Getting the address of a symbol that has a constant address. For
- example, if a symbol has a location like "DW_OP_addr", the address
- can be extracted.
-
- - Getting the offset of a virtual function in its vtable. There
- are two forms of this, one of which involves DW_OP_deref -- so this
- function handles derefs in a peculiar way to make this 'work'.
- (Probably this area should be rewritten.)
-
- - Getting the offset of a field, when it is constant.
-
- Opcodes that cannot be part of a constant expression, for example
- those involving registers, simply result in a return of
- 'false'.
-
- This function may emit a complaint. */
+/* See read.h. */
-static bool
+bool
decode_locdesc (struct dwarf_block *blk, struct dwarf2_cu *cu,
CORE_ADDR *result)
{
@@ -20849,9 +19040,19 @@ dwarf_decode_macros (struct dwarf2_cu *cu, unsigned int offset,
str_offsets_base = cu->str_offsets_base;
}
- dwarf_decode_macros (per_objfile, builder, section, lh,
- offset_size, offset, str_section, str_offsets_section,
- str_offsets_base, section_is_gnu, cu);
+ try
+ {
+ dwarf_decode_macros (per_objfile, builder, section, lh, offset_size,
+ offset, str_section, str_offsets_section,
+ str_offsets_base, section_is_gnu, cu);
+ }
+ catch (const gdb_exception_error &error)
+ {
+ /* Print the error and carry on with no (or partial) macro
+ information. */
+ exception_fprintf (gdb_stderr, error, _("While reading section %s: "),
+ section->get_name ());
+ }
}
/* Return the .debug_loc section to use for CU.
@@ -20924,6 +19125,7 @@ fill_in_loclist_baton (struct dwarf2_cu *cu,
else
baton->base_address = {};
baton->from_dwo = cu->dwo_unit != NULL;
+ baton->dwarf_version = cu->header.version;
}
static void
@@ -20938,7 +19140,7 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
/* .debug_loc{,.dwo} may not exist at all, or the offset may be outside
the section. If so, fall through to the complaint in the
other branch. */
- && attr->as_unsigned () < section->get_size (objfile))
+ && attr->as_unsigned () < section->size)
{
struct dwarf2_loclist_baton *baton;
@@ -20959,7 +19161,8 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
{
struct dwarf2_locexpr_baton *baton;
- baton = XOBNEW (&objfile->objfile_obstack, struct dwarf2_locexpr_baton);
+ baton = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct dwarf2_locexpr_baton);
baton->per_objfile = per_objfile;
baton->per_cu = cu->per_cu;
gdb_assert (baton->per_cu);
@@ -20991,16 +19194,15 @@ dwarf2_symbol_mark_computed (const struct attribute *attr, struct symbol *sym,
/* See read.h. */
-const comp_unit_head *
-dwarf2_per_cu_data::get_header () const
+const unit_head *
+dwarf2_per_cu::get_header () const
{
if (!m_header_read_in)
{
const gdb_byte *info_ptr
= this->section->buffer + to_underlying (this->sect_off);
- read_comp_unit_head (&m_header, info_ptr, this->section,
- rcuh_kind::COMPILE);
+ read_unit_head (&m_header, info_ptr, this->section, ruh_kind::COMPILE);
m_header_read_in = true;
}
@@ -21011,7 +19213,7 @@ dwarf2_per_cu_data::get_header () const
/* See read.h. */
int
-dwarf2_per_cu_data::addr_size () const
+dwarf2_per_cu::addr_size () const
{
return this->get_header ()->addr_size;
}
@@ -21019,7 +19221,7 @@ dwarf2_per_cu_data::addr_size () const
/* See read.h. */
int
-dwarf2_per_cu_data::offset_size () const
+dwarf2_per_cu::offset_size () const
{
return this->get_header ()->offset_size;
}
@@ -21027,9 +19229,9 @@ dwarf2_per_cu_data::offset_size () const
/* See read.h. */
int
-dwarf2_per_cu_data::ref_addr_size () const
+dwarf2_per_cu::ref_addr_size () const
{
- const comp_unit_head *header = this->get_header ();
+ const unit_head *header = this->get_header ();
if (header->version == 2)
return header->addr_size;
@@ -21040,8 +19242,7 @@ dwarf2_per_cu_data::ref_addr_size () const
/* See read.h. */
void
-dwarf2_per_cu_data::set_lang (enum language lang,
- dwarf_source_language dw_lang)
+dwarf2_per_cu::set_lang (enum language lang, dwarf_source_language dw_lang)
{
if (unit_type () == DW_UT_partial)
return;
@@ -21050,7 +19251,9 @@ dwarf2_per_cu_data::set_lang (enum language lang,
packed<language, LANGUAGE_BYTES> new_value = lang;
packed<language, LANGUAGE_BYTES> old_value = m_lang.exchange (new_value);
/* If already set, verify that it's the same value. */
- gdb_assert (old_value == language_unknown || old_value == lang);
+ gdb_assert (old_value == language_unknown
+ || old_value == language_minimal
+ || old_value == lang);
packed<dwarf_source_language, 2> new_dw = dw_lang;
packed<dwarf_source_language, 2> old_dw = m_dw_lang.exchange (new_dw);
@@ -21060,19 +19263,15 @@ dwarf2_per_cu_data::set_lang (enum language lang,
/* See read.h. */
void
-dwarf2_per_cu_data::ensure_lang (dwarf2_per_objfile *per_objfile)
+dwarf2_per_cu::ensure_lang (dwarf2_per_objfile *per_objfile)
{
if (lang (false) != language_unknown)
return;
- cutu_reader reader (this, per_objfile);
- if (reader.dummy_p)
- {
- set_lang (language_minimal, (dwarf_source_language)0);
- return;
- }
-
- prepare_one_comp_unit (reader.cu, reader.comp_unit_die, language_minimal);
+ /* Constructing this object will set the language as a side
+ effect. */
+ cutu_reader reader (*this, *per_objfile, nullptr, per_objfile->get_cu (this),
+ true, language_minimal, nullptr);
}
/* A helper function for dwarf2_find_containing_comp_unit that returns
@@ -21085,7 +19284,7 @@ static int
dwarf2_find_containing_comp_unit
(sect_offset sect_off,
unsigned int offset_in_dwz,
- const std::vector<dwarf2_per_cu_data_up> &all_units)
+ const std::vector<dwarf2_per_cu_up> &all_units)
{
int low, high;
@@ -21093,10 +19292,9 @@ dwarf2_find_containing_comp_unit
high = all_units.size () - 1;
while (high > low)
{
- struct dwarf2_per_cu_data *mid_cu;
int mid = low + (high - low) / 2;
+ dwarf2_per_cu *mid_cu = all_units[mid].get ();
- mid_cu = all_units[mid].get ();
if (mid_cu->is_dwz > offset_in_dwz
|| (mid_cu->is_dwz == offset_in_dwz
&& mid_cu->sect_off + mid_cu->length () > sect_off))
@@ -21108,17 +19306,16 @@ dwarf2_find_containing_comp_unit
return low;
}
-/* Locate the .debug_info compilation unit from CU's objfile which contains
- the DIE at OFFSET. Raises an error on failure. */
+/* See read.h. */
-static struct dwarf2_per_cu_data *
+dwarf2_per_cu *
dwarf2_find_containing_comp_unit (sect_offset sect_off,
unsigned int offset_in_dwz,
dwarf2_per_bfd *per_bfd)
{
int low = dwarf2_find_containing_comp_unit
(sect_off, offset_in_dwz, per_bfd->all_units);
- dwarf2_per_cu_data *this_cu = per_bfd->all_units[low].get ();
+ dwarf2_per_cu *this_cu = per_bfd->all_units[low].get ();
if (this_cu->is_dwz != offset_in_dwz || this_cu->sect_off > sect_off)
{
@@ -21126,7 +19323,7 @@ dwarf2_find_containing_comp_unit (sect_offset sect_off,
error (_(DWARF_ERROR_PREFIX
"could not find CU containing offset %s [in module %s]"),
sect_offset_str (sect_off),
- bfd_get_filename (per_bfd->obfd));
+ per_bfd->filename ());
gdb_assert (per_bfd->all_units[low-1]->sect_off
<= sect_off);
@@ -21150,26 +19347,35 @@ namespace find_containing_comp_unit {
static void
run_test ()
{
- dwarf2_per_cu_data_up one (new dwarf2_per_cu_data);
- dwarf2_per_cu_data *one_ptr = one.get ();
- dwarf2_per_cu_data_up two (new dwarf2_per_cu_data);
- dwarf2_per_cu_data *two_ptr = two.get ();
- dwarf2_per_cu_data_up three (new dwarf2_per_cu_data);
- dwarf2_per_cu_data *three_ptr = three.get ();
- dwarf2_per_cu_data_up four (new dwarf2_per_cu_data);
- dwarf2_per_cu_data *four_ptr = four.get ();
-
- one->set_length (5);
- two->sect_off = sect_offset (one->length ());
- two->set_length (7);
-
- three->set_length (5);
- three->is_dwz = 1;
- four->sect_off = sect_offset (three->length ());
- four->set_length (7);
- four->is_dwz = 1;
-
- std::vector<dwarf2_per_cu_data_up> units;
+ char dummy_per_bfd;
+ char dummy_section;
+
+ const auto create_dummy_per_cu = [&] (sect_offset sect_off,
+ unsigned int length,
+ bool is_dwz)
+ {
+ auto per_bfd = reinterpret_cast<dwarf2_per_bfd *> (&dummy_per_bfd);
+ auto section = reinterpret_cast<dwarf2_section_info *> (&dummy_section);
+
+ return dwarf2_per_cu_up (new dwarf2_per_cu (per_bfd, section, sect_off,
+ length, is_dwz));
+ };
+
+ /* Units in the main file. */
+ dwarf2_per_cu_up one = create_dummy_per_cu (sect_offset (0), 5, false);
+ dwarf2_per_cu *one_ptr = one.get ();
+ dwarf2_per_cu_up two
+ = create_dummy_per_cu (sect_offset (one->length ()), 7, false);
+ dwarf2_per_cu *two_ptr = two.get ();
+
+ /* Units in the supplementary (dwz) file. */
+ dwarf2_per_cu_up three = create_dummy_per_cu (sect_offset (0), 5, true);
+ dwarf2_per_cu *three_ptr = three.get ();
+ dwarf2_per_cu_up four
+ = create_dummy_per_cu (sect_offset (three->length ()), 7, true);
+ dwarf2_per_cu *four_ptr = four.get ();
+
+ std::vector<dwarf2_per_cu_up> units;
units.push_back (std::move (one));
units.push_back (std::move (two));
units.push_back (std::move (three));
@@ -21197,22 +19403,33 @@ run_test ()
#endif /* GDB_SELF_TEST */
-/* Initialize basic fields of dwarf_cu CU according to DIE COMP_UNIT_DIE. */
+/* Initialize basic fields of dwarf_cu CU according to DIE
+ COMP_UNIT_DIE. If COMP_UNIT_DIE is NULL, the CU is assumed to be a
+ CU one with no contents; in this case default values are used for
+ the fields. */
-static void
-prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die,
- enum language pretend_language)
+void
+cutu_reader::prepare_one_comp_unit (struct dwarf2_cu *cu,
+ enum language pretend_language)
{
struct attribute *attr;
- cu->producer = dwarf2_string_attr (comp_unit_die, DW_AT_producer, cu);
+ if (m_top_level_die == nullptr)
+ {
+ cu->set_producer (nullptr);
+ cu->language_defn = language_def (pretend_language);
+ cu->per_cu->set_unit_type (DW_UT_compile);
+ cu->per_cu->set_lang (pretend_language, (dwarf_source_language) 0);
+ return;
+ }
+
+ cu->set_producer (dwarf2_string_attr (m_top_level_die, DW_AT_producer, cu));
/* Set the language we're debugging. */
- attr = dwarf2_attr (comp_unit_die, DW_AT_language, cu);
+ attr = dwarf2_attr (m_top_level_die, DW_AT_language, cu);
enum language lang;
dwarf_source_language dw_lang = (dwarf_source_language) 0;
- if (cu->producer != nullptr
- && strstr (cu->producer, "IBM XL C for OpenCL") != NULL)
+ if (cu->producer_is_xlc_opencl ())
{
/* The XLCL doesn't generate DW_LANG_OpenCL because this
attribute is not standardised yet. As a workaround for the
@@ -21221,8 +19438,7 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die,
lang = language_opencl;
dw_lang = DW_LANG_OpenCL;
}
- else if (cu->producer != nullptr
- && strstr (cu->producer, "GNU Go ") != NULL)
+ else if (cu->producer_is_ggo ())
{
/* Similar hack for Go. */
lang = language_go;
@@ -21230,8 +19446,15 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die,
}
else if (attr != nullptr)
{
- lang = dwarf_lang_to_enum_language (attr->constant_value (0));
- dw_lang = (dwarf_source_language) attr->constant_value (0);
+ std::optional<ULONGEST> lang_val = attr->unsigned_constant ();
+ if (lang_val.has_value ())
+ {
+ lang = dwarf_lang_to_enum_language (*lang_val);
+ if (lang_val <= DW_LANG_hi_user)
+ dw_lang = (dwarf_source_language) *lang_val;
+ }
+ else
+ lang = language_minimal;
}
else
lang = pretend_language;
@@ -21239,15 +19462,14 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die,
cu->language_defn = language_def (lang);
/* Initialize the lto_artificial field. */
- attr = dwarf2_attr (comp_unit_die, DW_AT_name, cu);
+ attr = dwarf2_attr (m_top_level_die, DW_AT_name, cu);
if (attr != nullptr
- && cu->producer != nullptr
+ && cu->producer_is_gcc ()
&& attr->as_string () != nullptr
- && strcmp (attr->as_string (), "<artificial>") == 0
- && producer_is_gcc (cu->producer, nullptr, nullptr))
+ && strcmp (attr->as_string (), "<artificial>") == 0)
cu->per_cu->lto_artificial = true;
- switch (comp_unit_die->tag)
+ switch (m_top_level_die->tag)
{
case DW_TAG_compile_unit:
cu->per_cu->set_unit_type (DW_UT_compile);
@@ -21259,9 +19481,8 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die,
cu->per_cu->set_unit_type (DW_UT_type);
break;
default:
- error (_(DWARF_ERROR_PREFIX
- "unexpected tag '%s' at offset %s"),
- dwarf_tag_name (comp_unit_die->tag),
+ error (_(DWARF_ERROR_PREFIX "unexpected tag '%s' at offset %s"),
+ dwarf_tag_name (m_top_level_die->tag),
sect_offset_str (cu->per_cu->sect_off));
}
@@ -21271,7 +19492,7 @@ prepare_one_comp_unit (struct dwarf2_cu *cu, struct die_info *comp_unit_die,
/* See read.h. */
dwarf2_cu *
-dwarf2_per_objfile::get_cu (dwarf2_per_cu_data *per_cu)
+dwarf2_per_objfile::get_cu (dwarf2_per_cu *per_cu)
{
auto it = m_dwarf2_cus.find (per_cu);
if (it == m_dwarf2_cus.end ())
@@ -21283,8 +19504,7 @@ dwarf2_per_objfile::get_cu (dwarf2_per_cu_data *per_cu)
/* See read.h. */
void
-dwarf2_per_objfile::set_cu (dwarf2_per_cu_data *per_cu,
- std::unique_ptr<dwarf2_cu> cu)
+dwarf2_per_objfile::set_cu (dwarf2_per_cu *per_cu, dwarf2_cu_up cu)
{
gdb_assert (this->get_cu (per_cu) == nullptr);
@@ -21339,7 +19559,7 @@ dwarf2_per_objfile::age_comp_units ()
/* See read.h. */
void
-dwarf2_per_objfile::remove_cu (dwarf2_per_cu_data *per_cu)
+dwarf2_per_objfile::remove_cu (dwarf2_per_cu *per_cu)
{
auto it = m_dwarf2_cus.find (per_cu);
if (it == m_dwarf2_cus.end ())
@@ -21445,8 +19665,7 @@ set_die_type (struct die_info *die, struct type *type, struct dwarf2_cu *cu,
or return NULL if the die does not have a saved type. */
static struct type *
-get_die_type_at_offset (sect_offset sect_off,
- dwarf2_per_cu_data *per_cu,
+get_die_type_at_offset (sect_offset sect_off, dwarf2_per_cu *per_cu,
dwarf2_per_objfile *per_objfile)
{
auto it = per_objfile->die_type_hash.find ({per_cu, sect_off});
@@ -21475,9 +19694,7 @@ show_check_physname (struct ui_file *file, int from_tty,
value);
}
-void _initialize_dwarf2_read ();
-void
-_initialize_dwarf2_read ()
+INIT_GDB_FILE (dwarf2_read)
{
add_setshow_prefix_cmd ("dwarf", class_maintenance,
_("\