/* DWARF 2 debugging format support for GDB.
- Copyright (C) 1994-2021 Free Software Foundation, Inc.
+ Copyright (C) 1994-2022 Free Software Foundation, Inc.
Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
Inc. with support from Florida State University (under contract
#include "dwarf2/read.h"
#include "dwarf2/abbrev.h"
#include "dwarf2/attribute.h"
-#include "dwarf2/comp-unit.h"
+#include "dwarf2/comp-unit-head.h"
+#include "dwarf2/cu.h"
#include "dwarf2/index-cache.h"
#include "dwarf2/index-common.h"
#include "dwarf2/leb.h"
#include "gdbtypes.h"
#include "objfiles.h"
#include "dwarf2.h"
-#include "buildsym.h"
#include "demangle.h"
#include "gdb-demangle.h"
#include "filenames.h" /* for DOSish file names */
unsigned int offset_entry_count;
};
-/* Type used for delaying computation of method physnames.
- See comments for compute_delayed_physnames. */
-struct delayed_method_info
-{
- /* The type to which the method is attached, i.e., its parent class. */
- struct type *type;
-
- /* The index of the method in the type's function fieldlists. */
- int fnfield_index;
-
- /* The index of the method in the fieldlist. */
- int index;
-
- /* The name of the DIE. */
- const char *name;
-
- /* The DIE associated with this method. */
- struct die_info *die;
-};
-
-/* Internal state when decoding a particular compilation unit. */
-struct dwarf2_cu
-{
- explicit dwarf2_cu (dwarf2_per_cu_data *per_cu,
- dwarf2_per_objfile *per_objfile);
-
- DISABLE_COPY_AND_ASSIGN (dwarf2_cu);
-
- /* TU version of handle_DW_AT_stmt_list for read_type_unit_scope.
- Create the set of symtabs used by this TU, or if this TU is sharing
- symtabs with another TU and the symtabs have already been created
- then restore those symtabs in the line header.
- We don't need the pc/line-number mapping for type units. */
- void setup_type_unit_groups (struct die_info *die);
-
- /* Start a symtab for DWARF. NAME, COMP_DIR, LOW_PC are passed to the
- buildsym_compunit constructor. */
- struct compunit_symtab *start_symtab (const char *name,
- const char *comp_dir,
- CORE_ADDR low_pc);
-
- /* Reset the builder. */
- void reset_builder () { m_builder.reset (); }
-
- /* Return a type that is a generic pointer type, the size of which
- matches the address size given in the compilation unit header for
- this CU. */
- struct type *addr_type () const;
-
- /* Find an integer type the same size as the address size given in
- the compilation unit header for this CU. UNSIGNED_P controls if
- the integer is unsigned or not. */
- struct type *addr_sized_int_type (bool unsigned_p) const;
-
- /* The header of the compilation unit. */
- struct comp_unit_head header {};
-
- /* Base address of this compilation unit. */
- gdb::optional<CORE_ADDR> base_address;
-
- /* The language we are debugging. */
- enum language language = language_unknown;
- const struct language_defn *language_defn = nullptr;
-
- const char *producer = nullptr;
-
-private:
- /* The symtab builder for this CU. This is only non-NULL when full
- symbols are being read. */
- std::unique_ptr<buildsym_compunit> m_builder;
-
-public:
- /* The generic symbol table building routines have separate lists for
- file scope symbols and all all other scopes (local scopes). So
- we need to select the right one to pass to add_symbol_to_list().
- We do it by keeping a pointer to the correct list in list_in_scope.
-
- FIXME: The original dwarf code just treated the file scope as the
- first local scope, and all other local scopes as nested local
- scopes, and worked fine. Check to see if we really need to
- distinguish these in buildsym.c. */
- struct pending **list_in_scope = nullptr;
-
- /* Hash table holding all the loaded partial DIEs
- with partial_die->offset.SECT_OFF as hash. */
- htab_t partial_dies = nullptr;
-
- /* Storage for things with the same lifetime as this read-in compilation
- unit, including partial DIEs. */
- auto_obstack comp_unit_obstack;
-
- /* Backlink to our per_cu entry. */
- struct dwarf2_per_cu_data *per_cu;
-
- /* The dwarf2_per_objfile that owns this. */
- dwarf2_per_objfile *per_objfile;
-
- /* How many compilation units ago was this CU last referenced? */
- int last_used = 0;
-
- /* A hash table of DIE cu_offset for following references with
- die_info->offset.sect_off as hash. */
- htab_t die_hash = nullptr;
-
- /* Full DIEs if read in. */
- struct die_info *dies = nullptr;
-
- /* A set of pointers to dwarf2_per_cu_data objects for compilation
- units referenced by this one. Only set during full symbol processing;
- partial symbol tables do not have dependencies. */
- htab_t dependencies = nullptr;
-
- /* Header data from the line table, during full symbol processing. */
- struct line_header *line_header = nullptr;
- /* Non-NULL if LINE_HEADER is owned by this DWARF_CU. Otherwise,
- it's owned by dwarf2_per_bfd::line_header_hash. If non-NULL,
- this is the DW_TAG_compile_unit die for this CU. We'll hold on
- to the line header as long as this DIE is being processed. See
- process_die_scope. */
- die_info *line_header_die_owner = nullptr;
-
- /* A list of methods which need to have physnames computed
- after all type information has been read. */
- std::vector<delayed_method_info> method_list;
-
- /* To be copied to symtab->call_site_htab. */
- htab_t call_site_htab = nullptr;
-
- /* Non-NULL if this CU came from a DWO file.
- There is an invariant here that is important to remember:
- Except for attributes copied from the top level DIE in the "main"
- (or "stub") file in preparation for reading the DWO file
- (e.g., DW_AT_addr_base), we KISS: there is only *one* CU.
- Either there isn't a DWO file (in which case this is NULL and the point
- is moot), or there is and either we're not going to read it (in which
- case this is NULL) or there is and we are reading it (in which case this
- is non-NULL). */
- struct dwo_unit *dwo_unit = nullptr;
-
- /* The DW_AT_addr_base (DW_AT_GNU_addr_base) attribute if present.
- Note this value comes from the Fission stub CU/TU's DIE. */
- gdb::optional<ULONGEST> addr_base;
-
- /* The DW_AT_GNU_ranges_base attribute, if present.
-
- This is only relevant in the context of pre-DWARF 5 split units. In this
- context, there is a .debug_ranges section in the linked executable,
- containing all the ranges data for all the compilation units. Each
- skeleton/stub unit has (if needed) a DW_AT_GNU_ranges_base attribute that
- indicates the base of its contribution to that section. The DW_AT_ranges
- attributes in the split-unit are of the form DW_FORM_sec_offset and point
- into the .debug_ranges section of the linked file. However, they are not
- "true" DW_FORM_sec_offset, because they are relative to the base of their
- compilation unit's contribution, rather than relative to the beginning of
- the section. The DW_AT_GNU_ranges_base value must be added to it to make
- it relative to the beginning of the section.
-
- Note that the value is zero when we are not in a pre-DWARF 5 split-unit
- case, so this value can be added without needing to know whether we are in
- this case or not.
-
- N.B. If a DW_AT_ranges attribute is found on the DW_TAG_compile_unit in the
- skeleton/stub, it must not have the base added, as it already points to the
- right place. And since the DW_TAG_compile_unit DIE in the split-unit can't
- have a DW_AT_ranges attribute, we can use the
-
- die->tag != DW_AT_compile_unit
-
- to determine whether the base should be added or not. */
- ULONGEST gnu_ranges_base = 0;
-
- /* The DW_AT_rnglists_base attribute, if present.
-
- This is used when processing attributes of form DW_FORM_rnglistx in
- non-split units. Attributes of this form found in a split unit don't
- use it, as split-unit files have their own non-shared .debug_rnglists.dwo
- section. */
- ULONGEST rnglists_base = 0;
-
- /* The DW_AT_loclists_base attribute if present. */
- ULONGEST loclist_base = 0;
-
- /* When reading debug info generated by older versions of rustc, we
- have to rewrite some union types to be struct types with a
- variant part. This rewriting must be done after the CU is fully
- read in, because otherwise at the point of rewriting some struct
- type might not have been fully processed. So, we keep a list of
- all such types here and process them after expansion. */
- std::vector<struct type *> rust_unions;
-
- /* The DW_AT_str_offsets_base attribute if present. For DWARF 4 version DWO
- files, the value is implicitly zero. For DWARF 5 version DWO files, the
- value is often implicit and is the size of the header of
- .debug_str_offsets section (8 or 4, depending on the address size). */
- gdb::optional<ULONGEST> str_offsets_base;
-
- /* Mark used when releasing cached dies. */
- bool mark : 1;
-
- /* This CU references .debug_loc. See the symtab->locations_valid field.
- This test is imperfect as there may exist optimized debug code not using
- any location list and still facing inlining issues if handled as
- unoptimized code. For a future better test see GCC PR other/32998. */
- bool has_loclist : 1;
-
- /* These cache the results for producer_is_* fields. CHECKED_PRODUCER is true
- if all the producer_is_* fields are valid. This information is cached
- because profiling CU expansion showed excessive time spent in
- producer_is_gxx_lt_4_6. */
- bool checked_producer : 1;
- bool producer_is_gxx_lt_4_6 : 1;
- bool producer_is_gcc_lt_4_3 : 1;
- bool producer_is_icc : 1;
- bool producer_is_icc_lt_14 : 1;
- bool producer_is_codewarrior : 1;
-
- /* When true, the file that we're processing is known to have
- debugging info for C++ namespaces. GCC 3.3.x did not produce
- this information, but later versions do. */
-
- bool processing_has_namespace_info : 1;
-
- struct partial_die_info *find_partial_die (sect_offset sect_off);
-
- /* If this CU was inherited by another CU (via specification,
- abstract_origin, etc), this is the ancestor CU. */
- dwarf2_cu *ancestor;
-
- /* Get the buildsym_compunit for this CU. */
- buildsym_compunit *get_builder ()
- {
- /* If this CU has a builder associated with it, use that. */
- if (m_builder != nullptr)
- return m_builder.get ();
-
- /* Otherwise, search ancestors for a valid builder. */
- if (ancestor != nullptr)
- return ancestor->get_builder ();
-
- return nullptr;
- }
-};
-
/* A struct that can be used as a hash key for tables based on DW_AT_stmt_list.
This includes type_unit_group and quick_file_names. */
/* Disable assign but still keep copy ctor, which is needed
load_partial_dies. */
partial_die_info& operator=(const partial_die_info& rhs) = delete;
+ partial_die_info (const partial_die_info &) = default;
/* Adjust the partial die before generating a symbol for it. This
function may set the is_external flag or change the DIE's
unsigned int has_type : 1;
unsigned int has_specification : 1;
unsigned int has_pc_info : 1;
+ unsigned int has_range_info : 1;
unsigned int may_be_inlined : 1;
/* This DIE has been marked DW_AT_main_subprogram. */
sect_offset sect_off;
} d {};
- /* If HAS_PC_INFO, the PC range associated with this DIE. */
- CORE_ADDR lowpc = 0;
- CORE_ADDR highpc = 0;
+ union
+ {
+ /* If HAS_PC_INFO, the PC range associated with this DIE. */
+ struct
+ {
+ CORE_ADDR lowpc;
+ CORE_ADDR highpc;
+ };
+ /* If HAS_RANGE_INFO, the ranges offset associated with this DIE. */
+ ULONGEST ranges_offset;
+ };
/* Pointer into the info_buffer (or types_buffer) pointing at the target of
DW_AT_sibling, if any. */
has_type = 0;
has_specification = 0;
has_pc_info = 0;
+ has_range_info = 0;
may_be_inlined = 0;
main_subprogram = 0;
scope_set = 0;
is_dwz = 0;
spec_is_dwz = 0;
canonical_name = 0;
+ /* Don't set these using NSDMI (Non-static data member initialisation),
+ because g++-4.8 will error out. */
+ lowpc = 0;
+ highpc = 0;
}
};
static const char *read_stub_str_index (struct dwarf2_cu *cu,
ULONGEST str_index);
-static void set_cu_language (unsigned int, struct dwarf2_cu *);
-
static struct attribute *dwarf2_attr (struct die_info *, unsigned int,
struct dwarf2_cu *);
static line_header_up dwarf_decode_line_header (sect_offset sect_off,
struct dwarf2_cu *cu);
-static void dwarf_decode_lines (struct line_header *, const char *,
+static void dwarf_decode_lines (struct line_header *,
+ const file_and_directory &,
struct dwarf2_cu *, dwarf2_psymtab *,
CORE_ADDR, int decode_mapping);
static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
(sect_offset sect_off, unsigned int offset_in_dwz,
- dwarf2_per_objfile *per_objfile);
+ dwarf2_per_bfd *per_bfd);
static void prepare_one_comp_unit (struct dwarf2_cu *cu,
struct die_info *comp_unit_die,
static void process_full_type_unit (dwarf2_cu *cu,
enum language pretend_language);
-static void dwarf2_add_dependence (struct dwarf2_cu *,
- struct dwarf2_per_cu_data *);
-
-static void dwarf2_mark (struct dwarf2_cu *);
-
static struct type *get_die_type_at_offset (sect_offset,
dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile);
delete data;
}
-/* The return type of find_file_and_directory. Note, the enclosed
- string pointers are only valid while this object is valid. */
-
-struct file_and_directory
-{
- /* The filename. This is never NULL. */
- const char *name;
+static file_and_directory &find_file_and_directory
+ (struct die_info *die, struct dwarf2_cu *cu);
- /* The compilation directory. NULL if not known. If we needed to
- compute a new string, this points to COMP_DIR_STORAGE, otherwise,
- points directly to the DW_AT_comp_dir string attribute owned by
- the obstack that owns the DIE. */
- const char *comp_dir;
-
- /* If we needed to build a new string for comp_dir, this is what
- owns the storage. */
- std::string comp_dir_storage;
-};
-
-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,
+ gdb::unique_xmalloc_ptr<char> *name_holder);
static htab_up allocate_signatured_type_table ();
static void process_cu_includes (dwarf2_per_objfile *per_objfile);
static void check_producer (struct dwarf2_cu *cu);
-
-static void free_line_header_voidp (void *arg);
\f
/* Various complaints about symbol reading that don't abort the process. */
\f
+/* An iterator for all_comp_units that is based on index. This
+ approach makes it possible to iterate over all_comp_units safely,
+ when some caller in the loop may add new units. */
+
+class all_comp_units_iterator
+{
+public:
+
+ all_comp_units_iterator (dwarf2_per_bfd *per_bfd, bool start)
+ : m_per_bfd (per_bfd),
+ m_index (start ? 0 : per_bfd->all_comp_units.size ())
+ {
+ }
+
+ all_comp_units_iterator &operator++ ()
+ {
+ ++m_index;
+ return *this;
+ }
+
+ dwarf2_per_cu_data *operator* () const
+ {
+ return m_per_bfd->get_cu (m_index);
+ }
+
+ bool operator== (const all_comp_units_iterator &other) const
+ {
+ return m_index == other.m_index;
+ }
+
+
+ bool operator!= (const all_comp_units_iterator &other) const
+ {
+ return m_index != other.m_index;
+ }
+
+private:
+
+ dwarf2_per_bfd *m_per_bfd;
+ size_t m_index;
+};
+
+/* A range adapter for the all_comp_units_iterator. */
+class all_comp_units_range
+{
+public:
+
+ all_comp_units_range (dwarf2_per_bfd *per_bfd)
+ : m_per_bfd (per_bfd)
+ {
+ }
+
+ all_comp_units_iterator begin ()
+ {
+ return all_comp_units_iterator (m_per_bfd, true);
+ }
+
+ all_comp_units_iterator end ()
+ {
+ return all_comp_units_iterator (m_per_bfd, false);
+ }
+
+private:
+
+ dwarf2_per_bfd *m_per_bfd;
+};
+
/* See declaration. */
dwarf2_per_bfd::dwarf2_per_bfd (bfd *obfd, const dwarf2_debug_sections *names,
dwarf2_per_bfd::~dwarf2_per_bfd ()
{
for (auto &per_cu : all_comp_units)
- per_cu->imported_symtabs_free ();
+ {
+ per_cu->imported_symtabs_free ();
+ per_cu->free_cached_file_names ();
+ }
/* Everything else should be on this->obstack. */
}
bool
dwarf2_per_objfile::symtab_set_p (const dwarf2_per_cu_data *per_cu) const
{
- gdb_assert (per_cu->index < this->m_symtabs.size ());
-
- return this->m_symtabs[per_cu->index] != nullptr;
+ if (per_cu->index < this->m_symtabs.size ())
+ return this->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
{
- gdb_assert (per_cu->index < this->m_symtabs.size ());
-
- return this->m_symtabs[per_cu->index];
+ if (per_cu->index < this->m_symtabs.size ())
+ return this->m_symtabs[per_cu->index];
+ return nullptr;
}
/* See read.h. */
dwarf2_per_objfile::set_symtab (const dwarf2_per_cu_data *per_cu,
compunit_symtab *symtab)
{
- gdb_assert (per_cu->index < this->m_symtabs.size ());
+ 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;
}
/* The number of entries in file_names, real_names. */
unsigned int num_file_names;
+ /* The CU directory, as given by DW_AT_comp_dir. May be
+ nullptr. */
+ const char *comp_dir;
+
/* The file names from the line table, after being run through
file_full_name. */
const char **file_names;
expand_symtabs_matching. */
unsigned int mark : 1;
- /* True if we've tried to read the file table and found there isn't one.
- There will be no point in trying to read it again next time. */
- unsigned int no_file_data : 1;
+ /* True if we've tried to read the file table. There will be no
+ point in trying to read it again next time. */
+ bool files_read : 1;
};
/* A subclass of psymbol_functions that arranges to read the DWARF
{
bool has_symbols (struct objfile *objfile) override;
+ bool has_unexpanded_symtabs (struct objfile *objfile) override;
+
struct symtab *find_last_source_symtab (struct objfile *objfile) override;
void forget_cached_source_info (struct objfile *objfile) override;
return eq_stmt_list_entry (&ea->hash, &eb->hash);
}
-/* Delete function for a quick_file_names. */
-
-static void
-delete_file_name_entry (void *e)
-{
- struct quick_file_names *file_data = (struct quick_file_names *) e;
- int i;
-
- for (i = 0; i < file_data->num_file_names; ++i)
- {
- xfree ((void*) file_data->file_names[i]);
- if (file_data->real_names)
- xfree ((void*) file_data->real_names[i]);
- }
-
- /* The space for the struct itself lives on the obstack, so we don't
- free it here. */
-}
-
/* Create a quick_file_names hash table. */
static htab_up
{
return htab_up (htab_create_alloc (nr_initial_entries,
hash_file_name_entry, eq_file_name_entry,
- delete_file_name_entry, xcalloc, xfree));
+ nullptr, xcalloc, xfree));
}
/* Read in CU (dwarf2_cu object) for PER_CU in the context of PER_OBJFILE. This
{
dwarf2_per_cu_data_up result (new dwarf2_per_cu_data);
result->per_bfd = this;
- result->index = m_num_psymtabs++;
+ result->index = all_comp_units.size ();
return result;
}
/* See read.h. */
-std::unique_ptr<signatured_type>
-dwarf2_per_bfd::allocate_signatured_type ()
+signatured_type_up
+dwarf2_per_bfd::allocate_signatured_type (ULONGEST signature)
{
- std::unique_ptr<signatured_type> result (new signatured_type);
+ signatured_type_up result (new signatured_type (signature));
result->per_bfd = this;
- result->index = m_num_psymtabs++;
+ result->index = all_comp_units.size ();
+ result->is_debug_types = true;
tu_stats.nr_tus++;
return result;
}
for (offset_type i = 0; i < elements; i += 3)
{
- std::unique_ptr<signatured_type> sig_type;
+ signatured_type_up sig_type;
ULONGEST signature;
void **slot;
cu_offset type_offset_in_tu;
signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
bytes += 3 * 8;
- sig_type = per_bfd->allocate_signatured_type ();
- sig_type->signature = signature;
+ sig_type = per_bfd->allocate_signatured_type (signature);
sig_type->type_offset_in_tu = type_offset_in_tu;
- sig_type->is_debug_types = 1;
sig_type->section = section;
sig_type->sect_off = sect_off;
sig_type->v.quick
for (uint32_t i = 0; i < map.tu_count; ++i)
{
- std::unique_ptr<signatured_type> sig_type;
+ signatured_type_up sig_type;
void **slot;
sect_offset sect_off
section->buffer + to_underlying (sect_off),
rcuh_kind::TYPE);
- sig_type = per_objfile->per_bfd->allocate_signatured_type ();
- sig_type->signature = cu_header.signature;
+ sig_type = per_objfile->per_bfd->allocate_signatured_type
+ (cu_header.signature);
sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
- sig_type->is_debug_types = 1;
sig_type->section = section;
sig_type->sect_off = sect_off;
sig_type->v.quick
debug_info_offset_to_per_cu;
for (const auto &per_cu : per_bfd->all_comp_units)
{
+ /* A TU will not need aranges, and skipping them here is an easy
+ way of ignoring .debug_types -- and possibly seeing a
+ duplicate section offset -- entirely. */
+ if (per_cu->is_debug_types)
+ continue;
+
const auto insertpair
= debug_info_offset_to_per_cu.emplace (per_cu->sect_off,
per_cu.get ());
/* Must pad to an alignment boundary that is twice the address
size. It is undocumented by the DWARF standard but GCC does
- use it. */
- for (size_t padding = ((-(addr - section->buffer))
- & (2 * address_size - 1));
- padding > 0; padding--)
- if (*addr++ != 0)
- {
- warning (_("Section .debug_aranges in %s entry at offset %s "
- "padding is not zero, ignoring .debug_aranges."),
- objfile_name (objfile),
- plongest (entry_addr - section->buffer));
- return;
- }
+ use it. However, not every compiler does this. We can see
+ whether it has happened by looking at the total length of the
+ contents of the aranges for this CU -- it if isn't a multiple
+ of twice the address size, then we skip any leftover
+ bytes. */
+ addr += (entry_end - addr) % (2 * address_size);
for (;;)
{
++i;
map->constant_pool = buffer.slice (metadata[i]);
+ if (map->constant_pool.empty () && !map->symbol_table.empty ())
+ {
+ /* An empty constant pool implies that all symbol table entries are
+ empty. Make map->symbol_table.empty () == true. */
+ map->symbol_table
+ = offset_view (gdb::array_view<const gdb_byte> (symbol_table,
+ symbol_table));
+ }
+
return 1;
}
gdb_assert (! this_cu->is_debug_types);
+ this_cu->v.quick->files_read = true;
/* Our callers never want to match partial units -- instead they
will match the enclosing full CU. */
if (comp_unit_die->tag == DW_TAG_partial_unit)
- {
- this_cu->v.quick->no_file_data = 1;
- return;
- }
+ return;
lh_cu = this_cu;
slot = NULL;
lh = dwarf_decode_line_header (line_offset, cu);
}
- if (lh == NULL)
- {
- lh_cu->v.quick->no_file_data = 1;
- return;
- }
+
+ file_and_directory &fnd = find_file_and_directory (comp_unit_die, cu);
+
+ int offset = 0;
+ if (!fnd.is_unknown ())
+ ++offset;
+ 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;
- gdb_assert (slot != NULL);
- *slot = qfn;
-
- file_and_directory fnd = find_file_and_directory (comp_unit_die, cu);
+ /* There may not be a DW_AT_stmt_list. */
+ if (slot != nullptr)
+ *slot = qfn;
- int offset = 0;
- if (strcmp (fnd.name, "<unknown>") != 0)
- ++offset;
+ std::vector<const char *> include_names;
+ if (lh != nullptr)
+ {
+ for (const auto &entry : lh->file_names ())
+ {
+ gdb::unique_xmalloc_ptr<char> name_holder;
+ const char *include_name =
+ compute_include_file_name (lh.get (), entry, fnd, &name_holder);
+ if (include_name != nullptr)
+ {
+ include_name = per_objfile->objfile->intern (include_name);
+ include_names.push_back (include_name);
+ }
+ }
+ }
- qfn->num_file_names = offset + lh->file_names_size ();
+ 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);
if (offset != 0)
- qfn->file_names[0] = xstrdup (fnd.name);
- for (int i = 0; i < lh->file_names_size (); ++i)
- qfn->file_names[i + offset] = lh->file_full_name (i + 1,
- fnd.comp_dir).release ();
+ qfn->file_names[0] = xstrdup (fnd.get_name ());
+
+ if (!include_names.empty ())
+ memcpy (&qfn->file_names[offset], include_names.data (),
+ include_names.size () * sizeof (const char *));
+
qfn->real_names = NULL;
lh_cu->v.quick->file_names = qfn;
/* Nor type unit groups. */
gdb_assert (! this_cu->type_unit_group_p ());
- if (this_cu->v.quick->file_names != NULL)
+ if (this_cu->v.quick->files_read)
return this_cu->v.quick->file_names;
- /* If we know there is no line data, no point in looking again. */
- if (this_cu->v.quick->no_file_data)
- return NULL;
cutu_reader reader (this_cu, per_objfile);
if (!reader.dummy_p)
dw2_get_file_names_reader (&reader, reader.comp_unit_die);
- if (this_cu->v.quick->no_file_data)
- return NULL;
return this_cu->v.quick->file_names;
}
qfn->num_file_names, const char *);
if (qfn->real_names[index] == NULL)
- qfn->real_names[index] = gdb_realpath (qfn->file_names[index]).release ();
+ {
+ const char *dirname = nullptr;
+
+ if (!IS_ABSOLUTE_PATH (qfn->file_names[index]))
+ dirname = qfn->comp_dir;
+
+ gdb::unique_xmalloc_ptr<char> fullname;
+ fullname = find_source_or_rewrite (qfn->file_names[index], dirname);
+
+ qfn->real_names[index] = fullname.release ();
+ }
return qfn->real_names[index];
}
return compunit_primary_filetab (cust);
}
-/* Traversal function for dw2_forget_cached_source_info. */
+/* See read.h. */
-static int
-dw2_free_cached_file_names (void **slot, void *info)
+void
+dwarf2_per_cu_data::free_cached_file_names ()
{
- struct quick_file_names *file_data = (struct quick_file_names *) *slot;
+ if (per_bfd == nullptr || !per_bfd->using_index || v.quick == nullptr)
+ return;
- if (file_data->real_names)
+ struct quick_file_names *file_data = v.quick->file_names;
+ if (file_data != nullptr && file_data->real_names != nullptr)
{
- int i;
-
- for (i = 0; i < file_data->num_file_names; ++i)
+ for (int i = 0; i < file_data->num_file_names; ++i)
{
- xfree ((void*) file_data->real_names[i]);
- file_data->real_names[i] = NULL;
+ xfree ((void *) file_data->real_names[i]);
+ file_data->real_names[i] = nullptr;
}
}
-
- return 1;
}
void
{
dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
- htab_traverse_noresize (per_objfile->per_bfd->quick_file_names_table.get (),
- dw2_free_cached_file_names, NULL);
+ for (auto &per_cu : per_objfile->per_bfd->all_comp_units)
+ per_cu->free_cached_file_names ();
}
/* Struct used to manage iterating over all CUs looking for a symbol. */
dw_expand_symtabs_matching_file_matcher (per_objfile, file_matcher);
- if (symbol_matcher == NULL && lookup_name == NULL)
+ /* This invariant is documented in quick-functions.h. */
+ gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);
+ if (lookup_name == nullptr)
{
- for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
+ for (dwarf2_per_cu_data *per_cu
+ : all_comp_units_range (per_objfile->per_bfd))
{
QUIT;
- if (!dw2_expand_symtabs_matching_one (per_cu.get (), per_objfile,
+ if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
file_matcher,
expansion_notify))
return false;
for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
{
- if (per_objfile->symtab_set_p (per_cu.get ()))
+ if (!per_cu->is_debug_types
+ && per_objfile->symtab_set_p (per_cu.get ()))
{
if (per_cu->v.quick->file_names != nullptr)
qfn_cache.insert (per_cu->v.quick->file_names);
}
}
- for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
+ for (dwarf2_per_cu_data *per_cu
+ : all_comp_units_range (per_objfile->per_bfd))
{
/* We only need to look at symtabs not already expanded. */
- if (per_objfile->symtab_set_p (per_cu.get ()))
+ if (per_cu->is_debug_types || per_objfile->symtab_set_p (per_cu))
continue;
- quick_file_names *file_data = dw2_get_file_names (per_cu.get (),
- per_objfile);
+ quick_file_names *file_data = dw2_get_file_names (per_cu, per_objfile);
if (file_data == nullptr
|| qfn_cache.find (file_data) != qfn_cache.end ())
continue;
for (int j = 0; j < file_data->num_file_names; ++j)
{
const char *filename = file_data->file_names[j];
- filenames_cache.seen (filename);
- }
- }
+ const char *key = filename;
+ const char *fullname = nullptr;
- filenames_cache.traverse ([&] (const char *filename)
- {
- gdb::unique_xmalloc_ptr<char> this_real_name;
+ if (need_fullname)
+ {
+ fullname = dw2_get_real_path (per_objfile, file_data, j);
+ key = fullname;
+ }
- if (need_fullname)
- this_real_name = gdb_realpath (filename);
- fun (filename, this_real_name.get ());
- });
+ if (!filenames_cache.seen (key))
+ fun (filename, fullname);
+ }
+ }
}
bool
return true;
}
+/* See quick_symbol_functions::has_unexpanded_symtabs in quick-symbol.h. */
+
+bool
+dwarf2_base_index_functions::has_unexpanded_symtabs (struct objfile *objfile)
+{
+ dwarf2_per_objfile *per_objfile = get_dwarf2_per_objfile (objfile);
+
+ for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
+ {
+ /* Is this already expanded? */
+ if (per_objfile->symtab_set_p (per_cu.get ()))
+ continue;
+
+ /* It has not yet been expanded. */
+ return true;
+ }
+
+ return false;
+}
+
/* DWARF-5 debug_names reader. */
/* DWARF-5 augmentation string for GDB's DW_IDX_GNU_* extension. */
dw_expand_symtabs_matching_file_matcher (per_objfile, file_matcher);
- if (symbol_matcher == NULL && lookup_name == NULL)
+ /* This invariant is documented in quick-functions.h. */
+ gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);
+ if (lookup_name == nullptr)
{
- for (const auto &per_cu : per_objfile->per_bfd->all_comp_units)
+ for (dwarf2_per_cu_data *per_cu
+ : all_comp_units_range (per_objfile->per_bfd))
{
QUIT;
- if (!dw2_expand_symtabs_matching_one (per_cu.get (), per_objfile,
+ if (!dw2_expand_symtabs_matching_one (per_cu, per_objfile,
file_matcher,
expansion_notify))
return false;
if (per_bfd->using_index)
{
dwarf_read_debug_printf ("using_index already set");
- per_objfile->resize_symtabs ();
objfile->qf.push_front (make_dwarf_gdb_index ());
return;
}
create_all_comp_units (per_objfile);
per_bfd->quick_file_names_table
= create_quick_file_names_table (per_bfd->all_comp_units.size ());
- per_objfile->resize_symtabs ();
for (int i = 0; i < per_bfd->all_comp_units.size (); ++i)
{
if (per_bfd->debug_names_table != nullptr)
{
dwarf_read_debug_printf ("re-using shared debug names table");
- per_objfile->resize_symtabs ();
objfile->qf.push_front (make_dwarf_debug_names ());
return;
}
if (per_bfd->index_table != nullptr)
{
dwarf_read_debug_printf ("re-using shared index table");
- per_objfile->resize_symtabs ();
objfile->qf.push_front (make_dwarf_gdb_index ());
return;
}
if (dwarf2_read_debug_names (per_objfile))
{
dwarf_read_debug_printf ("found debug names");
- per_objfile->resize_symtabs ();
objfile->qf.push_front (make_dwarf_debug_names ());
return;
}
get_gdb_index_contents_from_section<dwz_file>))
{
dwarf_read_debug_printf ("found gdb index from file");
- per_objfile->resize_symtabs ();
objfile->qf.push_front (make_dwarf_gdb_index ());
return;
}
{
dwarf_read_debug_printf ("found gdb index from cache");
global_index_cache.hit ();
- per_objfile->resize_symtabs ();
objfile->qf.push_front (make_dwarf_gdb_index ());
return;
}
}
else
psf->set_partial_symtabs (per_bfd->partial_symtabs);
- per_objfile->resize_symtabs ();
return;
}
dwarf2_build_psymtabs_hard (per_objfile);
psymtabs.keep ();
- per_objfile->resize_symtabs ();
-
/* (maybe) store an index in the cache. */
global_index_cache.store (per_objfile);
}
compunit_symtab *get_compunit_symtab (struct objfile *objfile) const override
{
- return nullptr;
+ compunit_symtab *cust = includer ()->get_compunit_symtab (objfile);
+ while (cust != nullptr && cust->user != nullptr)
+ cust = cust->user;
+ return cust;
}
private:
static void
dwarf2_build_include_psymtabs (struct dwarf2_cu *cu,
struct die_info *die,
+ const file_and_directory &fnd,
dwarf2_psymtab *pst)
{
line_header_up lh;
that we pass in the raw text_low here; that is ok because we're
only decoding the line table to make include partial symtabs, and
so the addresses aren't really used. */
- dwarf_decode_lines (lh.get (), pst->dirname, cu, pst,
+ dwarf_decode_lines (lh.get (), fnd, cu, pst,
pst->raw_text_low (), 1);
}
end_ptr = info_ptr + section->size;
while (info_ptr < end_ptr)
{
- std::unique_ptr<signatured_type> sig_type;
+ signatured_type_up sig_type;
struct dwo_unit *dwo_tu;
void **slot;
const gdb_byte *ptr = info_ptr;
== per_objfile->per_bfd->all_comp_units.capacity ())
++per_objfile->per_bfd->tu_stats.nr_all_type_units_reallocs;
- std::unique_ptr<signatured_type> sig_type_holder
- = per_objfile->per_bfd->allocate_signatured_type ();
+ signatured_type_up sig_type_holder
+ = per_objfile->per_bfd->allocate_signatured_type (sig);
signatured_type *sig_type = sig_type_holder.get ();
- per_objfile->resize_symtabs ();
-
per_objfile->per_bfd->all_comp_units.emplace_back
(sig_type_holder.release ());
- sig_type->signature = sig;
- sig_type->is_debug_types = 1;
if (per_objfile->per_bfd->using_index)
{
sig_type->v.quick =
dwarf2_per_objfile *per_objfile = cu->per_objfile;
struct dwo_file *dwo_file;
struct dwo_unit find_dwo_entry, *dwo_entry;
- struct signatured_type find_sig_entry, *sig_entry;
void **slot;
gdb_assert (cu->dwo_unit && per_objfile->per_bfd->using_index);
the TU has an entry in .gdb_index, replace the recorded data from
.gdb_index with this TU. */
- find_sig_entry.signature = sig;
+ signatured_type find_sig_entry (sig);
slot = htab_find_slot (per_objfile->per_bfd->signatured_types.get (),
&find_sig_entry, INSERT);
- sig_entry = (struct signatured_type *) *slot;
+ signatured_type *sig_entry = (struct signatured_type *) *slot;
/* 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
dwarf2_per_objfile *per_objfile = cu->per_objfile;
struct dwp_file *dwp_file = get_dwp_file (per_objfile);
struct dwo_unit *dwo_entry;
- struct signatured_type find_sig_entry, *sig_entry;
void **slot;
gdb_assert (cu->dwo_unit && per_objfile->per_bfd->using_index);
if (per_objfile->per_bfd->signatured_types == NULL)
per_objfile->per_bfd->signatured_types = allocate_signatured_type_table ();
- find_sig_entry.signature = sig;
+ signatured_type find_sig_entry (sig);
slot = htab_find_slot (per_objfile->per_bfd->signatured_types.get (),
&find_sig_entry, INSERT);
- sig_entry = (struct signatured_type *) *slot;
+ signatured_type *sig_entry = (struct signatured_type *) *slot;
/* Have we already tried to read this TU?
Note: sig_entry can be NULL if the skeleton TU was removed (thus it
}
else
{
- struct signatured_type find_entry, *entry;
-
if (per_objfile->per_bfd->signatured_types == NULL)
return NULL;
- find_entry.signature = sig;
- entry = ((struct signatured_type *)
- htab_find (per_objfile->per_bfd->signatured_types.get (),
- &find_entry));
- return entry;
+ signatured_type find_entry (sig);
+ return ((struct signatured_type *)
+ htab_find (per_objfile->per_bfd->signatured_types.get (),
+ &find_entry));
}
}
return htab_up (htab_create_alloc (3,
hash_type_unit_group,
eq_type_unit_group,
- [] (void *arg)
- {
- type_unit_group *grp
- = (type_unit_group *) arg;
- delete grp;
- },
+ htab_delete_entry<type_unit_group>,
xcalloc, xfree));
}
CORE_ADDR best_lowpc = 0, best_highpc = 0;
dwarf2_psymtab *pst;
enum pc_bounds_kind cu_bounds_kind;
- const char *filename;
gdb_assert (! per_cu->is_debug_types);
prepare_one_comp_unit (cu, comp_unit_die, pretend_language);
/* Allocate a new partial symbol table structure. */
- gdb::unique_xmalloc_ptr<char> debug_filename;
static const char artificial[] = "<artificial>";
- filename = dwarf2_string_attr (comp_unit_die, DW_AT_name, cu);
- if (filename == NULL)
- filename = "";
- else if (strcmp (filename, artificial) == 0)
+ file_and_directory &fnd = find_file_and_directory (comp_unit_die, cu);
+ if (strcmp (fnd.get_name (), artificial) == 0)
{
- debug_filename.reset (concat (artificial, "@",
- sect_offset_str (per_cu->sect_off),
- (char *) NULL));
- filename = debug_filename.get ();
+ gdb::unique_xmalloc_ptr<char> debug_filename
+ (concat (artificial, "@",
+ sect_offset_str (per_cu->sect_off),
+ (char *) NULL));
+ fnd.set_name (std::move (debug_filename));
}
- pst = create_partial_symtab (per_cu, per_objfile, filename);
+ pst = create_partial_symtab (per_cu, per_objfile, fnd.get_name ());
/* This must be done before calling dwarf2_build_include_psymtabs. */
pst->dirname = dwarf2_string_attr (comp_unit_die, DW_AT_comp_dir, cu);
/* Get the list of files included in the current compilation unit,
and build a psymtab for each of them. */
- dwarf2_build_include_psymtabs (cu, comp_unit_die, pst);
+ dwarf2_build_include_psymtabs (cu, comp_unit_die, fnd, pst);
dwarf_read_debug_printf ("Psymtab for %s unit @%s: %s - %s"
", %d global, %d static syms",
cutu_reader reader (this_cu, per_objfile, nullptr, nullptr, false);
+ if (reader.comp_unit_die == nullptr)
+ return;
+
switch (reader.comp_unit_die->tag)
{
case DW_TAG_compile_unit:
reader.comp_unit_die,
pretend_language);
- this_cu->lang = reader.cu->language;
-
/* Age out any secondary CUs. */
per_objfile->age_comp_units ();
}
{}
/* This is used when sorting. */
- bool operator< (const tu_abbrev_offset &other)
+ bool operator< (const tu_abbrev_offset &other) const
{
return abbrev_offset < other.abbrev_offset;
}
{
struct dwo_unit *dwo_unit = (struct dwo_unit *) *slot;
dwarf2_per_objfile *per_objfile = (dwarf2_per_objfile *) info;
- struct signatured_type find_entry, *entry;
/* If this TU doesn't exist in the global table, add it and read it in. */
if (per_objfile->per_bfd->signatured_types == NULL)
per_objfile->per_bfd->signatured_types = allocate_signatured_type_table ();
- find_entry.signature = dwo_unit->signature;
+ signatured_type find_entry (dwo_unit->signature);
slot = htab_find_slot (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
/* This does the job that create_all_comp_units would have done for
this TU. */
- entry = add_type_unit (per_objfile, dwo_unit->signature, slot);
+ signatured_type *entry
+ = add_type_unit (per_objfile, dwo_unit->signature, slot);
fill_in_sig_entry_from_dwo_entry (per_objfile, entry, dwo_unit);
*slot = entry;
if (types_htab == nullptr)
types_htab = allocate_signatured_type_table ();
- auto sig_type = per_objfile->per_bfd->allocate_signatured_type ();
+ auto sig_type = per_objfile->per_bfd->allocate_signatured_type
+ (cu_header.signature);
signatured_type *sig_ptr = sig_type.get ();
- sig_type->signature = cu_header.signature;
sig_type->type_offset_in_tu = cu_header.type_cu_offset_in_tu;
this_cu.reset (sig_type.release ());
hex_string (sig_ptr->signature));
*slot = sig_ptr;
}
- this_cu->is_debug_types = (cu_header.unit_type == DW_UT_type);
this_cu->sect_off = sect_off;
this_cu->length = cu_header.length + cu_header.initial_length_size;
this_cu->is_dwz = is_dwz;
case DW_TAG_subprogram:
case DW_TAG_inlined_subroutine:
add_partial_subprogram (pdi, lowpc, highpc, set_addrmap, cu);
- if (cu->language == language_cplus)
+ if (cu->per_cu->lang == language_cplus)
scan_partial_symbols (pdi->die_child, lowpc, highpc,
set_addrmap, cu);
break;
{
add_partial_symbol (pdi, cu);
}
- if ((cu->language == language_rust
- || cu->language == language_cplus) && pdi->has_children)
+ if ((cu->per_cu->lang == language_rust
+ || cu->per_cu->lang == language_cplus)
+ && pdi->has_children)
scan_partial_symbols (pdi->die_child, lowpc, highpc,
set_addrmap, cu);
break;
}
per_cu = dwarf2_find_containing_comp_unit
- (pdi->d.sect_off, pdi->is_dwz, cu->per_objfile);
+ (pdi->d.sect_off, pdi->is_dwz,
+ cu->per_objfile->per_bfd);
/* Go read the partial unit, if needed. */
if (per_cu->v.psymtab == NULL)
process_psymtab_comp_unit (per_cu, cu->per_objfile, true,
- cu->language);
+ cu->per_cu->lang);
+
+ if (pdi->die_parent == nullptr
+ && per_cu->unit_type == DW_UT_compile
+ && per_cu->lang == language_cplus)
+ /* Regard import as hint. See corresponding code in
+ process_imported_unit_die. */
+ break;
cu->per_cu->imported_symtabs_push (per_cu);
}
/* 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. */
- if (cu->language == language_cplus
+ if (cu->per_cu->lang == language_cplus
&& parent->tag == DW_TAG_namespace
&& strcmp (parent->name (cu), "::") == 0
&& grandparent_scope == NULL)
|| parent->tag == DW_TAG_interface_type
|| parent->tag == DW_TAG_union_type
|| parent->tag == DW_TAG_enumeration_type
- || (cu->language == language_fortran
+ || (cu->per_cu->lang == language_fortran
&& parent->tag == DW_TAG_subprogram
&& pdi->tag == DW_TAG_subprogram))
{
partial_symbol psymbol;
memset (&psymbol, 0, sizeof (psymbol));
- psymbol.ginfo.set_language (cu->language, &objfile->objfile_obstack);
+ psymbol.ginfo.set_language (cu->per_cu->lang,
+ &objfile->objfile_obstack);
psymbol.ginfo.set_section_index (-1);
/* The code below indicates that the psymbol should be installed by
addr = (gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + baseaddr)
- baseaddr);
if (pdi->is_external
- || cu->language == language_ada
- || (cu->language == language_fortran
+ || cu->per_cu->lang == language_ada
+ || (cu->per_cu->lang == language_fortran
&& pdi->die_parent != NULL
&& pdi->die_parent->tag == DW_TAG_subprogram))
{
psymbol.ginfo.value.address = addr;
if (pdi->main_subprogram && actual_name != NULL)
- set_objfile_main_name (objfile, actual_name, cu->language);
+ set_objfile_main_name (objfile, actual_name, cu->per_cu->lang);
break;
case DW_TAG_constant:
psymbol.domain = VAR_DOMAIN;
static vs. global. */
psymbol.domain = STRUCT_DOMAIN;
psymbol.aclass = LOC_TYPEDEF;
- where = (cu->language == language_cplus
+ where = (cu->per_cu->lang == language_cplus
? psymbol_placement::GLOBAL
: psymbol_placement::STATIC);
break;
case DW_TAG_enumerator:
psymbol.domain = VAR_DOMAIN;
psymbol.aclass = LOC_CONST;
- where = (cu->language == language_cplus
+ where = (cu->per_cu->lang == language_cplus
? psymbol_placement::GLOBAL
: psymbol_placement::STATIC);
break;
{
if (built_actual_name != nullptr)
actual_name = objfile->intern (actual_name);
- if (pdi->linkage_name == nullptr || cu->language == language_ada)
+ if (pdi->linkage_name == nullptr
+ || cu->per_cu->lang == language_ada)
psymbol.ginfo.set_linkage_name (actual_name);
else
{
scan_partial_symbols (pdi->die_child, lowpc, highpc, set_addrmap, cu);
}
+static int
+dwarf2_ranges_read (unsigned, CORE_ADDR *, CORE_ADDR *, struct dwarf2_cu *,
+ dwarf2_psymtab *, dwarf_tag);
+
/* Read a partial die corresponding to a subprogram or an inlined
subprogram and create a partial symbol for that subprogram.
When the CU language allows it, this routine also defines a partial
}
}
- if (pdi->has_pc_info || (!pdi->is_external && pdi->may_be_inlined))
+ if (pdi->has_range_info
+ && dwarf2_ranges_read (pdi->ranges_offset, &pdi->lowpc, &pdi->highpc,
+ cu,
+ set_addrmap ? cu->per_cu->v.psymtab : nullptr,
+ pdi->tag))
+ {
+ if (pdi->lowpc < *lowpc)
+ *lowpc = pdi->lowpc;
+ if (pdi->highpc > *highpc)
+ *highpc = pdi->highpc;
+ }
+
+ if (pdi->has_pc_info || pdi->has_range_info
+ || (!pdi->is_external && pdi->may_be_inlined))
{
if (!pdi->is_declaration)
/* Ignore subprogram DIEs that do not have a name, they are
if (! pdi->has_children)
return;
- if (cu->language == language_ada || cu->language == language_fortran)
+ if (cu->per_cu->lang == language_ada
+ || cu->per_cu->lang == language_fortran)
{
pdi = pdi->die_child;
while (pdi != NULL)
/* Mark the dependence relation so that we don't flush PER_CU
too early. */
if (dependent_cu != NULL)
- dwarf2_add_dependence (dependent_cu, per_cu);
+ dependent_cu->add_dependence (per_cu);
/* If it's already on the queue, we have nothing to do. */
if (per_cu->queued)
/* Only C++ delays computing physnames. */
if (cu->method_list.empty ())
return;
- gdb_assert (cu->language == language_cplus);
+ gdb_assert (cu->per_cu->lang == language_cplus);
for (const delayed_method_info &mi : cu->method_list)
{
#define RUST_ENUM_PREFIX "RUST$ENCODED$ENUM$"
if (type->num_fields () == 1
- && startswith (TYPE_FIELD_NAME (type, 0), RUST_ENUM_PREFIX))
+ && startswith (type->field (0).name (), RUST_ENUM_PREFIX))
{
- const char *name = TYPE_FIELD_NAME (type, 0) + strlen (RUST_ENUM_PREFIX);
+ const char *name = type->field (0).name () + strlen (RUST_ENUM_PREFIX);
/* Decode the field name to find the offset of the
discriminant. */
name = tail;
if (*name != '$'
|| index >= field_type->num_fields ()
- || (TYPE_FIELD_LOC_KIND (field_type, index)
+ || (field_type->field (index).loc_kind ()
!= FIELD_LOC_KIND_BITPOS))
{
complaint (_("Could not parse Rust enum encoding string \"%s\""
"[in module %s]"),
- TYPE_FIELD_NAME (type, 0),
+ type->field (0).name (),
objfile_name (objfile));
return;
}
++name;
- bit_offset += TYPE_FIELD_BITPOS (field_type, index);
+ bit_offset += field_type->field (index).loc_bitpos ();
field_type = field_type->field (index).type ();
}
/* Put the discriminant at index 0. */
type->field (0).set_type (field_type);
TYPE_FIELD_ARTIFICIAL (type, 0) = 1;
- TYPE_FIELD_NAME (type, 0) = "<<discriminant>>";
- SET_FIELD_BITPOS (type->field (0), bit_offset);
+ type->field (0).set_name ("<<discriminant>>");
+ type->field (0).set_loc_bitpos (bit_offset);
/* The order of fields doesn't really matter, so put the real
field at index 1 and the data-less field at index 2. */
type->field (1) = saved_field;
- TYPE_FIELD_NAME (type, 1)
- = rust_last_path_segment (type->field (1).type ()->name ());
+ type->field (1).set_name
+ (rust_last_path_segment (type->field (1).type ()->name ()));
type->field (1).type ()->set_name
(rust_fully_qualify (&objfile->objfile_obstack, type->name (),
- TYPE_FIELD_NAME (type, 1)));
+ type->field (1).name ()));
const char *dataless_name
= rust_fully_qualify (&objfile->objfile_obstack, type->name (),
type->field (2).set_type (dataless_type);
/* NAME points into the original discriminant name, which
already has the correct lifetime. */
- TYPE_FIELD_NAME (type, 2) = name;
- SET_FIELD_BITPOS (type->field (2), 0);
+ type->field (2).set_name (name);
+ type->field (2).set_loc_bitpos (0);
/* Indicate that this is a variant type. */
static discriminant_range ranges[1] = { { 0, 0 } };
}
/* A union with a single anonymous field is probably an old-style
univariant enum. */
- else if (type->num_fields () == 1 && streq (TYPE_FIELD_NAME (type, 0), ""))
+ else if (type->num_fields () == 1 && streq (type->field (0).name (), ""))
{
/* Smash this type to be a structure type. We have to do this
because the type has already been recorded. */
struct type *field_type = type->field (0).type ();
const char *variant_name
= rust_last_path_segment (field_type->name ());
- TYPE_FIELD_NAME (type, 0) = variant_name;
+ type->field (0).set_name (variant_name);
field_type->set_name
(rust_fully_qualify (&objfile->objfile_obstack,
type->name (), variant_name));
/* Could be data-less variant, so keep going. */
disr_type = nullptr;
}
- else if (strcmp (TYPE_FIELD_NAME (disr_type, 0),
+ else if (strcmp (disr_type->field (0).name (),
"RUST$ENUM$DISR") != 0)
{
/* Not a Rust enum. */
/* Install the discriminant at index 0 in the union. */
type->field (0) = *disr_field;
TYPE_FIELD_ARTIFICIAL (type, 0) = 1;
- TYPE_FIELD_NAME (type, 0) = "<<discriminant>>";
+ type->field (0).set_name ("<<discriminant>>");
/* We need a way to find the correct discriminant given a
variant name. For convenience we build a map here. */
std::unordered_map<std::string, ULONGEST> discriminant_map;
for (int i = 0; i < enum_type->num_fields (); ++i)
{
- if (TYPE_FIELD_LOC_KIND (enum_type, i) == FIELD_LOC_KIND_ENUMVAL)
+ if (enum_type->field (i).loc_kind () == FIELD_LOC_KIND_ENUMVAL)
{
const char *name
- = rust_last_path_segment (TYPE_FIELD_NAME (enum_type, i));
- discriminant_map[name] = TYPE_FIELD_ENUMVAL (enum_type, i);
+ = rust_last_path_segment (enum_type->field (i).name ());
+ discriminant_map[name] = enum_type->field (i).loc_enumval ();
}
}
sub_type->set_num_fields (sub_type->num_fields () - 1);
sub_type->set_fields (sub_type->fields () + 1);
}
- TYPE_FIELD_NAME (type, i) = variant_name;
+ type->field (i).set_name (variant_name);
sub_type->set_name
(rust_fully_qualify (&objfile->objfile_obstack,
type->name (), variant_name));
static void
rust_union_quirks (struct dwarf2_cu *cu)
{
- gdb_assert (cu->language == language_rust);
+ gdb_assert (cu->per_cu->lang == language_rust);
for (type *type_ : cu->rust_unions)
quirk_rust_enum (type_, cu->per_objfile->objfile);
/* We don't need this any more. */
/* Clear the list here in case something was left over. */
cu->method_list.clear ();
- cu->language = pretend_language;
- cu->language_defn = language_def (cu->language);
-
dwarf2_find_base_address (cu->dies, cu);
/* Before we start reading the top-level DIE, ensure it has a valid tag
process_die (cu->dies, cu);
/* For now fudge the Go package. */
- if (cu->language == language_go)
+ if (cu->per_cu->lang == language_go)
fixup_go_packaging (cu);
/* Now that we have processed all the DIEs in the CU, all the types
physnames. */
compute_delayed_physnames (cu);
- if (cu->language == language_rust)
+ if (cu->per_cu->lang == language_rust)
rust_union_quirks (cu);
/* Some compilers don't define a DW_AT_high_pc attribute for the
/* 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. */
- if (!(cu->language == language_c
+ if (!(cu->per_cu->lang == language_c
&& COMPUNIT_FILETABS (cust)->language != language_unknown))
- COMPUNIT_FILETABS (cust)->language = cu->language;
+ COMPUNIT_FILETABS (cust)->language = cu->per_cu->lang;
/* GCC-4.0 has started to support -fvar-tracking. GCC-3.x still can
produce DW_AT_location with location lists but it can be possibly
if (gcc_4_minor >= 5)
cust->epilogue_unwind_valid = 1;
- cust->call_site_htab = cu->call_site_htab;
+ cust->set_call_site_htab (cu->call_site_htab);
}
per_objfile->set_symtab (cu->per_cu, cust);
/* Clear the list here in case something was left over. */
cu->method_list.clear ();
- cu->language = pretend_language;
- cu->language_defn = language_def (cu->language);
-
/* The symbol tables are set up in read_type_unit_scope. */
process_die (cu->dies, cu);
/* For now fudge the Go package. */
- if (cu->language == language_go)
+ if (cu->per_cu->lang == language_go)
fixup_go_packaging (cu);
/* Now that we have processed all the DIEs in the CU, all the types
physnames. */
compute_delayed_physnames (cu);
- if (cu->language == language_rust)
+ if (cu->per_cu->lang == language_rust)
rust_union_quirks (cu);
/* TUs share symbol tables.
compilation is from a C file generated by language preprocessors,
do not set the language if it was already deduced by
start_subfile. */
- if (!(cu->language == language_c
+ if (!(cu->per_cu->lang == language_c
&& COMPUNIT_FILETABS (cust)->language != language_c))
- COMPUNIT_FILETABS (cust)->language = cu->language;
+ COMPUNIT_FILETABS (cust)->language = cu->per_cu->lang;
}
}
else
bool is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
dwarf2_per_objfile *per_objfile = cu->per_objfile;
dwarf2_per_cu_data *per_cu
- = dwarf2_find_containing_comp_unit (sect_off, is_dwz, per_objfile);
+ = dwarf2_find_containing_comp_unit (sect_off, is_dwz,
+ per_objfile->per_bfd);
/* We're importing a C++ compilation unit with tag DW_TAG_compile_unit
into another compilation unit, at root level. Regard this as a hint,
return;
/* If necessary, add it to the queue and load its DIEs. */
- if (maybe_queue_comp_unit (cu, per_cu, per_objfile, cu->language))
+ if (maybe_queue_comp_unit (cu, per_cu, per_objfile,
+ cu->per_cu->lang))
load_full_comp_unit (per_cu, per_objfile, per_objfile->get_cu (per_cu),
- false, cu->language);
+ false, cu->per_cu->lang);
cu->per_cu->imported_symtabs_push (per_cu);
}
break;
case DW_TAG_subprogram:
/* Nested subprograms in Fortran get a prefix. */
- if (cu->language == language_fortran
+ if (cu->per_cu->lang == language_fortran
&& die->parent != NULL
&& die->parent->tag == DW_TAG_subprogram)
cu->processing_has_namespace_info = true;
/* We only need to handle this case for Ada -- in other
languages, it's normal for the compiler to emit a typedef
instead. */
- if (cu->language != language_ada)
+ if (cu->per_cu->lang != language_ada)
break;
/* FALLTHROUGH */
case DW_TAG_base_type:
case DW_TAG_imported_module:
cu->processing_has_namespace_info = true;
if (die->child != NULL && (die->tag == DW_TAG_imported_declaration
- || cu->language != language_fortran))
+ || cu->per_cu->lang != language_fortran))
complaint (_("Tag '%s' has unexpected children"),
dwarf_tag_name (die->tag));
read_import_statement (die, cu);
/* rustc emits invalid values for DW_AT_linkage_name. Ignore these.
See https://github.com/rust-lang/rust/issues/32925. */
- if (cu->language == language_rust && linkage_name != NULL
+ if (cu->per_cu->lang == language_rust && linkage_name != NULL
&& strchr (linkage_name, '{') != NULL)
linkage_name = NULL;
if (name == NULL)
name = dwarf2_name (die, cu);
+ enum language lang = cu->per_cu->lang;
+
/* For Fortran GDB prefers DW_AT_*linkage_name for the physname if present
but otherwise compute it by typename_concat inside GDB.
FIXME: Actually this is not really true, or at least not always true.
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 (cu->language == language_ada
- || (cu->language == 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
/* These are the only languages we know how to qualify names in. */
if (name != NULL
- && (cu->language == language_cplus
- || cu->language == language_fortran || cu->language == language_d
- || cu->language == language_rust))
+ && (lang == language_cplus
+ || lang == language_fortran || lang == language_d
+ || lang == language_rust))
{
if (die_needs_namespace (die, cu))
{
templates; two instantiated function templates are allowed to
differ only by their return types, which we do not add here. */
- if (cu->language == language_cplus && strchr (name, '<') == NULL)
+ if (lang == language_cplus && strchr (name, '<') == NULL)
{
struct attribute *attr;
struct die_info *child;
int first = 1;
- const language_defn *cplus_lang = language_def (cu->language);
die->building_fullname = 1;
if (child->tag == DW_TAG_template_type_param)
{
- cplus_lang->print_type (type, "", &buf, -1, 0,
- &type_print_raw_options);
+ cu->language_defn->print_type (type, "", &buf, -1, 0,
+ &type_print_raw_options);
continue;
}
if (type->has_no_signedness ())
/* GDB prints characters as NUMBER 'CHAR'. If that's
changed, this can use value_print instead. */
- cplus_lang->printchar (value, type, &buf);
+ cu->language_defn->printchar (value, type, &buf);
else
{
struct value_print_options opts;
else if (bytes != NULL)
{
v = allocate_value (type);
- memcpy (value_contents_writeable (v), bytes,
+ memcpy (value_contents_writeable (v).data (), bytes,
TYPE_LENGTH (type));
}
else
information, if PHYSNAME. */
if (physname && die->tag == DW_TAG_subprogram
- && cu->language == language_cplus)
+ && lang == language_cplus)
{
struct type *type = read_type_die (die, cu);
- c_type_print_args (type, &buf, 1, cu->language,
+ c_type_print_args (type, &buf, 1, lang,
&type_print_raw_options);
- if (cu->language == language_cplus)
+ if (lang == language_cplus)
{
/* Assume that an artificial first parameter is
"this", but do not crash if it is not. RealView
const std::string &intermediate_name = buf.string ();
- if (cu->language == language_cplus)
+ if (lang == language_cplus)
canonical_name
= dwarf2_canonicalize_name (intermediate_name.c_str (), cu,
objfile);
if (!die_needs_namespace (die, cu))
return dwarf2_compute_name (name, die, cu, 1);
- if (cu->language != language_rust)
+ if (cu->per_cu->lang != language_rust)
mangled = dw2_linkage_name (die, cu);
/* DW_AT_linkage_name is missing in some cases - depend on what GDB
gdb::unique_xmalloc_ptr<char> demangled;
if (mangled != NULL)
{
-
- if (language_def (cu->language)->store_sym_names_in_linkage_form_p ())
+ if (cu->language_defn->store_sym_names_in_linkage_form_p ())
{
/* Do nothing (do not demangle the symbol name). */
}
to look up their definition from their declaration so
the only disadvantage remains the minimal symbol variant
`long name(params)' does not have the proper inferior type. */
- demangled.reset (gdb_demangle (mangled,
- (DMGL_PARAMS | DMGL_ANSI
- | DMGL_RET_DROP)));
+ demangled = gdb_demangle (mangled, (DMGL_PARAMS | DMGL_ANSI
+ | DMGL_RET_DROP));
}
if (demangled)
canon = demangled.get ();
static struct using_direct **
using_directives (struct dwarf2_cu *cu)
{
- if (cu->language == language_ada
+ if (cu->per_cu->lang == language_ada
&& cu->get_builder ()->outermost_context_p ())
return cu->get_builder ()->get_global_using_directives ();
else
else if (strlen (imported_name_prefix) > 0)
canonical_name = obconcat (&objfile->objfile_obstack,
imported_name_prefix,
- (cu->language == language_d ? "." : "::"),
+ (cu->per_cu->lang == language_d
+ ? "."
+ : "::"),
imported_name, (char *) NULL);
else
canonical_name = imported_name;
- if (die->tag == DW_TAG_imported_module && cu->language == language_fortran)
+ if (die->tag == DW_TAG_imported_module
+ && cu->per_cu->lang == language_fortran)
for (child_die = die->child; child_die && child_die->tag;
child_die = child_die->sibling)
{
return cu->producer_is_gcc_lt_4_3;
}
-static file_and_directory
+static file_and_directory &
find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu)
{
- file_and_directory res;
+ if (cu->per_cu->fnd != nullptr)
+ return *cu->per_cu->fnd;
/* Find the filename. Do not use dwarf2_name here, since the filename
is not a source language identifier. */
- res.name = dwarf2_string_attr (die, DW_AT_name, cu);
- res.comp_dir = dwarf2_string_attr (die, DW_AT_comp_dir, cu);
-
- if (res.comp_dir == NULL
- && producer_is_gcc_lt_4_3 (cu) && res.name != NULL
- && IS_ABSOLUTE_PATH (res.name))
- {
- res.comp_dir_storage = ldirname (res.name);
- if (!res.comp_dir_storage.empty ())
- res.comp_dir = res.comp_dir_storage.c_str ();
- }
- if (res.comp_dir != NULL)
- {
- /* Irix 6.2 native cc prepends <machine>.: to the compilation
- directory, get rid of it. */
- const char *cp = strchr (res.comp_dir, ':');
-
- if (cp && cp != res.comp_dir && cp[-1] == '.' && cp[1] == '/')
- res.comp_dir = cp + 1;
- }
+ file_and_directory res (dwarf2_string_attr (die, DW_AT_name, cu),
+ dwarf2_string_attr (die, DW_AT_comp_dir, cu));
- if (res.name == NULL)
- res.name = "<unknown>";
+ if (res.get_comp_dir () == nullptr
+ && producer_is_gcc_lt_4_3 (cu)
+ && res.get_name () != nullptr
+ && IS_ABSOLUTE_PATH (res.get_name ()))
+ res.set_comp_dir (ldirname (res.get_name ()));
- return res;
+ cu->per_cu->fnd.reset (new file_and_directory (std::move (res)));
+ return *cu->per_cu->fnd;
}
/* Handle DW_AT_stmt_list for a compilation unit.
static void
handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu,
- const char *comp_dir, CORE_ADDR lowpc) /* ARI: editCase function */
+ const file_and_directory &fnd, CORE_ADDR lowpc) /* ARI: editCase function */
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
struct attribute *attr;
per_objfile->line_header_hash
.reset (htab_create_alloc (127, line_header_hash_voidp,
line_header_eq_voidp,
- free_line_header_voidp,
+ htab_delete_entry<line_header>,
xcalloc, xfree));
}
gdb_assert (die->tag != DW_TAG_partial_unit);
}
decode_mapping = (die->tag != DW_TAG_partial_unit);
- dwarf_decode_lines (cu->line_header, comp_dir, cu, NULL, lowpc,
+ dwarf_decode_lines (cu->line_header, fnd, cu, nullptr, lowpc,
decode_mapping);
}
struct die_info *child_die;
CORE_ADDR baseaddr;
- prepare_one_comp_unit (cu, die, cu->language);
+ prepare_one_comp_unit (cu, die, cu->per_cu->lang);
baseaddr = objfile->text_section_offset ();
get_scope_pc_bounds (die, &lowpc, &highpc, cu);
lowpc = highpc;
lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
- file_and_directory fnd = find_file_and_directory (die, cu);
+ file_and_directory &fnd = find_file_and_directory (die, cu);
- /* The XLCL doesn't generate DW_LANG_OpenCL because this attribute is not
- standardised yet. As a workaround for the language detection we fall
- back to the DW_AT_producer string. */
- if (cu->producer && strstr (cu->producer, "IBM XL C for OpenCL") != NULL)
- cu->language = language_opencl;
+ cu->start_symtab (fnd.get_name (), fnd.intern_comp_dir (objfile), lowpc);
- /* Similar hack for Go. */
- if (cu->producer && strstr (cu->producer, "GNU Go ") != NULL)
- set_cu_language (DW_LANG_Go, cu);
-
- cu->start_symtab (fnd.name, fnd.comp_dir, lowpc);
+ gdb_assert (per_objfile->sym_cu == nullptr);
+ scoped_restore restore_sym_cu
+ = make_scoped_restore (&per_objfile->sym_cu, cu);
/* Decode line number information if present. We do this before
processing child DIEs, so that the line header table is available
- for DW_AT_decl_file. */
- handle_DW_AT_stmt_list (die, cu, fnd.comp_dir, lowpc);
+ for DW_AT_decl_file. The PC check is here because, if LOWPC and
+ HIGHPC are both 0x0, then there won't be any interesting code in
+ the CU, but a check later on (in
+ lnp_state_machine::check_line_address) will fail to properly
+ exclude an entry that was removed via --gc-sections. */
+ if (lowpc != highpc)
+ handle_DW_AT_stmt_list (die, cu, fnd, lowpc);
/* Process all dies in compilation unit. */
if (die->child != NULL)
child_die = child_die->sibling;
}
}
+ per_objfile->sym_cu = nullptr;
/* Decode macro information, if present. Dwarf 2 macro information
refers to information in the line number info statement program
static htab_up
allocate_dwo_file_hash_table ()
{
- auto delete_dwo_file = [] (void *item)
- {
- struct dwo_file *dwo_file = (struct dwo_file *) item;
-
- delete dwo_file;
- };
-
return htab_up (htab_create_alloc (41,
hash_dwo_file,
eq_dwo_file,
- delete_dwo_file,
+ htab_delete_entry<dwo_file>,
xcalloc, xfree));
}
gdb::unique_xmalloc_ptr<char> search_path_holder;
if (search_cwd)
{
- if (*debug_file_directory != '\0')
+ if (!debug_file_directory.empty ())
{
search_path_holder.reset (concat (".", dirname_separator_string,
- debug_file_directory,
+ debug_file_directory.c_str (),
(char *) NULL));
search_path = search_path_holder.get ();
}
search_path = ".";
}
else
- search_path = debug_file_directory;
+ search_path = debug_file_directory.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));
/* That didn't work, try debug-file-directory, which, despite its name,
is a list of paths. */
- if (*debug_file_directory == '\0')
+ if (debug_file_directory.empty ())
return NULL;
return try_open_dwop_file (per_objfile, 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 (*debug_file_directory != '\0')
+ if (!debug_file_directory.empty ())
{
/* Don't implicitly search the current directory here.
If the user wants to search "." to handle this case,
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->language))
+ cu->per_cu->lang))
load_full_type_unit (sig_type, cu->per_objfile);
cu->per_cu->imported_symtabs_push (sig_type);
}
if (dwarf2_flag_true_p (die, DW_AT_main_subprogram, cu))
set_objfile_main_name (objfile, newobj->name->linkage_name (),
- cu->language);
+ cu->per_cu->lang);
/* If there is a location expression for DW_AT_frame_base, record
it. */
/* If we have a DW_AT_specification, we might need to import using
directives from the context of the specification DIE. See the
comment in determine_prefix. */
- if (cu->language == language_cplus
+ if (cu->per_cu->lang == language_cplus
&& dwarf2_attr (die, DW_AT_specification, cu))
{
struct dwarf2_cu *spec_cu = cu;
cstk.static_link, lowpc, highpc);
/* For C++, set the block's scope. */
- if ((cu->language == language_cplus
- || cu->language == language_fortran
- || cu->language == language_d
- || cu->language == language_rust)
+ if ((cu->per_cu->lang == language_cplus
+ || cu->per_cu->lang == language_fortran
+ || cu->per_cu->lang == language_d
+ || cu->per_cu->lang == language_rust)
&& cu->processing_has_namespace_info)
block_set_scope (block, determine_prefix (die, cu),
&objfile->objfile_obstack);
struct gdbarch *gdbarch = objfile->arch ();
CORE_ADDR pc, baseaddr;
struct attribute *attr;
- struct call_site *call_site, call_site_local;
void **slot;
int nparams;
struct die_info *child_die;
}
pc = attr->as_address () + baseaddr;
pc = gdbarch_adjust_dwarf2_addr (gdbarch, pc);
+ pc -= baseaddr;
if (cu->call_site_htab == NULL)
- cu->call_site_htab = htab_create_alloc_ex (16, core_addr_hash, core_addr_eq,
- NULL, &objfile->objfile_obstack,
+ cu->call_site_htab = htab_create_alloc_ex (16, call_site::hash,
+ call_site::eq, NULL,
+ &objfile->objfile_obstack,
hashtab_obstack_allocate, NULL);
- call_site_local.pc = pc;
+ struct call_site call_site_local (pc, nullptr, nullptr);
slot = htab_find_slot (cu->call_site_htab, &call_site_local, INSERT);
if (*slot != NULL)
{
nparams++;
}
- call_site
- = ((struct call_site *)
- obstack_alloc (&objfile->objfile_obstack,
- sizeof (*call_site)
- + (sizeof (*call_site->parameter) * (nparams - 1))));
+ struct call_site *call_site
+ = new (XOBNEWVAR (&objfile->objfile_obstack,
+ struct call_site,
+ sizeof (*call_site) + sizeof (call_site->parameter[0]) * nparams))
+ struct call_site (pc, cu->per_cu, per_objfile);
*slot = call_site;
- memset (call_site, 0, sizeof (*call_site) - sizeof (*call_site->parameter));
- call_site->pc = pc;
+
+ /* We never call the destructor of call_site, so we must ensure it is
+ trivially destructible. */
+ gdb_static_assert(std::is_trivially_destructible<struct call_site>::value);
if (dwarf2_flag_true_p (die, DW_AT_call_tail_call, cu)
|| dwarf2_flag_true_p (die, DW_AT_GNU_tail_call, cu))
/* This was a pre-DWARF-5 GNU extension alias for DW_AT_call_origin. */
attr = dwarf2_attr (die, DW_AT_abstract_origin, cu);
}
- SET_FIELD_DWARF_BLOCK (call_site->target, NULL);
+
+ call_site->target.set_loc_dwarf_block (nullptr);
if (!attr || (attr->form_is_block () && attr->as_block ()->size == 0))
/* Keep NULL DWARF_BLOCK. */;
else if (attr->form_is_block ())
dlbaton->per_objfile = per_objfile;
dlbaton->per_cu = cu->per_cu;
- SET_FIELD_DWARF_BLOCK (call_site->target, dlbaton);
+ call_site->target.set_loc_dwarf_block (dlbaton);
}
else if (attr->form_is_ref ())
{
"physname, for referencing DIE %s [in module %s]"),
sect_offset_str (die->sect_off), objfile_name (objfile));
else
- SET_FIELD_PHYSNAME (call_site->target, target_physname);
+ call_site->target.set_loc_physname (target_physname);
}
else
{
sect_offset_str (die->sect_off), objfile_name (objfile));
else
{
- lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
- SET_FIELD_PHYSADDR (call_site->target, lowpc);
+ lowpc = (gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr)
+ - baseaddr);
+ call_site->target.set_loc_physaddr (lowpc);
}
}
}
"block nor reference, for DIE %s [in module %s]"),
sect_offset_str (die->sect_off), objfile_name (objfile));
- call_site->per_cu = cu->per_cu;
- call_site->per_objfile = per_objfile;
-
for (child_die = die->child;
child_die && child_die->tag;
child_die = child_die->sibling)
{
struct rust_vtable_symbol *storage = NULL;
- if (cu->language == language_rust)
+ if (cu->per_cu->lang == language_rust)
{
struct type *containing_type = rust_containing_type (die, cu);
/* Base address selection entry. */
gdb::optional<CORE_ADDR> base;
const gdb_byte *buffer;
- CORE_ADDR baseaddr;
bool overflow = false;
ULONGEST addr_index;
struct dwarf2_section_info *rnglists_section;
}
buffer = rnglists_section->buffer + offset;
- baseaddr = objfile->text_section_offset ();
-
while (1)
{
/* Initialize it due to a false compiler warning. */
/* A not-uncommon case of bad debug info.
Don't pollute the addrmap with bad data. */
- if (range_beginning + baseaddr == 0
+ if (range_beginning == 0
&& !per_objfile->per_bfd->has_section_at_zero)
{
complaint (_(".debug_rnglists entry has start address of zero"
gdb::optional<CORE_ADDR> base;
unsigned int dummy;
const gdb_byte *buffer;
- CORE_ADDR baseaddr;
if (cu_header->version >= 5)
return dwarf2_rnglists_process (offset, cu, tag, callback);
}
buffer = per_objfile->per_bfd->ranges.buffer + offset;
- baseaddr = objfile->text_section_offset ();
-
while (1)
{
CORE_ADDR range_beginning, range_end;
/* A not-uncommon case of bad debug info.
Don't pollute the addrmap with bad data. */
- if (range_beginning + baseaddr == 0
+ if (range_beginning == 0
&& !per_objfile->per_bfd->has_section_at_zero)
{
complaint (_(".debug_ranges entry has start address of zero"
/* If the language does not allow nested subprograms (either inside
subprograms or lexical blocks), we're done. */
- if (cu->language != language_ada)
+ if (cu->per_cu->lang != language_ada)
return;
/* Check all the children of the given DIE. If it contains nested
{
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))
{
}
}
-/* Look for DW_AT_data_member_location. 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. */
+/* 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_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
- LONGEST *offset)
+handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
+ LONGEST *offset)
{
struct attribute *attr;
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 and store the results in FIELD. */
+/* Look for DW_AT_data_member_location or DW_AT_data_bit_offset and
+ store the results in FIELD. */
static void
-handle_data_member_location (struct die_info *die, struct dwarf2_cu *cu,
- struct field *field)
+handle_member_location (struct die_info *die, struct dwarf2_cu *cu,
+ struct field *field)
{
struct attribute *attr;
if (attr->form_is_constant ())
{
LONGEST offset = attr->constant_value (0);
- SET_FIELD_BITPOS (*field, offset * bits_per_byte);
+
+ /* Work around this GCC 11 bug, where it would erroneously use -1
+ data member locations, instead of 0:
+
+ Negative DW_AT_data_member_location
+ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101378
+ */
+ 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);
}
else if (attr->form_is_section_offset ())
dwarf2_complex_location_expr_complaint ();
bool handled;
CORE_ADDR offset = decode_locdesc (attr->as_block (), cu, &handled);
if (handled)
- SET_FIELD_BITPOS (*field, offset * bits_per_byte);
+ field->set_loc_bitpos (offset * bits_per_byte);
else
{
dwarf2_per_objfile *per_objfile = cu->per_objfile;
dlbaton->per_objfile = per_objfile;
dlbaton->per_cu = cu->per_cu;
- SET_FIELD_DWARF_BLOCK (*field, dlbaton);
+ field->set_loc_dwarf_block (dlbaton);
}
}
else
dwarf2_complex_location_expr_complaint ();
}
+ else
+ {
+ attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
+ if (attr != nullptr)
+ field->set_loc_bitpos (attr->constant_value (0));
+ }
}
/* Add an aggregate field to the field list. */
/* Get type of field. */
fp->set_type (die_type (die, cu));
- SET_FIELD_BITPOS (*fp, 0);
+ fp->set_loc_bitpos (0);
/* Get bit size of field (zero if none). */
attr = dwarf2_attr (die, DW_AT_bit_size, cu);
}
/* Get bit offset of field. */
- handle_data_member_location (die, cu, fp);
+ handle_member_location (die, cu, fp);
attr = dwarf2_attr (die, DW_AT_bit_offset, cu);
if (attr != nullptr && attr->form_is_constant ())
{
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. */
- SET_FIELD_BITPOS (*fp, (FIELD_BITPOS (*fp)
- + attr->constant_value (0)));
+ fp->set_loc_bitpos (fp->loc_bitpos () + attr->constant_value (0));
}
else
{
bit field. */
anonymous_size = TYPE_LENGTH (fp->type ());
}
- SET_FIELD_BITPOS (*fp,
- (FIELD_BITPOS (*fp)
- + anonymous_size * bits_per_byte
- - bit_offset - FIELD_BITSIZE (*fp)));
+ fp->set_loc_bitpos (fp->loc_bitpos ()
+ + anonymous_size * bits_per_byte
+ - bit_offset - FIELD_BITSIZE (*fp));
}
}
- attr = dwarf2_attr (die, DW_AT_data_bit_offset, cu);
- if (attr != NULL)
- SET_FIELD_BITPOS (*fp, (FIELD_BITPOS (*fp)
- + attr->constant_value (0)));
/* Get name of field. */
fieldname = dwarf2_name (die, cu);
/* The name is already allocated along with this objfile, so we don't
need to duplicate it for the type. */
- fp->name = fieldname;
+ fp->set_name (fieldname);
/* Change accessibility for artificial fields (e.g. virtual table
pointer or virtual base class pointer) to private. */
/* The name is already allocated along with this objfile, so we don't
need to duplicate it for the type. */
- SET_FIELD_PHYSNAME (*fp, physname ? physname : "");
+ fp->set_loc_physname (physname ? physname : "");
fp->set_type (die_type (die, cu));
- FIELD_NAME (*fp) = fieldname;
+ fp->set_name (fieldname);
}
else if (die->tag == DW_TAG_inheritance)
{
/* C++ base class field. */
- handle_data_member_location (die, cu, fp);
+ handle_member_location (die, cu, fp);
FIELD_BITSIZE (*fp) = 0;
fp->set_type (die_type (die, cu));
- FIELD_NAME (*fp) = fp->type ()->name ();
+ fp->set_name (fp->type ()->name ());
}
else
gdb_assert_not_reached ("missing case in dwarf2_add_field");
offset_map[fip->fields[i].offset] = i;
struct objfile *objfile = cu->per_objfile->objfile;
- gdb::array_view<variant_part> parts
+ gdb::array_view<const variant_part> parts
= create_variant_parts (&objfile->objfile_obstack, offset_map, fip,
fip->variant_parts);
type->set_fields
((struct field *) TYPE_ZALLOC (type, sizeof (struct field) * nfields));
- if (fip->non_public_fields && cu->language != language_ada)
+ if (fip->non_public_fields && cu->per_cu->lang != language_ada)
{
ALLOCATE_CPLUS_STRUCT_TYPE (type);
/* If the type has baseclasses, allocate and clear a bit vector for
TYPE_FIELD_VIRTUAL_BITS. */
- if (!fip->baseclasses.empty () && cu->language != language_ada)
+ if (!fip->baseclasses.empty () && cu->per_cu->lang != language_ada)
{
int num_bytes = B_BYTES (fip->baseclasses.size ());
unsigned char *pointer;
switch (field.accessibility)
{
case DW_ACCESS_private:
- if (cu->language != language_ada)
+ if (cu->per_cu->lang != language_ada)
SET_TYPE_FIELD_PRIVATE (type, i);
break;
case DW_ACCESS_protected:
- if (cu->language != language_ada)
+ if (cu->per_cu->lang != language_ada)
SET_TYPE_FIELD_PROTECTED (type, i);
break;
{
case DW_VIRTUALITY_virtual:
case DW_VIRTUALITY_pure_virtual:
- if (cu->language == language_ada)
+ if (cu->per_cu->lang == language_ada)
error (_("unexpected virtuality in component of Ada type"));
SET_TYPE_FIELD_VIRTUAL (type, i);
break;
const char *fieldname;
struct type *this_type;
- if (cu->language == language_ada)
+ if (cu->per_cu->lang == language_ada)
error (_("unexpected member function in Ada type"));
/* Get name of member function. */
fnp = &flp->fnfields.back ();
/* Delay processing of the physname until later. */
- if (cu->language == language_cplus)
+ if (cu->per_cu->lang == language_cplus)
add_to_method_list (type, i, flp->fnfields.size () - 1, fieldname,
die, cu);
else
dwarf2_attach_fn_fields_to_type (struct field_info *fip, struct type *type,
struct dwarf2_cu *cu)
{
- if (cu->language == language_ada)
+ if (cu->per_cu->lang == language_ada)
error (_("unexpected member functions in Ada type"));
ALLOCATE_CPLUS_STRUCT_TYPE (type);
return;
/* Check for __pfn and __delta members. */
- if (TYPE_FIELD_NAME (type, 0) == NULL
- || strcmp (TYPE_FIELD_NAME (type, 0), "__pfn") != 0
- || TYPE_FIELD_NAME (type, 1) == NULL
- || strcmp (TYPE_FIELD_NAME (type, 1), "__delta") != 0)
+ if (type->field (0).name () == NULL
+ || strcmp (type->field (0).name (), "__pfn") != 0
+ || type->field (1).name () == NULL
+ || strcmp (type->field (1).name (), "__delta") != 0)
return;
/* Find the type of the method. */
quirk_ada_thick_pointer_struct (struct die_info *die, struct dwarf2_cu *cu,
struct type *type)
{
- gdb_assert (cu->language == language_ada);
+ gdb_assert (cu->per_cu->lang == language_ada);
/* Check for a structure with two children. */
if (type->code () != TYPE_CODE_STRUCT || type->num_fields () != 2)
return;
/* Check for P_ARRAY and P_BOUNDS members. */
- if (TYPE_FIELD_NAME (type, 0) == NULL
- || strcmp (TYPE_FIELD_NAME (type, 0), "P_ARRAY") != 0
- || TYPE_FIELD_NAME (type, 1) == NULL
- || strcmp (TYPE_FIELD_NAME (type, 1), "P_BOUNDS") != 0)
+ if (type->field (0).name () == NULL
+ || strcmp (type->field (0).name (), "P_ARRAY") != 0
+ || type->field (1).name () == NULL
+ || strcmp (type->field (1).name (), "P_BOUNDS") != 0)
return;
/* Make sure we're looking at a pointer to an array. */
name = dwarf2_name (die, cu);
if (name != NULL)
{
- if (cu->language == language_cplus
- || cu->language == language_d
- || cu->language == language_rust)
+ if (cu->per_cu->lang == language_cplus
+ || cu->per_cu->lang == language_d
+ || cu->per_cu->lang == language_rust)
{
const char *full_name = dwarf2_full_name (name, die, cu);
type->set_code (TYPE_CODE_STRUCT);
}
- if (cu->language == language_cplus && die->tag == DW_TAG_class_type)
+ if (cu->per_cu->lang == language_cplus && die->tag == DW_TAG_class_type)
type->set_is_declared_class (true);
/* Store the calling convention in the type if it's available in
/* Rust doesn't have member functions in the C++ sense.
However, it does emit ordinary functions as children
of a struct DIE. */
- if (cu->language == language_rust)
+ if (cu->per_cu->lang == language_rust)
read_func_scope (child_die, cu);
else
{
i >= TYPE_N_BASECLASSES (t);
--i)
{
- const char *fieldname = TYPE_FIELD_NAME (t, i);
+ const char *fieldname = t->field (i).name ();
if (is_vtable_name (fieldname, cu))
{
i >= TYPE_N_BASECLASSES (type);
--i)
{
- if (strcmp (TYPE_FIELD_NAME (type, i), "__vfp") == 0)
+ if (strcmp (type->field (i).name (), "__vfp") == 0)
{
set_type_vptr_fieldno (type, i);
set_type_vptr_basetype (type, type);
/* Copy fi.nested_types_list linked list elements content into the
allocated array TYPE_NESTED_TYPES_ARRAY (type). */
- if (!fi.nested_types_list.empty () && cu->language != language_ada)
+ if (!fi.nested_types_list.empty ()
+ && cu->per_cu->lang != language_ada)
{
int count = fi.nested_types_list.size ();
}
quirk_gcc_member_function_pointer (type, objfile);
- if (cu->language == language_rust && die->tag == DW_TAG_union_type)
+ if (cu->per_cu->lang == language_rust && die->tag == DW_TAG_union_type)
cu->rust_unions.push_back (type);
- else if (cu->language == language_ada)
+ else if (cu->per_cu->lang == language_ada)
quirk_ada_thick_pointer_struct (die, cu, type);
/* NOTE: carlton/2004-03-16: GCC 3.4 (or at least one of its
fields.emplace_back ();
struct field &field = fields.back ();
- FIELD_NAME (field) = dwarf2_physname (name, child_die, cu);
- SET_FIELD_ENUMVAL (field, value);
+ field.set_name (dwarf2_physname (name, child_die, cu));
+ field.set_loc_enumval (value);
}
if (!fields.empty ())
else
return false;
- SET_FIELD_BITPOS (*field, 8 * offset);
+ field->set_loc_bitpos (8 * offset);
if (size != TYPE_LENGTH (field->type ()))
FIELD_BITSIZE (*field) = 8 * size;
/* Set the name of each field in the bounds. */
xsnprintf (name, sizeof (name), "LB%d", i / 2);
- FIELD_NAME (range_fields[i]) = objfile->intern (name);
+ range_fields[i].set_name (objfile->intern (name));
xsnprintf (name, sizeof (name), "UB%d", i / 2);
- FIELD_NAME (range_fields[i + 1]) = objfile->intern (name);
+ range_fields[i + 1].set_name (objfile->intern (name));
}
struct type *bounds = alloc_type (objfile);
bounds->num_fields () * sizeof (struct field));
int last_fieldno = range_fields.size () - 1;
- int bounds_size = (TYPE_FIELD_BITPOS (bounds, last_fieldno) / 8
+ int bounds_size = (bounds->field (last_fieldno).loc_bitpos () / 8
+ TYPE_LENGTH (bounds->field (last_fieldno).type ()));
TYPE_LENGTH (bounds) = align_up (bounds_size, max_align);
/* The names are chosen to coincide with what the compiler does with
-fgnat-encodings=all, which the Ada code in gdb already
understands. */
- TYPE_FIELD_NAME (result, 0) = "P_ARRAY";
+ result->field (0).set_name ("P_ARRAY");
result->field (0).set_type (lookup_pointer_type (type));
- TYPE_FIELD_NAME (result, 1) = "P_BOUNDS";
+ result->field (1).set_name ("P_BOUNDS");
result->field (1).set_type (lookup_pointer_type (bounds));
- SET_FIELD_BITPOS (result->field (1), 8 * bounds_offset);
+ result->field (1).set_loc_bitpos (8 * bounds_offset);
result->set_name (type->name ());
TYPE_LENGTH (result) = (TYPE_LENGTH (result->field (0).type ())
maybe_set_alignment (cu, die, type);
struct type *replacement_type = nullptr;
- if (cu->language == language_ada)
+ if (cu->per_cu->lang == language_ada)
{
replacement_type = quirk_ada_thick_pointer (die, cu, type);
if (replacement_type != nullptr)
FIXME: dsl/2004-8-20: If G77 is ever fixed, this will also need
version checking. */
- if (cu->language == language_fortran
+ if (cu->per_cu->lang == language_fortran
&& cu->producer && strstr (cu->producer, "GNU F77"))
{
return DW_ORD_row_major;
/* Pass 0 as the default as we know this attribute is constant
and the default value will not be returned. */
LONGEST sz = len->constant_value (0);
- prop_type = cu->per_objfile->int_type (sz, true);
+ prop_type = objfile_int_type (objfile, sz, true);
}
else
{
languages that allow unprototyped functions (Eg: Objective C).
For all other languages, assume that functions are always
prototyped. */
- if (cu->language != language_c
- && cu->language != language_objc
- && cu->language != language_opencl)
+ if (cu->per_cu->lang != language_c
+ && cu->per_cu->lang != language_objc
+ && cu->per_cu->lang != language_opencl)
return 1;
/* RealView does not emit DW_AT_prototyped. We can not distinguish
/* RealView does not mark THIS as const, which the testsuite
expects. GCC marks THIS as const in method definitions,
but not in the class specifications (GCC PR 43053). */
- if (cu->language == language_cplus && !TYPE_CONST (arg_type)
+ if (cu->per_cu->lang == language_cplus
+ && !TYPE_CONST (arg_type)
&& TYPE_FIELD_ARTIFICIAL (ftype, iparams))
{
int is_this = 0;
/* Try to find a suitable floating point builtin type of size BITS.
We're going to use the name of this type as the name for the complex
target type that we are about to create. */
- switch (cu->language)
+ switch (cu->per_cu->lang)
{
case language_fortran:
switch (bits)
}
if ((encoding == DW_ATE_signed_fixed || encoding == DW_ATE_unsigned_fixed)
- && cu->language == language_ada
+ && cu->per_cu->lang == language_ada
&& has_zero_over_zero_small_attribute (die, cu))
{
/* brobecker/2018-02-24: This is a fixed point type for which
than an "else if". */
const char *gnat_encoding_suffix = nullptr;
if ((encoding == DW_ATE_signed || encoding == DW_ATE_unsigned)
- && cu->language == language_ada
+ && cu->per_cu->lang == language_ada
&& name != nullptr)
{
gnat_encoding_suffix = gnat_encoded_fixed_point_type_info (name);
type = dwarf2_init_integer_type (cu, objfile, bits, 0, name);
break;
case DW_ATE_unsigned:
- if (cu->language == language_fortran
+ if (cu->per_cu->lang == language_fortran
&& name
&& startswith (name, "character("))
type = init_character_type (objfile, bits, 1, name);
type = dwarf2_init_integer_type (cu, objfile, bits, 1, name);
break;
case DW_ATE_signed_char:
- if (cu->language == language_ada || cu->language == language_m2
- || cu->language == language_pascal
- || cu->language == language_fortran)
+ if (cu->per_cu->lang == language_ada
+ || cu->per_cu->lang == language_m2
+ || cu->per_cu->lang == language_pascal
+ || cu->per_cu->lang == language_fortran)
type = init_character_type (objfile, bits, 0, name);
else
type = dwarf2_init_integer_type (cu, objfile, bits, 0, name);
break;
case DW_ATE_unsigned_char:
- if (cu->language == language_ada || cu->language == language_m2
- || cu->language == language_pascal
- || cu->language == language_fortran
- || cu->language == language_rust)
+ if (cu->per_cu->lang == language_ada
+ || cu->per_cu->lang == language_m2
+ || cu->per_cu->lang == language_pascal
+ || cu->per_cu->lang == language_fortran
+ || cu->per_cu->lang == language_rust)
type = init_character_type (objfile, bits, 1, name);
else
type = dwarf2_init_integer_type (cu, objfile, bits, 1, name);
break;
case DW_ATE_UTF:
{
- if (bits == 16)
- type = builtin_type (arch)->builtin_char16;
- else if (bits == 32)
- type = builtin_type (arch)->builtin_char32;
- else
- {
- complaint (_("unsupported DW_ATE_UTF bit size: '%d'"),
- bits);
- type = dwarf2_init_integer_type (cu, objfile, bits, 1, name);
- }
+ type = init_character_type (objfile, bits, 1, name);
return set_die_type (die, type, cu);
}
break;
break;
}
- if (name && strcmp (name, "char") == 0)
+ if (type->code () == TYPE_CODE_INT
+ && name != nullptr
+ && strcmp (name, "char") == 0)
type->set_has_no_signedness (true);
maybe_set_alignment (cu, die, type);
return set_die_type (die, type, cu);
}
+/* A helper function that returns the name of DIE, if it refers to a
+ variable declaration. */
+
+static const char *
+var_decl_name (struct die_info *die, struct dwarf2_cu *cu)
+{
+ if (die->tag != DW_TAG_variable)
+ return nullptr;
+
+ attribute *attr = dwarf2_attr (die, DW_AT_declaration, cu);
+ if (attr == nullptr || !attr->as_boolean ())
+ return nullptr;
+
+ attr = dwarf2_attr (die, DW_AT_name, cu);
+ if (attr == nullptr)
+ return nullptr;
+ return attr->as_string ();
+}
+
/* Parse dwarf attribute if it's a block, reference or constant and put the
resulting value of the attribute into struct bound_prop.
Returns 1 if ATTR could be resolved into PROP, 0 otherwise. */
baton->locexpr.per_cu = cu->per_cu;
baton->locexpr.per_objfile = per_objfile;
- struct dwarf_block *block = attr->as_block ();
+ struct dwarf_block *block;
+ if (attr->form == DW_FORM_data16)
+ {
+ size_t data_size = 16;
+ block = XOBNEW (obstack, struct dwarf_block);
+ block->size = (data_size
+ + 2 /* Extra bytes for DW_OP and arg. */);
+ gdb_byte *data = XOBNEWVEC (obstack, gdb_byte, block->size);
+ data[0] = DW_OP_implicit_value;
+ data[1] = data_size;
+ memcpy (&data[2], attr->as_block ()->data, data_size);
+ block->data = data;
+ }
+ else
+ block = attr->as_block ();
+
baton->locexpr.size = block->size;
baton->locexpr.data = block->data;
switch (attr->name)
if (target_attr == NULL)
target_attr = dwarf2_attr (target_die, DW_AT_data_member_location,
target_cu);
+ if (target_attr == nullptr)
+ target_attr = dwarf2_attr (target_die, DW_AT_data_bit_offset,
+ target_cu);
if (target_attr == NULL)
- return 0;
+ {
+ const char *name = var_decl_name (target_die, target_cu);
+ if (name != nullptr)
+ {
+ prop->set_variable_name (name);
+ return 1;
+ }
+ return 0;
+ }
switch (target_attr->name)
{
}
break;
case DW_AT_data_member_location:
+ case DW_AT_data_bit_offset:
{
LONGEST offset;
- if (!handle_data_member_location (target_die, target_cu,
- &offset))
+ if (!handle_member_location (target_die, target_cu, &offset))
return 0;
baton = XOBNEW (obstack, struct dwarf2_property_baton);
}
else if (attr->form_is_constant ())
prop->set_const_val (attr->constant_value (0));
- else
+ else if (attr->form_is_section_offset ())
{
- dwarf2_invalid_attrib_class_complaint (dwarf_form_name (attr->form),
- dwarf2_name (die, cu));
- return 0;
+ switch (attr->name)
+ {
+ case DW_AT_string_length:
+ baton = XOBNEW (obstack, struct dwarf2_property_baton);
+ baton->property_type = default_type;
+ fill_in_loclist_baton (cu, &baton->loclist, attr);
+ prop->set_loclist (baton);
+ gdb_assert (prop->baton () != NULL);
+ break;
+ default:
+ goto invalid;
+ }
}
+ else
+ goto invalid;
return 1;
-}
-
-/* See read.h. */
-
-struct type *
-dwarf2_per_objfile::int_type (int size_in_bytes, bool unsigned_p) const
-{
- struct type *int_type;
- /* Helper macro to examine the various builtin types. */
-#define TRY_TYPE(F) \
- int_type = (unsigned_p \
- ? objfile_type (objfile)->builtin_unsigned_ ## F \
- : objfile_type (objfile)->builtin_ ## F); \
- if (int_type != NULL && TYPE_LENGTH (int_type) == size_in_bytes) \
- return int_type
-
- TRY_TYPE (char);
- TRY_TYPE (short);
- TRY_TYPE (int);
- TRY_TYPE (long);
- TRY_TYPE (long_long);
-
-#undef TRY_TYPE
-
- gdb_assert_not_reached ("unable to find suitable integer type");
+ invalid:
+ dwarf2_invalid_attrib_class_complaint (dwarf_form_name (attr->form),
+ dwarf2_name (die, cu));
+ return 0;
}
/* See read.h. */
-struct type *
-dwarf2_cu::addr_sized_int_type (bool unsigned_p) const
-{
- int addr_size = this->per_cu->addr_size ();
- return this->per_objfile->int_type (addr_size, unsigned_p);
-}
-
/* Read the DW_AT_type attribute for a sub-range. If this attribute is not
present (which is valid) then compute the default type based on the
compilation units address size. */
/* Set LOW_DEFAULT_IS_VALID if current language and DWARF version allow
omitting DW_AT_lower_bound. */
- switch (cu->language)
+ switch (cu->per_cu->lang)
{
case language_c:
case language_cplus:
range_type->bounds ()->flag_upper_bound_is_count = 1;
/* Ada expects an empty array on no boundary attributes. */
- if (attr == NULL && cu->language != language_ada)
+ if (attr == NULL && cu->per_cu->lang != language_ada)
range_type->bounds ()->high.set_undefined ();
name = dwarf2_name (die, cu);
of the type is deferred to a different unit. When encountering
such a type, we treat it as a stub, and try to resolve it later on,
when needed. */
- if (cu->language == language_ada)
+ if (cu->per_cu->lang == language_ada)
type->set_is_stub (true);
return set_die_type (die, type, cu);
last_die = NULL;
gdb_assert (cu->per_cu != NULL);
- if (cu->per_cu->load_all_dies)
+ if (cu->load_all_dies)
load_all = 1;
cu->partial_dies
/* Check for template arguments. We never save these; if
they're seen, we just mark the parent, and go on our way. */
if (parent_die != NULL
- && cu->language == language_cplus
+ && cu->per_cu->lang == language_cplus
&& (abbrev->tag == DW_TAG_template_type_param
|| abbrev->tag == DW_TAG_template_value_param))
{
/* We only recurse into c++ subprograms looking for template arguments.
Skip their other children. */
if (!load_all
- && cu->language == language_cplus
+ && cu->per_cu->lang == language_cplus
&& parent_die != NULL
&& parent_die->tag == DW_TAG_subprogram
&& abbrev->tag != DW_TAG_inlined_subroutine)
later variables referencing them via DW_AT_specification (for
static members). */
if (!load_all
- && !is_type_tag_for_partial (abbrev->tag, cu->language)
+ && !is_type_tag_for_partial (abbrev->tag, cu->per_cu->lang)
&& abbrev->tag != DW_TAG_constant
&& abbrev->tag != DW_TAG_enumerator
&& abbrev->tag != DW_TAG_subprogram
|| last_die->tag == DW_TAG_namespace
|| last_die->tag == DW_TAG_module
|| last_die->tag == DW_TAG_enumeration_type
- || (cu->language == language_cplus
+ || (cu->per_cu->lang == language_cplus
&& last_die->tag == DW_TAG_subprogram
&& (last_die->raw_name == NULL
|| strchr (last_die->raw_name, '<') == NULL))
- || (cu->language != language_c
+ || (cu->per_cu->lang != language_c
&& (last_die->tag == DW_TAG_class_type
|| last_die->tag == DW_TAG_interface_type
|| last_die->tag == DW_TAG_structure_type
|| last_die->tag == DW_TAG_union_type))
- || ((cu->language == language_ada
- || cu->language == language_fortran)
+ || ((cu->per_cu->lang == language_ada
+ || cu->per_cu->lang == language_fortran)
&& (last_die->tag == DW_TAG_subprogram
|| last_die->tag == DW_TAG_lexical_block))))
{
information, we support this practice for backward
compatibility. */
if (attr.constant_value (0) == DW_CC_program
- && cu->language == language_fortran)
+ && cu->per_cu->lang == language_fortran)
main_subprogram = 1;
break;
case DW_AT_inline:
{
/* Offset in the .debug_ranges or .debug_rnglist section (depending
on DWARF version). */
- ULONGEST ranges_offset = attr.as_unsigned ();
+ ranges_offset = attr.as_unsigned ();
/* See dwarf2_cu::gnu_ranges_base's doc for why we might want to add
this value. */
if (tag != DW_TAG_compile_unit)
ranges_offset += cu->gnu_ranges_base;
- if (dwarf2_ranges_read (ranges_offset, &lowpc, &highpc, cu,
- nullptr, tag))
- has_pc_info = 1;
+ has_range_info = 1;
}
break;
of the order in which the name and linkage name were emitted.
Really, though, this is just a workaround for the fact that gdb
doesn't store both the name and the linkage name. */
- if (cu->language == language_ada && linkage_name != nullptr)
+ if (cu->per_cu->lang == language_ada && linkage_name != nullptr)
raw_name = linkage_name;
if (high_pc_relative)
}
dwarf2_per_cu_data *per_cu
= dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
- per_objfile);
+ per_objfile->per_bfd);
cu = per_objfile->get_cu (per_cu);
if (cu == NULL || cu->partial_dies == NULL)
/* If we didn't find it, and not all dies have been loaded,
load them all and try again. */
- if (pd == NULL && cu->per_cu->load_all_dies == 0)
+ if (pd == NULL && cu->load_all_dies == 0)
{
- cu->per_cu->load_all_dies = 1;
+ cu->load_all_dies = 1;
/* This is nasty. When we reread the DIEs, somewhere up the call chain
THIS_CU->cu may already be in use. So we can't just free it and
}
if (pd == NULL)
- error (_("Dwarf Error: Cannot not find DIE at %s [from module %s]\n"),
+ error (_("Dwarf Error: Cannot find DIE at %s [from module %s]\n"),
sect_offset_str (sect_off), bfd_get_filename (objfile->obfd));
return { cu, pd };
}
/* If there is no parent die to provide a namespace, and there are
children, see if we can determine the namespace from their linkage
name. */
- if (cu->language == language_cplus
+ if (cu->per_cu->lang == language_cplus
&& !cu->per_objfile->per_bfd->types.empty ()
&& die_parent == NULL
&& has_children
break;
}
default:
- gdb_assert_not_reached (_("Unexpected DWARF form."));
+ gdb_assert_not_reached ("Unexpected DWARF form.");
}
}
/* See read.h. */
+const char *
+dwarf2_per_objfile::read_line_string (const gdb_byte *buf,
+ unsigned int offset_size)
+{
+ bfd *abfd = objfile->obfd;
+ ULONGEST str_offset = read_offset (abfd, buf, offset_size);
+
+ return per_bfd->line_str.read_string (objfile, str_offset, "DW_FORM_line_strp");
+}
+
+/* See read.h. */
+
const char *
dwarf2_per_objfile::read_line_string (const gdb_byte *buf,
const struct comp_unit_head *cu_header,
}
}
-static void
-set_cu_language (unsigned int lang, struct dwarf2_cu *cu)
+static enum language
+dwarf_lang_to_enum_language (unsigned int lang)
{
+ enum language language;
+
switch (lang)
{
case DW_LANG_C89:
case DW_LANG_C11:
case DW_LANG_C:
case DW_LANG_UPC:
- cu->language = language_c;
+ language = language_c;
break;
case DW_LANG_Java:
case DW_LANG_C_plus_plus:
case DW_LANG_C_plus_plus_11:
case DW_LANG_C_plus_plus_14:
- cu->language = language_cplus;
+ language = language_cplus;
break;
case DW_LANG_D:
- cu->language = language_d;
+ language = language_d;
break;
case DW_LANG_Fortran77:
case DW_LANG_Fortran90:
case DW_LANG_Fortran95:
case DW_LANG_Fortran03:
case DW_LANG_Fortran08:
- cu->language = language_fortran;
+ language = language_fortran;
break;
case DW_LANG_Go:
- cu->language = language_go;
+ language = language_go;
break;
case DW_LANG_Mips_Assembler:
- cu->language = language_asm;
+ language = language_asm;
break;
case DW_LANG_Ada83:
case DW_LANG_Ada95:
- cu->language = language_ada;
+ language = language_ada;
break;
case DW_LANG_Modula2:
- cu->language = language_m2;
+ language = language_m2;
break;
case DW_LANG_Pascal83:
- cu->language = language_pascal;
+ language = language_pascal;
break;
case DW_LANG_ObjC:
- cu->language = language_objc;
+ language = language_objc;
break;
case DW_LANG_Rust:
case DW_LANG_Rust_old:
- cu->language = language_rust;
+ language = language_rust;
+ break;
+ case DW_LANG_OpenCL:
+ language = language_opencl;
break;
case DW_LANG_Cobol74:
case DW_LANG_Cobol85:
default:
- cu->language = language_minimal;
+ language = language_minimal;
break;
}
- cu->language_defn = language_def (cu->language);
+
+ return language;
}
/* Return the named attribute or NULL if not there. */
return follow_die_ref (die, spec_attr, spec_cu);
}
-/* Stub for free_line_header to match void * callback types. */
-
-static void
-free_line_header_voidp (void *arg)
-{
- struct line_header *lh = (struct line_header *) arg;
-
- delete lh;
-}
-
/* A convenience function to find the proper .debug_line section for a CU. */
static struct dwarf2_section_info *
}
/* Subroutine of dwarf_decode_lines to simplify it.
- Return the file name of the psymtab for the given file_entry.
- COMP_DIR is the compilation directory (DW_AT_comp_dir) or NULL if unknown.
+ Return the file name for the given file_entry.
+ CU_INFO describes the CU's DW_AT_name and DW_AT_comp_dir.
If space for the result is malloc'd, *NAME_HOLDER will be set.
- Returns NULL if FILE_INDEX should be ignored, i.e., it is pst->filename. */
+ Returns NULL if FILE_INDEX should be ignored, i.e., it is
+ equivalent to CU_INFO. */
static const char *
-psymtab_include_file_name (const struct line_header *lh, const file_entry &fe,
- const dwarf2_psymtab *pst,
- const char *comp_dir,
+compute_include_file_name (const struct line_header *lh, const file_entry &fe,
+ const file_and_directory &cu_info,
gdb::unique_xmalloc_ptr<char> *name_holder)
{
const char *include_name = fe.name;
const char *include_name_to_compare = include_name;
- const char *pst_filename;
- int file_is_pst;
const char *dir_name = fe.include_dir (lh);
gdb::unique_xmalloc_ptr<char> hold_compare;
if (!IS_ABSOLUTE_PATH (include_name)
- && (dir_name != NULL || comp_dir != NULL))
+ && (dir_name != nullptr || cu_info.get_comp_dir () != nullptr))
{
- /* Avoid creating a duplicate psymtab for PST.
- We do this by comparing INCLUDE_NAME and PST_FILENAME.
+ /* Avoid creating a duplicate name for CU_INFO.
+ We do this by comparing INCLUDE_NAME and CU_INFO.
Before we do the comparison, however, we need to account
for DIR_NAME and COMP_DIR.
First prepend dir_name (if non-NULL). If we still don't
include_name = name_holder->get ();
include_name_to_compare = include_name;
}
- if (!IS_ABSOLUTE_PATH (include_name) && comp_dir != NULL)
+ if (!IS_ABSOLUTE_PATH (include_name)
+ && cu_info.get_comp_dir () != nullptr)
{
- hold_compare.reset (concat (comp_dir, SLASH_STRING,
+ hold_compare.reset (concat (cu_info.get_comp_dir (), SLASH_STRING,
include_name, (char *) NULL));
include_name_to_compare = hold_compare.get ();
}
}
- pst_filename = pst->filename;
gdb::unique_xmalloc_ptr<char> copied_name;
- if (!IS_ABSOLUTE_PATH (pst_filename) && pst->dirname != NULL)
+ const char *cu_filename = cu_info.get_name ();
+ if (!IS_ABSOLUTE_PATH (cu_filename) && cu_info.get_comp_dir () != nullptr)
{
- copied_name.reset (concat (pst->dirname, SLASH_STRING,
- pst_filename, (char *) NULL));
- pst_filename = copied_name.get ();
+ copied_name.reset (concat (cu_info.get_comp_dir (), SLASH_STRING,
+ cu_filename, (char *) NULL));
+ cu_filename = copied_name.get ();
}
- file_is_pst = FILENAME_CMP (include_name_to_compare, pst_filename) == 0;
-
- if (file_is_pst)
- return NULL;
+ if (FILENAME_CMP (include_name_to_compare, cu_filename) == 0)
+ return nullptr;
return include_name;
}
previous version of the code. */
else if (m_op_index == 0 || end_sequence)
{
- fe->included_p = 1;
+ fe->included_p = true;
if (m_record_lines_p)
{
/* When we switch files we insert an end maker in the first file,
the list of files included by the unit represented by PST, and
builds all the associated partial symbol tables.
- COMP_DIR is the compilation directory (DW_AT_comp_dir) or NULL if unknown.
+ FND holds the CU file name and directory, if known.
It is used for relative paths in the line table.
- NOTE: When processing partial symtabs (pst != NULL),
- comp_dir == pst->dirname.
- NOTE: It is important that psymtabs have the same file name (via strcmp)
- as the corresponding symtab. Since COMP_DIR is not used in the name of the
- symtab we don't use it in the name of the psymtabs we create.
- E.g. expand_line_sal requires this when finding psymtabs to expand.
- A good testcase for this is mb-inline.exp.
+ NOTE: It is important that psymtabs have the same file name (via
+ strcmp) as the corresponding symtab. Since the directory is not
+ used in the name of the symtab we don't use it in the name of the
+ psymtabs we create. E.g. expand_line_sal requires this when
+ finding psymtabs to expand. A good testcase for this is
+ mb-inline.exp.
LOWPC is the lowest address in CU (or 0 if not known).
table is read in. */
static void
-dwarf_decode_lines (struct line_header *lh, const char *comp_dir,
+dwarf_decode_lines (struct line_header *lh, const file_and_directory &fnd,
struct dwarf2_cu *cu, dwarf2_psymtab *pst,
CORE_ADDR lowpc, int decode_mapping)
{
/* Now that we're done scanning the Line Header Program, we can
create the psymtab of each included file. */
for (auto &file_entry : lh->file_names ())
- if (file_entry.included_p == 1)
+ if (file_entry.included_p)
{
gdb::unique_xmalloc_ptr<char> name_holder;
const char *include_name =
- psymtab_include_file_name (lh, file_entry, pst,
- comp_dir, &name_holder);
+ compute_include_file_name (lh, file_entry, fnd, &name_holder);
if (include_name != NULL)
dwarf2_create_include_psymtab
(cu->per_objfile->per_bfd, include_name, pst,
cu->get_builder ()->start_subfile (filename);
}
-/* Start a symtab for DWARF. NAME, COMP_DIR, LOW_PC are passed to the
- buildsym_compunit constructor. */
-
-struct compunit_symtab *
-dwarf2_cu::start_symtab (const char *name, const char *comp_dir,
- CORE_ADDR low_pc)
-{
- gdb_assert (m_builder == nullptr);
-
- m_builder.reset (new struct buildsym_compunit
- (this->per_objfile->objfile,
- name, comp_dir, language, low_pc));
-
- list_in_scope = get_builder ()->get_file_symbols ();
-
- get_builder ()->record_debugformat ("DWARF 2");
- get_builder ()->record_producer (producer);
-
- processing_has_namespace_info = false;
-
- return get_builder ()->get_compunit_symtab ();
-}
-
static void
var_decode_location (struct attribute *attr, struct symbol *sym,
struct dwarf2_cu *cu)
OBJSTAT (objfile, n_syms++);
/* Cache this symbol's name and the name's demangled form (if any). */
- sym->set_language (cu->language, &objfile->objfile_obstack);
+ sym->set_language (cu->per_cu->lang, &objfile->objfile_obstack);
/* Fortran does not have mangling standard and the mangling does differ
between gfortran, iFort etc. */
const char *physname
- = (cu->language == language_fortran
+ = (cu->per_cu->lang == language_fortran
? dwarf2_full_name (name, die, cu)
: dwarf2_physname (name, die, cu));
const char *linkagename = dw2_linkage_name (die, cu);
- if (linkagename == nullptr || cu->language == language_ada)
+ if (linkagename == nullptr || cu->per_cu->lang == language_ada)
sym->set_linkage_name (physname);
else
{
sym->set_linkage_name (linkagename);
}
+ /* Handle DW_AT_artificial. */
+ attr = dwarf2_attr (die, DW_AT_artificial, cu);
+ if (attr != nullptr)
+ sym->artificial = attr->as_boolean ();
+
/* Default assumptions.
Use the passed type or decode it from the die. */
SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
SYMBOL_ACLASS_INDEX (sym) = LOC_BLOCK;
attr2 = dwarf2_attr (die, DW_AT_external, cu);
if ((attr2 != nullptr && attr2->as_boolean ())
- || cu->language == language_ada
- || cu->language == language_fortran)
+ || cu->per_cu->lang == language_ada
+ || cu->per_cu->lang == language_fortran)
{
/* Subprograms marked external are stored as a global symbol.
Ada and Fortran subprograms, whether marked external or
/* Fortran explicitly imports any global symbols to the local
scope by DW_TAG_common_block. */
- if (cu->language == language_fortran && die->parent
+ if (cu->per_cu->lang == language_fortran && die->parent
&& die->parent->tag == DW_TAG_common_block)
attr2 = NULL;
/* Fortran explicitly imports any global symbols to the local
scope by DW_TAG_common_block. */
- if (cu->language == language_fortran && die->parent
+ if (cu->per_cu->lang == language_fortran && die->parent
&& die->parent->tag == DW_TAG_common_block)
{
/* SYMBOL_CLASS doesn't matter here because
buildsym_compunit *builder = cu->get_builder ();
list_to_add
= (cu->list_in_scope == builder->get_file_symbols ()
- && cu->language == language_cplus
+ && cu->per_cu->lang == language_cplus
? builder->get_global_symbols ()
: cu->list_in_scope);
/* The semantics of C++ state that "struct foo {
... }" also defines a typedef for "foo". */
- if (cu->language == language_cplus
- || cu->language == language_ada
- || cu->language == language_d
- || cu->language == language_rust)
+ if (cu->per_cu->lang == language_cplus
+ || cu->per_cu->lang == language_ada
+ || cu->per_cu->lang == language_d
+ || cu->per_cu->lang == language_rust)
{
/* The symbol's name is already allocated along
with this objfile, so we don't need to
list_to_add
= (cu->list_in_scope == cu->get_builder ()->get_file_symbols ()
- && cu->language == language_cplus
+ && cu->per_cu->lang == language_cplus
? cu->get_builder ()->get_global_symbols ()
: cu->list_in_scope);
}
/* For the benefit of old versions of GCC, check for anonymous
namespaces based on the demangled name. */
if (!cu->processing_has_namespace_info
- && cu->language == language_cplus)
+ && cu->per_cu->lang == language_cplus)
cp_scan_for_anonymous_namespaces (cu->get_builder (), sym, objfile);
}
return (sym);
{
/* Assume that the Ada compiler was GNAT, which always produces
the auxiliary information. */
- return (cu->language == language_ada);
+ return (cu->per_cu->lang == language_ada);
}
/* Return the auxiliary type of the die in question using its
struct dwarf2_per_cu_data *per_cu;
sect_offset sect_off = attr->get_ref_die_offset ();
- per_cu = dwarf2_find_containing_comp_unit (sect_off, 1, per_objfile);
+ 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 ())
struct type *parent_type;
const char *retval;
- if (cu->language != language_cplus
- && cu->language != language_fortran && cu->language != language_d
- && cu->language != language_rust)
+ if (cu->per_cu->lang != language_cplus
+ && cu->per_cu->lang != language_fortran
+ && cu->per_cu->lang != language_d
+ && cu->per_cu->lang != language_rust)
return "";
retval = anonymous_struct_prefix (die, cu);
/* 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. */
- if (cu->language == language_cplus
+ if (cu->per_cu->lang == language_cplus
&& strcmp (parent_type->name (), "::") == 0)
return "";
/* We give a name to even anonymous namespaces. */
case DW_TAG_compile_unit:
case DW_TAG_partial_unit:
/* gcc-4.5 -gdwarf-4 can drop the enclosing namespace. Cope. */
- if (cu->language == language_cplus
+ if (cu->per_cu->lang == language_cplus
&& !per_objfile->per_bfd->types.empty ()
&& die->child != NULL
&& (die->tag == DW_TAG_class_type
case DW_TAG_subprogram:
/* Nested subroutines in Fortran get a prefix with the name
of the parent's subroutine. */
- if (cu->language == language_fortran)
+ if (cu->per_cu->lang == language_fortran)
{
if ((die->tag == DW_TAG_subprogram)
&& (dwarf2_name (parent, cu) != NULL))
return dwarf2_name (parent, cu);
}
- return determine_prefix (parent, cu);
+ return "";
case DW_TAG_enumeration_type:
parent_type = read_type_die (parent, cu);
if (parent_type->is_declared_class ())
if (suffix == NULL || suffix[0] == '\0'
|| prefix == NULL || prefix[0] == '\0')
sep = "";
- else if (cu->language == language_d)
+ else if (cu->per_cu->lang == language_d)
{
/* For D, the 'main' function could be defined in any module, but it
should never be prefixed. */
else
sep = ".";
}
- else if (cu->language == language_fortran && physname)
+ else if (cu->per_cu->lang == language_fortran && physname)
{
/* This is gfortran specific mangling. Normally DW_AT_linkage_name or
DW_AT_MIPS_linkage_name is preferred and used instead. */
dwarf2_canonicalize_name (const char *name, struct dwarf2_cu *cu,
struct objfile *objfile)
{
- if (name && cu->language == language_cplus)
+ if (name && cu->per_cu->lang == language_cplus)
{
gdb::unique_xmalloc_ptr<char> canon_name
= cp_canonicalize_string (name);
{
unsigned int i;
- print_spaces (indent, f);
- fprintf_unfiltered (f, "Die: %s (abbrev %d, offset %s)\n",
+ fprintf_unfiltered (f, "%*sDie: %s (abbrev %d, offset %s)\n",
+ indent, "",
dwarf_tag_name (die->tag), die->abbrev,
sect_offset_str (die->sect_off));
if (die->parent != NULL)
- {
- print_spaces (indent, f);
- fprintf_unfiltered (f, " parent at offset: %s\n",
- sect_offset_str (die->parent->sect_off));
- }
+ fprintf_unfiltered (f, "%*s parent at offset: %s\n",
+ indent, "",
+ sect_offset_str (die->parent->sect_off));
- print_spaces (indent, f);
- fprintf_unfiltered (f, " has children: %s\n",
- dwarf_bool_name (die->child != NULL));
+ fprintf_unfiltered (f, "%*s has children: %s\n",
+ indent, "",
+ dwarf_bool_name (die->child != NULL));
- print_spaces (indent, f);
- fprintf_unfiltered (f, " attributes:\n");
+ fprintf_unfiltered (f, "%*s attributes:\n", indent, "");
for (i = 0; i < die->num_attrs; ++i)
{
- print_spaces (indent, f);
- fprintf_unfiltered (f, " %s (%s) ",
- dwarf_attr_name (die->attrs[i].name),
- dwarf_form_name (die->attrs[i].form));
+ fprintf_unfiltered (f, "%*s %s (%s) ",
+ indent, "",
+ dwarf_attr_name (die->attrs[i].name),
+ dwarf_form_name (die->attrs[i].form));
switch (die->attrs[i].form)
{
if (die->child != NULL)
{
- print_spaces (indent, f);
- fprintf_unfiltered (f, " Children:");
+ fprintf_unfiltered (f, "%*s Children:", indent, "");
if (level + 1 < max_level)
{
fprintf_unfiltered (f, "\n");
struct dwarf2_per_cu_data *per_cu;
per_cu = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
- per_objfile);
+ per_objfile->per_bfd);
dwarf_read_debug_printf_v ("target CU offset: %s, "
"target CU DIEs loaded: %d",
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->language)
+ if (maybe_queue_comp_unit (cu, per_cu, per_objfile, cu->per_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->language);
+ false, cu->per_cu->lang);
target_cu = per_objfile->get_cu (per_cu);
gdb_assert (target_cu != nullptr);
*ref_cu = target_cu;
temp_die.sect_off = sect_off;
- if (target_cu != cu)
- target_cu->ancestor = cu;
-
return (struct die_info *) htab_find_with_hash (target_cu->die_hash,
&temp_die,
to_underlying (sect_off));
struct type *
dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
dwarf2_per_cu_data *per_cu,
- dwarf2_per_objfile *per_objfile)
+ dwarf2_per_objfile *per_objfile,
+ const char **var_name)
{
struct die_info *die;
if (!die)
return NULL;
+ if (var_name != nullptr)
+ *var_name = var_decl_name (die, cu);
return die_type (die, cu);
}
struct dwarf2_cu **ref_cu)
{
struct die_info temp_die;
- struct dwarf2_cu *sig_cu, *cu = *ref_cu;
+ struct dwarf2_cu *sig_cu;
struct die_info *die;
dwarf2_per_objfile *per_objfile = (*ref_cu)->per_objfile;
}
*ref_cu = sig_cu;
- if (sig_cu != cu)
- sig_cu->ancestor = cu;
-
return die;
}
struct dwarf2_section_info *str_offsets_section;
struct dwarf2_section_info *str_section;
- ULONGEST str_offsets_base;
+ gdb::optional<ULONGEST> str_offsets_base;
if (cu->dwo_unit != nullptr)
{
{
str_offsets_section = &per_objfile->per_bfd->str_offsets;
str_section = &per_objfile->per_bfd->str;
- str_offsets_base = *cu->str_offsets_base;
+ str_offsets_base = cu->str_offsets_base;
}
dwarf_decode_macros (per_objfile, builder, section, lh,
return header->offset_size;
}
-/* See read.h. */
-
-struct type *
-dwarf2_cu::addr_type () const
-{
- struct objfile *objfile = this->per_objfile->objfile;
- struct type *void_type = objfile_type (objfile)->builtin_void;
- struct type *addr_type = lookup_pointer_type (void_type);
- int addr_size = this->per_cu->addr_size ();
-
- if (TYPE_LENGTH (addr_type) == addr_size)
- return addr_type;
-
- addr_type = addr_sized_int_type (addr_type->is_unsigned ());
- return addr_type;
-}
-
/* A helper function for dwarf2_find_containing_comp_unit that returns
the index of the result, and that searches a vector. It will
return a result even if the offset in question does not actually
static struct dwarf2_per_cu_data *
dwarf2_find_containing_comp_unit (sect_offset sect_off,
unsigned int offset_in_dwz,
- dwarf2_per_objfile *per_objfile)
+ dwarf2_per_bfd *per_bfd)
{
int low = dwarf2_find_containing_comp_unit
- (sect_off, offset_in_dwz, per_objfile->per_bfd->all_comp_units);
- dwarf2_per_cu_data *this_cu
- = per_objfile->per_bfd->all_comp_units[low].get ();
+ (sect_off, offset_in_dwz, per_bfd->all_comp_units);
+ dwarf2_per_cu_data *this_cu = per_bfd->all_comp_units[low].get ();
if (this_cu->is_dwz != offset_in_dwz || this_cu->sect_off > sect_off)
{
error (_("Dwarf Error: could not find partial DIE containing "
"offset %s [in module %s]"),
sect_offset_str (sect_off),
- bfd_get_filename (per_objfile->objfile->obfd));
+ bfd_get_filename (per_bfd->obfd));
- gdb_assert (per_objfile->per_bfd->all_comp_units[low-1]->sect_off
+ gdb_assert (per_bfd->all_comp_units[low-1]->sect_off
<= sect_off);
- return per_objfile->per_bfd->all_comp_units[low - 1].get ();
+ return per_bfd->all_comp_units[low - 1].get ();
}
else
{
- if (low == per_objfile->per_bfd->all_comp_units.size () - 1
+ if (low == per_bfd->all_comp_units.size () - 1
&& sect_off >= this_cu->sect_off + this_cu->length)
error (_("invalid dwarf2 offset %s"), sect_offset_str (sect_off));
gdb_assert (sect_off < this_cu->sect_off + this_cu->length);
#endif /* GDB_SELF_TEST */
-/* Initialize dwarf2_cu to read PER_CU, in the context of PER_OBJFILE. */
-
-dwarf2_cu::dwarf2_cu (dwarf2_per_cu_data *per_cu,
- dwarf2_per_objfile *per_objfile)
- : per_cu (per_cu),
- per_objfile (per_objfile),
- mark (false),
- has_loclist (false),
- checked_producer (false),
- producer_is_gxx_lt_4_6 (false),
- producer_is_gcc_lt_4_3 (false),
- producer_is_icc (false),
- producer_is_icc_lt_14 (false),
- producer_is_codewarrior (false),
- processing_has_namespace_info (false)
-{
-}
-
/* Initialize basic fields of dwarf_cu CU according to DIE COMP_UNIT_DIE. */
static void
{
struct attribute *attr;
+ cu->producer = dwarf2_string_attr (comp_unit_die, DW_AT_producer, cu);
+
/* Set the language we're debugging. */
attr = dwarf2_attr (comp_unit_die, DW_AT_language, cu);
- if (attr != nullptr)
- set_cu_language (attr->constant_value (0), cu);
- else
+ if (cu->producer != nullptr
+ && strstr (cu->producer, "IBM XL C for OpenCL") != NULL)
{
- cu->language = pretend_language;
- cu->language_defn = language_def (cu->language);
+ /* The XLCL doesn't generate DW_LANG_OpenCL because this
+ attribute is not standardised yet. As a workaround for the
+ language detection we fall back to the DW_AT_producer
+ string. */
+ cu->per_cu->lang = language_opencl;
}
-
- cu->producer = dwarf2_string_attr (comp_unit_die, DW_AT_producer, cu);
+ else if (cu->producer != nullptr
+ && strstr (cu->producer, "GNU Go ") != NULL)
+ {
+ /* Similar hack for Go. */
+ cu->per_cu->lang = language_go;
+ }
+ else if (attr != nullptr)
+ cu->per_cu->lang = dwarf_lang_to_enum_language (attr->constant_value (0));
+ else
+ cu->per_cu->lang = pretend_language;
+ cu->language_defn = language_def (cu->per_cu->lang);
}
/* See read.h. */
/* Start by clearing all marks. */
for (auto pair : m_dwarf2_cus)
- pair.second->mark = false;
+ pair.second->clear_mark ();
/* Traverse all CUs, mark them and their dependencies if used recently
enough. */
cu->last_used++;
if (cu->last_used <= dwarf_max_cache_age)
- dwarf2_mark (cu);
+ cu->mark ();
}
/* Delete all CUs still not marked. */
{
dwarf2_cu *cu = it->second;
- if (!cu->mark)
+ if (!cu->is_marked ())
{
dwarf_read_debug_printf_v ("deleting old CU %s",
sect_offset_str (cu->per_cu->sect_off));
return get_die_type_at_offset (die->sect_off, cu->per_cu, cu->per_objfile);
}
-/* Add a dependence relationship from CU to REF_PER_CU. */
-
-static void
-dwarf2_add_dependence (struct dwarf2_cu *cu,
- struct dwarf2_per_cu_data *ref_per_cu)
-{
- void **slot;
-
- if (cu->dependencies == NULL)
- cu->dependencies
- = htab_create_alloc_ex (5, htab_hash_pointer, htab_eq_pointer,
- NULL, &cu->comp_unit_obstack,
- hashtab_obstack_allocate,
- dummy_obstack_deallocate);
-
- slot = htab_find_slot (cu->dependencies, ref_per_cu, INSERT);
- if (*slot == NULL)
- *slot = ref_per_cu;
-}
-
-/* Subroutine of dwarf2_mark to pass to htab_traverse.
- Set the mark field in every compilation unit in the
- cache that we must keep because we are keeping CU.
-
- DATA is the dwarf2_per_objfile object in which to look up CUs. */
-
-static int
-dwarf2_mark_helper (void **slot, void *data)
-{
- dwarf2_per_cu_data *per_cu = (dwarf2_per_cu_data *) *slot;
- dwarf2_per_objfile *per_objfile = (dwarf2_per_objfile *) data;
- dwarf2_cu *cu = per_objfile->get_cu (per_cu);
-
- /* cu->dependencies references may not yet have been ever read if QUIT aborts
- reading of the chain. As such dependencies remain valid it is not much
- useful to track and undo them during QUIT cleanups. */
- if (cu == nullptr)
- return 1;
-
- if (cu->mark)
- return 1;
-
- cu->mark = true;
-
- if (cu->dependencies != nullptr)
- htab_traverse (cu->dependencies, dwarf2_mark_helper, per_objfile);
-
- return 1;
-}
-
-/* Set the mark field in CU and in every other compilation unit in the
- cache that we must keep because we are keeping CU. */
-
-static void
-dwarf2_mark (struct dwarf2_cu *cu)
-{
- if (cu->mark)
- return;
-
- cu->mark = true;
-
- if (cu->dependencies != nullptr)
- htab_traverse (cu->dependencies, dwarf2_mark_helper, cu->per_objfile);
-}
-
/* Trivial hash function for partial_die_info: the hash value of a DIE
is its offset in .debug_info for this objfile. */
void
_initialize_dwarf2_read ()
{
- add_basic_prefix_cmd ("dwarf", class_maintenance, _("\
+ add_setshow_prefix_cmd ("dwarf", class_maintenance,
+ _("\
Set DWARF specific variables.\n\
Configure DWARF variables such as the cache size."),
- &set_dwarf_cmdlist,
- 0/*allow-unknown*/, &maintenance_set_cmdlist);
-
- add_show_prefix_cmd ("dwarf", class_maintenance, _("\
+ _("\
Show DWARF specific variables.\n\
Show DWARF variables such as the cache size."),
- &show_dwarf_cmdlist,
- 0/*allow-unknown*/, &maintenance_show_cmdlist);
+ &set_dwarf_cmdlist, &show_dwarf_cmdlist,
+ &maintenance_set_cmdlist, &maintenance_show_cmdlist);
add_setshow_zinteger_cmd ("max-cache-age", class_obscure,
&dwarf_max_cache_age, _("\