#include "psympriv.h"
#include <sys/stat.h>
#include "completer.h"
-#include "common/vec.h"
+#include "gdbsupport/vec.h"
#include "c-lang.h"
#include "go-lang.h"
#include "valprint.h"
#include "gdb_bfd.h"
#include "f-lang.h"
#include "source.h"
-#include "common/filestuff.h"
+#include "gdbsupport/filestuff.h"
#include "build-id.h"
#include "namespace.h"
-#include "common/gdb_unlinker.h"
-#include "common/function-view.h"
-#include "common/gdb_optional.h"
-#include "common/underlying.h"
-#include "common/byte-vector.h"
-#include "common/hash_enum.h"
+#include "gdbsupport/gdb_unlinker.h"
+#include "gdbsupport/function-view.h"
+#include "gdbsupport/gdb_optional.h"
+#include "gdbsupport/underlying.h"
+#include "gdbsupport/byte-vector.h"
+#include "gdbsupport/hash_enum.h"
#include "filename-seen-cache.h"
#include "producer.h"
#include <fcntl.h>
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
-#include "common/selftest.h"
+#include "gdbsupport/selftest.h"
#include <cmath>
#include <set>
#include <forward_list>
#include "rust-lang.h"
-#include "common/pathstuff.h"
+#include "gdbsupport/pathstuff.h"
/* When == 1, print basic high level tracing messages.
When > 1, be more verbose.
/* When non-zero, do not reject deprecated .gdb_index sections. */
static int use_deprecated_index_sections = 0;
-static const struct objfile_data *dwarf2_objfile_data_key;
+static const struct objfile_key<dwarf2_per_objfile> dwarf2_objfile_data_key;
/* The "aclass" indices for various kinds of computed DWARF symbols. */
bool symbol_name_slot_invalid (offset_type idx) const override
{
const auto &bucket = this->symbol_table[idx];
- return bucket.name == 0 && bucket.vec;
+ return bucket.name == 0 && bucket.vec == 0;
}
/* Convenience method to get at the name of the symbol at IDX in the
dwarf2_per_objfile *
get_dwarf2_per_objfile (struct objfile *objfile)
{
- return ((struct dwarf2_per_objfile *)
- objfile_data (objfile, dwarf2_objfile_data_key));
-}
-
-/* Set the dwarf2_per_objfile associated to OBJFILE. */
-
-void
-set_dwarf2_per_objfile (struct objfile *objfile,
- struct dwarf2_per_objfile *dwarf2_per_objfile)
-{
- gdb_assert (get_dwarf2_per_objfile (objfile) == NULL);
- set_objfile_data (objfile, dwarf2_objfile_data_key, dwarf2_per_objfile);
+ return dwarf2_objfile_data_key.get (objfile);
}
/* Default names of the debugging sections. */
struct dwarf2_section_info str_offsets;
/* In the case of a virtual DWO file, these two are unused. */
struct dwarf2_section_info info;
- VEC (dwarf2_section_info_def) *types;
+ std::vector<dwarf2_section_info> types;
};
/* CUs/TUs in DWP/DWO files. */
struct dwo_file
{
+ dwo_file () = default;
+ DISABLE_COPY_AND_ASSIGN (dwo_file);
+
/* The DW_AT_GNU_dwo_name attribute.
For virtual DWO files the name is constructed from the section offsets
of abbrev,line,loc,str_offsets so that we combine virtual DWO files
from related CU+TUs. */
- const char *dwo_name;
+ const char *dwo_name = nullptr;
/* The DW_AT_comp_dir attribute. */
- const char *comp_dir;
+ const char *comp_dir = nullptr;
/* The bfd, when the file is open. Otherwise this is NULL.
This is unused(NULL) for virtual DWO files where we use dwp_file.dbfd. */
- bfd *dbfd;
+ gdb_bfd_ref_ptr dbfd;
/* The sections that make up this DWO file.
Remember that for virtual DWO files in DWP V2, these are virtual
sections (for lack of a better name). */
- struct dwo_sections sections;
+ struct dwo_sections sections {};
/* The CUs in the file.
Each element is a struct dwo_unit. Multiple CUs per DWO are supported as
an extension to handle LLVM's Link Time Optimization output (where
multiple source files may be compiled into a single object/dwo pair). */
- htab_t cus;
+ htab_t cus {};
/* Table of TUs in the file.
Each element is a struct dwo_unit. */
- htab_t tus;
+ htab_t tus {};
};
/* These sections are what may appear in a DWP file. */
asection **elf_sections = nullptr;
};
-/* This represents a '.dwz' file. */
-
-struct dwz_file
-{
- dwz_file (gdb_bfd_ref_ptr &&bfd)
- : dwz_bfd (std::move (bfd))
- {
- }
-
- /* A dwz file can only contain a few sections. */
- struct dwarf2_section_info abbrev {};
- struct dwarf2_section_info info {};
- struct dwarf2_section_info str {};
- struct dwarf2_section_info line {};
- struct dwarf2_section_info macro {};
- struct dwarf2_section_info gdb_index {};
- struct dwarf2_section_info debug_names {};
-
- /* The dwz's BFD. */
- gdb_bfd_ref_ptr dwz_bfd;
-
- /* If we loaded the index from an external file, this contains the
- resources associated to the open file, memory mapping, etc. */
- std::unique_ptr<index_cache_resource> index_cache_res;
-};
-
/* Struct used to pass misc. parameters to read_die_and_children, et
al. which are used for both .debug_info and .debug_types dies.
All parameters here are unchanging for the life of the call. This
return &file_names[vec_index];
}
- /* Const version of the above. */
- const file_entry *file_name_at (unsigned int index) const
- {
- if (index >= file_names.size ())
- return NULL;
- return &file_names[index];
- }
-
/* Offset of line number information in .debug_line section. */
sect_offset sect_off {};
static struct partial_die_info *load_partial_dies
(const struct die_reader_specs *, const gdb_byte *, int);
-static struct partial_die_info *find_partial_die (sect_offset, int,
- struct dwarf2_cu *);
+/* A pair of partial_die_info and compilation unit. */
+struct cu_partial_die_info
+{
+ /* The compilation unit of the partial_die_info. */
+ struct dwarf2_cu *cu;
+ /* A partial_die_info. */
+ struct partial_die_info *pdi;
+
+ cu_partial_die_info (struct dwarf2_cu *cu, struct partial_die_info *pdi)
+ : cu (cu),
+ pdi (pdi)
+ { /* Nothhing. */ }
+
+private:
+ cu_partial_die_info () = delete;
+};
+
+static const struct cu_partial_die_info find_partial_die (sect_offset, int,
+ struct dwarf2_cu *);
static const gdb_byte *read_attribute (const struct die_reader_specs *,
struct attribute *, struct attr_abbrev *,
static unsigned int read_2_bytes (bfd *, const gdb_byte *);
+/* Read the next three bytes (little-endian order) as an unsigned integer. */
+static unsigned int read_3_bytes (bfd *, const gdb_byte *);
+
static unsigned int read_4_bytes (bfd *, const gdb_byte *);
static ULONGEST read_8_bytes (bfd *, const gdb_byte *);
static int attr_to_dynamic_prop (const struct attribute *attr,
struct die_info *die, struct dwarf2_cu *cu,
- struct dynamic_prop *prop);
+ struct dynamic_prop *prop, struct type *type);
/* memory allocation interface */
static void process_queue (struct dwarf2_per_objfile *dwarf2_per_objfile);
+static struct type *dwarf2_per_cu_addr_type (struct dwarf2_per_cu_data *per_cu);
+static struct type *dwarf2_per_cu_addr_sized_int_type
+ (struct dwarf2_per_cu_data *per_cu, bool unsigned_p);
+
/* Class, the destructor of which frees all allocated queue entries. This
will only have work to do if an error was thrown while processing the
dwarf. If no error was thrown then the queue entries should have all
static void queue_and_load_all_dwo_tus (struct dwarf2_per_cu_data *);
-static void free_dwo_file (struct dwo_file *);
-
-/* A unique_ptr helper to free a dwo_file. */
-
-struct dwo_file_deleter
-{
- void operator() (struct dwo_file *df) const
- {
- free_dwo_file (df);
- }
-};
-
/* A unique pointer to a dwo_file. */
-typedef std::unique_ptr<struct dwo_file, dwo_file_deleter> dwo_file_up;
+typedef std::unique_ptr<struct dwo_file> dwo_file_up;
static void process_cu_includes (struct dwarf2_per_objfile *dwarf2_per_objfile);
{
CORE_ADDR addr;
- if (attr->form != DW_FORM_addr && attr->form != DW_FORM_GNU_addr_index)
+ if (attr->form != DW_FORM_addr && attr->form != DW_FORM_addrx
+ && attr->form != DW_FORM_GNU_addr_index)
{
/* Aside from a few clearly defined exceptions, attributes that
contain an address must always be in DW_FORM_addr form.
locate_sections (obfd, sec, *names);
}
-static void free_dwo_files (htab_t dwo_files, struct objfile *objfile);
-
dwarf2_per_objfile::~dwarf2_per_objfile ()
{
/* Cached DIE trees use xmalloc and the comp_unit_obstack. */
for (signatured_type *sig_type : all_type_units)
VEC_free (dwarf2_per_cu_ptr, sig_type->per_cu.imported_symtabs);
- VEC_free (dwarf2_section_info_def, types);
-
- if (dwo_files != NULL)
- free_dwo_files (dwo_files, objfile);
-
/* Everything else should be on the objfile obstack. */
}
= get_dwarf2_per_objfile (objfile);
if (dwarf2_per_objfile == NULL)
- {
- /* Initialize per-objfile state. */
- dwarf2_per_objfile
- = new (&objfile->objfile_obstack) struct dwarf2_per_objfile (objfile,
- names);
- set_dwarf2_per_objfile (objfile, dwarf2_per_objfile);
- }
+ dwarf2_per_objfile = dwarf2_objfile_data_key.emplace (objfile, objfile,
+ names);
+
return (!dwarf2_per_objfile->info.is_virtual
&& dwarf2_per_objfile->info.s.section != NULL
&& !dwarf2_per_objfile->abbrev.is_virtual
type_section.s.section = sectp;
type_section.size = bfd_get_section_size (sectp);
- VEC_safe_push (dwarf2_section_info_def, this->types,
- &type_section);
+ this->types.push_back (type_section);
}
else if (section_is_p (sectp->name, &names.gdb_index))
{
if (info->readin)
return;
info->buffer = NULL;
- info->readin = 1;
+ info->readin = true;
if (dwarf2_section_empty_p (info))
return;
asection **sectp, const gdb_byte **bufp,
bfd_size_type *sizep)
{
- struct dwarf2_per_objfile *data
- = (struct dwarf2_per_objfile *) objfile_data (objfile,
- dwarf2_objfile_data_key);
+ struct dwarf2_per_objfile *data = dwarf2_objfile_data_key.get (objfile);
struct dwarf2_section_info *info;
/* We may see an objfile without any DWARF, in which case we just
}
}
-/* Open the separate '.dwz' debug file, if needed. Return NULL if
- there is no .gnu_debugaltlink section in the file. Error if there
- is such a section but the file cannot be found. */
+/* See dwarf2read.h. */
-static struct dwz_file *
+struct dwz_file *
dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
const char *filename;
const uint8_t offset_size = dwarf5_is_dwarf64 ? 8 : 4;
if (addr + entry_length > section->buffer + section->size)
{
- warning (_("Section .debug_aranges in %s entry at offset %zu "
+ warning (_("Section .debug_aranges in %s entry at offset %s "
"length %s exceeds section length %s, "
"ignoring .debug_aranges."),
- objfile_name (objfile), entry_addr - section->buffer,
+ objfile_name (objfile),
+ plongest (entry_addr - section->buffer),
plongest (bytes_read + entry_length),
pulongest (section->size));
return;
addr += 2;
if (version != 2)
{
- warning (_("Section .debug_aranges in %s entry at offset %zu "
+ warning (_("Section .debug_aranges in %s entry at offset %s "
"has unsupported version %d, ignoring .debug_aranges."),
- objfile_name (objfile), entry_addr - section->buffer,
- version);
+ objfile_name (objfile),
+ plongest (entry_addr - section->buffer), version);
return;
}
= debug_info_offset_to_per_cu.find (sect_offset (debug_info_offset));
if (per_cu_it == debug_info_offset_to_per_cu.cend ())
{
- warning (_("Section .debug_aranges in %s entry at offset %zu "
+ warning (_("Section .debug_aranges in %s entry at offset %s "
"debug_info_offset %s does not exists, "
"ignoring .debug_aranges."),
- objfile_name (objfile), entry_addr - section->buffer,
+ objfile_name (objfile),
+ plongest (entry_addr - section->buffer),
pulongest (debug_info_offset));
return;
}
const uint8_t address_size = *addr++;
if (address_size < 1 || address_size > 8)
{
- warning (_("Section .debug_aranges in %s entry at offset %zu "
+ warning (_("Section .debug_aranges in %s entry at offset %s "
"address_size %u is invalid, ignoring .debug_aranges."),
- objfile_name (objfile), entry_addr - section->buffer,
- address_size);
+ objfile_name (objfile),
+ plongest (entry_addr - section->buffer), address_size);
return;
}
const uint8_t segment_selector_size = *addr++;
if (segment_selector_size != 0)
{
- warning (_("Section .debug_aranges in %s entry at offset %zu "
+ warning (_("Section .debug_aranges in %s entry at offset %s "
"segment_selector_size %u is not supported, "
"ignoring .debug_aranges."),
- objfile_name (objfile), entry_addr - section->buffer,
+ objfile_name (objfile),
+ plongest (entry_addr - section->buffer),
segment_selector_size);
return;
}
padding > 0; padding--)
if (*addr++ != 0)
{
- warning (_("Section .debug_aranges in %s entry at offset %zu "
+ warning (_("Section .debug_aranges in %s entry at offset %s "
"padding is not zero, ignoring .debug_aranges."),
- objfile_name (objfile), entry_addr - section->buffer);
+ objfile_name (objfile),
+ plongest (entry_addr - section->buffer));
return;
}
{
if (addr + 2 * address_size > entry_end)
{
- warning (_("Section .debug_aranges in %s entry at offset %zu "
+ warning (_("Section .debug_aranges in %s entry at offset %s "
"address list is not properly terminated, "
"ignoring .debug_aranges."),
- objfile_name (objfile), entry_addr - section->buffer);
+ objfile_name (objfile),
+ plongest (entry_addr - section->buffer));
return;
}
ULONGEST start = extract_unsigned_integer (addr, address_size,
if (types_list_elements)
{
- struct dwarf2_section_info *section;
-
/* We can only handle a single .debug_types when we have an
index. */
- if (VEC_length (dwarf2_section_info_def, dwarf2_per_objfile->types) != 1)
+ if (dwarf2_per_objfile->types.size () != 1)
return 0;
- section = VEC_index (dwarf2_section_info_def,
- dwarf2_per_objfile->types, 0);
+ dwarf2_section_info *section = &dwarf2_per_objfile->types[0];
create_signatured_type_table_from_index (dwarf2_per_objfile, section,
types_list, types_list_elements);
{
/* The dwarf2_per_objfile owning the CUs we are iterating on. */
struct dwarf2_per_objfile *dwarf2_per_objfile;
- /* If non-zero, only look for symbols that match BLOCK_INDEX. */
- int want_specific_block;
- /* One of GLOBAL_BLOCK or STATIC_BLOCK.
- Unused if !WANT_SPECIFIC_BLOCK. */
- int block_index;
+ /* If set, only look for symbols that match that block. Valid values are
+ GLOBAL_BLOCK and STATIC_BLOCK. */
+ gdb::optional<int> block_index;
/* The kind of symbol we're looking for. */
domain_enum domain;
/* The list of CUs from the index entry of the symbol,
int global_seen;
};
-/* Initialize the index symtab iterator ITER.
- If WANT_SPECIFIC_BLOCK is non-zero, only look for symbols
- in block BLOCK_INDEX. Otherwise BLOCK_INDEX is ignored. */
+/* Initialize the index symtab iterator ITER. */
static void
dw2_symtab_iter_init (struct dw2_symtab_iterator *iter,
struct dwarf2_per_objfile *dwarf2_per_objfile,
- int want_specific_block,
- int block_index,
+ gdb::optional<int> block_index,
domain_enum domain,
const char *name)
{
iter->dwarf2_per_objfile = dwarf2_per_objfile;
- iter->want_specific_block = want_specific_block;
iter->block_index = block_index;
iter->domain = domain;
iter->next = 0;
offset_type cu_index_and_attrs =
MAYBE_SWAP (iter->vec[iter->next + 1]);
offset_type cu_index = GDB_INDEX_CU_VALUE (cu_index_and_attrs);
- int want_static = iter->block_index != GLOBAL_BLOCK;
- /* This value is only valid for index versions >= 7. */
- int is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (cu_index_and_attrs);
gdb_index_symbol_kind symbol_kind =
GDB_INDEX_SYMBOL_KIND_VALUE (cu_index_and_attrs);
/* Only check the symbol attributes if they're present.
/* Check static vs global. */
if (attrs_valid)
{
- if (iter->want_specific_block
- && want_static != is_static)
- continue;
+ bool is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (cu_index_and_attrs);
+
+ if (iter->block_index.has_value ())
+ {
+ bool want_static = *iter->block_index == STATIC_BLOCK;
+
+ if (is_static != want_static)
+ continue;
+ }
+
/* Work around gold/15646. */
if (!is_static && iter->global_seen)
continue;
struct dw2_symtab_iterator iter;
struct dwarf2_per_cu_data *per_cu;
- dw2_symtab_iter_init (&iter, dwarf2_per_objfile, 1, block_index, domain, name);
+ dw2_symtab_iter_init (&iter, dwarf2_per_objfile, block_index, domain, name);
while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
{
struct symbol *sym, *with_opaque = NULL;
struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu, false);
const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
- struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
+ const struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
sym = block_find_symbol (block, name, domain,
block_find_non_opaque_type_preferred,
struct dw2_symtab_iterator iter;
struct dwarf2_per_cu_data *per_cu;
- /* Note: It doesn't matter what we pass for block_index here. */
- dw2_symtab_iter_init (&iter, dwarf2_per_objfile, 0, GLOBAL_BLOCK, VAR_DOMAIN,
- func_name);
+ dw2_symtab_iter_init (&iter, dwarf2_per_objfile, {}, VAR_DOMAIN, func_name);
while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
dw2_instantiate_symtab (per_cu, false);
dw2_map_matching_symbols (struct objfile *objfile,
const char * name, domain_enum domain,
int global,
- int (*callback) (struct block *,
+ int (*callback) (const struct block *,
struct symbol *, void *),
void *data, symbol_name_match_type match,
symbol_compare_ftype *ordered_compare)
if (addr != abbrev_table_start + abbrev_table_size)
{
warning (_("Section .debug_names in %s has abbreviation_table "
- "of size %zu vs. written as %u, ignoring .debug_names."),
- filename, addr - abbrev_table_start, abbrev_table_size);
+ "of size %s vs. written as %u, ignoring .debug_names."),
+ filename, plongest (addr - abbrev_table_start),
+ abbrev_table_size);
return false;
}
map.entry_pool = addr;
{
/* We can only handle a single .debug_types when we have an
index. */
- if (VEC_length (dwarf2_section_info_def, dwarf2_per_objfile->types) != 1)
+ if (dwarf2_per_objfile->types.size () != 1)
return false;
- dwarf2_section_info *section = VEC_index (dwarf2_section_info_def,
- dwarf2_per_objfile->types, 0);
+ dwarf2_section_info *section = &dwarf2_per_objfile->types[0];
create_signatured_type_table_from_debug_names
(dwarf2_per_objfile, *map, section, &dwarf2_per_objfile->abbrev);
class dw2_debug_names_iterator
{
public:
- /* If WANT_SPECIFIC_BLOCK is true, only look for symbols in block
- BLOCK_INDEX. Otherwise BLOCK_INDEX is ignored. */
dw2_debug_names_iterator (const mapped_debug_names &map,
- bool want_specific_block,
- block_enum block_index, domain_enum domain,
+ gdb::optional<block_enum> block_index,
+ domain_enum domain,
const char *name)
- : m_map (map), m_want_specific_block (want_specific_block),
- m_block_index (block_index), m_domain (domain),
+ : m_map (map), m_block_index (block_index), m_domain (domain),
m_addr (find_vec_in_debug_names (map, name))
{}
/* The internalized form of .debug_names. */
const mapped_debug_names &m_map;
- /* If true, only look for symbols that match BLOCK_INDEX. */
- const bool m_want_specific_block = false;
-
- /* One of GLOBAL_BLOCK or STATIC_BLOCK.
- Unused if !WANT_SPECIFIC_BLOCK - FIRST_LOCAL_BLOCK is an invalid
- value. */
- const block_enum m_block_index = FIRST_LOCAL_BLOCK;
+ /* If set, only look for symbols that match that block. Valid values are
+ GLOBAL_BLOCK and STATIC_BLOCK. */
+ const gdb::optional<block_enum> m_block_index;
/* The kind of symbol we're looking for. */
const domain_enum m_domain = UNDEF_DOMAIN;
{
int (*cmp) (const char *, const char *);
+ gdb::unique_xmalloc_ptr<char> without_params;
if (current_language->la_language == language_cplus
|| current_language->la_language == language_fortran
|| current_language->la_language == language_d)
if (strchr (name, '(') != NULL)
{
- gdb::unique_xmalloc_ptr<char> without_params
- = cp_remove_params (name);
-
+ without_params = cp_remove_params (name);
if (without_params != NULL)
- {
- name = without_params.get();
- }
+ name = without_params.get ();
}
}
return NULL;
}
const mapped_debug_names::index_val &indexval = indexval_it->second;
- bool have_is_static = false;
- bool is_static;
+ enum class symbol_linkage {
+ unknown,
+ static_,
+ extern_,
+ } symbol_linkage_ = symbol_linkage::unknown;
dwarf2_per_cu_data *per_cu = NULL;
for (const mapped_debug_names::index_val::attr &attr : indexval.attr_vec)
{
case DW_IDX_GNU_internal:
if (!m_map.augmentation_is_gdb)
break;
- have_is_static = true;
- is_static = true;
+ symbol_linkage_ = symbol_linkage::static_;
break;
case DW_IDX_GNU_external:
if (!m_map.augmentation_is_gdb)
break;
- have_is_static = true;
- is_static = false;
+ symbol_linkage_ = symbol_linkage::extern_;
break;
}
}
goto again;
/* Check static vs global. */
- if (have_is_static)
+ if (symbol_linkage_ != symbol_linkage::unknown && m_block_index.has_value ())
{
- const bool want_static = m_block_index != GLOBAL_BLOCK;
- if (m_want_specific_block && want_static != is_static)
- goto again;
+ const bool want_static = *m_block_index == STATIC_BLOCK;
+ const bool symbol_is_static =
+ symbol_linkage_ == symbol_linkage::static_;
+ if (want_static != symbol_is_static)
+ goto again;
}
/* Match dw2_symtab_iter_next, symbol_kind
}
const auto &map = *mapp;
- dw2_debug_names_iterator iter (map, true /* want_specific_block */,
- block_index, domain, name);
+ dw2_debug_names_iterator iter (map, block_index, domain, name);
struct compunit_symtab *stab_best = NULL;
struct dwarf2_per_cu_data *per_cu;
struct symbol *sym, *with_opaque = NULL;
struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu, false);
const struct blockvector *bv = COMPUNIT_BLOCKVECTOR (stab);
- struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
+ const struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
sym = block_find_symbol (block, name, domain,
block_find_non_opaque_type_preferred,
{
const mapped_debug_names &map = *dwarf2_per_objfile->debug_names_table;
- /* Note: It doesn't matter what we pass for block_index here. */
- dw2_debug_names_iterator iter (map, false /* want_specific_block */,
- GLOBAL_BLOCK, VAR_DOMAIN, func_name);
+ dw2_debug_names_iterator iter (map, {}, VAR_DOMAIN, func_name);
struct dwarf2_per_cu_data *per_cu;
while ((per_cu = iter.next ()) != NULL)
init_psymbol_list (objfile, 1024);
- TRY
+ try
{
/* This isn't really ideal: all the data we allocate on the
objfile's obstack is still uselessly kept around. However,
/* (maybe) store an index in the cache. */
global_index_cache.store (dwarf2_per_objfile);
}
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
exception_print (gdb_stderr, except);
}
- END_CATCH
}
/* Return the total length of the CU described by HEADER. */
static void
create_debug_types_hash_table (struct dwarf2_per_objfile *dwarf2_per_objfile,
struct dwo_file *dwo_file,
- VEC (dwarf2_section_info_def) *types,
+ gdb::array_view<dwarf2_section_info> type_sections,
htab_t &types_htab)
{
- int ix;
- struct dwarf2_section_info *section;
-
- if (VEC_empty (dwarf2_section_info_def, types))
- return;
-
- for (ix = 0;
- VEC_iterate (dwarf2_section_info_def, types, ix, section);
- ++ix)
- create_debug_type_hash_table (dwarf2_per_objfile, dwo_file, section,
+ for (dwarf2_section_info §ion : type_sections)
+ create_debug_type_hash_table (dwarf2_per_objfile, dwo_file, §ion,
types_htab, rcuh_kind::TYPE);
}
comp_dir = dwarf2_attr (stub_comp_unit_die, DW_AT_comp_dir, cu);
/* There should be a DW_AT_addr_base attribute here (if needed).
- We need the value before we can process DW_FORM_GNU_addr_index. */
+ We need the value before we can process DW_FORM_GNU_addr_index
+ or DW_FORM_addrx. */
cu->addr_base = 0;
attr = dwarf2_attr (stub_comp_unit_die, DW_AT_GNU_addr_base, cu);
if (attr)
if (get_dwp_file (dwarf2_per_objfile) == NULL
&& dwarf2_per_objfile->dwo_files != NULL)
{
- htab_traverse_noresize (dwarf2_per_objfile->dwo_files,
+ htab_traverse_noresize (dwarf2_per_objfile->dwo_files.get (),
process_dwo_file_for_skeletonless_type_units,
dwarf2_per_objfile);
}
real_pdi = pdi;
while (real_pdi->has_specification)
- real_pdi = find_partial_die (real_pdi->spec_offset,
- real_pdi->spec_is_dwz, cu);
+ {
+ auto res = find_partial_die (real_pdi->spec_offset,
+ real_pdi->spec_is_dwz, cu);
+ real_pdi = res.pdi;
+ cu = res.cu;
+ }
parent = real_pdi->die_parent;
if (parent == NULL)
/* FIXME drow/2004-04-01: What should we be doing with
function-local names? For partial symbols, we should probably be
ignoring them. */
- complaint (_("unhandled containing DIE tag %d for DIE at %s"),
- parent->tag, sect_offset_str (pdi->sect_off));
+ complaint (_("unhandled containing DIE tag %s for DIE at %s"),
+ dwarf_tag_name (parent->tag),
+ sect_offset_str (pdi->sect_off));
parent->scope = grandparent_scope;
}
0, cu->language, objfile);
break;
case DW_TAG_module:
- add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name != NULL,
- MODULE_DOMAIN, LOC_TYPEDEF, -1,
- psymbol_placement::GLOBAL,
- 0, cu->language, objfile);
+ /* With Fortran 77 there might be a "BLOCK DATA" module
+ available without any name. If so, we skip the module as it
+ doesn't bring any value. */
+ if (actual_name != nullptr)
+ add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name != NULL,
+ MODULE_DOMAIN, LOC_TYPEDEF, -1,
+ psymbol_placement::GLOBAL,
+ 0, cu->language, objfile);
break;
case DW_TAG_class_type:
case DW_TAG_interface_type:
case DW_FORM_block4:
info_ptr += 4 + read_4_bytes (abfd, info_ptr);
break;
+ case DW_FORM_addrx:
+ case DW_FORM_strx:
case DW_FORM_sdata:
case DW_FORM_udata:
case DW_FORM_ref_udata:
{
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
const char *saved_package_name
- = (const char *) obstack_copy0 (&objfile->per_bfd->storage_obstack,
- package_name,
- strlen (package_name));
+ = obstack_strdup (&objfile->per_bfd->storage_obstack, package_name);
struct type *type = init_type (objfile, TYPE_CODE_MODULE, 0,
saved_package_name);
struct symbol *sym;
INTERMEDIATE_NAME is already canonical, then we need to
copy it to the appropriate obstack. */
if (canonical_name == NULL || canonical_name == intermediate_name.c_str ())
- name = ((const char *)
- obstack_copy0 (&objfile->per_bfd->storage_obstack,
- intermediate_name.c_str (),
- intermediate_name.length ()));
+ name = obstack_strdup (&objfile->per_bfd->storage_obstack,
+ intermediate_name);
else
name = canonical_name;
}
retval = canon;
if (need_copy)
- retval = ((const char *)
- obstack_copy0 (&objfile->per_bfd->storage_obstack,
- retval, strlen (retval)));
+ retval = obstack_strdup (&objfile->per_bfd->storage_obstack, retval);
return retval;
}
/* Allocate a hash table for DWO files. */
-static htab_t
+static htab_up
allocate_dwo_file_hash_table (struct objfile *objfile)
{
- return htab_create_alloc_ex (41,
- hash_dwo_file,
- eq_dwo_file,
- NULL,
- &objfile->objfile_obstack,
- hashtab_obstack_allocate,
- dummy_obstack_deallocate);
+ auto delete_dwo_file = [] (void *item)
+ {
+ struct dwo_file *dwo_file = (struct dwo_file *) item;
+
+ delete dwo_file;
+ };
+
+ return htab_up (htab_create_alloc_ex (41,
+ hash_dwo_file,
+ eq_dwo_file,
+ delete_dwo_file,
+ &objfile->objfile_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate));
}
/* Lookup DWO file DWO_NAME. */
dwarf2_per_objfile->dwo_files
= allocate_dwo_file_hash_table (dwarf2_per_objfile->objfile);
- memset (&find_entry, 0, sizeof (find_entry));
find_entry.dwo_name = dwo_name;
find_entry.comp_dir = comp_dir;
- slot = htab_find_slot (dwarf2_per_objfile->dwo_files, &find_entry, INSERT);
+ slot = htab_find_slot (dwarf2_per_objfile->dwo_files.get (), &find_entry,
+ INSERT);
return slot;
}
fprintf_unfiltered (gdb_stdlog, "Creating virtual DWO: %s\n",
virtual_dwo_name.c_str ());
}
- dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file);
- dwo_file->dwo_name
- = (const char *) obstack_copy0 (&objfile->objfile_obstack,
- virtual_dwo_name.c_str (),
- virtual_dwo_name.size ());
+ dwo_file = new struct dwo_file;
+ dwo_file->dwo_name = obstack_strdup (&objfile->objfile_obstack,
+ virtual_dwo_name);
dwo_file->comp_dir = comp_dir;
dwo_file->sections.abbrev = sections.abbrev;
dwo_file->sections.line = sections.line;
memset (&result, 0, sizeof (result));
result.s.containing_section = section;
- result.is_virtual = 1;
+ result.is_virtual = true;
if (size == 0)
return result;
fprintf_unfiltered (gdb_stdlog, "Creating virtual DWO: %s\n",
virtual_dwo_name.c_str ());
}
- dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file);
- dwo_file->dwo_name
- = (const char *) obstack_copy0 (&objfile->objfile_obstack,
- virtual_dwo_name.c_str (),
- virtual_dwo_name.size ());
+ dwo_file = new struct dwo_file;
+ dwo_file->dwo_name = obstack_strdup (&objfile->objfile_obstack,
+ virtual_dwo_name);
dwo_file->comp_dir = comp_dir;
dwo_file->sections.abbrev =
create_dwp_v2_section (dwarf2_per_objfile, &dwp_file->sections.abbrev,
memset (&type_section, 0, sizeof (type_section));
type_section.s.section = sectp;
type_section.size = bfd_get_section_size (sectp);
- VEC_safe_push (dwarf2_section_info_def, dwo_sections->types,
- &type_section);
+ dwo_sections->types.push_back (type_section);
}
}
const char *dwo_name, const char *comp_dir)
{
struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
- struct objfile *objfile = dwarf2_per_objfile->objfile;
- gdb_bfd_ref_ptr dbfd (open_dwo_file (dwarf2_per_objfile, dwo_name, comp_dir));
+ gdb_bfd_ref_ptr dbfd = open_dwo_file (dwarf2_per_objfile, dwo_name, comp_dir);
if (dbfd == NULL)
{
if (dwarf_read_debug)
return NULL;
}
- /* We use a unique pointer here, despite the obstack allocation,
- because a dwo_file needs some cleanup if it is abandoned. */
- dwo_file_up dwo_file (OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct dwo_file));
+ dwo_file_up dwo_file (new struct dwo_file);
dwo_file->dwo_name = dwo_name;
dwo_file->comp_dir = comp_dir;
- dwo_file->dbfd = dbfd.release ();
+ dwo_file->dbfd = std::move (dbfd);
- bfd_map_over_sections (dwo_file->dbfd, dwarf2_locate_dwo_sections,
+ bfd_map_over_sections (dwo_file->dbfd.get (), dwarf2_locate_dwo_sections,
&dwo_file->sections);
create_cus_hash_table (dwarf2_per_objfile, *dwo_file, dwo_file->sections.info,
htab_traverse_noresize (dwo_file->tus, queue_and_load_dwo_tu, per_cu);
}
-/* Free all resources associated with DWO_FILE.
- Close the DWO file and munmap the sections. */
-
-static void
-free_dwo_file (struct dwo_file *dwo_file)
-{
- /* Note: dbfd is NULL for virtual DWO files. */
- gdb_bfd_unref (dwo_file->dbfd);
-
- VEC_free (dwarf2_section_info_def, dwo_file->sections.types);
-}
-
-/* Traversal function for free_dwo_files. */
-
-static int
-free_dwo_file_from_slot (void **slot, void *info)
-{
- struct dwo_file *dwo_file = (struct dwo_file *) *slot;
-
- free_dwo_file (dwo_file);
-
- return 1;
-}
-
-/* Free all resources associated with DWO_FILES. */
-
-static void
-free_dwo_files (htab_t dwo_files, struct objfile *objfile)
-{
- htab_traverse_noresize (dwo_files, free_dwo_file_from_slot, objfile);
-}
-\f
/* Read in various DIEs. */
/* DW_AT_abstract_origin inherits whole DIEs (not just their attributes).
newobj->name = new_symbol (die, read_type_die (die, cu), cu,
(struct symbol *) templ_func);
+ if (dwarf2_flag_true_p (die, DW_AT_main_subprogram, cu))
+ set_objfile_main_name (objfile, SYMBOL_LINKAGE_NAME (newobj->name),
+ cu->language);
+
/* If there is a location expression for DW_AT_frame_base, record
it. */
attr = dwarf2_attr (die, DW_AT_frame_base, cu);
{
newobj->static_link
= XOBNEW (&objfile->objfile_obstack, struct dynamic_prop);
- attr_to_dynamic_prop (attr, die, cu, newobj->static_link);
+ attr_to_dynamic_prop (attr, die, cu, newobj->static_link,
+ dwarf2_per_cu_addr_type (cu->per_cu));
}
cu->list_in_scope = cu->get_builder ()->get_local_symbols ();
struct die_info *origin_die
= follow_die_ref (die, abstract_origin, &origin_cu);
dwarf2_per_objfile *dpo = cu->per_cu->dwarf2_per_objfile;
- dpo->abstract_to_concrete[origin_die].push_back (die);
+ dpo->abstract_to_concrete[origin_die->sect_off].push_back (die->sect_off);
}
}
field for our sole member child. */
struct attribute *discr = dwarf2_attr (child_die, DW_AT_discr_value, cu);
- for (struct die_info *variant_child = child_die->child;
+ for (die_info *variant_child = child_die->child;
variant_child != NULL;
variant_child = sibling_die (variant_child))
{
if (has_template_parameters)
{
- /* Make sure that the symtab is set on the new symbols.
- Even though they don't appear in this symtab directly,
- other parts of gdb assume that symbols do, and this is
- reasonably true. */
- for (int i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (type); ++i)
- symbol_set_symtab (TYPE_TEMPLATE_ARGUMENT (type, i),
- symbol_symtab (sym));
+ struct symtab *symtab;
+ if (sym != nullptr)
+ symtab = symbol_symtab (sym);
+ else if (cu->line_header != nullptr)
+ {
+ /* Any related symtab will do. */
+ symtab
+ = cu->line_header->file_name_at (file_name_index (1))->symtab;
+ }
+ else
+ {
+ symtab = nullptr;
+ complaint (_("could not find suitable "
+ "symtab for template parameter"
+ " - DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (objfile));
+ }
+
+ if (symtab != nullptr)
+ {
+ /* Make sure that the symtab is set on the new symbols.
+ Even though they don't appear in this symtab directly,
+ other parts of gdb assume that symbols do, and this is
+ reasonably true. */
+ for (int i = 0; i < TYPE_N_TEMPLATE_ARGUMENTS (type); ++i)
+ symbol_set_symtab (TYPE_TEMPLATE_ARGUMENT (type, i), symtab);
+ }
}
}
}
if (attr != NULL)
{
int stride_ok;
+ struct type *prop_type
+ = dwarf2_per_cu_addr_sized_int_type (cu->per_cu, false);
byte_stride_prop
= (struct dynamic_prop *) alloca (sizeof (struct dynamic_prop));
- stride_ok = attr_to_dynamic_prop (attr, die, cu, byte_stride_prop);
+ stride_ok = attr_to_dynamic_prop (attr, die, cu, byte_stride_prop,
+ prop_type);
if (!stride_ok)
{
complaint (_("unable to read array DW_AT_byte_stride "
struct type *type;
module_name = dwarf2_name (die, cu);
- if (!module_name)
- complaint (_("DW_TAG_module has no name, offset %s"),
- sect_offset_str (die->sect_off));
type = init_type (objfile, TYPE_CODE_MODULE, 0, module_name);
return set_die_type (die, type, cu);
return type;
}
+/* Initialise and return a floating point type of size BITS suitable for
+ use as a component of a complex number. The NAME_HINT is passed through
+ when initialising the floating point type and is the name of the complex
+ type.
+
+ As DWARF doesn't currently provide an explicit name for the components
+ of a complex number, but it can be helpful to have these components
+ named, we try to select a suitable name based on the size of the
+ component. */
+static struct type *
+dwarf2_init_complex_target_type (struct dwarf2_cu *cu,
+ struct objfile *objfile,
+ int bits, const char *name_hint)
+{
+ gdbarch *gdbarch = get_objfile_arch (objfile);
+ struct type *tt = nullptr;
+
+ /* 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)
+ {
+ case language_fortran:
+ switch (bits)
+ {
+ case 32:
+ tt = builtin_f_type (gdbarch)->builtin_real;
+ break;
+ case 64:
+ tt = builtin_f_type (gdbarch)->builtin_real_s8;
+ break;
+ case 96: /* The x86-32 ABI specifies 96-bit long double. */
+ case 128:
+ tt = builtin_f_type (gdbarch)->builtin_real_s16;
+ break;
+ }
+ break;
+ default:
+ switch (bits)
+ {
+ case 32:
+ tt = builtin_type (gdbarch)->builtin_float;
+ break;
+ case 64:
+ tt = builtin_type (gdbarch)->builtin_double;
+ break;
+ case 96: /* The x86-32 ABI specifies 96-bit long double. */
+ case 128:
+ tt = builtin_type (gdbarch)->builtin_long_double;
+ break;
+ }
+ break;
+ }
+
+ /* If the type we found doesn't match the size we were looking for, then
+ pretend we didn't find a type at all, the complex target type we
+ create will then be nameless. */
+ if (tt != nullptr && TYPE_LENGTH (tt) * TARGET_CHAR_BIT != bits)
+ tt = nullptr;
+
+ const char *name = (tt == nullptr) ? nullptr : TYPE_NAME (tt);
+ return dwarf2_init_float_type (objfile, bits, name, name_hint);
+}
+
/* Find a representation of a given base type and install
it in the TYPE field of the die. */
type = init_boolean_type (objfile, bits, 1, name);
break;
case DW_ATE_complex_float:
- type = dwarf2_init_float_type (objfile, bits / 2, NULL, name);
+ type = dwarf2_init_complex_target_type (cu, objfile, bits / 2, name);
type = init_complex_type (objfile, name, type);
break;
case DW_ATE_decimal_float:
static int
attr_to_dynamic_prop (const struct attribute *attr, struct die_info *die,
- struct dwarf2_cu *cu, struct dynamic_prop *prop)
+ struct dwarf2_cu *cu, struct dynamic_prop *prop,
+ struct type *default_type)
{
struct dwarf2_property_baton *baton;
struct obstack *obstack
= &cu->per_cu->dwarf2_per_objfile->objfile->objfile_obstack;
+ gdb_assert (default_type != NULL);
+
if (attr == NULL || prop == NULL)
return 0;
if (attr_form_is_block (attr))
{
baton = XOBNEW (obstack, struct dwarf2_property_baton);
- baton->referenced_type = NULL;
+ baton->property_type = default_type;
baton->locexpr.per_cu = cu->per_cu;
baton->locexpr.size = DW_BLOCK (attr)->size;
baton->locexpr.data = DW_BLOCK (attr)->data;
+ baton->locexpr.is_reference = false;
prop->data.baton = baton;
prop->kind = PROP_LOCEXPR;
gdb_assert (prop->data.baton != NULL);
if (attr_form_is_section_offset (target_attr))
{
baton = XOBNEW (obstack, struct dwarf2_property_baton);
- baton->referenced_type = die_type (target_die, target_cu);
+ baton->property_type = die_type (target_die, target_cu);
fill_in_loclist_baton (cu, &baton->loclist, target_attr);
prop->data.baton = baton;
prop->kind = PROP_LOCLIST;
else if (attr_form_is_block (target_attr))
{
baton = XOBNEW (obstack, struct dwarf2_property_baton);
- baton->referenced_type = die_type (target_die, target_cu);
+ baton->property_type = die_type (target_die, target_cu);
baton->locexpr.per_cu = cu->per_cu;
baton->locexpr.size = DW_BLOCK (target_attr)->size;
baton->locexpr.data = DW_BLOCK (target_attr)->data;
+ baton->locexpr.is_reference = true;
prop->data.baton = baton;
prop->kind = PROP_LOCEXPR;
gdb_assert (prop->data.baton != NULL);
return 0;
baton = XOBNEW (obstack, struct dwarf2_property_baton);
- baton->referenced_type = read_type_die (target_die->parent,
+ baton->property_type = read_type_die (target_die->parent,
target_cu);
baton->offset_info.offset = offset;
baton->offset_info.type = die_type (target_die, target_cu);
return 1;
}
+/* Find an integer type the same size as the address size given in the
+ compilation unit header for PER_CU. UNSIGNED_P controls if the integer
+ is unsigned or not. */
+
+static struct type *
+dwarf2_per_cu_addr_sized_int_type (struct dwarf2_per_cu_data *per_cu,
+ bool unsigned_p)
+{
+ struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
+ int addr_size = dwarf2_per_cu_addr_size (per_cu);
+ 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) == addr_size) \
+ 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");
+}
+
+/* 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. */
+
+static struct type *
+read_subrange_index_type (struct die_info *die, struct dwarf2_cu *cu)
+{
+ struct type *index_type = die_type (die, cu);
+
+ /* Dwarf-2 specifications explicitly allows to create subrange types
+ without specifying a base type.
+ In that case, the base type must be set to the type of
+ the lower bound, upper bound or count, in that order, if any of these
+ three attributes references an object that has a type.
+ If no base type is found, the Dwarf-2 specifications say that
+ a signed integer type of size equal to the size of an address should
+ be used.
+ For the following C code: `extern char gdb_int [];'
+ GCC produces an empty range DIE.
+ FIXME: muller/2010-05-28: Possible references to object for low bound,
+ high bound or count are not yet handled by this code. */
+ if (TYPE_CODE (index_type) == TYPE_CODE_VOID)
+ index_type = dwarf2_per_cu_addr_sized_int_type (cu->per_cu, false);
+
+ return index_type;
+}
+
/* Read the given DW_AT_subrange DIE. */
static struct type *
const char *name;
ULONGEST negative_mask;
- orig_base_type = die_type (die, cu);
+ orig_base_type = read_subrange_index_type (die, cu);
+
/* If ORIG_BASE_TYPE is a typedef, it will not be TYPE_UNSIGNED,
whereas the real type might be. So, we use ORIG_BASE_TYPE when
creating the range type, but we use the result of check_typedef
attr = dwarf2_attr (die, DW_AT_lower_bound, cu);
if (attr)
- attr_to_dynamic_prop (attr, die, cu, &low);
+ attr_to_dynamic_prop (attr, die, cu, &low, base_type);
else if (!low_default_is_valid)
complaint (_("Missing DW_AT_lower_bound "
"- DIE at %s [in module %s]"),
struct attribute *attr_ub, *attr_count;
attr = attr_ub = dwarf2_attr (die, DW_AT_upper_bound, cu);
- if (!attr_to_dynamic_prop (attr, die, cu, &high))
+ if (!attr_to_dynamic_prop (attr, die, cu, &high, base_type))
{
attr = attr_count = dwarf2_attr (die, DW_AT_count, cu);
- if (attr_to_dynamic_prop (attr, die, cu, &high))
+ if (attr_to_dynamic_prop (attr, die, cu, &high, base_type))
{
/* If bounds are constant do the final calculation here. */
if (low.kind == PROP_CONST && high.kind == PROP_CONST)
sect_offset_str (die->sect_off),
objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
}
-
- }
-
- /* Dwarf-2 specifications explicitly allows to create subrange types
- without specifying a base type.
- In that case, the base type must be set to the type of
- the lower bound, upper bound or count, in that order, if any of these
- three attributes references an object that has a type.
- If no base type is found, the Dwarf-2 specifications say that
- a signed integer type of size equal to the size of an address should
- be used.
- For the following C code: `extern char gdb_int [];'
- GCC produces an empty range DIE.
- FIXME: muller/2010-05-28: Possible references to object for low bound,
- high bound or count are not yet handled by this code. */
- if (TYPE_CODE (base_type) == TYPE_CODE_VOID)
- {
- struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
- int addr_size = gdbarch_addr_bit (gdbarch) /8;
- struct type *int_type = objfile_type (objfile)->builtin_int;
-
- /* Test "int", "long int", and "long long int" objfile types,
- and select the first one having a size above or equal to the
- architecture address size. */
- if (int_type && TYPE_LENGTH (int_type) >= addr_size)
- base_type = int_type;
- else
- {
- int_type = objfile_type (objfile)->builtin_long;
- if (int_type && TYPE_LENGTH (int_type) >= addr_size)
- base_type = int_type;
- else
- {
- int_type = objfile_type (objfile)->builtin_long_long;
- if (int_type && TYPE_LENGTH (int_type) >= addr_size)
- base_type = int_type;
- }
- }
}
/* Normally, the DWARF producers are expected to use a signed
/* Note that both forms of linkage name might appear. We
assume they will be the same, and we only store the last
one we see. */
- if (cu->language == language_ada)
- name = DW_STRING (&attr);
linkage_name = DW_STRING (&attr);
break;
case DW_AT_low_pc:
main_subprogram = DW_UNSND (&attr);
break;
+ case DW_AT_ranges:
+ {
+ /* It would be nice to reuse dwarf2_get_pc_bounds here,
+ but that requires a full DIE, so instead we just
+ reimplement it. */
+ int need_ranges_base = tag != DW_TAG_compile_unit;
+ unsigned int ranges_offset = (DW_UNSND (&attr)
+ + (need_ranges_base
+ ? cu->ranges_base
+ : 0));
+
+ /* Value of the DW_AT_ranges attribute is the offset in the
+ .debug_ranges section. */
+ if (dwarf2_ranges_read (ranges_offset, &lowpc, &highpc, cu,
+ nullptr))
+ has_pc_info = 1;
+ }
+ break;
+
default:
break;
}
}
+ /* For Ada, if both the name and the linkage name appear, we prefer
+ the latter. This lets "catch exception" work better, regardless
+ 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)
+ name = linkage_name;
+
if (high_pc_relative)
highpc += lowpc;
outside their CU (they do however referencing other types via
DW_FORM_ref_sig8). */
-static struct partial_die_info *
+static const struct cu_partial_die_info
find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
{
struct dwarf2_per_objfile *dwarf2_per_objfile
{
pd = cu->find_partial_die (sect_off);
if (pd != NULL)
- return pd;
+ return { cu, pd };
/* We missed recording what we needed.
Load all dies and try again. */
per_cu = cu->per_cu;
_("could not find partial DIE %s "
"in cache [from module %s]\n"),
sect_offset_str (sect_off), bfd_get_filename (objfile->obfd));
- return pd;
+ return { per_cu->cu, pd };
}
/* See if we can figure out if the class lives in a namespace. We do
real_pdi = struct_pdi;
while (real_pdi->has_specification)
- real_pdi = find_partial_die (real_pdi->spec_offset,
- real_pdi->spec_is_dwz, cu);
+ {
+ auto res = find_partial_die (real_pdi->spec_offset,
+ real_pdi->spec_is_dwz, cu);
+ real_pdi = res.pdi;
+ cu = res.cu;
+ }
if (real_pdi->die_parent != NULL)
return;
{
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
struct_pdi->name
- = ((const char *)
- obstack_copy0 (&objfile->per_bfd->storage_obstack,
- actual_class_name,
- strlen (actual_class_name)));
+ = obstack_strdup (&objfile->per_bfd->storage_obstack,
+ actual_class_name);
xfree (actual_class_name);
}
break;
{
struct partial_die_info *spec_die;
- spec_die = find_partial_die (spec_offset, spec_is_dwz, cu);
+ auto res = find_partial_die (spec_offset, spec_is_dwz, cu);
+ spec_die = res.pdi;
+ cu = res.cu;
spec_die->fixup (cu);
children, see if we can determine the namespace from their linkage
name. */
if (cu->language == language_cplus
- && !VEC_empty (dwarf2_section_info_def,
- cu->per_cu->dwarf2_per_objfile->types)
+ && !cu->per_cu->dwarf2_per_objfile->types.empty ()
&& die_parent == NULL
&& has_children
&& (tag == DW_TAG_class_type
base = demangled;
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- name
- = ((const char *)
- obstack_copy0 (&objfile->per_bfd->storage_obstack,
- base, strlen (base)));
+ name = obstack_strdup (&objfile->per_bfd->storage_obstack, base);
xfree (demangled);
}
}
case DW_FORM_implicit_const:
DW_SND (attr) = implicit_const;
break;
+ case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
if (reader->dwo_file == NULL)
{
DW_ADDR (attr) = read_addr_index_from_leb128 (cu, info_ptr, &bytes_read);
info_ptr += bytes_read;
break;
+ case DW_FORM_strx:
+ case DW_FORM_strx1:
+ case DW_FORM_strx2:
+ case DW_FORM_strx3:
+ case DW_FORM_strx4:
case DW_FORM_GNU_str_index:
if (reader->dwo_file == NULL)
{
bfd_get_filename (abfd));
}
{
- ULONGEST str_index =
- read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
-
+ ULONGEST str_index;
+ if (form == DW_FORM_strx1)
+ {
+ str_index = read_1_byte (abfd, info_ptr);
+ info_ptr += 1;
+ }
+ else if (form == DW_FORM_strx2)
+ {
+ str_index = read_2_bytes (abfd, info_ptr);
+ info_ptr += 2;
+ }
+ else if (form == DW_FORM_strx3)
+ {
+ str_index = read_3_bytes (abfd, info_ptr);
+ info_ptr += 3;
+ }
+ else if (form == DW_FORM_strx4)
+ {
+ str_index = read_4_bytes (abfd, info_ptr);
+ info_ptr += 4;
+ }
+ else
+ {
+ str_index = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+ info_ptr += bytes_read;
+ }
DW_STRING (attr) = read_str_index (reader, str_index);
DW_STRING_IS_CANONICAL (attr) = 0;
- info_ptr += bytes_read;
}
break;
default:
}
static unsigned int
+read_3_bytes (bfd *abfd, const gdb_byte *buf)
+{
+ unsigned int result = 0;
+ for (int i = 0; i < 3; ++i)
+ {
+ unsigned char byte = bfd_get_8 (abfd, buf);
+ buf++;
+ result |= ((unsigned int) byte << (i * 8));
+ }
+ return result;
+}
+
+static unsigned int
read_4_bytes (bfd *abfd, const gdb_byte *buf)
{
return bfd_get_32 (abfd, buf);
addr_size);
}
-/* Given a DW_FORM_GNU_str_index, fetch the string.
+/* Given a DW_FORM_GNU_str_index or DW_FORM_strx, fetch the string.
This is only used by the Fission support. */
static const char *
&reader->dwo_file->sections.str_offsets;
const gdb_byte *info_ptr;
ULONGEST str_offset;
- static const char form_name[] = "DW_FORM_GNU_str_index";
+ static const char form_name[] = "DW_FORM_GNU_str_index or DW_FORM_strx";
dwarf2_read_section (objfile, str_section);
dwarf2_read_section (objfile, str_offsets_section);
{
if (attr->form == DW_FORM_strp || attr->form == DW_FORM_line_strp
|| attr->form == DW_FORM_string
+ || attr->form == DW_FORM_strx
|| attr->form == DW_FORM_GNU_str_index
|| attr->form == DW_FORM_GNU_strp_alt)
str = DW_STRING (attr);
/* Handle one degenerate form of location expression specially, to
preserve GDB's previous behavior when section offsets are
- specified. If this is just a DW_OP_addr or DW_OP_GNU_addr_index
- then mark this symbol as LOC_STATIC. */
+ specified. If this is just a DW_OP_addr, DW_OP_addrx, or
+ DW_OP_GNU_addr_index then mark this symbol as LOC_STATIC. */
if (attr_form_is_block (attr)
&& ((DW_BLOCK (attr)->data[0] == DW_OP_addr
&& DW_BLOCK (attr)->size == 1 + cu_header->addr_size)
- || (DW_BLOCK (attr)->data[0] == DW_OP_GNU_addr_index
+ || ((DW_BLOCK (attr)->data[0] == DW_OP_GNU_addr_index
+ || DW_BLOCK (attr)->data[0] == DW_OP_addrx)
&& (DW_BLOCK (attr)->size
== 1 + leb128_size (&DW_BLOCK (attr)->data[1])))))
{
switch (attr->form)
{
case DW_FORM_addr:
+ case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
{
gdb_byte *data;
break;
case DW_FORM_string:
case DW_FORM_strp:
+ case DW_FORM_strx:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_strp_alt:
/* DW_STRING is already allocated on the objfile obstack, point
objfile_name (objfile),
sect_offset_str (cu->header.sect_off),
sect_offset_str (die->sect_off));
- saved = (char *) obstack_copy0 (&objfile->objfile_obstack,
- message.c_str (), message.length ());
+ saved = obstack_strdup (&objfile->objfile_obstack, message);
return init_type (objfile, TYPE_CODE_ERROR, 0, saved);
}
if (actual_name_len > die_name_len + 2
&& actual_name[actual_name_len
- die_name_len - 1] == ':')
- name = (char *) obstack_copy0 (
+ name = obstack_strndup (
&objfile->per_bfd->storage_obstack,
actual_name, actual_name_len - die_name_len - 2);
}
return "";
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
- return (char *) obstack_copy0 (&objfile->per_bfd->storage_obstack,
- DW_STRING (attr),
- &base[-1] - DW_STRING (attr));
+ return obstack_strndup (&objfile->per_bfd->storage_obstack,
+ DW_STRING (attr),
+ &base[-1] - DW_STRING (attr));
}
/* Return the name of the namespace/class that DIE is defined within,
case DW_TAG_partial_unit:
/* gcc-4.5 -gdwarf-4 can drop the enclosing namespace. Cope. */
if (cu->language == language_cplus
- && !VEC_empty (dwarf2_section_info_def, dwarf2_per_objfile->types)
+ && !dwarf2_per_objfile->types.empty ()
&& die->child != NULL
&& (die->tag == DW_TAG_class_type
|| die->tag == DW_TAG_structure_type
if (!canon_name.empty ())
{
if (canon_name != name)
- name = (const char *) obstack_copy0 (obstack,
- canon_name.c_str (),
- canon_name.length ());
+ name = obstack_strdup (obstack, canon_name);
}
}
/* FIXME: we already did this for the partial symbol... */
DW_STRING (attr)
- = ((const char *)
- obstack_copy0 (&objfile->per_bfd->storage_obstack,
- demangled, strlen (demangled)));
+ = obstack_strdup (&objfile->per_bfd->storage_obstack,
+ demangled);
DW_STRING_IS_CANONICAL (attr) = 1;
xfree (demangled);
return follow_die_ref (die, attr, ext_cu);
}
+/* A convenience function that returns an "unknown" DWARF name,
+ including the value of V. STR is the name of the entity being
+ printed, e.g., "TAG". */
+
+static const char *
+dwarf_unknown (const char *str, unsigned v)
+{
+ char *cell = get_print_cell ();
+ xsnprintf (cell, PRINT_CELL_SIZE, "DW_%s_<unknown: %u>", str, v);
+ return cell;
+}
+
/* Convert a DIE tag into its string name. */
static const char *
const char *name = get_DW_TAG_name (tag);
if (name == NULL)
- return "DW_TAG_<unknown>";
+ return dwarf_unknown ("TAG", tag);
return name;
}
name = get_DW_AT_name (attr);
if (name == NULL)
- return "DW_AT_<unknown>";
+ return dwarf_unknown ("AT", attr);
return name;
}
const char *name = get_DW_FORM_name (form);
if (name == NULL)
- return "DW_FORM_<unknown>";
+ return dwarf_unknown ("FORM", form);
return name;
}
const char *name = get_DW_ATE_name (enc);
if (name == NULL)
- return "DW_ATE_<unknown>";
+ return dwarf_unknown ("ATE", enc);
return name;
}
switch (die->attrs[i].form)
{
case DW_FORM_addr:
+ case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
fprintf_unfiltered (f, "address: ");
fputs_filtered (hex_string (DW_ADDR (&die->attrs[i])), f);
case DW_FORM_string:
case DW_FORM_strp:
case DW_FORM_line_strp:
+ case DW_FORM_strx:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_strp_alt:
fprintf_unfiltered (f, "string: \"%s\" (%s canonicalized)",
attr = dwarf2_attr (die, DW_AT_location, cu);
if (!attr && resolve_abstract_p
- && (dwarf2_per_objfile->abstract_to_concrete.find (die)
+ && (dwarf2_per_objfile->abstract_to_concrete.find (die->sect_off)
!= dwarf2_per_objfile->abstract_to_concrete.end ()))
{
CORE_ADDR pc = (*get_frame_pc) (baton);
+ CORE_ADDR baseaddr
+ = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
+ struct gdbarch *gdbarch = get_objfile_arch (objfile);
- for (const auto &cand : dwarf2_per_objfile->abstract_to_concrete[die])
+ for (const auto &cand_off
+ : dwarf2_per_objfile->abstract_to_concrete[die->sect_off])
{
- if (!cand->parent
+ struct dwarf2_cu *cand_cu = cu;
+ struct die_info *cand
+ = follow_die_offset (cand_off, per_cu->is_dwz, &cand_cu);
+ if (!cand
+ || !cand->parent
|| cand->parent->tag != DW_TAG_subprogram)
continue;
CORE_ADDR pc_low, pc_high;
get_scope_pc_bounds (cand->parent, &pc_low, &pc_high, cu);
- if (pc_low == ((CORE_ADDR) -1)
- || !(pc_low <= pc && pc < pc_high))
+ if (pc_low == ((CORE_ADDR) -1))
+ continue;
+ pc_low = gdbarch_adjust_dwarf2_addr (gdbarch, pc_low + baseaddr);
+ pc_high = gdbarch_adjust_dwarf2_addr (gdbarch, pc_high + baseaddr);
+ if (!(pc_low <= pc && pc < pc_high))
continue;
die = cand;
switch (attr->form)
{
case DW_FORM_addr:
+ case DW_FORM_addrx:
case DW_FORM_GNU_addr_index:
{
gdb_byte *tem;
break;
case DW_FORM_string:
case DW_FORM_strp:
+ case DW_FORM_strx:
case DW_FORM_GNU_str_index:
case DW_FORM_GNU_strp_alt:
/* DW_STRING is already allocated on the objfile obstack, point
case DW_OP_GNU_uninit:
break;
+ case DW_OP_addrx:
case DW_OP_GNU_addr_index:
case DW_OP_GNU_const_index:
stack[++stacki] = read_addr_index_from_leb128 (cu, &data[i],
bytes += 4 + read_4_bytes (abfd, bytes);
break;
+ case DW_FORM_addrx:
case DW_FORM_sdata:
+ case DW_FORM_strx:
case DW_FORM_udata:
case DW_FORM_GNU_addr_index:
case DW_FORM_GNU_str_index:
is_define ? _("definition") : _("undefinition"),
line == 0 ? _("zero") : _("non-zero"), line, body);
- if (is_define)
+ if (body == NULL)
+ {
+ /* Fedora's rpm-build's "debugedit" binary
+ corrupted .debug_macro sections.
+
+ For more info, see
+ https://bugzilla.redhat.com/show_bug.cgi?id=1708786 */
+ complaint (_("debug info gives %s invalid macro %s "
+ "without body (corrupted?) at line %d "
+ "on file %s"),
+ at_commandline ? _("command-line") : _("in-file"),
+ is_define ? _("definition") : _("undefinition"),
+ line, current_file->filename);
+ }
+ else if (is_define)
parse_macro_definition (current_file, line, body);
else
{
return ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
}
+/* Return a type that is a generic pointer type, the size of which matches
+ the address size given in the compilation unit header for PER_CU. */
+static struct type *
+dwarf2_per_cu_addr_type (struct dwarf2_per_cu_data *per_cu)
+{
+ struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
+ struct type *void_type = objfile_type (objfile)->builtin_void;
+ struct type *addr_type = lookup_pointer_type (void_type);
+ int addr_size = dwarf2_per_cu_addr_size (per_cu);
+
+ if (TYPE_LENGTH (addr_type) == addr_size)
+ return addr_type;
+
+ addr_type
+ = dwarf2_per_cu_addr_sized_int_type (per_cu, TYPE_UNSIGNED (addr_type));
+ return addr_type;
+}
+
/* Return DWARF version number of PER_CU. */
short
}
else
{
- this_cu = dwarf2_per_objfile->all_comp_units[low];
if (low == dwarf2_per_objfile->all_comp_units.size () - 1
&& sect_off >= this_cu->sect_off + this_cu->length)
error (_("invalid dwarf2 offset %s"), sect_offset_str (sect_off));
}
}
-/* Cleanup function for the dwarf2_per_objfile data. */
-
-static void
-dwarf2_free_objfile (struct objfile *objfile, void *datum)
-{
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = static_cast<struct dwarf2_per_objfile *> (datum);
-
- delete dwarf2_per_objfile;
-}
-
/* A set of CU "per_cu" pointer, DIE offset, and GDB type pointer.
We store these in a hash table separate from the DIEs, and preserve them
when the DIEs are flushed out of cache.
attr = dwarf2_attr (die, DW_AT_allocated, cu);
if (attr_form_is_block (attr))
{
- if (attr_to_dynamic_prop (attr, die, cu, &prop))
+ struct type *prop_type
+ = dwarf2_per_cu_addr_sized_int_type (cu->per_cu, false);
+ if (attr_to_dynamic_prop (attr, die, cu, &prop, prop_type))
add_dyn_prop (DYN_PROP_ALLOCATED, prop, type);
}
else if (attr != NULL)
attr = dwarf2_attr (die, DW_AT_associated, cu);
if (attr_form_is_block (attr))
{
- if (attr_to_dynamic_prop (attr, die, cu, &prop))
+ struct type *prop_type
+ = dwarf2_per_cu_addr_sized_int_type (cu->per_cu, false);
+ if (attr_to_dynamic_prop (attr, die, cu, &prop, prop_type))
add_dyn_prop (DYN_PROP_ASSOCIATED, prop, type);
}
else if (attr != NULL)
/* Read DW_AT_data_location and set in type. */
attr = dwarf2_attr (die, DW_AT_data_location, cu);
- if (attr_to_dynamic_prop (attr, die, cu, &prop))
+ if (attr_to_dynamic_prop (attr, die, cu, &prop,
+ dwarf2_per_cu_addr_type (cu->per_cu)))
add_dyn_prop (DYN_PROP_DATA_LOCATION, prop, type);
if (dwarf2_per_objfile->die_type_hash == NULL)
void
_initialize_dwarf2_read (void)
{
- dwarf2_objfile_data_key
- = register_objfile_data_with_cleanup (nullptr, dwarf2_free_objfile);
-
add_prefix_cmd ("dwarf", class_maintenance, set_dwarf_cmd, _("\
Set DWARF specific variables.\n\
-Configure DWARF variables such as the cache size"),
+Configure DWARF variables such as the cache size."),
&set_dwarf_cmdlist, "maintenance set dwarf ",
0/*allow-unknown*/, &maintenance_set_cmdlist);
add_prefix_cmd ("dwarf", class_maintenance, show_dwarf_cmd, _("\
-Show DWARF specific variables\n\
-Show DWARF variables such as the cache size"),
+Show DWARF specific variables.\n\
+Show DWARF variables such as the cache size."),
&show_dwarf_cmdlist, "maintenance show dwarf ",
0/*allow-unknown*/, &maintenance_show_cmdlist);