#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.
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. */
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);
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. */
}
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;
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 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);
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;
{
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)
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);
}
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);
}
{
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->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);
}
}
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 "
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:
}
}
+ /* 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;
{
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;
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);
}
}
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);
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;
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
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)
{
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);