/* DWARF 2 debugging format support for GDB.
- Copyright (C) 1994-2018 Free Software Foundation, Inc.
+ Copyright (C) 1994-2019 Free Software Foundation, Inc.
Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
Inc. with support from Florida State University (under contract
#include "defs.h"
#include "dwarf2read.h"
+#include "dwarf-index-cache.h"
#include "dwarf-index-common.h"
#include "bfd.h"
#include "elf-bfd.h"
#include "macrotab.h"
#include "language.h"
#include "complaints.h"
-#include "bcache.h"
#include "dwarf2expr.h"
#include "dwarf2loc.h"
#include "cp-support.h"
#include "psympriv.h"
#include <sys/stat.h>
#include "completer.h"
-#include "vec.h"
+#include "common/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 "filestuff.h"
+#include "common/filestuff.h"
#include "build-id.h"
#include "namespace.h"
#include "common/gdb_unlinker.h"
#include <algorithm>
#include <unordered_set>
#include <unordered_map>
-#include "selftest.h"
+#include "common/selftest.h"
#include <cmath>
#include <set>
#include <forward_list>
struct mapped_index_base
{
+ mapped_index_base () = default;
+ DISABLE_COPY_AND_ASSIGN (mapped_index_base);
+
/* The name_component table (a sorted vector). See name_component's
description above. */
std::vector<name_component> name_components;
};
/* Index data format version. */
- int version;
-
- /* The total length of the buffer. */
- off_t total_size;
+ int version = 0;
/* The address table data. */
gdb::array_view<const gdb_byte> address_table;
gdb::array_view<symbol_table_slot> symbol_table;
/* A pointer to the constant pool. */
- const char *constant_pool;
+ const char *constant_pool = nullptr;
bool symbol_name_slot_invalid (offset_type idx) const override
{
DISABLE_COPY_AND_ASSIGN (dwarf2_cu);
+ /* TU version of handle_DW_AT_stmt_list for read_type_unit_scope.
+ Create the set of symtabs used by this TU, or if this TU is sharing
+ symtabs with another TU and the symtabs have already been created
+ then restore those symtabs in the line header.
+ We don't need the pc/line-number mapping for type units. */
+ void setup_type_unit_groups (struct die_info *die);
+
+ /* Start a symtab for DWARF. NAME, COMP_DIR, LOW_PC are passed to the
+ buildsym_compunit constructor. */
+ struct compunit_symtab *start_symtab (const char *name,
+ const char *comp_dir,
+ CORE_ADDR low_pc);
+
+ /* Reset the builder. */
+ void reset_builder () { m_builder.reset (); }
+
/* The header of the compilation unit. */
struct comp_unit_head header {};
const char *producer = nullptr;
+private:
+ /* The symtab builder for this CU. This is only non-NULL when full
+ symbols are being read. */
+ std::unique_ptr<buildsym_compunit> m_builder;
+
+public:
/* The generic symbol table building routines have separate lists for
file scope symbols and all all other scopes (local scopes). So
we need to select the right one to pass to add_symbol_to_list().
std::vector<struct type *> rust_unions;
/* Mark used when releasing cached dies. */
- unsigned int mark : 1;
+ bool mark : 1;
/* This CU references .debug_loc. See the symtab->locations_valid field.
This test is imperfect as there may exist optimized debug code not using
any location list and still facing inlining issues if handled as
unoptimized code. For a future better test see GCC PR other/32998. */
- unsigned int has_loclist : 1;
+ bool has_loclist : 1;
- /* These cache the results for producer_is_* fields. CHECKED_PRODUCER is set
+ /* These cache the results for producer_is_* fields. CHECKED_PRODUCER is true
if all the producer_is_* fields are valid. This information is cached
because profiling CU expansion showed excessive time spent in
producer_is_gxx_lt_4_6. */
- unsigned int checked_producer : 1;
- unsigned int producer_is_gxx_lt_4_6 : 1;
- unsigned int producer_is_gcc_lt_4_3 : 1;
- unsigned int producer_is_icc_lt_14 : 1;
-
- /* When set, the file that we're processing is known to have
+ bool checked_producer : 1;
+ bool producer_is_gxx_lt_4_6 : 1;
+ bool producer_is_gcc_lt_4_3 : 1;
+ bool producer_is_icc : 1;
+ bool producer_is_icc_lt_14 : 1;
+ bool producer_is_codewarrior : 1;
+
+ /* When true, the file that we're processing is known to have
debugging info for C++ namespaces. GCC 3.3.x did not produce
this information, but later versions do. */
- unsigned int processing_has_namespace_info : 1;
+ bool processing_has_namespace_info : 1;
struct partial_die_info *find_partial_die (sect_offset sect_off);
+
+ /* If this CU was inherited by another CU (via specification,
+ abstract_origin, etc), this is the ancestor CU. */
+ dwarf2_cu *ancestor;
+
+ /* Get the buildsym_compunit for this CU. */
+ buildsym_compunit *get_builder ()
+ {
+ /* If this CU has a builder associated with it, use that. */
+ if (m_builder != nullptr)
+ return m_builder.get ();
+
+ /* Otherwise, search ancestors for a valid builder. */
+ if (ancestor != nullptr)
+ return ancestor->get_builder ();
+
+ return nullptr;
+ }
};
/* A struct that can be used as a hash key for tables based on DW_AT_stmt_list.
struct dwp_file
{
+ dwp_file (const char *name_, gdb_bfd_ref_ptr &&abfd)
+ : name (name_),
+ dbfd (std::move (abfd))
+ {
+ }
+
/* Name of the file. */
const char *name;
/* File format version. */
- int version;
+ int version = 0;
/* The bfd. */
- bfd *dbfd;
+ gdb_bfd_ref_ptr dbfd;
/* Section info for this file. */
- struct dwp_sections sections;
+ struct dwp_sections sections {};
/* Table of CUs in the file. */
- const struct dwp_hash_table *cus;
+ const struct dwp_hash_table *cus = nullptr;
/* Table of TUs in the file. */
- const struct dwp_hash_table *tus;
+ const struct dwp_hash_table *tus = nullptr;
/* Tables of loaded CUs/TUs. Each entry is a struct dwo_unit *. */
- htab_t loaded_cus;
- htab_t loaded_tus;
+ htab_t loaded_cus {};
+ htab_t loaded_tus {};
/* Table to map ELF section numbers to their sections.
This is only needed for the DWP V1 file format. */
- unsigned int num_sections;
- asection **elf_sections;
+ unsigned int num_sections = 0;
+ 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;
+ 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. */
- bfd *dwz_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
struct dwarf2_cu *, struct partial_symtab *,
CORE_ADDR, int decode_mapping);
-static void dwarf2_start_subfile (const char *, const char *);
-
-static struct compunit_symtab *dwarf2_start_symtab (struct dwarf2_cu *,
- const char *, const char *,
- CORE_ADDR);
+static void dwarf2_start_subfile (struct dwarf2_cu *, const char *,
+ const char *);
static struct symbol *new_symbol (struct die_info *, struct type *,
struct dwarf2_cu *, struct symbol * = NULL);
static void read_module (struct die_info *die, struct dwarf2_cu *cu);
-static struct using_direct **using_directives (enum language);
+static struct using_direct **using_directives (struct dwarf2_cu *cu);
static void read_import_statement (struct die_info *die, struct dwarf2_cu *);
static int create_all_type_units (struct dwarf2_per_objfile *dwarf2_per_objfile);
-static void load_full_comp_unit (struct dwarf2_per_cu_data *,
+static void load_full_comp_unit (struct dwarf2_per_cu_data *, bool,
enum language);
static void process_full_comp_unit (struct dwarf2_per_cu_data *,
static void init_cutu_and_read_dies
(struct dwarf2_per_cu_data *this_cu, struct abbrev_table *abbrev_table,
- int use_existing_cu, int keep,
+ int use_existing_cu, int keep, bool skip_partial,
die_reader_func_ftype *die_reader_func, void *data);
static void init_cutu_and_read_dies_simple
static void queue_and_load_all_dwo_tus (struct dwarf2_per_cu_data *);
-static void free_dwo_file_cleanup (void *);
+static void free_dwo_file (struct dwo_file *);
+
+/* A unique_ptr helper to free a dwo_file. */
-struct free_dwo_file_cleanup_data
+struct dwo_file_deleter
{
- struct dwo_file *dwo_file;
- struct dwarf2_per_objfile *dwarf2_per_objfile;
+ 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;
+
static void process_cu_includes (struct dwarf2_per_objfile *dwarf2_per_objfile);
static void check_producer (struct dwarf2_cu *cu);
static void
dwarf2_statement_list_fits_in_line_number_section_complaint (void)
{
- complaint (&symfile_complaints,
- _("statement list doesn't fit in .debug_line section"));
+ complaint (_("statement list doesn't fit in .debug_line section"));
}
static void
dwarf2_debug_line_missing_file_complaint (void)
{
- complaint (&symfile_complaints,
- _(".debug_line section has line data without a file"));
+ complaint (_(".debug_line section has line data without a file"));
}
static void
dwarf2_debug_line_missing_end_sequence_complaint (void)
{
- complaint (&symfile_complaints,
- _(".debug_line section has line "
+ complaint (_(".debug_line section has line "
"program sequence without an end"));
}
static void
dwarf2_complex_location_expr_complaint (void)
{
- complaint (&symfile_complaints, _("location expression too complex"));
+ complaint (_("location expression too complex"));
}
static void
dwarf2_const_value_length_mismatch_complaint (const char *arg1, int arg2,
int arg3)
{
- complaint (&symfile_complaints,
- _("const value length mismatch for '%s', got %d, expected %d"),
+ complaint (_("const value length mismatch for '%s', got %d, expected %d"),
arg1, arg2, arg3);
}
static void
dwarf2_section_buffer_overflow_complaint (struct dwarf2_section_info *section)
{
- complaint (&symfile_complaints,
- _("debug info runs off end of %s section"
+ complaint (_("debug info runs off end of %s section"
" [in module %s]"),
get_section_name (section),
get_section_file_name (section));
static void
dwarf2_macro_malformed_definition_complaint (const char *arg1)
{
- complaint (&symfile_complaints,
- _("macro debug info contains a "
+ complaint (_("macro debug info contains a "
"malformed macro definition:\n`%s'"),
arg1);
}
static void
dwarf2_invalid_attrib_class_complaint (const char *arg1, const char *arg2)
{
- complaint (&symfile_complaints,
- _("invalid attribute class or form for '%s' in '%s'"),
+ complaint (_("invalid attribute class or form for '%s' in '%s'"),
arg1, arg2);
}
if (line_header_hash)
htab_delete (line_header_hash);
- for (int ix = 0; ix < n_comp_units; ++ix)
- VEC_free (dwarf2_per_cu_ptr, all_comp_units[ix]->imported_symtabs);
+ for (dwarf2_per_cu_data *per_cu : all_comp_units)
+ VEC_free (dwarf2_per_cu_ptr, per_cu->imported_symtabs);
- for (int ix = 0; ix < n_type_units; ++ix)
- VEC_free (dwarf2_per_cu_ptr,
- all_type_units[ix]->per_cu.imported_symtabs);
- xfree (all_type_units);
+ 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);
- if (dwp_file != NULL)
- gdb_bfd_unref (dwp_file->dbfd);
-
- if (dwz_file != NULL && dwz_file->dwz_bfd)
- gdb_bfd_unref (dwz_file->dwz_bfd);
-
- if (index_table != NULL)
- index_table->~mapped_index ();
/* Everything else should be on the objfile obstack. */
}
dwarf2_get_dwz_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
const char *filename;
- struct dwz_file *result;
bfd_size_type buildid_len_arg;
size_t buildid_len;
bfd_byte *buildid;
if (dwarf2_per_objfile->dwz_file != NULL)
- return dwarf2_per_objfile->dwz_file;
+ return dwarf2_per_objfile->dwz_file.get ();
bfd_set_error (bfd_error_no_error);
gdb::unique_xmalloc_ptr<char> data
if (dwz_bfd != NULL)
{
if (!build_id_verify (dwz_bfd.get (), buildid_len, buildid))
- dwz_bfd.release ();
+ dwz_bfd.reset (nullptr);
}
if (dwz_bfd == NULL)
error (_("could not find '.gnu_debugaltlink' file for %s"),
objfile_name (dwarf2_per_objfile->objfile));
- result = OBSTACK_ZALLOC (&dwarf2_per_objfile->objfile->objfile_obstack,
- struct dwz_file);
- result->dwz_bfd = dwz_bfd.release ();
+ std::unique_ptr<struct dwz_file> result
+ (new struct dwz_file (std::move (dwz_bfd)));
- bfd_map_over_sections (result->dwz_bfd, locate_dwz_sections, result);
+ bfd_map_over_sections (result->dwz_bfd.get (), locate_dwz_sections,
+ result.get ());
- gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd, result->dwz_bfd);
- dwarf2_per_objfile->dwz_file = result;
- return result;
+ gdb_bfd_record_inclusion (dwarf2_per_objfile->objfile->obfd,
+ result->dwz_bfd.get ());
+ dwarf2_per_objfile->dwz_file = std::move (result);
+ return dwarf2_per_objfile->dwz_file.get ();
}
\f
/* DWARF quick_symbols_functions support. */
processing PER_CU->CU. dw2_setup must have been already called. */
static void
-load_cu (struct dwarf2_per_cu_data *per_cu)
+load_cu (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
{
if (per_cu->is_debug_types)
load_full_type_unit (per_cu);
else
- load_full_comp_unit (per_cu, language_minimal);
+ load_full_comp_unit (per_cu, skip_partial, language_minimal);
if (per_cu->cu == NULL)
return; /* Dummy CU. */
/* Read in the symbols for PER_CU. */
static void
-dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
+dw2_do_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
{
struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
: (per_cu->v.psymtab == NULL || !per_cu->v.psymtab->readin))
{
queue_comp_unit (per_cu, language_minimal);
- load_cu (per_cu);
+ load_cu (per_cu, skip_partial);
/* If we just loaded a CU from a DWO, and we're working with an index
that may badly handle TUs, load all the TUs in that DWO as well.
table. */
static struct compunit_symtab *
-dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu)
+dw2_instantiate_symtab (struct dwarf2_per_cu_data *per_cu, bool skip_partial)
{
struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
{
free_cached_comp_units freer (dwarf2_per_objfile);
scoped_restore decrementer = increment_reading_symtab ();
- dw2_do_instantiate_symtab (per_cu);
+ dw2_do_instantiate_symtab (per_cu, skip_partial);
process_cu_includes (dwarf2_per_objfile);
}
return per_cu->v.quick->compunit_symtab;
}
-/* Return the CU/TU given its index.
+/* See declaration. */
- This is intended for loops like:
+dwarf2_per_cu_data *
+dwarf2_per_objfile::get_cutu (int index)
+{
+ if (index >= this->all_comp_units.size ())
+ {
+ index -= this->all_comp_units.size ();
+ gdb_assert (index < this->all_type_units.size ());
+ return &this->all_type_units[index]->per_cu;
+ }
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_units); ++i)
- {
- struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (i);
+ return this->all_comp_units[index];
+}
- ...;
- }
-*/
+/* See declaration. */
-static struct dwarf2_per_cu_data *
-dw2_get_cutu (struct dwarf2_per_objfile *dwarf2_per_objfile,
- int index)
+dwarf2_per_cu_data *
+dwarf2_per_objfile::get_cu (int index)
{
- if (index >= dwarf2_per_objfile->n_comp_units)
- {
- index -= dwarf2_per_objfile->n_comp_units;
- gdb_assert (index < dwarf2_per_objfile->n_type_units);
- return &dwarf2_per_objfile->all_type_units[index]->per_cu;
- }
+ gdb_assert (index >= 0 && index < this->all_comp_units.size ());
- return dwarf2_per_objfile->all_comp_units[index];
+ return this->all_comp_units[index];
}
-/* Return the CU given its index.
- This differs from dw2_get_cutu in that it's for when you know INDEX
- refers to a CU. */
+/* See declaration. */
-static struct dwarf2_per_cu_data *
-dw2_get_cu (struct dwarf2_per_objfile *dwarf2_per_objfile, int index)
+signatured_type *
+dwarf2_per_objfile::get_tu (int index)
{
- gdb_assert (index >= 0 && index < dwarf2_per_objfile->n_comp_units);
+ gdb_assert (index >= 0 && index < this->all_type_units.size ());
- return dwarf2_per_objfile->all_comp_units[index];
+ return this->all_type_units[index];
}
/* Return a new dwarf2_per_cu_data allocated on OBJFILE's
CUs. */
static void
-create_cus_from_index_list (struct objfile *objfile,
+create_cus_from_index_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
const gdb_byte *cu_list, offset_type n_elements,
struct dwarf2_section_info *section,
- int is_dwz,
- int base_offset)
+ int is_dwz)
{
- offset_type i;
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = get_dwarf2_per_objfile (objfile);
-
- for (i = 0; i < n_elements; i += 2)
+ for (offset_type i = 0; i < n_elements; i += 2)
{
gdb_static_assert (sizeof (ULONGEST) >= 8);
ULONGEST length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE);
cu_list += 2 * 8;
- dwarf2_per_objfile->all_comp_units[base_offset + i / 2]
+ dwarf2_per_cu_data *per_cu
= create_cu_from_index_list (dwarf2_per_objfile, section, is_dwz,
sect_off, length);
+ dwarf2_per_objfile->all_comp_units.push_back (per_cu);
}
}
the CU objects for this objfile. */
static void
-create_cus_from_index (struct objfile *objfile,
+create_cus_from_index (struct dwarf2_per_objfile *dwarf2_per_objfile,
const gdb_byte *cu_list, offset_type cu_list_elements,
const gdb_byte *dwz_list, offset_type dwz_elements)
{
- struct dwz_file *dwz;
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = get_dwarf2_per_objfile (objfile);
-
- dwarf2_per_objfile->n_comp_units = (cu_list_elements + dwz_elements) / 2;
- dwarf2_per_objfile->all_comp_units =
- XOBNEWVEC (&objfile->objfile_obstack, struct dwarf2_per_cu_data *,
- dwarf2_per_objfile->n_comp_units);
+ gdb_assert (dwarf2_per_objfile->all_comp_units.empty ());
+ dwarf2_per_objfile->all_comp_units.reserve
+ ((cu_list_elements + dwz_elements) / 2);
- create_cus_from_index_list (objfile, cu_list, cu_list_elements,
- &dwarf2_per_objfile->info, 0, 0);
+ create_cus_from_index_list (dwarf2_per_objfile, cu_list, cu_list_elements,
+ &dwarf2_per_objfile->info, 0);
if (dwz_elements == 0)
return;
- dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
- create_cus_from_index_list (objfile, dwz_list, dwz_elements, &dwz->info, 1,
- cu_list_elements / 2);
+ dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+ create_cus_from_index_list (dwarf2_per_objfile, dwz_list, dwz_elements,
+ &dwz->info, 1);
}
/* Create the signatured type hash table from the index. */
static void
-create_signatured_type_table_from_index (struct objfile *objfile,
- struct dwarf2_section_info *section,
- const gdb_byte *bytes,
- offset_type elements)
+create_signatured_type_table_from_index
+ (struct dwarf2_per_objfile *dwarf2_per_objfile,
+ struct dwarf2_section_info *section,
+ const gdb_byte *bytes,
+ offset_type elements)
{
- offset_type i;
- htab_t sig_types_hash;
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = get_dwarf2_per_objfile (objfile);
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
- dwarf2_per_objfile->n_type_units
- = dwarf2_per_objfile->n_allocated_type_units
- = elements / 3;
- dwarf2_per_objfile->all_type_units =
- XNEWVEC (struct signatured_type *, dwarf2_per_objfile->n_type_units);
+ gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
+ dwarf2_per_objfile->all_type_units.reserve (elements / 3);
- sig_types_hash = allocate_signatured_type_table (objfile);
+ htab_t sig_types_hash = allocate_signatured_type_table (objfile);
- for (i = 0; i < elements; i += 3)
+ for (offset_type i = 0; i < elements; i += 3)
{
struct signatured_type *sig_type;
ULONGEST signature;
slot = htab_find_slot (sig_types_hash, sig_type, INSERT);
*slot = sig_type;
- dwarf2_per_objfile->all_type_units[i / 3] = sig_type;
+ dwarf2_per_objfile->all_type_units.push_back (sig_type);
}
dwarf2_per_objfile->signatured_types = sig_types_hash;
dwarf2_read_section (objfile, section);
dwarf2_read_section (objfile, abbrev_section);
- dwarf2_per_objfile->n_type_units
- = dwarf2_per_objfile->n_allocated_type_units
- = map.tu_count;
- dwarf2_per_objfile->all_type_units
- = XNEWVEC (struct signatured_type *, dwarf2_per_objfile->n_type_units);
+ gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
+ dwarf2_per_objfile->all_type_units.reserve (map.tu_count);
htab_t sig_types_hash = allocate_signatured_type_table (objfile);
for (uint32_t i = 0; i < map.tu_count; ++i)
{
struct signatured_type *sig_type;
- ULONGEST signature;
void **slot;
- cu_offset type_offset_in_tu;
sect_offset sect_off
= (sect_offset) (extract_unsigned_integer
slot = htab_find_slot (sig_types_hash, sig_type, INSERT);
*slot = sig_type;
- dwarf2_per_objfile->all_type_units[i] = sig_type;
+ dwarf2_per_objfile->all_type_units.push_back (sig_type);
}
dwarf2_per_objfile->signatured_types = sig_types_hash;
if (lo > hi)
{
- complaint (&symfile_complaints,
- _(".gdb_index address table has invalid range (%s - %s)"),
+ complaint (_(".gdb_index address table has invalid range (%s - %s)"),
hex_string (lo), hex_string (hi));
continue;
}
- if (cu_index >= dwarf2_per_objfile->n_comp_units)
+ if (cu_index >= dwarf2_per_objfile->all_comp_units.size ())
{
- complaint (&symfile_complaints,
- _(".gdb_index address table has invalid CU number %u"),
+ complaint (_(".gdb_index address table has invalid CU number %u"),
(unsigned) cu_index);
continue;
}
- lo = gdbarch_adjust_dwarf2_addr (gdbarch, lo + baseaddr);
- hi = gdbarch_adjust_dwarf2_addr (gdbarch, hi + baseaddr);
+ lo = gdbarch_adjust_dwarf2_addr (gdbarch, lo + baseaddr) - baseaddr;
+ hi = gdbarch_adjust_dwarf2_addr (gdbarch, hi + baseaddr) - baseaddr;
addrmap_set_empty (mutable_map, lo, hi - 1,
- dw2_get_cutu (dwarf2_per_objfile, cu_index));
+ dwarf2_per_objfile->get_cu (cu_index));
}
- objfile->psymtabs_addrmap = addrmap_create_fixed (mutable_map,
- &objfile->objfile_obstack);
+ objfile->partial_symtabs->psymtabs_addrmap
+ = addrmap_create_fixed (mutable_map, objfile->partial_symtabs->obstack ());
}
/* Read the address map data from DWARF-5 .debug_aranges, and use it to
dwarf2_per_cu_data *,
gdb::hash_enum<sect_offset>>
debug_info_offset_to_per_cu;
- for (int cui = 0; cui < dwarf2_per_objfile->n_comp_units; ++cui)
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
{
- dwarf2_per_cu_data *per_cu = dw2_get_cutu (dwarf2_per_objfile, cui);
const auto insertpair
= debug_info_offset_to_per_cu.emplace (per_cu->sect_off, per_cu);
if (!insertpair.second)
continue;
}
ULONGEST end = start + length;
- start = gdbarch_adjust_dwarf2_addr (gdbarch, start + baseaddr);
- end = gdbarch_adjust_dwarf2_addr (gdbarch, end + baseaddr);
+ start = (gdbarch_adjust_dwarf2_addr (gdbarch, start + baseaddr)
+ - baseaddr);
+ end = (gdbarch_adjust_dwarf2_addr (gdbarch, end + baseaddr)
+ - baseaddr);
addrmap_set_empty (mutable_map, start, end - 1, per_cu);
}
}
- objfile->psymtabs_addrmap = addrmap_create_fixed (mutable_map,
- &objfile->objfile_obstack);
+ objfile->partial_symtabs->psymtabs_addrmap
+ = addrmap_create_fixed (mutable_map, objfile->partial_symtabs->obstack ());
}
/* Find a slot in the mapped index INDEX for the object named NAME.
}
}
-/* A helper function that reads the .gdb_index from SECTION and fills
- in MAP. FILENAME is the name of the file containing the section;
- it is used for error reporting. DEPRECATED_OK is nonzero if it is
+/* A helper function that reads the .gdb_index from BUFFER and fills
+ in MAP. FILENAME is the name of the file containing the data;
+ it is used for error reporting. DEPRECATED_OK is true if it is
ok to use deprecated sections.
CU_LIST, CU_LIST_ELEMENTS, TYPES_LIST, and TYPES_LIST_ELEMENTS are
out parameters that are filled in with information about the CU and
TU lists in the section.
- Returns 1 if all went well, 0 otherwise. */
-
-static int
-read_index_from_section (struct objfile *objfile,
- const char *filename,
- int deprecated_ok,
- struct dwarf2_section_info *section,
- struct mapped_index *map,
- const gdb_byte **cu_list,
- offset_type *cu_list_elements,
- const gdb_byte **types_list,
- offset_type *types_list_elements)
-{
- const gdb_byte *addr;
- offset_type version;
- offset_type *metadata;
- int i;
-
- if (dwarf2_section_empty_p (section))
- return 0;
-
- /* Older elfutils strip versions could keep the section in the main
- executable while splitting it for the separate debug info file. */
- if ((get_section_flags (section) & SEC_HAS_CONTENTS) == 0)
- return 0;
+ Returns true if all went well, false otherwise. */
- dwarf2_read_section (objfile, section);
+static bool
+read_gdb_index_from_buffer (struct objfile *objfile,
+ const char *filename,
+ bool deprecated_ok,
+ gdb::array_view<const gdb_byte> buffer,
+ struct mapped_index *map,
+ const gdb_byte **cu_list,
+ offset_type *cu_list_elements,
+ const gdb_byte **types_list,
+ offset_type *types_list_elements)
+{
+ const gdb_byte *addr = &buffer[0];
- addr = section->buffer;
/* Version check. */
- version = MAYBE_SWAP (*(offset_type *) addr);
+ offset_type version = MAYBE_SWAP (*(offset_type *) addr);
/* Versions earlier than 3 emitted every copy of a psymbol. This
causes the index to behave very poorly for certain requests. Version 3
contained incomplete addrmap. So, it seems better to just ignore such
return 0;
map->version = version;
- map->total_size = section->size;
- metadata = (offset_type *) (addr + sizeof (offset_type));
+ offset_type *metadata = (offset_type *) (addr + sizeof (offset_type));
- i = 0;
+ int i = 0;
*cu_list = addr + MAYBE_SWAP (metadata[i]);
*cu_list_elements = ((MAYBE_SWAP (metadata[i + 1]) - MAYBE_SWAP (metadata[i]))
/ 8);
return 1;
}
+/* Callback types for dwarf2_read_gdb_index. */
+
+typedef gdb::function_view
+ <gdb::array_view<const gdb_byte>(objfile *, dwarf2_per_objfile *)>
+ get_gdb_index_contents_ftype;
+typedef gdb::function_view
+ <gdb::array_view<const gdb_byte>(objfile *, dwz_file *)>
+ get_gdb_index_contents_dwz_ftype;
+
/* Read .gdb_index. If everything went ok, initialize the "quick"
elements of all the CUs and return 1. Otherwise, return 0. */
static int
-dwarf2_read_index (struct objfile *objfile)
+dwarf2_read_gdb_index
+ (struct dwarf2_per_objfile *dwarf2_per_objfile,
+ get_gdb_index_contents_ftype get_gdb_index_contents,
+ get_gdb_index_contents_dwz_ftype get_gdb_index_contents_dwz)
{
- struct mapped_index local_map, *map;
const gdb_byte *cu_list, *types_list, *dwz_list = NULL;
offset_type cu_list_elements, types_list_elements, dwz_list_elements = 0;
struct dwz_file *dwz;
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = get_dwarf2_per_objfile (objfile);
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
- if (!read_index_from_section (objfile, objfile_name (objfile),
- use_deprecated_index_sections,
- &dwarf2_per_objfile->gdb_index, &local_map,
- &cu_list, &cu_list_elements,
- &types_list, &types_list_elements))
+ gdb::array_view<const gdb_byte> main_index_contents
+ = get_gdb_index_contents (objfile, dwarf2_per_objfile);
+
+ if (main_index_contents.empty ())
+ return 0;
+
+ std::unique_ptr<struct mapped_index> map (new struct mapped_index);
+ if (!read_gdb_index_from_buffer (objfile, objfile_name (objfile),
+ use_deprecated_index_sections,
+ main_index_contents, map.get (), &cu_list,
+ &cu_list_elements, &types_list,
+ &types_list_elements))
return 0;
/* Don't use the index if it's empty. */
- if (local_map.symbol_table.empty ())
+ if (map->symbol_table.empty ())
return 0;
/* If there is a .dwz file, read it so we can get its CU list as
const gdb_byte *dwz_types_ignore;
offset_type dwz_types_elements_ignore;
- if (!read_index_from_section (objfile, bfd_get_filename (dwz->dwz_bfd),
- 1,
- &dwz->gdb_index, &dwz_map,
- &dwz_list, &dwz_list_elements,
- &dwz_types_ignore,
- &dwz_types_elements_ignore))
+ gdb::array_view<const gdb_byte> dwz_index_content
+ = get_gdb_index_contents_dwz (objfile, dwz);
+
+ if (dwz_index_content.empty ())
+ return 0;
+
+ if (!read_gdb_index_from_buffer (objfile,
+ bfd_get_filename (dwz->dwz_bfd), 1,
+ dwz_index_content, &dwz_map,
+ &dwz_list, &dwz_list_elements,
+ &dwz_types_ignore,
+ &dwz_types_elements_ignore))
{
warning (_("could not read '.gdb_index' section from %s; skipping"),
bfd_get_filename (dwz->dwz_bfd));
}
}
- create_cus_from_index (objfile, cu_list, cu_list_elements, dwz_list,
- dwz_list_elements);
+ create_cus_from_index (dwarf2_per_objfile, cu_list, cu_list_elements,
+ dwz_list, dwz_list_elements);
if (types_list_elements)
{
section = VEC_index (dwarf2_section_info_def,
dwarf2_per_objfile->types, 0);
- create_signatured_type_table_from_index (objfile, section, types_list,
- types_list_elements);
+ create_signatured_type_table_from_index (dwarf2_per_objfile, section,
+ types_list, types_list_elements);
}
- create_addrmap_from_index (dwarf2_per_objfile, &local_map);
-
- map = XOBNEW (&objfile->objfile_obstack, struct mapped_index);
- map = new (map) mapped_index ();
- *map = local_map;
+ create_addrmap_from_index (dwarf2_per_objfile, map.get ());
- dwarf2_per_objfile->index_table = map;
+ dwarf2_per_objfile->index_table = std::move (map);
dwarf2_per_objfile->using_index = 1;
dwarf2_per_objfile->quick_file_names_table =
- create_quick_file_names_table (dwarf2_per_objfile->n_comp_units);
+ create_quick_file_names_table (dwarf2_per_objfile->all_comp_units.size ());
return 1;
}
{
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
- int index = dwarf2_per_objfile->n_comp_units - 1;
- dwarf2_per_cu_data *dwarf_cu = dw2_get_cutu (dwarf2_per_objfile, index);
- compunit_symtab *cust = dw2_instantiate_symtab (dwarf_cu);
+ dwarf2_per_cu_data *dwarf_cu = dwarf2_per_objfile->all_comp_units.back ();
+ compunit_symtab *cust = dw2_instantiate_symtab (dwarf_cu, false);
if (cust == NULL)
return NULL;
/* This may expand more than one symtab, and we want to iterate over
all of them. */
- dw2_instantiate_symtab (per_cu);
+ dw2_instantiate_symtab (per_cu, false);
return iterate_over_some_symtabs (name, real_path, objfile->compunit_symtabs,
last_made, callback);
(struct objfile *objfile, const char *name, const char *real_path,
gdb::function_view<bool (symtab *)> callback)
{
- int i;
const char *name_basename = lbasename (name);
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
/* The rule is CUs specify all the files, including those used by
any TU, so there's no need to scan TUs here. */
- for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
{
- int j;
- struct dwarf2_per_cu_data *per_cu = dw2_get_cu (dwarf2_per_objfile, i);
- struct quick_file_names *file_data;
-
/* We only need to look at symtabs not already expanded. */
if (per_cu->v.quick->compunit_symtab)
continue;
- file_data = dw2_get_file_names (per_cu);
+ quick_file_names *file_data = dw2_get_file_names (per_cu);
if (file_data == NULL)
continue;
- for (j = 0; j < file_data->num_file_names; ++j)
+ for (int j = 0; j < file_data->num_file_names; ++j)
{
const char *this_name = file_data->file_names[j];
const char *this_real_name;
iter->next = 0;
iter->global_seen = 0;
- mapped_index *index = dwarf2_per_objfile->index_table;
+ mapped_index *index = dwarf2_per_objfile->index_table.get ();
/* index is NULL if OBJF_READNOW. */
if (index != NULL && find_slot_in_mapped_hash (index, name, &iter->vec))
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);
- struct dwarf2_per_cu_data *per_cu;
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);
&& symbol_kind != GDB_INDEX_SYMBOL_KIND_NONE);
/* Don't crash on bad data. */
- if (cu_index >= (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_units))
+ if (cu_index >= (dwarf2_per_objfile->all_comp_units.size ()
+ + dwarf2_per_objfile->all_type_units.size ()))
{
- complaint (&symfile_complaints,
- _(".gdb_index entry has bad CU index"
+ complaint (_(".gdb_index entry has bad CU index"
" [in module %s]"),
objfile_name (dwarf2_per_objfile->objfile));
continue;
}
- per_cu = dw2_get_cutu (dwarf2_per_objfile, cu_index);
+ dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (cu_index);
/* Skip if already read in. */
if (per_cu->v.quick->compunit_symtab)
while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
{
struct symbol *sym, *with_opaque = NULL;
- struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu);
+ 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 dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
- int total = dwarf2_per_objfile->n_comp_units + dwarf2_per_objfile->n_type_units;
+ int total = (dwarf2_per_objfile->all_comp_units.size ()
+ + dwarf2_per_objfile->all_type_units.size ());
int count = 0;
for (int i = 0; i < total; ++i)
{
- struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (dwarf2_per_objfile, i);
+ dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
if (!per_cu->v.quick->compunit_symtab)
++count;
printf_filtered ("\n");
}
-static void
-dw2_relocate (struct objfile *objfile,
- const struct section_offsets *new_offsets,
- const struct section_offsets *delta)
-{
- /* There's nothing to relocate here. */
-}
-
static void
dw2_expand_symtabs_for_function (struct objfile *objfile,
const char *func_name)
func_name);
while ((per_cu = dw2_symtab_iter_next (&iter)) != NULL)
- dw2_instantiate_symtab (per_cu);
+ dw2_instantiate_symtab (per_cu, false);
}
{
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
- int total_units = (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_units);
+ int total_units = (dwarf2_per_objfile->all_comp_units.size ()
+ + dwarf2_per_objfile->all_type_units.size ());
for (int i = 0; i < total_units; ++i)
{
- struct dwarf2_per_cu_data *per_cu
- = dw2_get_cutu (dwarf2_per_objfile, i);
+ dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
- dw2_instantiate_symtab (per_cu);
+ /* We don't want to directly expand a partial CU, because if we
+ read it with the wrong language, then assertion failures can
+ be triggered later on. See PR symtab/23010. So, tell
+ dw2_instantiate_symtab to skip partial CUs -- any important
+ partial CU will be read via DW_TAG_imported_unit anyway. */
+ dw2_instantiate_symtab (per_cu, true);
}
}
There can be an order of magnitude (or more) more type units
than comp units, and we avoid them if we can. */
- for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
{
- int j;
- struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (dwarf2_per_objfile, i);
- struct quick_file_names *file_data;
-
/* We only need to look at symtabs not already expanded. */
if (per_cu->v.quick->compunit_symtab)
continue;
- file_data = dw2_get_file_names (per_cu);
+ quick_file_names *file_data = dw2_get_file_names (per_cu);
if (file_data == NULL)
continue;
- for (j = 0; j < file_data->num_file_names; ++j)
+ for (int j = 0; j < file_data->num_file_names; ++j)
{
const char *this_fullname = file_data->file_names[j];
if (filename_cmp (this_fullname, fullname) == 0)
{
- dw2_instantiate_symtab (per_cu);
+ dw2_instantiate_symtab (per_cu, false);
break;
}
}
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)
DISABLE_COPY_AND_ASSIGN (mock_mapped_index);
/* Return the number of names in the symbol table. */
- virtual size_t symbol_name_count () const
+ size_t symbol_name_count () const override
{
return m_symbol_table.size ();
}
/* Get the name of the symbol at IDX in the symbol table. */
- virtual const char *symbol_name_at (offset_type idx) const
+ const char *symbol_name_at (offset_type idx) const override
{
return m_symbol_table[idx];
}
bool symtab_was_null
= (per_cu->v.quick->compunit_symtab == NULL);
- dw2_instantiate_symtab (per_cu);
+ dw2_instantiate_symtab (per_cu, false);
if (expansion_notify != NULL
&& symtab_was_null
vec_len = MAYBE_SWAP (vec[0]);
for (vec_idx = 0; vec_idx < vec_len; ++vec_idx)
{
- struct dwarf2_per_cu_data *per_cu;
offset_type cu_index_and_attrs = MAYBE_SWAP (vec[vec_idx + 1]);
/* This value is only valid for index versions >= 7. */
int is_static = GDB_INDEX_SYMBOL_STATIC_VALUE (cu_index_and_attrs);
}
/* Don't crash on bad data. */
- if (cu_index >= (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_units))
+ if (cu_index >= (dwarf2_per_objfile->all_comp_units.size ()
+ + dwarf2_per_objfile->all_type_units.size ()))
{
- complaint (&symfile_complaints,
- _(".gdb_index entry has bad CU index"
+ complaint (_(".gdb_index entry has bad CU index"
" [in module %s]"),
objfile_name (dwarf2_per_objfile->objfile));
continue;
}
- per_cu = dw2_get_cutu (dwarf2_per_objfile, cu_index);
+ dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (cu_index);
dw2_expand_symtabs_matching_one (per_cu, file_matcher,
expansion_notify);
}
/* The rule is CUs specify all the files, including those used by
any TU, so there's no need to scan TUs here. */
- for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
{
- int j;
- struct dwarf2_per_cu_data *per_cu = dw2_get_cu (dwarf2_per_objfile, i);
- struct quick_file_names *file_data;
- void **slot;
-
QUIT;
per_cu->v.quick->mark = 0;
if (per_cu->v.quick->compunit_symtab)
continue;
- file_data = dw2_get_file_names (per_cu);
+ quick_file_names *file_data = dw2_get_file_names (per_cu);
if (file_data == NULL)
continue;
continue;
}
- for (j = 0; j < file_data->num_file_names; ++j)
+ for (int j = 0; j < file_data->num_file_names; ++j)
{
const char *this_real_name;
}
}
- slot = htab_find_slot (per_cu->v.quick->mark
- ? visited_found.get ()
- : visited_not_found.get (),
- file_data, INSERT);
+ void **slot = htab_find_slot (per_cu->v.quick->mark
+ ? visited_found.get ()
+ : visited_not_found.get (),
+ file_data, INSERT);
*slot = file_data;
}
}
struct dwarf2_per_cu_data *data;
struct compunit_symtab *result;
- if (!objfile->psymtabs_addrmap)
+ if (!objfile->partial_symtabs->psymtabs_addrmap)
return NULL;
- data = (struct dwarf2_per_cu_data *) addrmap_find (objfile->psymtabs_addrmap,
- pc);
+ CORE_ADDR baseaddr = ANOFFSET (objfile->section_offsets,
+ SECT_OFF_TEXT (objfile));
+ data = (struct dwarf2_per_cu_data *) addrmap_find
+ (objfile->partial_symtabs->psymtabs_addrmap, pc - baseaddr);
if (!data)
return NULL;
paddress (get_objfile_arch (objfile), pc));
result
- = recursively_find_pc_sect_compunit_symtab (dw2_instantiate_symtab (data),
+ = recursively_find_pc_sect_compunit_symtab (dw2_instantiate_symtab (data,
+ false),
pc);
gdb_assert (result != NULL);
return result;
by any TU, so there's no need to scan TUs here. We can
ignore file names coming from already-expanded CUs. */
- for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
{
- dwarf2_per_cu_data *per_cu = dw2_get_cutu (dwarf2_per_objfile, i);
-
if (per_cu->v.quick->compunit_symtab)
{
void **slot = htab_find_slot (visited.get (),
}
}
- for (int i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
{
- dwarf2_per_cu_data *per_cu = dw2_get_cu (dwarf2_per_objfile, i);
- struct quick_file_names *file_data;
- void **slot;
-
/* We only need to look at symtabs not already expanded. */
if (per_cu->v.quick->compunit_symtab)
continue;
- file_data = dw2_get_file_names (per_cu);
+ quick_file_names *file_data = dw2_get_file_names (per_cu);
if (file_data == NULL)
continue;
- slot = htab_find_slot (visited.get (), file_data, INSERT);
+ void **slot = htab_find_slot (visited.get (), file_data, INSERT);
if (*slot)
{
/* Already visited. */
dw2_lookup_symbol,
dw2_print_stats,
dw2_dump,
- dw2_relocate,
dw2_expand_symtabs_for_function,
dw2_expand_all_symtabs,
dw2_expand_symtabs_with_fullname,
const gdb_byte *abbrev_table_start = addr;
for (;;)
{
- unsigned int bytes_read;
const ULONGEST index_num = read_unsigned_leb128 (abfd, addr, &bytes_read);
addr += bytes_read;
if (index_num == 0)
create_cus_from_debug_names_list (struct dwarf2_per_objfile *dwarf2_per_objfile,
const mapped_debug_names &map,
dwarf2_section_info §ion,
- bool is_dwz, int base_offset)
+ bool is_dwz)
{
sect_offset sect_off_prev;
for (uint32_t i = 0; i <= map.cu_count; ++i)
if (i >= 1)
{
const ULONGEST length = sect_off_next - sect_off_prev;
- dwarf2_per_objfile->all_comp_units[base_offset + (i - 1)]
+ dwarf2_per_cu_data *per_cu
= create_cu_from_index_list (dwarf2_per_objfile, §ion, is_dwz,
sect_off_prev, length);
+ dwarf2_per_objfile->all_comp_units.push_back (per_cu);
}
sect_off_prev = sect_off_next;
}
const mapped_debug_names &map,
const mapped_debug_names &dwz_map)
{
- struct objfile *objfile = dwarf2_per_objfile->objfile;
-
- dwarf2_per_objfile->n_comp_units = map.cu_count + dwz_map.cu_count;
- dwarf2_per_objfile->all_comp_units
- = XOBNEWVEC (&objfile->objfile_obstack, struct dwarf2_per_cu_data *,
- dwarf2_per_objfile->n_comp_units);
+ gdb_assert (dwarf2_per_objfile->all_comp_units.empty ());
+ dwarf2_per_objfile->all_comp_units.reserve (map.cu_count + dwz_map.cu_count);
create_cus_from_debug_names_list (dwarf2_per_objfile, map,
dwarf2_per_objfile->info,
- false /* is_dwz */,
- 0 /* base_offset */);
+ false /* is_dwz */);
if (dwz_map.cu_count == 0)
return;
dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
create_cus_from_debug_names_list (dwarf2_per_objfile, dwz_map, dwz->info,
- true /* is_dwz */,
- map.cu_count /* base_offset */);
+ true /* is_dwz */);
}
/* Read .debug_names. If everything went ok, initialize the "quick"
static bool
dwarf2_read_debug_names (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
- mapped_debug_names local_map (dwarf2_per_objfile);
+ std::unique_ptr<mapped_debug_names> map
+ (new mapped_debug_names (dwarf2_per_objfile));
mapped_debug_names dwz_map (dwarf2_per_objfile);
struct objfile *objfile = dwarf2_per_objfile->objfile;
if (!read_debug_names_from_section (objfile, objfile_name (objfile),
&dwarf2_per_objfile->debug_names,
- local_map))
+ *map))
return false;
/* Don't use the index if it's empty. */
- if (local_map.name_count == 0)
+ if (map->name_count == 0)
return false;
/* If there is a .dwz file, read it so we can get its CU list as
}
}
- create_cus_from_debug_names (dwarf2_per_objfile, local_map, dwz_map);
+ create_cus_from_debug_names (dwarf2_per_objfile, *map, dwz_map);
- if (local_map.tu_count != 0)
+ if (map->tu_count != 0)
{
/* We can only handle a single .debug_types when we have an
index. */
dwarf2_per_objfile->types, 0);
create_signatured_type_table_from_debug_names
- (dwarf2_per_objfile, local_map, section, &dwarf2_per_objfile->abbrev);
+ (dwarf2_per_objfile, *map, section, &dwarf2_per_objfile->abbrev);
}
create_addrmap_from_aranges (dwarf2_per_objfile,
&dwarf2_per_objfile->debug_aranges);
- dwarf2_per_objfile->debug_names_table.reset
- (new mapped_debug_names (dwarf2_per_objfile));
- *dwarf2_per_objfile->debug_names_table = std::move (local_map);
+ dwarf2_per_objfile->debug_names_table = std::move (map);
dwarf2_per_objfile->using_index = 1;
dwarf2_per_objfile->quick_file_names_table =
- create_quick_file_names_table (dwarf2_per_objfile->n_comp_units);
+ create_quick_file_names_table (dwarf2_per_objfile->all_comp_units.size ());
return true;
}
--namei;
if (namei >= map.name_count)
{
- complaint (&symfile_complaints,
- _("Wrong .debug_names with name index %u but name_count=%u "
+ complaint (_("Wrong .debug_names with name index %u but name_count=%u "
"[in module %s]"),
namei, map.name_count,
objfile_name (map.dwarf2_per_objfile->objfile));
#if 0 /* An expensive sanity check. */
if (namei_full_hash != dwarf5_djb_hash (namei_string))
{
- complaint (&symfile_complaints,
- _("Wrong .debug_names hash for string at index %u "
+ complaint (_("Wrong .debug_names hash for string at index %u "
"[in module %s]"),
namei, objfile_name (dwarf2_per_objfile->objfile));
return NULL;
{
if (namei >= map.name_count)
{
- complaint (&symfile_complaints,
- _("Wrong .debug_names with name index %u but name_count=%u "
+ complaint (_("Wrong .debug_names with name index %u but name_count=%u "
"[in module %s]"),
namei, map.name_count,
objfile_name (map.dwarf2_per_objfile->objfile));
const auto indexval_it = m_map.abbrev_map.find (abbrev);
if (indexval_it == m_map.abbrev_map.cend ())
{
- complaint (&symfile_complaints,
- _("Wrong .debug_names undefined abbrev code %s "
+ complaint (_("Wrong .debug_names undefined abbrev code %s "
"[in module %s]"),
pulongest (abbrev), objfile_name (objfile));
return NULL;
m_addr += bytes_read;
break;
default:
- complaint (&symfile_complaints,
- _("Unsupported .debug_names form %s [in module %s]"),
+ complaint (_("Unsupported .debug_names form %s [in module %s]"),
dwarf_form_name (attr.form),
objfile_name (objfile));
return NULL;
{
case DW_IDX_compile_unit:
/* Don't crash on bad data. */
- if (ull >= dwarf2_per_objfile->n_comp_units)
+ if (ull >= dwarf2_per_objfile->all_comp_units.size ())
{
- complaint (&symfile_complaints,
- _(".debug_names entry has bad CU index %s"
+ complaint (_(".debug_names entry has bad CU index %s"
" [in module %s]"),
pulongest (ull),
objfile_name (dwarf2_per_objfile->objfile));
continue;
}
- per_cu = dw2_get_cutu (dwarf2_per_objfile, ull);
+ per_cu = dwarf2_per_objfile->get_cutu (ull);
break;
case DW_IDX_type_unit:
/* Don't crash on bad data. */
- if (ull >= dwarf2_per_objfile->n_type_units)
+ if (ull >= dwarf2_per_objfile->all_type_units.size ())
{
- complaint (&symfile_complaints,
- _(".debug_names entry has bad TU index %s"
+ complaint (_(".debug_names entry has bad TU index %s"
" [in module %s]"),
pulongest (ull),
objfile_name (dwarf2_per_objfile->objfile));
continue;
}
- per_cu = dw2_get_cutu (dwarf2_per_objfile,
- dwarf2_per_objfile->n_comp_units + ull);
+ per_cu = &dwarf2_per_objfile->get_tu (ull)->per_cu;
break;
case DW_IDX_GNU_internal:
if (!m_map.augmentation_is_gdb)
while ((per_cu = iter.next ()) != NULL)
{
struct symbol *sym, *with_opaque = NULL;
- struct compunit_symtab *stab = dw2_instantiate_symtab (per_cu);
+ 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 dwarf2_per_cu_data *per_cu;
while ((per_cu = iter.next ()) != NULL)
- dw2_instantiate_symtab (per_cu);
+ dw2_instantiate_symtab (per_cu, false);
}
}
dw2_debug_names_lookup_symbol,
dw2_print_stats,
dw2_debug_names_dump,
- dw2_relocate,
dw2_debug_names_expand_symtabs_for_function,
dw2_expand_all_symtabs,
dw2_expand_symtabs_with_fullname,
dw2_map_symbol_filenames
};
+/* Get the content of the .gdb_index section of OBJ. SECTION_OWNER should point
+ to either a dwarf2_per_objfile or dwz_file object. */
+
+template <typename T>
+static gdb::array_view<const gdb_byte>
+get_gdb_index_contents_from_section (objfile *obj, T *section_owner)
+{
+ dwarf2_section_info *section = §ion_owner->gdb_index;
+
+ if (dwarf2_section_empty_p (section))
+ return {};
+
+ /* Older elfutils strip versions could keep the section in the main
+ executable while splitting it for the separate debug info file. */
+ if ((get_section_flags (section) & SEC_HAS_CONTENTS) == 0)
+ return {};
+
+ dwarf2_read_section (obj, section);
+
+ /* dwarf2_section_info::size is a bfd_size_type, while
+ gdb::array_view works with size_t. On 32-bit hosts, with
+ --enable-64-bit-bfd, bfd_size_type is a 64-bit type, while size_t
+ is 32-bit. So we need an explicit narrowing conversion here.
+ This is fine, because it's impossible to allocate or mmap an
+ array/buffer larger than what size_t can represent. */
+ return gdb::make_array_view (section->buffer, section->size);
+}
+
+/* Lookup the index cache for the contents of the index associated to
+ DWARF2_OBJ. */
+
+static gdb::array_view<const gdb_byte>
+get_gdb_index_contents_from_cache (objfile *obj, dwarf2_per_objfile *dwarf2_obj)
+{
+ const bfd_build_id *build_id = build_id_bfd_get (obj->obfd);
+ if (build_id == nullptr)
+ return {};
+
+ return global_index_cache.lookup_gdb_index (build_id,
+ &dwarf2_obj->index_cache_res);
+}
+
+/* Same as the above, but for DWZ. */
+
+static gdb::array_view<const gdb_byte>
+get_gdb_index_contents_from_cache_dwz (objfile *obj, dwz_file *dwz)
+{
+ const bfd_build_id *build_id = build_id_bfd_get (dwz->dwz_bfd.get ());
+ if (build_id == nullptr)
+ return {};
+
+ return global_index_cache.lookup_gdb_index (build_id, &dwz->index_cache_res);
+}
+
/* See symfile.h. */
bool
expanded anyway. */
if ((objfile->flags & OBJF_READNOW))
{
- int i;
-
dwarf2_per_objfile->using_index = 1;
create_all_comp_units (dwarf2_per_objfile);
create_all_type_units (dwarf2_per_objfile);
- dwarf2_per_objfile->quick_file_names_table =
- create_quick_file_names_table (dwarf2_per_objfile->n_comp_units);
+ dwarf2_per_objfile->quick_file_names_table
+ = create_quick_file_names_table
+ (dwarf2_per_objfile->all_comp_units.size ());
- for (i = 0; i < (dwarf2_per_objfile->n_comp_units
- + dwarf2_per_objfile->n_type_units); ++i)
+ for (int i = 0; i < (dwarf2_per_objfile->all_comp_units.size ()
+ + dwarf2_per_objfile->all_type_units.size ()); ++i)
{
- dwarf2_per_cu_data *per_cu = dw2_get_cutu (dwarf2_per_objfile, i);
+ dwarf2_per_cu_data *per_cu = dwarf2_per_objfile->get_cutu (i);
per_cu->v.quick = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct dwarf2_per_cu_quick_data);
return true;
}
- if (dwarf2_read_index (objfile))
+ if (dwarf2_read_gdb_index (dwarf2_per_objfile,
+ get_gdb_index_contents_from_section<struct dwarf2_per_objfile>,
+ get_gdb_index_contents_from_section<dwz_file>))
{
*index_kind = dw_index_kind::GDB_INDEX;
return true;
}
+ /* ... otherwise, try to find the index in the index cache. */
+ if (dwarf2_read_gdb_index (dwarf2_per_objfile,
+ get_gdb_index_contents_from_cache,
+ get_gdb_index_contents_from_cache_dwz))
+ {
+ global_index_cache.hit ();
+ *index_kind = dw_index_kind::GDB_INDEX;
+ return true;
+ }
+
+ global_index_cache.miss ();
return false;
}
struct dwarf2_per_objfile *dwarf2_per_objfile
= get_dwarf2_per_objfile (objfile);
- if (objfile->global_psymbols.capacity () == 0
- && objfile->static_psymbols.capacity () == 0)
- init_psymbol_list (objfile, 1024);
+ 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,
psymtab_discarder psymtabs (objfile);
dwarf2_build_psymtabs_hard (dwarf2_per_objfile);
psymtabs.keep ();
+
+ /* (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. */
cu_header->offset_size = (bytes_read == 4) ? 4 : 8;
info_ptr += bytes_read;
cu_header->version = read_2_bytes (abfd, info_ptr);
+ if (cu_header->version < 2 || cu_header->version > 5)
+ error (_("Dwarf Error: wrong version in compilation unit header "
+ "(is %d, should be 2, 3, 4 or 5) [in module %s]"),
+ cu_header->version, filename);
info_ptr += 2;
if (cu_header->version < 5)
switch (section_kind)
{
const char *filename = get_section_file_name (section);
- if (header->version < 2 || header->version > 5)
- error (_("Dwarf Error: wrong version in compilation unit header "
- "(is %d, should be 2, 3, 4 or 5) [in module %s]"), header->version,
- filename);
-
if (to_underlying (header->abbrev_sect_off)
>= dwarf2_section_size (dwarf2_per_objfile->objfile, abbrev_section))
error (_("Dwarf Error: bad offset (%s) in compilation unit header "
subpst->dirname = pst->dirname;
}
- subpst->textlow = 0;
- subpst->texthigh = 0;
-
- subpst->dependencies
- = XOBNEW (&objfile->objfile_obstack, struct partial_symtab *);
+ subpst->dependencies = objfile->partial_symtabs->allocate_dependencies (1);
subpst->dependencies[0] = pst;
subpst->number_of_dependencies = 1;
- subpst->globals_offset = 0;
- subpst->n_global_syms = 0;
- subpst->statics_offset = 0;
- subpst->n_static_syms = 0;
- subpst->compunit_symtab = NULL;
subpst->read_symtab = pst->read_symtab;
- subpst->readin = 0;
/* No private part is necessary for include psymtabs. This property
can be used to differentiate between such include psymtabs and
if (lh == NULL)
return; /* No linetable, so no includes. */
- /* NOTE: pst->dirname is DW_AT_comp_dir (if present). */
- dwarf_decode_lines (lh.get (), pst->dirname, cu, pst, pst->textlow, 1);
+ /* NOTE: pst->dirname is DW_AT_comp_dir (if present). Also note
+ that we pass in the raw text_low here; that is ok because we're
+ only decoding the line table to make include partial symtabs, and
+ so the addresses aren't really used. */
+ dwarf_decode_lines (lh.get (), pst->dirname, cu, pst,
+ pst->raw_text_low (), 1);
}
static hashval_t
add_signatured_type_cu_to_table (void **slot, void *datum)
{
struct signatured_type *sigt = (struct signatured_type *) *slot;
- struct signatured_type ***datap = (struct signatured_type ***) datum;
+ std::vector<signatured_type *> *all_type_units
+ = (std::vector<signatured_type *> *) datum;
- **datap = sigt;
- ++*datap;
+ all_type_units->push_back (sigt);
return 1;
}
dup_sect_off = dup_tu->per_cu.sect_off;
}
- complaint (&symfile_complaints,
- _("debug type entry at offset %s is duplicate to"
+ complaint (_("debug type entry at offset %s is duplicate to"
" the entry at offset %s, signature %s"),
sect_offset_str (sect_off), sect_offset_str (dup_sect_off),
hex_string (header.signature));
create_all_type_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
htab_t types_htab = NULL;
- struct signatured_type **iter;
create_debug_type_hash_table (dwarf2_per_objfile, NULL,
&dwarf2_per_objfile->info, types_htab,
dwarf2_per_objfile->signatured_types = types_htab;
- dwarf2_per_objfile->n_type_units
- = dwarf2_per_objfile->n_allocated_type_units
- = htab_elements (types_htab);
- dwarf2_per_objfile->all_type_units =
- XNEWVEC (struct signatured_type *, dwarf2_per_objfile->n_type_units);
- iter = &dwarf2_per_objfile->all_type_units[0];
- htab_traverse_noresize (types_htab, add_signatured_type_cu_to_table, &iter);
- gdb_assert (iter - &dwarf2_per_objfile->all_type_units[0]
- == dwarf2_per_objfile->n_type_units);
+ gdb_assert (dwarf2_per_objfile->all_type_units.empty ());
+ dwarf2_per_objfile->all_type_units.reserve (htab_elements (types_htab));
+
+ htab_traverse_noresize (types_htab, add_signatured_type_cu_to_table,
+ &dwarf2_per_objfile->all_type_units);
return 1;
}
void **slot)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
- int n_type_units = dwarf2_per_objfile->n_type_units;
- struct signatured_type *sig_type;
- gdb_assert (n_type_units <= dwarf2_per_objfile->n_allocated_type_units);
- ++n_type_units;
- if (n_type_units > dwarf2_per_objfile->n_allocated_type_units)
- {
- if (dwarf2_per_objfile->n_allocated_type_units == 0)
- dwarf2_per_objfile->n_allocated_type_units = 1;
- dwarf2_per_objfile->n_allocated_type_units *= 2;
- dwarf2_per_objfile->all_type_units
- = XRESIZEVEC (struct signatured_type *,
- dwarf2_per_objfile->all_type_units,
- dwarf2_per_objfile->n_allocated_type_units);
- ++dwarf2_per_objfile->tu_stats.nr_all_type_units_reallocs;
- }
- dwarf2_per_objfile->n_type_units = n_type_units;
+ if (dwarf2_per_objfile->all_type_units.size ()
+ == dwarf2_per_objfile->all_type_units.capacity ())
+ ++dwarf2_per_objfile->tu_stats.nr_all_type_units_reallocs;
- sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct signatured_type);
- dwarf2_per_objfile->all_type_units[n_type_units - 1] = sig_type;
+ signatured_type *sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct signatured_type);
+
+ dwarf2_per_objfile->all_type_units.push_back (sig_type);
sig_type->signature = sig;
sig_type->per_cu.is_debug_types = 1;
if (dwarf2_per_objfile->using_index)
init_cutu_and_read_dies (struct dwarf2_per_cu_data *this_cu,
struct abbrev_table *abbrev_table,
int use_existing_cu, int keep,
+ bool skip_partial,
die_reader_func_ftype *die_reader_func,
void *data)
{
init_cu_die_reader (&reader, cu, section, NULL, abbrev_table);
info_ptr = read_full_die (&reader, &comp_unit_die, info_ptr, &has_children);
+ if (skip_partial && comp_unit_die->tag == DW_TAG_partial_unit)
+ return;
+
/* If we are in a DWO stub, process it and then read in the "real" CU/TU
from the DWO file. read_cutu_die_from_dwo will allocate the abbreviation
table from the DWO file and pass the ownership over to us. It will be
if (has_children)
{
- complaint (&symfile_complaints,
- _("compilation unit with DW_AT_GNU_dwo_name"
+ complaint (_("compilation unit with DW_AT_GNU_dwo_name"
" has children (offset %s) [in module %s]"),
sect_offset_str (this_cu->sect_off),
bfd_get_filename (abfd));
{
unsigned int line_offset = to_underlying (line_offset_struct);
struct partial_symtab *pst;
- char *name;
+ std::string name;
/* Give the symtab a useful name for debug purposes. */
if ((line_offset & NO_STMT_LIST_TYPE_UNIT_PSYMTAB) != 0)
- name = xstrprintf ("<type_units_%d>",
- (line_offset & ~NO_STMT_LIST_TYPE_UNIT_PSYMTAB));
+ name = string_printf ("<type_units_%d>",
+ (line_offset & ~NO_STMT_LIST_TYPE_UNIT_PSYMTAB));
else
- name = xstrprintf ("<type_units_at_0x%x>", line_offset);
+ name = string_printf ("<type_units_at_0x%x>", line_offset);
- pst = create_partial_symtab (per_cu, name);
+ pst = create_partial_symtab (per_cu, name.c_str ());
pst->anonymous = 1;
-
- xfree (name);
}
tu_group->hash.dwo_unit = cu->dwo_unit;
struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
struct partial_symtab *pst;
- pst = start_psymtab_common (objfile, name, 0,
- objfile->global_psymbols,
- objfile->static_psymbols);
+ pst = start_psymtab_common (objfile, name, 0);
pst->psymtabs_addrmap_supported = 1;
prepare_one_comp_unit (cu, comp_unit_die, info->pretend_language);
- cu->list_in_scope = &file_symbols;
-
/* Allocate a new partial symbol table structure. */
filename = dwarf2_string_attr (comp_unit_die, DW_AT_name, cu);
if (filename == NULL)
cu_bounds_kind = dwarf2_get_pc_bounds (comp_unit_die, &best_lowpc,
&best_highpc, cu, pst);
if (cu_bounds_kind == PC_BOUNDS_HIGH_LOW && best_lowpc < best_highpc)
- /* Store the contiguous range if it is not empty; it can be empty for
- CUs with no code. */
- addrmap_set_empty (objfile->psymtabs_addrmap,
- gdbarch_adjust_dwarf2_addr (gdbarch,
- best_lowpc + baseaddr),
- gdbarch_adjust_dwarf2_addr (gdbarch,
- best_highpc + baseaddr) - 1,
- pst);
+ {
+ CORE_ADDR low
+ = (gdbarch_adjust_dwarf2_addr (gdbarch, best_lowpc + baseaddr)
+ - baseaddr);
+ CORE_ADDR high
+ = (gdbarch_adjust_dwarf2_addr (gdbarch, best_highpc + baseaddr)
+ - baseaddr - 1);
+ /* Store the contiguous range if it is not empty; it can be
+ empty for CUs with no code. */
+ addrmap_set_empty (objfile->partial_symtabs->psymtabs_addrmap,
+ low, high, pst);
+ }
/* Check if comp unit has_children.
If so, read the rest of the partial symbols from this comp unit.
best_highpc = highpc;
}
}
- pst->textlow = gdbarch_adjust_dwarf2_addr (gdbarch, best_lowpc + baseaddr);
- pst->texthigh = gdbarch_adjust_dwarf2_addr (gdbarch, best_highpc + baseaddr);
+ pst->set_text_low (gdbarch_adjust_dwarf2_addr (gdbarch,
+ best_lowpc + baseaddr)
+ - baseaddr);
+ pst->set_text_high (gdbarch_adjust_dwarf2_addr (gdbarch,
+ best_highpc + baseaddr)
+ - baseaddr);
end_psymtab_common (objfile, pst);
/* Fill in 'dependencies' here; we fill in 'users' in a
post-pass. */
pst->number_of_dependencies = len;
- pst->dependencies =
- XOBNEWVEC (&objfile->objfile_obstack, struct partial_symtab *, len);
+ pst->dependencies
+ = objfile->partial_symtabs->allocate_dependencies (len);
for (i = 0;
VEC_iterate (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
i, iter);
dwarf2_build_include_psymtabs (cu, comp_unit_die, pst);
if (dwarf_read_debug)
- {
- struct gdbarch *gdbarch = get_objfile_arch (objfile);
-
- fprintf_unfiltered (gdb_stdlog,
- "Psymtab for %s unit @%s: %s - %s"
- ", %d global, %d static syms\n",
- per_cu->is_debug_types ? "type" : "comp",
- sect_offset_str (per_cu->sect_off),
- paddress (gdbarch, pst->textlow),
- paddress (gdbarch, pst->texthigh),
- pst->n_global_syms, pst->n_static_syms);
- }
+ fprintf_unfiltered (gdb_stdlog,
+ "Psymtab for %s unit @%s: %s - %s"
+ ", %d global, %d static syms\n",
+ per_cu->is_debug_types ? "type" : "comp",
+ sect_offset_str (per_cu->sect_off),
+ paddress (gdbarch, pst->text_low (objfile)),
+ paddress (gdbarch, pst->text_high (objfile)),
+ pst->n_global_syms, pst->n_static_syms);
}
/* Subroutine of dwarf2_build_psymtabs_hard to simplify it.
free_one_cached_comp_unit (this_cu);
if (this_cu->is_debug_types)
- init_cutu_and_read_dies (this_cu, NULL, 0, 0, build_type_psymtabs_reader,
- NULL);
+ init_cutu_and_read_dies (this_cu, NULL, 0, 0, false,
+ build_type_psymtabs_reader, NULL);
else
{
process_psymtab_comp_unit_data info;
info.want_partial_unit = want_partial_unit;
info.pretend_language = pretend_language;
- init_cutu_and_read_dies (this_cu, NULL, 0, 0,
+ init_cutu_and_read_dies (this_cu, NULL, 0, 0, false,
process_psymtab_comp_unit_reader, &info);
}
VEC_safe_push (sig_type_ptr, tu_group->tus, sig_type);
prepare_one_comp_unit (cu, type_unit_die, language_minimal);
- cu->list_in_scope = &file_symbols;
pst = create_partial_symtab (per_cu, "");
pst->anonymous = 1;
struct tu_abbrev_offset
{
- struct signatured_type *sig_type;
+ tu_abbrev_offset (signatured_type *sig_type_, sect_offset abbrev_offset_)
+ : sig_type (sig_type_), abbrev_offset (abbrev_offset_)
+ {}
+
+ signatured_type *sig_type;
sect_offset abbrev_offset;
};
struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
abbrev_table_up abbrev_table;
sect_offset abbrev_offset;
- int i;
/* It's up to the caller to not call us multiple times. */
gdb_assert (dwarf2_per_objfile->type_unit_groups == NULL);
- if (dwarf2_per_objfile->n_type_units == 0)
+ if (dwarf2_per_objfile->all_type_units.empty ())
return;
/* TUs typically share abbrev tables, and there can be way more TUs than
/* Sort in a separate table to maintain the order of all_type_units
for .gdb_index: TU indices directly index all_type_units. */
- std::vector<struct tu_abbrev_offset> sorted_by_abbrev
- (dwarf2_per_objfile->n_type_units);
- for (i = 0; i < dwarf2_per_objfile->n_type_units; ++i)
- {
- struct signatured_type *sig_type = dwarf2_per_objfile->all_type_units[i];
+ std::vector<tu_abbrev_offset> sorted_by_abbrev;
+ sorted_by_abbrev.reserve (dwarf2_per_objfile->all_type_units.size ());
+
+ for (signatured_type *sig_type : dwarf2_per_objfile->all_type_units)
+ sorted_by_abbrev.emplace_back
+ (sig_type, read_abbrev_offset (dwarf2_per_objfile,
+ sig_type->per_cu.section,
+ sig_type->per_cu.sect_off));
- sorted_by_abbrev[i].sig_type = sig_type;
- sorted_by_abbrev[i].abbrev_offset =
- read_abbrev_offset (dwarf2_per_objfile,
- sig_type->per_cu.section,
- sig_type->per_cu.sect_off);
- }
std::sort (sorted_by_abbrev.begin (), sorted_by_abbrev.end (),
sort_tu_by_abbrev_offset);
abbrev_offset = (sect_offset) ~(unsigned) 0;
- for (i = 0; i < dwarf2_per_objfile->n_type_units; ++i)
+ for (const tu_abbrev_offset &tu : sorted_by_abbrev)
{
- const struct tu_abbrev_offset *tu = &sorted_by_abbrev[i];
-
/* Switch to the next abbrev table if necessary. */
if (abbrev_table == NULL
- || tu->abbrev_offset != abbrev_offset)
+ || tu.abbrev_offset != abbrev_offset)
{
- abbrev_offset = tu->abbrev_offset;
+ abbrev_offset = tu.abbrev_offset;
abbrev_table =
abbrev_table_read_table (dwarf2_per_objfile,
&dwarf2_per_objfile->abbrev,
++tu_stats->nr_uniq_abbrev_tables;
}
- init_cutu_and_read_dies (&tu->sig_type->per_cu, abbrev_table.get (),
- 0, 0, build_type_psymtabs_reader, NULL);
+ init_cutu_and_read_dies (&tu.sig_type->per_cu, abbrev_table.get (),
+ 0, 0, false, build_type_psymtabs_reader, NULL);
}
}
struct tu_stats *tu_stats = &dwarf2_per_objfile->tu_stats;
fprintf_unfiltered (gdb_stdlog, "Type unit statistics:\n");
- fprintf_unfiltered (gdb_stdlog, " %d TUs\n",
- dwarf2_per_objfile->n_type_units);
+ fprintf_unfiltered (gdb_stdlog, " %zu TUs\n",
+ dwarf2_per_objfile->all_type_units.size ());
fprintf_unfiltered (gdb_stdlog, " %d uniq abbrev tables\n",
tu_stats->nr_uniq_abbrev_tables);
fprintf_unfiltered (gdb_stdlog, " %d symtabs from stmt_list entries\n",
gdb_assert (IS_TYPE_UNIT_GROUP (per_cu));
pst->number_of_dependencies = len;
- pst->dependencies =
- XOBNEWVEC (&objfile->objfile_obstack, struct partial_symtab *, len);
+ pst->dependencies = objfile->partial_symtabs->allocate_dependencies (len);
for (i = 0;
VEC_iterate (sig_type_ptr, tu_group->tus, i, iter);
++i)
*slot = entry;
/* This does the job that build_type_psymtabs_1 would have done. */
- init_cutu_and_read_dies (&entry->per_cu, NULL, 0, 0,
+ init_cutu_and_read_dies (&entry->per_cu, NULL, 0, 0, false,
build_type_psymtabs_reader, NULL);
return 1;
static void
set_partial_user (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
- int i;
-
- for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
{
- struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (dwarf2_per_objfile, i);
struct partial_symtab *pst = per_cu->v.psymtab;
- int j;
if (pst == NULL)
continue;
- for (j = 0; j < pst->number_of_dependencies; ++j)
+ for (int j = 0; j < pst->number_of_dependencies; ++j)
{
/* Set the 'user' field only if it is not already set. */
if (pst->dependencies[j]->user == NULL)
static void
dwarf2_build_psymtabs_hard (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
- int i;
struct objfile *objfile = dwarf2_per_objfile->objfile;
if (dwarf_read_debug)
auto_obstack temp_obstack;
scoped_restore save_psymtabs_addrmap
- = make_scoped_restore (&objfile->psymtabs_addrmap,
+ = make_scoped_restore (&objfile->partial_symtabs->psymtabs_addrmap,
addrmap_create_mutable (&temp_obstack));
- for (i = 0; i < dwarf2_per_objfile->n_comp_units; ++i)
- {
- struct dwarf2_per_cu_data *per_cu = dw2_get_cutu (dwarf2_per_objfile, i);
-
- process_psymtab_comp_unit (per_cu, 0, language_minimal);
- }
+ for (dwarf2_per_cu_data *per_cu : dwarf2_per_objfile->all_comp_units)
+ process_psymtab_comp_unit (per_cu, 0, language_minimal);
/* This has to wait until we read the CUs, we need the list of DWOs. */
process_skeletonless_type_units (dwarf2_per_objfile);
set_partial_user (dwarf2_per_objfile);
- objfile->psymtabs_addrmap = addrmap_create_fixed (objfile->psymtabs_addrmap,
- &objfile->objfile_obstack);
+ objfile->partial_symtabs->psymtabs_addrmap
+ = addrmap_create_fixed (objfile->partial_symtabs->psymtabs_addrmap,
+ objfile->partial_symtabs->obstack ());
/* At this point we want to keep the address map. */
save_psymtabs_addrmap.release ();
static void
load_partial_comp_unit (struct dwarf2_per_cu_data *this_cu)
{
- init_cutu_and_read_dies (this_cu, NULL, 1, 1,
+ init_cutu_and_read_dies (this_cu, NULL, 1, 1, false,
load_partial_comp_unit_reader, NULL);
}
read_comp_units_from_section (struct dwarf2_per_objfile *dwarf2_per_objfile,
struct dwarf2_section_info *section,
struct dwarf2_section_info *abbrev_section,
- unsigned int is_dwz,
- int *n_allocated,
- int *n_comp_units,
- struct dwarf2_per_cu_data ***all_comp_units)
+ unsigned int is_dwz)
{
const gdb_byte *info_ptr;
struct objfile *objfile = dwarf2_per_objfile->objfile;
this_cu->dwarf2_per_objfile = dwarf2_per_objfile;
this_cu->section = section;
- if (*n_comp_units == *n_allocated)
- {
- *n_allocated *= 2;
- *all_comp_units = XRESIZEVEC (struct dwarf2_per_cu_data *,
- *all_comp_units, *n_allocated);
- }
- (*all_comp_units)[*n_comp_units] = this_cu;
- ++*n_comp_units;
+ dwarf2_per_objfile->all_comp_units.push_back (this_cu);
info_ptr = info_ptr + this_cu->length;
}
static void
create_all_comp_units (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
- int n_allocated;
- int n_comp_units;
- struct dwarf2_per_cu_data **all_comp_units;
- struct dwz_file *dwz;
- struct objfile *objfile = dwarf2_per_objfile->objfile;
-
- n_comp_units = 0;
- n_allocated = 10;
- all_comp_units = XNEWVEC (struct dwarf2_per_cu_data *, n_allocated);
-
+ gdb_assert (dwarf2_per_objfile->all_comp_units.empty ());
read_comp_units_from_section (dwarf2_per_objfile, &dwarf2_per_objfile->info,
- &dwarf2_per_objfile->abbrev, 0,
- &n_allocated, &n_comp_units, &all_comp_units);
+ &dwarf2_per_objfile->abbrev, 0);
- dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
+ dwz_file *dwz = dwarf2_get_dwz_file (dwarf2_per_objfile);
if (dwz != NULL)
read_comp_units_from_section (dwarf2_per_objfile, &dwz->info, &dwz->abbrev,
- 1, &n_allocated, &n_comp_units,
- &all_comp_units);
-
- dwarf2_per_objfile->all_comp_units = XOBNEWVEC (&objfile->objfile_obstack,
- struct dwarf2_per_cu_data *,
- n_comp_units);
- memcpy (dwarf2_per_objfile->all_comp_units, all_comp_units,
- n_comp_units * sizeof (struct dwarf2_per_cu_data *));
- xfree (all_comp_units);
- dwarf2_per_objfile->n_comp_units = n_comp_units;
+ 1);
}
/* Process all loaded DIEs for compilation unit CU, starting at
/* FIXME drow/2004-04-01: What should we be doing with
function-local names? For partial symbols, we should probably be
ignoring them. */
- complaint (&symfile_complaints,
- _("unhandled containing DIE tag %d for DIE at %s"),
+ complaint (_("unhandled containing DIE tag %d for DIE at %s"),
parent->tag, sect_offset_str (pdi->sect_off));
parent->scope = grandparent_scope;
}
{
case DW_TAG_inlined_subroutine:
case DW_TAG_subprogram:
- addr = gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + baseaddr);
+ addr = (gdbarch_adjust_dwarf2_addr (gdbarch, pdi->lowpc + baseaddr)
+ - baseaddr);
if (pdi->is_external || cu->language == language_ada)
{
/* brobecker/2007-12-26: Normally, only "external" DIEs are part
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
VAR_DOMAIN, LOC_BLOCK,
- &objfile->global_psymbols,
- addr, cu->language, objfile);
+ SECT_OFF_TEXT (objfile),
+ psymbol_placement::GLOBAL,
+ addr,
+ cu->language, objfile);
}
else
{
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
VAR_DOMAIN, LOC_BLOCK,
- &objfile->static_psymbols,
+ SECT_OFF_TEXT (objfile),
+ psymbol_placement::STATIC,
addr, cu->language, objfile);
}
set_objfile_main_name (objfile, actual_name, cu->language);
break;
case DW_TAG_constant:
- {
- std::vector<partial_symbol *> *list;
-
- if (pdi->is_external)
- list = &objfile->global_psymbols;
- else
- list = &objfile->static_psymbols;
- add_psymbol_to_list (actual_name, strlen (actual_name),
- built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC,
- list, 0, cu->language, objfile);
- }
+ add_psymbol_to_list (actual_name, strlen (actual_name),
+ built_actual_name != NULL, VAR_DOMAIN, LOC_STATIC,
+ -1, (pdi->is_external
+ ? psymbol_placement::GLOBAL
+ : psymbol_placement::STATIC),
+ 0, cu->language, objfile);
break;
case DW_TAG_variable:
if (pdi->d.locdesc)
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
VAR_DOMAIN, LOC_STATIC,
- &objfile->global_psymbols,
- addr + baseaddr,
- cu->language, objfile);
+ SECT_OFF_TEXT (objfile),
+ psymbol_placement::GLOBAL,
+ addr, cu->language, objfile);
}
else
{
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
VAR_DOMAIN, LOC_STATIC,
- &objfile->static_psymbols,
- has_loc ? addr + baseaddr : (CORE_ADDR) 0,
+ SECT_OFF_TEXT (objfile),
+ psymbol_placement::STATIC,
+ has_loc ? addr : 0,
cu->language, objfile);
}
break;
case DW_TAG_subrange_type:
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
- VAR_DOMAIN, LOC_TYPEDEF,
- &objfile->static_psymbols,
+ VAR_DOMAIN, LOC_TYPEDEF, -1,
+ psymbol_placement::STATIC,
0, cu->language, objfile);
break;
case DW_TAG_imported_declaration:
case DW_TAG_namespace:
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
- VAR_DOMAIN, LOC_TYPEDEF,
- &objfile->global_psymbols,
+ VAR_DOMAIN, LOC_TYPEDEF, -1,
+ psymbol_placement::GLOBAL,
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,
- &objfile->global_psymbols,
+ MODULE_DOMAIN, LOC_TYPEDEF, -1,
+ psymbol_placement::GLOBAL,
0, cu->language, objfile);
break;
case DW_TAG_class_type:
static vs. global. */
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
- STRUCT_DOMAIN, LOC_TYPEDEF,
+ STRUCT_DOMAIN, LOC_TYPEDEF, -1,
cu->language == language_cplus
- ? &objfile->global_psymbols
- : &objfile->static_psymbols,
+ ? psymbol_placement::GLOBAL
+ : psymbol_placement::STATIC,
0, cu->language, objfile);
break;
case DW_TAG_enumerator:
add_psymbol_to_list (actual_name, strlen (actual_name),
built_actual_name != NULL,
- VAR_DOMAIN, LOC_CONST,
+ VAR_DOMAIN, LOC_CONST, -1,
cu->language == language_cplus
- ? &objfile->global_psymbols
- : &objfile->static_psymbols,
+ ? psymbol_placement::GLOBAL
+ : psymbol_placement::STATIC,
0, cu->language, objfile);
break;
default:
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
CORE_ADDR baseaddr;
- CORE_ADDR highpc;
- CORE_ADDR lowpc;
+ CORE_ADDR this_highpc;
+ CORE_ADDR this_lowpc;
baseaddr = ANOFFSET (objfile->section_offsets,
SECT_OFF_TEXT (objfile));
- lowpc = gdbarch_adjust_dwarf2_addr (gdbarch,
- pdi->lowpc + baseaddr);
- highpc = gdbarch_adjust_dwarf2_addr (gdbarch,
- pdi->highpc + baseaddr);
- addrmap_set_empty (objfile->psymtabs_addrmap, lowpc, highpc - 1,
+ this_lowpc
+ = (gdbarch_adjust_dwarf2_addr (gdbarch,
+ pdi->lowpc + baseaddr)
+ - baseaddr);
+ this_highpc
+ = (gdbarch_adjust_dwarf2_addr (gdbarch,
+ pdi->highpc + baseaddr)
+ - baseaddr);
+ addrmap_set_empty (objfile->partial_symtabs->psymtabs_addrmap,
+ this_lowpc, this_highpc - 1,
cu->per_cu->v.psymtab);
}
}
while (pdi)
{
if (pdi->tag != DW_TAG_enumerator || pdi->name == NULL)
- complaint (&symfile_complaints, _("malformed enumerator DIE ignored"));
+ complaint (_("malformed enumerator DIE ignored"));
else
add_partial_symbol (pdi, cu);
pdi = pdi->die_sibling;
{
read_attribute (reader, &attr, &abbrev->attrs[i], info_ptr);
if (attr.form == DW_FORM_ref_addr)
- complaint (&symfile_complaints,
- _("ignoring absolute DW_AT_sibling"));
+ complaint (_("ignoring absolute DW_AT_sibling"));
else
{
sect_offset off = dwarf2_get_ref_die_offset (&attr);
const gdb_byte *sibling_ptr = buffer + to_underlying (off);
if (sibling_ptr < info_ptr)
- complaint (&symfile_complaints,
- _("DW_AT_sibling points backwards"));
+ complaint (_("DW_AT_sibling points backwards"));
else if (sibling_ptr > reader->buffer_end)
dwarf2_section_buffer_overflow_complaint (reader->die_section);
else
return;
}
- dw2_do_instantiate_symtab (per_cu);
+ dw2_do_instantiate_symtab (per_cu, false);
}
/* Trivial hash function for die_info: the hash value of a DIE
static void
load_full_comp_unit (struct dwarf2_per_cu_data *this_cu,
+ bool skip_partial,
enum language pretend_language)
{
gdb_assert (! this_cu->is_debug_types);
- init_cutu_and_read_dies (this_cu, NULL, 1, 1,
+ init_cutu_and_read_dies (this_cu, NULL, 1, 1, skip_partial,
load_full_comp_unit_reader, &pretend_language);
}
return;
gdb_assert (cu->language == language_cplus);
- for (struct delayed_method_info &mi : cu->method_list)
+ for (const delayed_method_info &mi : cu->method_list)
{
const char *physname;
struct fn_fieldlist *fn_flp
struct pending *list;
int i;
- for (list = global_symbols; list != NULL; list = list->next)
+ for (list = *cu->get_builder ()->get_global_symbols ();
+ list != NULL;
+ list = list->next)
{
for (i = 0; i < list->nsyms; ++i)
{
struct objfile *objfile
= cu->per_cu->dwarf2_per_objfile->objfile;
if (strcmp (package_name, this_package_name) != 0)
- complaint (&symfile_complaints,
- _("Symtab %s has objects from two different Go packages: %s and %s"),
+ complaint (_("Symtab %s has objects from two different Go packages: %s and %s"),
(symbol_symtab (sym) != NULL
? symtab_to_filename_for_display
(symbol_symtab (sym))
saved_package_name);
struct symbol *sym;
- TYPE_TAG_NAME (type) = TYPE_NAME (type);
-
sym = allocate_symbol (objfile);
SYMBOL_SET_LANGUAGE (sym, language_go, &objfile->objfile_obstack);
SYMBOL_SET_NAMES (sym, saved_package_name,
SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
SYMBOL_TYPE (sym) = type;
- add_symbol_to_list (sym, &global_symbols);
+ add_symbol_to_list (sym, cu->get_builder ()->get_global_symbols ());
xfree (package_name);
}
|| (TYPE_FIELD_LOC_KIND (field_type, index)
!= FIELD_LOC_KIND_BITPOS))
{
- complaint (&symfile_complaints,
- _("Could not parse Rust enum encoding string \"%s\""
+ complaint (_("Could not parse Rust enum encoding string \"%s\""
"[in module %s]"),
TYPE_FIELD_NAME (type, 0),
objfile_name (objfile));
TYPE_FIELDS (union_type)
= (struct field *) TYPE_ZALLOC (type, 3 * sizeof (struct field));
TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
+ set_type_align (union_type, TYPE_RAW_ALIGN (type));
/* Put the discriminant must at index 0. */
TYPE_FIELD_TYPE (union_type, 0) = field_type;
TYPE_CODE (union_type) = TYPE_CODE_UNION;
TYPE_NFIELDS (union_type) = TYPE_NFIELDS (type);
TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
+ set_type_align (union_type, TYPE_RAW_ALIGN (type));
TYPE_FIELDS (union_type) = TYPE_FIELDS (type);
struct type *field_type = TYPE_FIELD_TYPE (union_type, 0);
{
disr_type = TYPE_FIELD_TYPE (type, i);
- if (TYPE_NFIELDS (disr_type) == 0)
+ if (TYPE_CODE (disr_type) != TYPE_CODE_STRUCT)
+ {
+ /* All fields of a true enum will be structs. */
+ return;
+ }
+ else if (TYPE_NFIELDS (disr_type) == 0)
{
/* Could be data-less variant, so keep going. */
+ disr_type = nullptr;
}
else if (strcmp (TYPE_FIELD_NAME (disr_type, 0),
"RUST$ENUM$DISR") != 0)
TYPE_CODE (union_type) = TYPE_CODE_UNION;
TYPE_NFIELDS (union_type) = 1 + TYPE_NFIELDS (type);
TYPE_LENGTH (union_type) = TYPE_LENGTH (type);
+ set_type_align (union_type, TYPE_RAW_ALIGN (type));
TYPE_FIELDS (union_type)
= (struct field *) TYPE_ZALLOC (union_type,
(TYPE_NFIELDS (union_type)
if (iter != discriminant_map.end ())
disc->discriminants[i] = iter->second;
- /* Remove the discriminant field. */
+ /* Remove the discriminant field, if it exists. */
struct type *sub_type = TYPE_FIELD_TYPE (union_type, i);
- --TYPE_NFIELDS (sub_type);
- ++TYPE_FIELDS (sub_type);
+ if (TYPE_NFIELDS (sub_type) > 0)
+ {
+ --TYPE_NFIELDS (sub_type);
+ ++TYPE_FIELDS (sub_type);
+ }
TYPE_FIELD_NAME (union_type, i) = variant_name;
TYPE_NAME (sub_type)
= rust_fully_qualify (&objfile->objfile_obstack,
rust_union_quirks (struct dwarf2_cu *cu)
{
gdb_assert (cu->language == language_rust);
- for (struct type *type : cu->rust_unions)
- quirk_rust_enum (type, cu->per_cu->dwarf2_per_objfile->objfile);
+ for (type *type_ : cu->rust_unions)
+ quirk_rust_enum (type_, cu->per_cu->dwarf2_per_objfile->objfile);
+ /* We don't need this any more. */
+ cu->rust_unions.clear ();
}
/* Return the symtab for PER_CU. This works properly regardless of
included by PER_CU. */
static void
-recursively_compute_inclusions (VEC (compunit_symtab_ptr) **result,
+recursively_compute_inclusions (std::vector<compunit_symtab *> *result,
htab_t all_children, htab_t all_type_symtabs,
struct dwarf2_per_cu_data *per_cu,
struct compunit_symtab *immediate_parent)
if (*slot == NULL)
{
*slot = cust;
- VEC_safe_push (compunit_symtab_ptr, *result, cust);
+ result->push_back (cust);
if (cust->user == NULL)
cust->user = immediate_parent;
}
}
else
{
- VEC_safe_push (compunit_symtab_ptr, *result, cust);
+ result->push_back (cust);
if (cust->user == NULL)
cust->user = immediate_parent;
}
{
int ix, len;
struct dwarf2_per_cu_data *per_cu_iter;
- struct compunit_symtab *compunit_symtab_iter;
- VEC (compunit_symtab_ptr) *result_symtabs = NULL;
+ std::vector<compunit_symtab *> result_symtabs;
htab_t all_children, all_type_symtabs;
struct compunit_symtab *cust = get_compunit_symtab (per_cu);
}
/* Now we have a transitive closure of all the included symtabs. */
- len = VEC_length (compunit_symtab_ptr, result_symtabs);
+ len = result_symtabs.size ();
cust->includes
= XOBNEWVEC (&per_cu->dwarf2_per_objfile->objfile->objfile_obstack,
struct compunit_symtab *, len + 1);
- for (ix = 0;
- VEC_iterate (compunit_symtab_ptr, result_symtabs, ix,
- compunit_symtab_iter);
- ++ix)
- cust->includes[ix] = compunit_symtab_iter;
+ memcpy (cust->includes, result_symtabs.data (),
+ len * sizeof (compunit_symtab *));
cust->includes[len] = NULL;
- VEC_free (compunit_symtab_ptr, result_symtabs);
htab_delete (all_children);
htab_delete (all_type_symtabs);
}
static void
process_cu_includes (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
- int ix;
- struct dwarf2_per_cu_data *iter;
-
- for (ix = 0;
- VEC_iterate (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus,
- ix, iter);
- ++ix)
+ for (dwarf2_per_cu_data *iter : dwarf2_per_objfile->just_read_cus)
{
if (! iter->is_debug_types)
compute_compunit_symtab_includes (iter);
}
- VEC_free (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus);
+ dwarf2_per_objfile->just_read_cus.clear ();
}
/* Generate full symbol information for PER_CU, whose DIEs have
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
- buildsym_init ();
- scoped_free_pendings free_pending;
-
/* Clear the list here in case something was left over. */
cu->method_list.clear ();
- cu->list_in_scope = &file_symbols;
-
cu->language = pretend_language;
cu->language_defn = language_def (cu->language);
get_scope_pc_bounds (cu->dies, &lowpc, &highpc, cu);
addr = gdbarch_adjust_dwarf2_addr (gdbarch, highpc + baseaddr);
- static_block = end_symtab_get_static_block (addr, 0, 1);
+ static_block = cu->get_builder ()->end_symtab_get_static_block (addr, 0, 1);
/* If the comp unit has DW_AT_ranges, it may have discontiguous ranges.
Also, DW_AT_ranges may record ranges not belonging to any child DIEs
this comp unit. */
dwarf2_record_block_ranges (cu->dies, static_block, baseaddr, cu);
- cust = end_symtab_from_static_block (static_block,
- SECT_OFF_TEXT (objfile), 0);
+ cust = cu->get_builder ()->end_symtab_from_static_block (static_block,
+ SECT_OFF_TEXT (objfile),
+ 0);
if (cust != NULL)
{
}
/* Push it for inclusion processing later. */
- VEC_safe_push (dwarf2_per_cu_ptr, dwarf2_per_objfile->just_read_cus, per_cu);
+ dwarf2_per_objfile->just_read_cus.push_back (per_cu);
+
+ /* Not needed any more. */
+ cu->reset_builder ();
}
/* Generate full symbol information for type unit PER_CU, whose DIEs have
gdb_assert (per_cu->is_debug_types);
sig_type = (struct signatured_type *) per_cu;
- buildsym_init ();
- scoped_free_pendings free_pending;
-
/* Clear the list here in case something was left over. */
cu->method_list.clear ();
- cu->list_in_scope = &file_symbols;
-
cu->language = pretend_language;
cu->language_defn = language_def (cu->language);
this TU's symbols to the existing symtab. */
if (sig_type->type_unit_group->compunit_symtab == NULL)
{
- cust = end_expandable_symtab (0, SECT_OFF_TEXT (objfile));
+ buildsym_compunit *builder = cu->get_builder ();
+ cust = builder->end_expandable_symtab (0, SECT_OFF_TEXT (objfile));
sig_type->type_unit_group->compunit_symtab = cust;
if (cust != NULL)
}
else
{
- augment_type_symtab ();
+ cu->get_builder ()->augment_type_symtab ();
cust = sig_type->type_unit_group->compunit_symtab;
}
pst->compunit_symtab = cust;
pst->readin = 1;
}
+
+ /* Not needed any more. */
+ cu->reset_builder ();
}
/* Process an imported unit DIE. */
/* If necessary, add it to the queue and load its DIEs. */
if (maybe_queue_comp_unit (cu, per_cu, cu->language))
- load_full_comp_unit (per_cu, cu->language);
+ load_full_comp_unit (per_cu, false, cu->language);
VEC_safe_push (dwarf2_per_cu_ptr, cu->per_cu->imported_symtabs,
per_cu);
case DW_TAG_common_inclusion:
break;
case DW_TAG_namespace:
- cu->processing_has_namespace_info = 1;
+ cu->processing_has_namespace_info = true;
read_namespace (die, cu);
break;
case DW_TAG_module:
- cu->processing_has_namespace_info = 1;
+ cu->processing_has_namespace_info = true;
read_module (die, cu);
break;
case DW_TAG_imported_declaration:
- cu->processing_has_namespace_info = 1;
+ cu->processing_has_namespace_info = true;
if (read_namespace_alias (die, cu))
break;
- /* The declaration is not a global namespace alias: fall through. */
+ /* The declaration is not a global namespace alias. */
+ /* Fall through. */
case DW_TAG_imported_module:
- cu->processing_has_namespace_info = 1;
+ cu->processing_has_namespace_info = true;
if (die->child != NULL && (die->tag == DW_TAG_imported_declaration
|| cu->language != language_fortran))
- complaint (&symfile_complaints, _("Tag '%s' has unexpected children"),
+ complaint (_("Tag '%s' has unexpected children"),
dwarf_tag_name (die->tag));
read_import_statement (die, cu);
break;
attr = dwarf2_attr (child, DW_AT_type, cu);
if (attr == NULL)
{
- complaint (&symfile_complaints,
- _("template parameter missing DW_AT_type"));
+ complaint (_("template parameter missing DW_AT_type"));
buf.puts ("UNKNOWN_TYPE");
continue;
}
if (child->tag == DW_TAG_template_type_param)
{
- c_print_type (type, "", &buf, -1, 0, &type_print_raw_options);
+ c_print_type (type, "", &buf, -1, 0, cu->language,
+ &type_print_raw_options);
continue;
}
attr = dwarf2_attr (child, DW_AT_const_value, cu);
if (attr == NULL)
{
- complaint (&symfile_complaints,
- _("template parameter missing "
+ complaint (_("template parameter missing "
"DW_AT_const_value"));
buf.puts ("UNKNOWN_VALUE");
continue;
opts.raw = 1;
value_print (v, &buf, &opts);
release_value (v);
- value_free (v);
}
}
compute DW_AT_linkage_name incorrectly. But in such case
GDB would need to be bug-to-bug compatible. */
- complaint (&symfile_complaints,
- _("Computed physname <%s> does not match demangled <%s> "
+ complaint (_("Computed physname <%s> does not match demangled <%s> "
"(from linkage <%s>) - DIE at %s [in module %s]"),
physname, canon, mangled, sect_offset_str (die->sect_off),
objfile_name (objfile));
if (num == MAX_NESTED_IMPORTED_DECLARATIONS)
{
- complaint (&symfile_complaints,
- _("DIE at %s has too many recursively imported "
+ complaint (_("DIE at %s has too many recursively imported "
"declarations"), sect_offset_str (d->sect_off));
return 0;
}
}
/* Return the using directives repository (global or local?) to use in the
- current context for LANGUAGE.
+ current context for CU.
For Ada, imported declarations can materialize renamings, which *may* be
global. However it is impossible (for now?) in DWARF to distinguish
global only in Ada. */
static struct using_direct **
-using_directives (enum language language)
+using_directives (struct dwarf2_cu *cu)
{
- if (language == language_ada && context_stack_depth == 0)
- return &global_using_directives;
+ if (cu->language == language_ada
+ && cu->get_builder ()->outermost_context_p ())
+ return cu->get_builder ()->get_global_using_directives ();
else
- return &local_using_directives;
+ return cu->get_builder ()->get_local_using_directives ();
}
/* Read the import statement specified by the given die and record it. */
import_attr = dwarf2_attr (die, DW_AT_import, cu);
if (import_attr == NULL)
{
- complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"),
+ complaint (_("Tag '%s' has no DW_AT_import"),
dwarf_tag_name (die->tag));
return;
}
if (child_die->tag != DW_TAG_imported_declaration)
{
- complaint (&symfile_complaints,
- _("child DW_TAG_imported_declaration expected "
+ complaint (_("child DW_TAG_imported_declaration expected "
"- DIE at %s [in module %s]"),
sect_offset_str (child_die->sect_off),
objfile_name (objfile));
import_attr = dwarf2_attr (child_die, DW_AT_import, cu);
if (import_attr == NULL)
{
- complaint (&symfile_complaints, _("Tag '%s' has no DW_AT_import"),
+ complaint (_("Tag '%s' has no DW_AT_import"),
dwarf_tag_name (child_die->tag));
continue;
}
imported_name = dwarf2_name (imported_die, imported_cu);
if (imported_name == NULL)
{
- complaint (&symfile_complaints,
- _("child DW_TAG_imported_declaration has unknown "
+ complaint (_("child DW_TAG_imported_declaration has unknown "
"imported name - DIE at %s [in module %s]"),
sect_offset_str (child_die->sect_off),
objfile_name (objfile));
process_die (child_die, cu);
}
- add_using_directive (using_directives (cu->language),
+ add_using_directive (using_directives (cu),
import_prefix,
canonical_name,
import_alias,
types, but gives them a size of zero. Starting with version 14,
ICC is compatible with GCC. */
-static int
+static bool
producer_is_icc_lt_14 (struct dwarf2_cu *cu)
{
if (!cu->checked_producer)
return cu->producer_is_icc_lt_14;
}
+/* ICC generates a DW_AT_type for C void functions. This was observed on
+ ICC 14.0.5.212, and appears to be against the DWARF spec (V5 3.3.2)
+ which says that void functions should not have a DW_AT_type. */
+
+static bool
+producer_is_icc (struct dwarf2_cu *cu)
+{
+ if (!cu->checked_producer)
+ check_producer (cu);
+
+ return cu->producer_is_icc;
+}
+
/* Check for possibly missing DW_AT_comp_dir with relative .debug_line
directory paths. GCC SVN r127613 (new option -fdebug-prefix-map) fixed
this, it was first present in GCC release 4.3.0. */
-static int
+static bool
producer_is_gcc_lt_4_3 (struct dwarf2_cu *cu)
{
if (!cu->checked_producer)
struct die_info *child_die;
CORE_ADDR baseaddr;
+ prepare_one_comp_unit (cu, die, cu->language);
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
get_scope_pc_bounds (die, &lowpc, &highpc, cu);
file_and_directory fnd = find_file_and_directory (die, cu);
- prepare_one_comp_unit (cu, die, cu->language);
-
/* The XLCL doesn't generate DW_LANG_OpenCL because this attribute is not
standardised yet. As a workaround for the language detection we fall
back to the DW_AT_producer string. */
if (cu->producer && strstr (cu->producer, "GNU Go ") != NULL)
set_cu_language (DW_LANG_Go, cu);
- dwarf2_start_symtab (cu, fnd.name, fnd.comp_dir, lowpc);
+ cu->start_symtab (fnd.name, fnd.comp_dir, lowpc);
/* Decode line number information if present. We do this before
processing child DIEs, so that the line header table is available
if (attr && cu->line_header)
{
if (dwarf2_attr (die, DW_AT_macro_info, cu))
- complaint (&symfile_complaints,
- _("CU refers to both DW_AT_macros and DW_AT_macro_info"));
+ complaint (_("CU refers to both DW_AT_macros and DW_AT_macro_info"));
dwarf_decode_macros (cu, DW_UNSND (attr), 1);
}
}
}
-/* TU version of handle_DW_AT_stmt_list for read_type_unit_scope.
- Create the set of symtabs used by this TU, or if this TU is sharing
- symtabs with another TU and the symtabs have already been created
- then restore those symtabs in the line header.
- We don't need the pc/line-number mapping for type units. */
-
-static void
-setup_type_unit_groups (struct die_info *die, struct dwarf2_cu *cu)
+void
+dwarf2_cu::setup_type_unit_groups (struct die_info *die)
{
- struct dwarf2_per_cu_data *per_cu = cu->per_cu;
struct type_unit_group *tu_group;
int first_time;
struct attribute *attr;
gdb_assert (per_cu->is_debug_types);
sig_type = (struct signatured_type *) per_cu;
- attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
+ attr = dwarf2_attr (die, DW_AT_stmt_list, this);
/* If we're using .gdb_index (includes -readnow) then
per_cu->type_unit_group may not have been set up yet. */
if (sig_type->type_unit_group == NULL)
- sig_type->type_unit_group = get_type_unit_group (cu, attr);
+ sig_type->type_unit_group = get_type_unit_group (this, attr);
tu_group = sig_type->type_unit_group;
/* If we've already processed this stmt_list there's no real need to
if (attr != NULL)
{
sect_offset line_offset = (sect_offset) DW_UNSND (attr);
- lh = dwarf_decode_line_header (line_offset, cu);
+ lh = dwarf_decode_line_header (line_offset, this);
}
if (lh == NULL)
{
if (first_time)
- dwarf2_start_symtab (cu, "", NULL, 0);
+ start_symtab ("", NULL, 0);
else
{
gdb_assert (tu_group->symtabs == NULL);
- restart_symtab (tu_group->compunit_symtab, "", 0);
+ gdb_assert (m_builder == nullptr);
+ struct compunit_symtab *cust = tu_group->compunit_symtab;
+ m_builder.reset (new struct buildsym_compunit
+ (COMPUNIT_OBJFILE (cust), "",
+ COMPUNIT_DIRNAME (cust),
+ compunit_language (cust),
+ 0, cust));
}
return;
}
- cu->line_header = lh.release ();
- cu->line_header_die_owner = die;
+ line_header = lh.release ();
+ line_header_die_owner = die;
if (first_time)
{
- struct compunit_symtab *cust = dwarf2_start_symtab (cu, "", NULL, 0);
+ struct compunit_symtab *cust = start_symtab ("", NULL, 0);
/* Note: We don't assign tu_group->compunit_symtab yet because we're
still initializing it, and our caller (a few levels up)
process_full_type_unit still needs to know if this is the first
time. */
- tu_group->num_symtabs = cu->line_header->file_names.size ();
+ tu_group->num_symtabs = line_header->file_names.size ();
tu_group->symtabs = XNEWVEC (struct symtab *,
- cu->line_header->file_names.size ());
+ line_header->file_names.size ());
- for (i = 0; i < cu->line_header->file_names.size (); ++i)
+ for (i = 0; i < line_header->file_names.size (); ++i)
{
- file_entry &fe = cu->line_header->file_names[i];
-
- dwarf2_start_subfile (fe.name, fe.include_dir (cu->line_header));
+ file_entry &fe = line_header->file_names[i];
- if (current_subfile->symtab == NULL)
+ dwarf2_start_subfile (this, fe.name,
+ fe.include_dir (line_header));
+ buildsym_compunit *b = get_builder ();
+ if (b->get_current_subfile ()->symtab == NULL)
{
/* NOTE: start_subfile will recognize when it's been
passed a file it has already seen. So we can't
assume there's a simple mapping from
cu->line_header->file_names to subfiles, plus
cu->line_header->file_names may contain dups. */
- current_subfile->symtab
- = allocate_symtab (cust, current_subfile->name);
+ b->get_current_subfile ()->symtab
+ = allocate_symtab (cust, b->get_current_subfile ()->name);
}
- fe.symtab = current_subfile->symtab;
+ fe.symtab = b->get_current_subfile ()->symtab;
tu_group->symtabs[i] = fe.symtab;
}
}
else
{
- restart_symtab (tu_group->compunit_symtab, "", 0);
+ gdb_assert (m_builder == nullptr);
+ struct compunit_symtab *cust = tu_group->compunit_symtab;
+ m_builder.reset (new struct buildsym_compunit
+ (COMPUNIT_OBJFILE (cust), "",
+ COMPUNIT_DIRNAME (cust),
+ compunit_language (cust),
+ 0, cust));
- for (i = 0; i < cu->line_header->file_names.size (); ++i)
+ for (i = 0; i < line_header->file_names.size (); ++i)
{
- file_entry &fe = cu->line_header->file_names[i];
+ file_entry &fe = line_header->file_names[i];
fe.symtab = tu_group->symtabs[i];
}
/* Initialize (or reinitialize) the machinery for building symtabs.
We do this before processing child DIEs, so that the line header table
is available for DW_AT_decl_file. */
- setup_type_unit_groups (die, cu);
+ cu->setup_type_unit_groups (die);
if (die->child != NULL)
{
attr = dwarf2_attr (comp_unit_die, DW_AT_GNU_dwo_id, cu);
if (attr == NULL)
{
- complaint (&symfile_complaints,
- _("Dwarf Error: debug entry at offset %s is missing"
+ complaint (_("Dwarf Error: debug entry at offset %s is missing"
" its dwo_id [in module %s]"),
sect_offset_str (sect_off), dwo_file->dwo_name);
return;
const struct dwo_unit *dup_cu = (const struct dwo_unit *)*slot;
sect_offset dup_sect_off = dup_cu->sect_off;
- complaint (&symfile_complaints,
- _("debug cu entry at offset %s is duplicate to"
+ complaint (_("debug cu entry at offset %s is duplicate to"
" the entry at offset %s, signature %s"),
sect_offset_str (sect_off), sect_offset_str (dup_sect_off),
hex_string (dwo_unit->signature));
struct dwp_file *dwp_file, int is_debug_types)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
- bfd *dbfd = dwp_file->dbfd;
+ bfd *dbfd = dwp_file->dbfd.get ();
const gdb_byte *index_ptr, *index_end;
struct dwarf2_section_info *index;
uint32_t version, nr_columns, nr_units, nr_slots;
if (nr_slots != 0 || nr_units != 0
|| (version == 2 && nr_columns != 0))
{
- complaint (&symfile_complaints,
- _("Empty DWP but nr_slots,nr_units,nr_columns not"
+ complaint (_("Empty DWP but nr_slots,nr_units,nr_columns not"
" all zero [in modules %s]"),
dwp_file->name);
}
{
const gdb_byte *ids_ptr = htab->unit_table + sizeof (uint32_t) * nr_slots;
int *ids = htab->section_pool.v2.section_ids;
+ size_t sizeof_ids = sizeof (htab->section_pool.v2.section_ids);
/* Reverse map for error checking. */
int ids_seen[DW_SECT_MAX + 1];
int i;
" in section table [in module %s]"),
dwp_file->name);
}
- memset (ids, 255, (DW_SECT_MAX + 1) * sizeof (int32_t));
- memset (ids_seen, 255, (DW_SECT_MAX + 1) * sizeof (int32_t));
+ memset (ids, 255, sizeof_ids);
+ memset (ids_seen, 255, sizeof (ids_seen));
for (i = 0; i < nr_columns; ++i)
{
int id = read_4_bytes (dbfd, ids_ptr + i * sizeof (uint32_t));
struct objfile *objfile = dwarf2_per_objfile->objfile;
const struct dwp_hash_table *dwp_htab =
is_debug_types ? dwp_file->tus : dwp_file->cus;
- bfd *dbfd = dwp_file->dbfd;
+ bfd *dbfd = dwp_file->dbfd.get ();
const char *kind = is_debug_types ? "TU" : "CU";
struct dwo_file *dwo_file;
struct dwo_unit *dwo_unit;
struct objfile *objfile = dwarf2_per_objfile->objfile;
const struct dwp_hash_table *dwp_htab =
is_debug_types ? dwp_file->tus : dwp_file->cus;
- bfd *dbfd = dwp_file->dbfd;
+ bfd *dbfd = dwp_file->dbfd.get ();
const char *kind = is_debug_types ? "TU" : "CU";
struct dwo_file *dwo_file;
struct dwo_unit *dwo_unit;
{
const struct dwp_hash_table *dwp_htab =
is_debug_types ? dwp_file->tus : dwp_file->cus;
- bfd *dbfd = dwp_file->dbfd;
+ bfd *dbfd = dwp_file->dbfd.get ();
uint32_t mask = dwp_htab->nr_slots - 1;
uint32_t hash = signature & mask;
uint32_t hash2 = ((signature >> 32) & mask) | 1;
{
struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct dwo_file *dwo_file;
- struct cleanup *cleanups;
gdb_bfd_ref_ptr dbfd (open_dwo_file (dwarf2_per_objfile, dwo_name, comp_dir));
if (dbfd == NULL)
fprintf_unfiltered (gdb_stdlog, "DWO file not found: %s\n", dwo_name);
return NULL;
}
- dwo_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwo_file);
+
+ /* 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->dwo_name = dwo_name;
dwo_file->comp_dir = comp_dir;
dwo_file->dbfd = dbfd.release ();
- free_dwo_file_cleanup_data *cleanup_data = XNEW (free_dwo_file_cleanup_data);
- cleanup_data->dwo_file = dwo_file;
- cleanup_data->dwarf2_per_objfile = dwarf2_per_objfile;
-
- cleanups = make_cleanup (free_dwo_file_cleanup, cleanup_data);
-
bfd_map_over_sections (dwo_file->dbfd, dwarf2_locate_dwo_sections,
&dwo_file->sections);
create_cus_hash_table (dwarf2_per_objfile, *dwo_file, dwo_file->sections.info,
dwo_file->cus);
- create_debug_types_hash_table (dwarf2_per_objfile, dwo_file,
+ create_debug_types_hash_table (dwarf2_per_objfile, dwo_file.get (),
dwo_file->sections.types, dwo_file->tus);
- discard_cleanups (cleanups);
-
if (dwarf_read_debug)
fprintf_unfiltered (gdb_stdlog, "DWO file found: %s\n", dwo_name);
- return dwo_file;
+ return dwo_file.release ();
}
/* This function is mapped across the sections and remembers the offset and
By convention the name of the DWP file is ${objfile}.dwp.
The result is NULL if it can't be found. */
-static struct dwp_file *
+static std::unique_ptr<struct dwp_file>
open_and_init_dwp_file (struct dwarf2_per_objfile *dwarf2_per_objfile)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
- struct dwp_file *dwp_file;
/* Try to find first .dwp for the binary file before any symbolic links
resolving. */
{
if (dwarf_read_debug)
fprintf_unfiltered (gdb_stdlog, "DWP file not found: %s\n", dwp_name.c_str ());
- return NULL;
+ return std::unique_ptr<dwp_file> ();
}
- dwp_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_file);
- dwp_file->name = bfd_get_filename (dbfd.get ());
- dwp_file->dbfd = dbfd.release ();
- /* +1: section 0 is unused */
- dwp_file->num_sections = bfd_count_sections (dwp_file->dbfd) + 1;
+ const char *name = bfd_get_filename (dbfd.get ());
+ std::unique_ptr<struct dwp_file> dwp_file
+ (new struct dwp_file (name, std::move (dbfd)));
+
+ dwp_file->num_sections = elf_numsections (dwp_file->dbfd);
dwp_file->elf_sections =
OBSTACK_CALLOC (&objfile->objfile_obstack,
dwp_file->num_sections, asection *);
- bfd_map_over_sections (dwp_file->dbfd, dwarf2_locate_common_dwp_sections,
- dwp_file);
+ bfd_map_over_sections (dwp_file->dbfd.get (),
+ dwarf2_locate_common_dwp_sections,
+ dwp_file.get ());
- dwp_file->cus = create_dwp_hash_table (dwarf2_per_objfile, dwp_file, 0);
+ dwp_file->cus = create_dwp_hash_table (dwarf2_per_objfile, dwp_file.get (),
+ 0);
- dwp_file->tus = create_dwp_hash_table (dwarf2_per_objfile, dwp_file, 1);
+ dwp_file->tus = create_dwp_hash_table (dwarf2_per_objfile, dwp_file.get (),
+ 1);
/* The DWP file version is stored in the hash table. Oh well. */
if (dwp_file->cus && dwp_file->tus
dwp_file->version = 2;
if (dwp_file->version == 2)
- bfd_map_over_sections (dwp_file->dbfd, dwarf2_locate_v2_dwp_sections,
- dwp_file);
+ bfd_map_over_sections (dwp_file->dbfd.get (),
+ dwarf2_locate_v2_dwp_sections,
+ dwp_file.get ());
dwp_file->loaded_cus = allocate_dwp_loaded_cutus_table (objfile);
dwp_file->loaded_tus = allocate_dwp_loaded_cutus_table (objfile);
= open_and_init_dwp_file (dwarf2_per_objfile);
dwarf2_per_objfile->dwp_checked = 1;
}
- return dwarf2_per_objfile->dwp_file;
+ return dwarf2_per_objfile->dwp_file.get ();
}
/* Subroutine of lookup_dwo_comp_unit, lookup_dwo_type_unit.
}
/* Free all resources associated with DWO_FILE.
- Close the DWO file and munmap the sections.
- All memory should be on the objfile obstack. */
+ Close the DWO file and munmap the sections. */
static void
-free_dwo_file (struct dwo_file *dwo_file, struct objfile *objfile)
+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);
}
-/* Wrapper for free_dwo_file for use in cleanups. */
-
-static void
-free_dwo_file_cleanup (void *arg)
-{
- struct free_dwo_file_cleanup_data *data
- = (struct free_dwo_file_cleanup_data *) arg;
- struct objfile *objfile = data->dwarf2_per_objfile->objfile;
-
- free_dwo_file (data->dwo_file, objfile);
-
- xfree (data);
-}
-
/* 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;
- struct objfile *objfile = (struct objfile *) info;
- free_dwo_file (dwo_file, objfile);
+ free_dwo_file (dwo_file);
return 1;
}
if (die->tag != origin_die->tag
&& !(die->tag == DW_TAG_inlined_subroutine
&& origin_die->tag == DW_TAG_subprogram))
- complaint (&symfile_complaints,
- _("DIE %s and its abstract origin %s have different tags"),
+ complaint (_("DIE %s and its abstract origin %s have different tags"),
sect_offset_str (die->sect_off),
sect_offset_str (origin_die->sect_off));
if (child_die->tag != child_origin_die->tag
&& !(child_die->tag == DW_TAG_inlined_subroutine
&& child_origin_die->tag == DW_TAG_subprogram))
- complaint (&symfile_complaints,
- _("Child DIE %s and its abstract origin %s have "
+ complaint (_("Child DIE %s and its abstract origin %s have "
"different tags"),
sect_offset_str (child_die->sect_off),
sect_offset_str (child_origin_die->sect_off));
if (child_origin_die->parent != origin_die)
- complaint (&symfile_complaints,
- _("Child DIE %s and its abstract origin %s have "
+ complaint (_("Child DIE %s and its abstract origin %s have "
"different parents"),
sect_offset_str (child_die->sect_off),
sect_offset_str (child_origin_die->sect_off));
sect_offset *offsets_end = offsets.data () + offsets.size ();
for (offsetp = offsets.data () + 1; offsetp < offsets_end; offsetp++)
if (offsetp[-1] == *offsetp)
- complaint (&symfile_complaints,
- _("Multiple children of DIE %s refer "
+ complaint (_("Multiple children of DIE %s refer "
"to DIE %s as their abstract origin"),
sect_offset_str (die->sect_off), sect_offset_str (*offsetp));
illegal according to the DWARF standard. */
if (name == NULL)
{
- complaint (&symfile_complaints,
- _("missing name for subprogram DIE at %s"),
+ complaint (_("missing name for subprogram DIE at %s"),
sect_offset_str (die->sect_off));
return;
}
{
attr = dwarf2_attr (die, DW_AT_external, cu);
if (!attr || !DW_UNSND (attr))
- complaint (&symfile_complaints,
- _("cannot get low and high bounds "
+ complaint (_("cannot get low and high bounds "
"for subprogram DIE at %s"),
sect_offset_str (die->sect_off));
return;
}
}
- newobj = push_context (0, lowpc);
+ newobj = cu->get_builder ()->push_context (0, lowpc);
newobj->name = new_symbol (die, read_type_die (die, cu), cu,
(struct symbol *) templ_func);
attr_to_dynamic_prop (attr, die, cu, newobj->static_link);
}
- cu->list_in_scope = &local_symbols;
+ cu->list_in_scope = cu->get_builder ()->get_local_symbols ();
if (die->child != NULL)
{
}
}
- newobj = pop_context ();
+ struct context_stack cstk = cu->get_builder ()->pop_context ();
/* Make a block for the local symbols within. */
- block = finish_block (newobj->name, &local_symbols, newobj->old_blocks,
- newobj->static_link, lowpc, highpc);
+ block = cu->get_builder ()->finish_block (cstk.name, cstk.old_blocks,
+ cstk.static_link, lowpc, highpc);
/* For C++, set the block's scope. */
if ((cu->language == language_cplus
/* If we have address ranges, record them. */
dwarf2_record_block_ranges (die, block, baseaddr, cu);
- gdbarch_make_symbol_special (gdbarch, newobj->name, objfile);
+ gdbarch_make_symbol_special (gdbarch, cstk.name, objfile);
/* Attach template arguments to function. */
if (!template_args.empty ())
memcpy (templ_func->template_arguments,
template_args.data (),
(templ_func->n_template_arguments * sizeof (struct symbol *)));
+
+ /* 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 (symbol *sym : template_args)
+ symbol_set_symtab (sym, symbol_symtab (templ_func));
}
/* In C++, we can have functions nested inside functions (e.g., when
a function declares a class that has methods). This means that
when we finish processing a function scope, we may need to go
back to building a containing block's symbol lists. */
- local_symbols = newobj->locals;
- local_using_directives = newobj->local_using_directives;
+ *cu->get_builder ()->get_local_symbols () = cstk.locals;
+ cu->get_builder ()->set_local_using_directives (cstk.local_using_directives);
/* If we've finished processing a top-level function, subsequent
symbols go in the file symbol list. */
- if (outermost_context_p ())
- cu->list_in_scope = &file_symbols;
+ if (cu->get_builder ()->outermost_context_p ())
+ cu->list_in_scope = cu->get_builder ()->get_file_symbols ();
}
/* Process all the DIES contained within a lexical block scope. Start
{
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- struct context_stack *newobj;
CORE_ADDR lowpc, highpc;
struct die_info *child_die;
CORE_ADDR baseaddr;
lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
highpc = gdbarch_adjust_dwarf2_addr (gdbarch, highpc + baseaddr);
- push_context (0, lowpc);
+ cu->get_builder ()->push_context (0, lowpc);
if (die->child != NULL)
{
child_die = die->child;
}
}
inherit_abstract_dies (die, cu);
- newobj = pop_context ();
+ struct context_stack cstk = cu->get_builder ()->pop_context ();
- if (local_symbols != NULL || local_using_directives != NULL)
+ if (*cu->get_builder ()->get_local_symbols () != NULL
+ || (*cu->get_builder ()->get_local_using_directives ()) != NULL)
{
struct block *block
- = finish_block (0, &local_symbols, newobj->old_blocks, NULL,
- newobj->start_addr, highpc);
+ = cu->get_builder ()->finish_block (0, cstk.old_blocks, NULL,
+ cstk.start_addr, highpc);
/* Note that recording ranges after traversing children, as we
do here, means that recording a parent's ranges entails
to do. */
dwarf2_record_block_ranges (die, block, baseaddr, cu);
}
- local_symbols = newobj->locals;
- local_using_directives = newobj->local_using_directives;
+ *cu->get_builder ()->get_local_symbols () = cstk.locals;
+ cu->get_builder ()->set_local_using_directives (cstk.local_using_directives);
}
/* Read in DW_TAG_call_site and insert it to CU->call_site_htab. */
}
if (!attr)
{
- complaint (&symfile_complaints,
- _("missing DW_AT_call_return_pc for DW_TAG_call_site "
+ complaint (_("missing DW_AT_call_return_pc for DW_TAG_call_site "
"DIE %s [in module %s]"),
sect_offset_str (die->sect_off), objfile_name (objfile));
return;
slot = htab_find_slot (cu->call_site_htab, &call_site_local, INSERT);
if (*slot != NULL)
{
- complaint (&symfile_complaints,
- _("Duplicate PC %s for DW_TAG_call_site "
+ complaint (_("Duplicate PC %s for DW_TAG_call_site "
"DIE %s [in module %s]"),
paddress (gdbarch, pc), sect_offset_str (die->sect_off),
objfile_name (objfile));
if (child_die->tag != DW_TAG_call_site_parameter
&& child_die->tag != DW_TAG_GNU_call_site_parameter)
{
- complaint (&symfile_complaints,
- _("Tag %d is not DW_TAG_call_site_parameter in "
+ complaint (_("Tag %d is not DW_TAG_call_site_parameter in "
"DW_TAG_call_site child DIE %s [in module %s]"),
child_die->tag, sect_offset_str (child_die->sect_off),
objfile_name (objfile));
TYPE_TAIL_CALL_LIST (func_type) = call_site;
}
else
- complaint (&symfile_complaints,
- _("Cannot find function owning DW_TAG_call_site "
+ complaint (_("Cannot find function owning DW_TAG_call_site "
"DIE %s [in module %s]"),
sect_offset_str (die->sect_off), objfile_name (objfile));
}
if (target_physname == NULL)
target_physname = dwarf2_physname (NULL, target_die, target_cu);
if (target_physname == NULL)
- complaint (&symfile_complaints,
- _("DW_AT_call_target target DIE has invalid "
+ complaint (_("DW_AT_call_target target DIE has invalid "
"physname, for referencing DIE %s [in module %s]"),
sect_offset_str (die->sect_off), objfile_name (objfile));
else
/* DW_AT_entry_pc should be preferred. */
if (dwarf2_get_pc_bounds (target_die, &lowpc, NULL, target_cu, NULL)
<= PC_BOUNDS_INVALID)
- complaint (&symfile_complaints,
- _("DW_AT_call_target target DIE has invalid "
+ complaint (_("DW_AT_call_target target DIE has invalid "
"low pc, for referencing DIE %s [in module %s]"),
sect_offset_str (die->sect_off), objfile_name (objfile));
else
}
}
else
- complaint (&symfile_complaints,
- _("DW_TAG_call_site DW_AT_call_target is neither "
+ complaint (_("DW_TAG_call_site DW_AT_call_target is neither "
"block nor reference, for DIE %s [in module %s]"),
sect_offset_str (die->sect_off), objfile_name (objfile));
/* As DW_OP_GNU_parameter_ref uses CU-relative offset this
binding can be done only inside one CU. Such referenced DIE
therefore cannot be even moved to DW_TAG_partial_unit. */
- complaint (&symfile_complaints,
- _("DW_AT_call_parameter offset is not in CU for "
+ complaint (_("DW_AT_call_parameter offset is not in CU for "
"DW_TAG_call_site child DIE %s [in module %s]"),
sect_offset_str (child_die->sect_off),
objfile_name (objfile));
}
else if (loc == NULL || origin != NULL || !attr_form_is_block (loc))
{
- complaint (&symfile_complaints,
- _("No DW_FORM_block* DW_AT_location for "
+ complaint (_("No DW_FORM_block* DW_AT_location for "
"DW_TAG_call_site child DIE %s [in module %s]"),
sect_offset_str (child_die->sect_off), objfile_name (objfile));
continue;
parameter->kind = CALL_SITE_PARAMETER_FB_OFFSET;
else
{
- complaint (&symfile_complaints,
- _("Only single DW_OP_reg or DW_OP_fbreg is supported "
+ complaint (_("Only single DW_OP_reg or DW_OP_fbreg is supported "
"for DW_FORM_block* DW_AT_location is supported for "
"DW_TAG_call_site child DIE %s "
"[in module %s]"),
attr = dwarf2_attr (child_die, DW_AT_GNU_call_site_value, cu);
if (!attr_form_is_block (attr))
{
- complaint (&symfile_complaints,
- _("No DW_FORM_block* DW_AT_call_value for "
+ complaint (_("No DW_FORM_block* DW_AT_call_value for "
"DW_TAG_call_site child DIE %s [in module %s]"),
sect_offset_str (child_die->sect_off),
objfile_name (objfile));
if (attr)
{
if (!attr_form_is_block (attr))
- complaint (&symfile_complaints,
- _("No DW_FORM_block* DW_AT_call_data_value for "
+ complaint (_("No DW_FORM_block* DW_AT_call_data_value for "
"DW_TAG_call_site child DIE %s [in module %s]"),
sect_offset_str (child_die->sect_off),
objfile_name (objfile));
}
}
- new_symbol (die, NULL, cu, storage);
+ struct symbol *res = new_symbol (die, NULL, cu, storage);
+ struct attribute *abstract_origin
+ = dwarf2_attr (die, DW_AT_abstract_origin, cu);
+ struct attribute *loc = dwarf2_attr (die, DW_AT_location, cu);
+ if (res == NULL && loc && abstract_origin)
+ {
+ /* We have a variable without a name, but with a location and an abstract
+ origin. This may be a concrete instance of an abstract variable
+ referenced from an DW_OP_GNU_variable_value, so save it to find it back
+ later. */
+ struct dwarf2_cu *origin_cu = cu;
+ struct die_info *origin_die
+ = follow_die_ref (die, abstract_origin, &origin_cu);
+ dwarf2_per_objfile *dpo = cu->per_cu->dwarf2_per_objfile;
+ dpo->abstract_to_concrete[origin_die].push_back (die);
+ }
}
/* Call CALLBACK from DW_AT_ranges attribute value OFFSET
dwarf2_read_section (objfile, &dwarf2_per_objfile->rnglists);
if (offset >= dwarf2_per_objfile->rnglists.size)
{
- complaint (&symfile_complaints,
- _("Offset %d out of bounds for DW_AT_ranges attribute"),
+ complaint (_("Offset %d out of bounds for DW_AT_ranges attribute"),
offset);
return false;
}
buffer += bytes_read;
break;
default:
- complaint (&symfile_complaints,
- _("Invalid .debug_rnglists data (no base address)"));
+ complaint (_("Invalid .debug_rnglists data (no base address)"));
return false;
}
if (rlet == DW_RLE_end_of_list || overflow)
{
/* We have no valid base address for the ranges
data. */
- complaint (&symfile_complaints,
- _("Invalid .debug_rnglists data (no base address)"));
+ complaint (_("Invalid .debug_rnglists data (no base address)"));
return false;
}
if (range_beginning > range_end)
{
/* Inverted range entries are invalid. */
- complaint (&symfile_complaints,
- _("Invalid .debug_rnglists data (inverted range)"));
+ complaint (_("Invalid .debug_rnglists data (inverted range)"));
return false;
}
if (range_beginning + baseaddr == 0
&& !dwarf2_per_objfile->has_section_at_zero)
{
- complaint (&symfile_complaints,
- _(".debug_rnglists entry has start address of zero"
+ complaint (_(".debug_rnglists entry has start address of zero"
" [in module %s]"), objfile_name (objfile));
continue;
}
if (overflow)
{
- complaint (&symfile_complaints,
- _("Offset %d is not terminated "
+ complaint (_("Offset %d is not terminated "
"for DW_AT_ranges attribute"),
offset);
return false;
dwarf2_read_section (objfile, &dwarf2_per_objfile->ranges);
if (offset >= dwarf2_per_objfile->ranges.size)
{
- complaint (&symfile_complaints,
- _("Offset %d out of bounds for DW_AT_ranges attribute"),
+ complaint (_("Offset %d out of bounds for DW_AT_ranges attribute"),
offset);
return 0;
}
{
/* We have no valid base address for the ranges
data. */
- complaint (&symfile_complaints,
- _("Invalid .debug_ranges data (no base address)"));
+ complaint (_("Invalid .debug_ranges data (no base address)"));
return 0;
}
if (range_beginning > range_end)
{
/* Inverted range entries are invalid. */
- complaint (&symfile_complaints,
- _("Invalid .debug_ranges data (inverted range)"));
+ complaint (_("Invalid .debug_ranges data (inverted range)"));
return 0;
}
if (range_beginning + baseaddr == 0
&& !dwarf2_per_objfile->has_section_at_zero)
{
- complaint (&symfile_complaints,
- _(".debug_ranges entry has start address of zero"
+ complaint (_(".debug_ranges entry has start address of zero"
" [in module %s]"), objfile_name (objfile));
continue;
}
CORE_ADDR lowpc;
CORE_ADDR highpc;
- lowpc = gdbarch_adjust_dwarf2_addr (gdbarch,
- range_beginning + baseaddr);
- highpc = gdbarch_adjust_dwarf2_addr (gdbarch,
- range_end + baseaddr);
- addrmap_set_empty (objfile->psymtabs_addrmap, lowpc, highpc - 1,
- ranges_pst);
+ lowpc = (gdbarch_adjust_dwarf2_addr (gdbarch,
+ range_beginning + baseaddr)
+ - baseaddr);
+ highpc = (gdbarch_adjust_dwarf2_addr (gdbarch,
+ range_end + baseaddr)
+ - baseaddr);
+ addrmap_set_empty (objfile->partial_symtabs->psymtabs_addrmap,
+ lowpc, highpc - 1, ranges_pst);
}
/* FIXME: This is recording everything as a low-high
low = gdbarch_adjust_dwarf2_addr (gdbarch, low + baseaddr);
high = gdbarch_adjust_dwarf2_addr (gdbarch, high + baseaddr);
- record_block_range (block, low, high - 1);
+ cu->get_builder ()->record_block_range (block, low, high - 1);
}
}
address range list in the .debug_ranges section. */
unsigned long offset = (DW_UNSND (attr)
+ (need_ranges_base ? cu->ranges_base : 0));
- const gdb_byte *buffer;
-
- /* For some target architectures, but not others, the
- read_address function sign-extends the addresses it returns.
- To recognize base address selection entries, we need a
- mask. */
- unsigned int addr_size = cu->header.addr_size;
- CORE_ADDR base_select_mask = ~(~(CORE_ADDR)1 << (addr_size * 8 - 1));
-
- /* The base address, to which the next pair is relative. Note
- that this 'base' is a DWARF concept: most entries in a range
- list are relative, to reduce the number of relocs against the
- debugging information. This is separate from this function's
- 'baseaddr' argument, which GDB uses to relocate debugging
- information from a shared library based on the address at
- which the library was loaded. */
- CORE_ADDR base = cu->base_address;
- int base_known = cu->base_known;
+ std::vector<blockrange> blockvec;
dwarf2_ranges_process (offset, cu,
[&] (CORE_ADDR start, CORE_ADDR end)
{
end += baseaddr;
start = gdbarch_adjust_dwarf2_addr (gdbarch, start);
end = gdbarch_adjust_dwarf2_addr (gdbarch, end);
- record_block_range (block, start, end - 1);
+ cu->get_builder ()->record_block_range (block, start, end - 1);
+ blockvec.emplace_back (start, end);
});
+
+ BLOCK_RANGES(block) = make_blockranges (objfile, blockvec);
}
}
cu->producer_is_gcc_lt_4_3 = major < 4 || (major == 4 && minor < 3);
}
else if (producer_is_icc (cu->producer, &major, &minor))
- cu->producer_is_icc_lt_14 = major < 14;
+ {
+ cu->producer_is_icc = true;
+ cu->producer_is_icc_lt_14 = major < 14;
+ }
+ else if (startswith (cu->producer, "CodeWarrior S12/L-ISA"))
+ cu->producer_is_codewarrior = true;
else
{
/* For other non-GCC compilers, expect their behavior is DWARF version
compliant. */
}
- cu->checked_producer = 1;
+ cu->checked_producer = true;
}
/* Check for GCC PR debug/45124 fix which is not present in any G++ version up
to 4.5.any while it is present already in G++ 4.6.0 - the PR has been fixed
during 4.6.0 experimental. */
-static int
+static bool
producer_is_gxx_lt_4_6 (struct dwarf2_cu *cu)
{
if (!cu->checked_producer)
return cu->producer_is_gxx_lt_4_6;
}
+
+/* Codewarrior (at least as of version 5.0.40) generates dwarf line information
+ with incorrect is_stmt attributes. */
+
+static bool
+producer_is_codewarrior (struct dwarf2_cu *cu)
+{
+ if (!cu->checked_producer)
+ check_producer (cu);
+
+ return cu->producer_is_codewarrior;
+}
+
/* Return the default accessibility type if it is not overriden by
DW_AT_accessibility. */
SET_FIELD_BITPOS (*fp, offset * bits_per_byte);
FIELD_BITSIZE (*fp) = 0;
FIELD_TYPE (*fp) = die_type (die, cu);
- FIELD_NAME (*fp) = type_name_no_tag (fp->type);
+ FIELD_NAME (*fp) = TYPE_NAME (fp->type);
}
else if (die->tag == DW_TAG_variant_part)
{
fp->type = get_die_type (die, cu);
fp->artificial = 1;
fp->name = "<<variant>>";
+
+ /* Normally a DW_TAG_variant_part won't have a size, but our
+ representation requires one, so set it to the maximum of the
+ child sizes. */
+ if (TYPE_LENGTH (fp->type) == 0)
+ {
+ unsigned max = 0;
+ for (int i = 0; i < TYPE_NFIELDS (fp->type); ++i)
+ if (TYPE_LENGTH (TYPE_FIELD_TYPE (fp->type, i)) > max)
+ max = TYPE_LENGTH (TYPE_FIELD_TYPE (fp->type, i));
+ TYPE_LENGTH (fp->type) = max;
+ }
}
else
gdb_assert_not_reached ("missing case in dwarf2_add_field");
fp.is_protected = 1;
break;
default:
- complaint (&symfile_complaints,
- _("Unhandled DW_AT_accessibility value (%x)"), accessibility);
+ complaint (_("Unhandled DW_AT_accessibility value (%x)"), accessibility);
}
if (die->tag == DW_TAG_typedef)
default:
/* Unknown accessibility. Complain and treat it as public. */
{
- complaint (&symfile_complaints, _("unsupported accessibility %d"),
+ complaint (_("unsupported accessibility %d"),
field.accessibility);
}
break;
fnp->voffset = VOFFSET_STATIC;
}
else
- complaint (&symfile_complaints, _("member function type missing for '%s'"),
+ complaint (_("member function type missing for '%s'"),
dwarf2_full_name (fieldname, die, cu));
/* Get fcontext from DW_AT_containing_type if present. */
if (TYPE_NFIELDS (this_type) == 0
|| !TYPE_FIELD_ARTIFICIAL (this_type, 0))
{
- complaint (&symfile_complaints,
- _("cannot determine context for virtual member "
+ complaint (_("cannot determine context for virtual member "
"function \"%s\" (offset %s)"),
fieldname, sect_offset_str (die->sect_off));
}
if (attr && DW_UNSND (attr))
{
/* GCC does this, as of 2008-08-25; PR debug/37237. */
- complaint (&symfile_complaints,
- _("Member function \"%s\" (offset %s) is virtual "
+ complaint (_("Member function \"%s\" (offset %s) is virtual "
"but the vtable offset is not specified"),
fieldname, sect_offset_str (die->sect_off));
ALLOCATE_CPLUS_STRUCT_TYPE (type);
smash_to_methodptr_type (type, new_type);
}
+/* If the DIE has a DW_AT_alignment attribute, return its value, doing
+ appropriate error checking and issuing complaints if there is a
+ problem. */
+
+static ULONGEST
+get_alignment (struct dwarf2_cu *cu, struct die_info *die)
+{
+ struct attribute *attr = dwarf2_attr (die, DW_AT_alignment, cu);
+
+ if (attr == nullptr)
+ return 0;
+
+ if (!attr_form_is_constant (attr))
+ {
+ complaint (_("DW_AT_alignment must have constant form"
+ " - DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ return 0;
+ }
+
+ ULONGEST align;
+ if (attr->form == DW_FORM_sdata)
+ {
+ LONGEST val = DW_SND (attr);
+ if (val < 0)
+ {
+ complaint (_("DW_AT_alignment value must not be negative"
+ " - DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ return 0;
+ }
+ align = val;
+ }
+ else
+ align = DW_UNSND (attr);
+
+ if (align == 0)
+ {
+ complaint (_("DW_AT_alignment value must not be zero"
+ " - DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ return 0;
+ }
+ if ((align & (align - 1)) != 0)
+ {
+ complaint (_("DW_AT_alignment value must be a power of 2"
+ " - DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ return 0;
+ }
+
+ return align;
+}
+
+/* If the DIE has a DW_AT_alignment attribute, use its value to set
+ the alignment for TYPE. */
+
+static void
+maybe_set_alignment (struct dwarf2_cu *cu, struct die_info *die,
+ struct type *type)
+{
+ if (!set_type_align (type, get_alignment (cu, die)))
+ complaint (_("DW_AT_alignment value too large"
+ " - DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+}
/* Called when we find the DIE that starts a structure or union scope
(definition) to create a type for the structure or union. Fill in
if (get_die_type (die, cu) != NULL)
return get_die_type (die, cu);
- TYPE_TAG_NAME (type) = full_name;
- if (die->tag == DW_TAG_structure_type
- || die->tag == DW_TAG_class_type)
- TYPE_NAME (type) = TYPE_TAG_NAME (type);
+ TYPE_NAME (type) = full_name;
}
else
{
/* The name is already allocated along with this objfile, so
we don't need to duplicate it for the type. */
- TYPE_TAG_NAME (type) = name;
- if (die->tag == DW_TAG_class_type)
- TYPE_NAME (type) = TYPE_TAG_NAME (type);
+ TYPE_NAME (type) = name;
}
}
TYPE_LENGTH (type) = 0;
}
+ maybe_set_alignment (cu, die, type);
+
if (producer_is_icc_lt_14 (cu) && (TYPE_LENGTH (type) == 0))
{
/* ICC<14 does not output the required DW_AT_declaration on
/* We don't handle this but we might as well report it if we see
it. */
if (dwarf2_attr (child_die, DW_AT_discr_list, cu) != nullptr)
- complaint (&symfile_complaints,
- _("DW_AT_discr_list is not supported yet"
+ complaint (_("DW_AT_discr_list is not supported yet"
" - DIE at %s [in module %s]"),
sect_offset_str (child_die->sect_off),
objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
discriminant_info. */
bool is_variant_part = TYPE_FLAG_DISCRIMINATED_UNION (type);
sect_offset discr_offset;
+ bool has_template_parameters = false;
if (is_variant_part)
{
}
else
{
- complaint (&symfile_complaints,
- _("DW_AT_discr does not have DIE reference form"
+ complaint (_("DW_AT_discr does not have DIE reference form"
" - DIE at %s [in module %s]"),
sect_offset_str (die->sect_off),
objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
/* Attach template arguments to type. */
if (!template_args.empty ())
{
+ has_template_parameters = true;
ALLOCATE_CPLUS_STRUCT_TYPE (type);
TYPE_N_TEMPLATE_ARGUMENTS (type) = template_args.size ();
TYPE_TEMPLATE_ARGUMENTS (type)
/* Complain if virtual function table field not found. */
if (i < TYPE_N_BASECLASSES (t))
- complaint (&symfile_complaints,
- _("virtual function table pointer "
+ complaint (_("virtual function table pointer "
"not found when defining class '%s'"),
- TYPE_TAG_NAME (type) ? TYPE_TAG_NAME (type) :
- "");
+ TYPE_NAME (type) ? TYPE_NAME (type) : "");
}
else
{
attribute, and a declaration attribute. */
if (dwarf2_attr (die, DW_AT_byte_size, cu) != NULL
|| !die_is_declaration (die, cu))
- new_symbol (die, type, cu);
+ {
+ struct symbol *sym = new_symbol (die, type, cu);
+
+ 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));
+ }
+ }
}
/* Assuming DIE is an enumeration type, and TYPE is its associated type,
TYPE_CODE (type) = TYPE_CODE_ENUM;
name = dwarf2_full_name (NULL, die, cu);
if (name != NULL)
- TYPE_TAG_NAME (type) = name;
+ TYPE_NAME (type) = name;
attr = dwarf2_attr (die, DW_AT_type, cu);
if (attr != NULL)
TYPE_LENGTH (type) = 0;
}
+ maybe_set_alignment (cu, die, type);
+
/* The enumeration DIE can be incomplete. In Ada, any type can be
declared as private in the package spec, and then defined only
inside the package body. Such types are known as Taft Amendment
TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TYPE_TARGET_TYPE (type));
if (TYPE_LENGTH (type) == 0)
TYPE_LENGTH (type) = TYPE_LENGTH (TYPE_TARGET_TYPE (type));
+ if (TYPE_RAW_ALIGN (type) == 0
+ && TYPE_RAW_ALIGN (TYPE_TARGET_TYPE (type)) != 0)
+ set_type_align (type, TYPE_RAW_ALIGN (TYPE_TARGET_TYPE (type)));
}
TYPE_DECLARED_CLASS (type) = dwarf2_flag_true_p (die, DW_AT_enum_class, cu);
stride_ok = attr_to_dynamic_prop (attr, die, cu, byte_stride_prop);
if (!stride_ok)
{
- complaint (&symfile_complaints,
- _("unable to read array DW_AT_byte_stride "
+ complaint (_("unable to read array DW_AT_byte_stride "
" - DIE at %s [in module %s]"),
sect_offset_str (die->sect_off),
objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
if (DW_UNSND (attr) >= TYPE_LENGTH (type))
TYPE_LENGTH (type) = DW_UNSND (attr);
else
- complaint (&symfile_complaints,
- _("DW_AT_byte_size for array type smaller "
+ complaint (_("DW_AT_byte_size for array type smaller "
"than the total size of elements"));
}
if (name)
TYPE_NAME (type) = name;
+ maybe_set_alignment (cu, die, type);
+
/* Install the type in the die. */
set_die_type (die, type, cu);
if (attr)
TYPE_LENGTH (set_type) = DW_UNSND (attr);
+ maybe_set_alignment (cu, die, set_type);
+
return set_die_type (die, set_type, cu);
}
not specified by DWARF. It seems to have been
emitted by gfortran at least as recently as:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23057. */
- complaint (&symfile_complaints,
- _("Variable in common block has "
+ complaint (_("Variable in common block has "
"DW_AT_data_member_location "
"- DIE at %s [in module %s]"),
sect_offset_str (child_die->sect_off),
/* Create the type. */
type = init_type (objfile, TYPE_CODE_NAMESPACE, 0, name);
- TYPE_TAG_NAME (type) = TYPE_NAME (type);
return set_die_type (die, type, cu);
}
const char *previous_prefix = determine_prefix (die, cu);
std::vector<const char *> excludes;
- add_using_directive (using_directives (cu->language),
+ add_using_directive (using_directives (cu),
previous_prefix, TYPE_NAME (type), NULL,
NULL, excludes, 0, &objfile->objfile_obstack);
}
module_name = dwarf2_name (die, cu);
if (!module_name)
- complaint (&symfile_complaints,
- _("DW_TAG_module has no name, offset %s"),
+ 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);
- /* determine_prefix uses TYPE_TAG_NAME. */
- TYPE_TAG_NAME (type) = TYPE_NAME (type);
-
return set_die_type (die, type, cu);
}
else
addr_class = DW_ADDR_none;
- /* If the pointer size or address class is different than the
- default, create a type variant marked as such and set the
- length accordingly. */
- if (TYPE_LENGTH (type) != byte_size || addr_class != DW_ADDR_none)
+ ULONGEST alignment = get_alignment (cu, die);
+
+ /* If the pointer size, alignment, or address class is different
+ than the default, create a type variant marked as such and set
+ the length accordingly. */
+ if (TYPE_LENGTH (type) != byte_size
+ || (alignment != 0 && TYPE_RAW_ALIGN (type) != 0
+ && alignment != TYPE_RAW_ALIGN (type))
+ || addr_class != DW_ADDR_none)
{
if (gdbarch_address_class_type_flags_p (gdbarch))
{
}
else if (TYPE_LENGTH (type) != byte_size)
{
- complaint (&symfile_complaints,
- _("invalid pointer size %d"), byte_size);
+ complaint (_("invalid pointer size %d"), byte_size);
+ }
+ else if (TYPE_RAW_ALIGN (type) != alignment)
+ {
+ complaint (_("Invalid DW_AT_alignment"
+ " - DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
}
else
{
}
TYPE_LENGTH (type) = byte_size;
+ set_type_align (type, alignment);
return set_die_type (die, type, cu);
}
{
TYPE_LENGTH (type) = cu_header->addr_size;
}
+ maybe_set_alignment (cu, die, type);
return set_die_type (die, type, cu);
}
{
/* Self-referential typedefs are, it seems, not allowed by the DWARF
spec and cause infinite loops in GDB. */
- complaint (&symfile_complaints,
- _("Self-referential DW_TAG_typedef "
+ complaint (_("Self-referential DW_TAG_typedef "
"- DIE at %s [in module %s]"),
sect_offset_str (die->sect_off), objfile_name (objfile));
TYPE_TARGET_TYPE (this_type) = NULL;
return type;
}
+/* Allocate an integer type of size BITS and name NAME. */
+
+static struct type *
+dwarf2_init_integer_type (struct dwarf2_cu *cu, struct objfile *objfile,
+ int bits, int unsigned_p, const char *name)
+{
+ struct type *type;
+
+ /* Versions of Intel's C Compiler generate an integer type called "void"
+ instead of using DW_TAG_unspecified_type. This has been seen on
+ at least versions 14, 17, and 18. */
+ if (bits == 0 && producer_is_icc (cu) && name != nullptr
+ && strcmp (name, "void") == 0)
+ type = objfile_type (objfile)->builtin_void;
+ else
+ type = init_integer_type (objfile, bits, unsigned_p, name);
+
+ 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;
+
+ switch (bits)
+ {
+ case 32:
+ tt = builtin_type (gdbarch)->builtin_float;
+ break;
+ case 64:
+ tt = builtin_type (gdbarch)->builtin_double;
+ break;
+ case 128:
+ tt = builtin_type (gdbarch)->builtin_long_double;
+ break;
+ }
+
+ 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. */
name = dwarf2_name (die, cu);
if (!name)
{
- complaint (&symfile_complaints,
- _("DW_AT_name missing from DW_TAG_base_type"));
+ complaint (_("DW_AT_name missing from DW_TAG_base_type"));
}
switch (encoding)
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:
type = dwarf2_init_float_type (objfile, bits, name, name);
break;
case DW_ATE_signed:
- type = init_integer_type (objfile, bits, 0, name);
+ type = dwarf2_init_integer_type (cu, objfile, bits, 0, name);
break;
case DW_ATE_unsigned:
if (cu->language == language_fortran
&& startswith (name, "character("))
type = init_character_type (objfile, bits, 1, name);
else
- type = init_integer_type (objfile, bits, 1, name);
+ type = dwarf2_init_integer_type (cu, objfile, bits, 1, name);
break;
case DW_ATE_signed_char:
if (cu->language == language_ada || cu->language == language_m2
|| cu->language == language_fortran)
type = init_character_type (objfile, bits, 0, name);
else
- type = init_integer_type (objfile, bits, 0, name);
+ type = dwarf2_init_integer_type (cu, objfile, bits, 0, name);
break;
case DW_ATE_unsigned_char:
if (cu->language == language_ada || cu->language == language_m2
|| cu->language == language_rust)
type = init_character_type (objfile, bits, 1, name);
else
- type = init_integer_type (objfile, bits, 1, name);
+ type = dwarf2_init_integer_type (cu, objfile, bits, 1, name);
break;
case DW_ATE_UTF:
{
type = builtin_type (arch)->builtin_char32;
else
{
- complaint (&symfile_complaints,
- _("unsupported DW_ATE_UTF bit size: '%d'"),
+ complaint (_("unsupported DW_ATE_UTF bit size: '%d'"),
bits);
- type = init_integer_type (objfile, bits, 1, name);
+ type = dwarf2_init_integer_type (cu, objfile, bits, 1, name);
}
return set_die_type (die, type, cu);
}
break;
default:
- complaint (&symfile_complaints, _("unsupported DW_AT_encoding: '%s'"),
+ complaint (_("unsupported DW_AT_encoding: '%s'"),
dwarf_type_encoding_name (encoding));
type = init_type (objfile, TYPE_CODE_ERROR, bits, name);
break;
if (name && strcmp (name, "char") == 0)
TYPE_NOSIGN (type) = 1;
+ maybe_set_alignment (cu, die, type);
+
return set_die_type (die, type, cu);
}
int low_default_is_valid;
int high_bound_is_count = 0;
const char *name;
- LONGEST negative_mask;
+ ULONGEST negative_mask;
orig_base_type = die_type (die, cu);
/* If ORIG_BASE_TYPE is a typedef, it will not be TYPE_UNSIGNED,
if (attr)
attr_to_dynamic_prop (attr, die, cu, &low);
else if (!low_default_is_valid)
- complaint (&symfile_complaints, _("Missing DW_AT_lower_bound "
+ complaint (_("Missing DW_AT_lower_bound "
"- DIE at %s [in module %s]"),
sect_offset_str (die->sect_off),
objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
- attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
+ 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))
{
- attr = dwarf2_attr (die, DW_AT_count, cu);
+ attr = attr_count = dwarf2_attr (die, DW_AT_count, cu);
if (attr_to_dynamic_prop (attr, die, cu, &high))
{
/* If bounds are constant do the final calculation here. */
else
high_bound_is_count = 1;
}
+ else
+ {
+ if (attr_ub != NULL)
+ complaint (_("Unresolved DW_AT_upper_bound "
+ "- DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ if (attr_count != NULL)
+ complaint (_("Unresolved DW_AT_count "
+ "- DIE at %s [in module %s]"),
+ sect_offset_str (die->sect_off),
+ objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
+ }
+
}
/* Dwarf-2 specifications explicitly allows to create subrange types
the bounds as signed, and thus sign-extend their values, when
the base type is signed. */
negative_mask =
- -((LONGEST) 1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1));
+ -((ULONGEST) 1 << (TYPE_LENGTH (base_type) * TARGET_CHAR_BIT - 1));
if (low.kind == PROP_CONST
&& !TYPE_UNSIGNED (base_type) && (low.data.const_val & negative_mask))
low.data.const_val |= negative_mask;
if (attr)
TYPE_LENGTH (range_type) = DW_UNSND (attr);
+ maybe_set_alignment (cu, die, range_type);
+
set_die_type (die, range_type, cu);
/* set_die_type should be already done. */
{
if (building_psymtab && pdi.name != NULL)
add_psymbol_to_list (pdi.name, strlen (pdi.name), 0,
- VAR_DOMAIN, LOC_TYPEDEF,
- &objfile->static_psymbols,
+ VAR_DOMAIN, LOC_TYPEDEF, -1,
+ psymbol_placement::STATIC,
0, cu->language, objfile);
info_ptr = locate_pdi_sibling (reader, &pdi, info_ptr);
continue;
/* The exception for DW_TAG_typedef with has_children above is
a workaround of GCC PR debug/47510. In the case of this complaint
- type_name_no_tag_or_error will error on such types later.
+ type_name_or_error will error on such types later.
GDB skipped children of DW_TAG_typedef by the shortcut above and then
it could not find the child DIEs referenced later, this is checked
above. In correct DWARF DW_TAG_typedef should have no children. */
if (pdi.tag == DW_TAG_typedef && pdi.has_children)
- complaint (&symfile_complaints,
- _("DW_TAG_typedef has childen - GCC PR debug/47510 bug "
+ complaint (_("DW_TAG_typedef has childen - GCC PR debug/47510 bug "
"- DIE at %s [in module %s]"),
sect_offset_str (pdi.sect_off), objfile_name (objfile));
&& parent_die->has_specification == 0)
{
if (pdi.name == NULL)
- complaint (&symfile_complaints,
- _("malformed enumerator DIE ignored"));
+ complaint (_("malformed enumerator DIE ignored"));
else if (building_psymtab)
add_psymbol_to_list (pdi.name, strlen (pdi.name), 0,
- VAR_DOMAIN, LOC_CONST,
+ VAR_DOMAIN, LOC_CONST, -1,
cu->language == language_cplus
- ? &objfile->global_psymbols
- : &objfile->static_psymbols,
+ ? psymbol_placement::GLOBAL
+ : psymbol_placement::STATIC,
0, cu->language, objfile);
info_ptr = locate_pdi_sibling (reader, &pdi, info_ptr);
/* Ignore absolute siblings, they might point outside of
the current compile unit. */
if (attr.form == DW_FORM_ref_addr)
- complaint (&symfile_complaints,
- _("ignoring absolute DW_AT_sibling"));
+ complaint (_("ignoring absolute DW_AT_sibling"));
else
{
const gdb_byte *buffer = reader->buffer;
const gdb_byte *sibling_ptr = buffer + to_underlying (off);
if (sibling_ptr < info_ptr)
- complaint (&symfile_complaints,
- _("DW_AT_sibling points backwards"));
+ complaint (_("DW_AT_sibling points backwards"));
else if (sibling_ptr > reader->buffer_end)
dwarf2_section_buffer_overflow_complaint (reader->die_section);
else
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;
}
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- complaint (&symfile_complaints,
- _("DW_AT_low_pc %s is zero "
+ complaint (_("DW_AT_low_pc %s is zero "
"for DIE at %s [in module %s]"),
paddress (gdbarch, lowpc),
sect_offset_str (sect_off),
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- complaint (&symfile_complaints,
- _("DW_AT_low_pc %s is not < DW_AT_high_pc %s "
+ complaint (_("DW_AT_low_pc %s is not < DW_AT_high_pc %s "
"for DIE at %s [in module %s]"),
paddress (gdbarch, lowpc),
paddress (gdbarch, highpc),
&& DW_UNSND (attr) >= 0xffffffff)
{
complaint
- (&symfile_complaints,
- _("Suspicious DW_AT_byte_size value treated as zero instead of %s"),
+ (_("Suspicious DW_AT_byte_size value treated as zero instead of %s"),
hex_string (DW_UNSND (attr)));
DW_UNSND (attr) = 0;
}
|| cu_header->initial_length_size == 12);
if (cu_header->initial_length_size != *bytes_read)
- complaint (&symfile_complaints,
- _("intermixed 32-bit and 64-bit DWARF sections"));
+ complaint (_("intermixed 32-bit and 64-bit DWARF sections"));
*offset_size = (*bytes_read == 4) ? 4 : 8;
return length;
read_signed_leb128 (bfd *abfd, const gdb_byte *buf,
unsigned int *bytes_read_ptr)
{
- LONGEST result;
+ ULONGEST result;
int shift, num_read;
unsigned char byte;
byte = bfd_get_8 (abfd, buf);
buf++;
num_read++;
- result |= ((LONGEST) (byte & 127) << shift);
+ result |= ((ULONGEST) (byte & 127) << shift);
shift += 7;
if ((byte & 128) == 0)
{
}
}
if ((shift < 8 * sizeof (result)) && (byte & 0x40))
- result |= -(((LONGEST) 1) << shift);
+ result |= -(((ULONGEST) 1) << shift);
*bytes_read_ptr = num_read;
return result;
}
unsigned int addr_index)
{
struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
- struct objfile *objfile = dwarf2_per_objfile->objfile;
struct dwarf2_cu *cu = per_cu->cu;
ULONGEST addr_base;
int addr_size;
/* Note: We can't use init_cutu_and_read_dies_simple here,
we need addr_base. */
- init_cutu_and_read_dies (per_cu, NULL, 0, 0,
+ init_cutu_and_read_dies (per_cu, NULL, 0, 0, false,
dwarf2_read_addr_index_reader, &aidata);
addr_base = aidata.addr_base;
addr_size = aidata.addr_size;
|| attr->form == DW_FORM_GNU_strp_alt)
str = DW_STRING (attr);
else
- complaint (&symfile_complaints,
- _("string type expected for attribute %s for "
+ complaint (_("string type expected for attribute %s for "
"DIE at %s in module %s"),
dwarf_attr_name (name), sect_offset_str (die->sect_off),
objfile_name (cu->per_cu->dwarf2_per_objfile->objfile));
case DW_LNCT_MD5:
break;
default:
- complaint (&symfile_complaints,
- _("Unknown format content type %s"),
+ complaint (_("Unknown format content type %s"),
pulongest (content_type));
}
}
if (section->buffer == NULL)
{
if (cu->dwo_unit && cu->per_cu->is_debug_types)
- complaint (&symfile_complaints, _("missing .debug_line.dwo section"));
+ complaint (_("missing .debug_line.dwo section"));
else
- complaint (&symfile_complaints, _("missing .debug_line section"));
+ complaint (_("missing .debug_line section"));
return 0;
}
{
/* This is a version we don't understand. The format could have
changed in ways we don't handle properly so just punt. */
- complaint (&symfile_complaints,
- _("unsupported version in .debug_line section"));
+ complaint (_("unsupported version in .debug_line section"));
return NULL;
}
if (lh->version >= 5)
line_ptr += 1;
if (segment_selector_size != 0)
{
- complaint (&symfile_complaints,
- _("unsupported segment selector size %u "
+ complaint (_("unsupported segment selector size %u "
"in .debug_line section"),
segment_selector_size);
return NULL;
if (lh->maximum_ops_per_instruction == 0)
{
lh->maximum_ops_per_instruction = 1;
- complaint (&symfile_complaints,
- _("invalid maximum_ops_per_instruction "
+ complaint (_("invalid maximum_ops_per_instruction "
"in `.debug_line' section"));
}
/* Read directory table. */
read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (),
&cu->header,
- [] (struct line_header *lh, const char *name,
+ [] (struct line_header *header, const char *name,
dir_index d_index, unsigned int mod_time,
unsigned int length)
{
- lh->add_include_dir (name);
+ header->add_include_dir (name);
});
/* Read file name table. */
read_formatted_entries (dwarf2_per_objfile, abfd, &line_ptr, lh.get (),
&cu->header,
- [] (struct line_header *lh, const char *name,
+ [] (struct line_header *header, const char *name,
dir_index d_index, unsigned int mod_time,
unsigned int length)
{
- lh->add_file_name (name, d_index, mod_time, length);
+ header->add_file_name (name, d_index, mod_time, length);
});
}
else
lh->statement_program_start = line_ptr;
if (line_ptr > (section->buffer + section->size))
- complaint (&symfile_complaints,
- _("line number info header doesn't "
+ complaint (_("line number info header doesn't "
"fit in `.debug_line' section"));
return lh;
public:
/* Initialize a machine state for the start of a line number
program. */
- lnp_state_machine (gdbarch *arch, line_header *lh, bool record_lines_p);
+ lnp_state_machine (struct dwarf2_cu *cu, gdbarch *arch, line_header *lh,
+ bool record_lines_p);
file_entry *current_file ()
{
we're processing the end of a sequence. */
void record_line (bool end_sequence);
- /* Check address and if invalid nop-out the rest of the lines in this
- sequence. */
+ /* Check ADDRESS is zero and less than UNRELOCATED_LOWPC and if true
+ nop-out rest of the lines in this sequence. */
void check_line_address (struct dwarf2_cu *cu,
const gdb_byte *line_ptr,
- CORE_ADDR lowpc, CORE_ADDR address);
+ CORE_ADDR unrelocated_lowpc, CORE_ADDR address);
void handle_set_discriminator (unsigned int discriminator)
{
/* Handle DW_LNE_end_sequence. */
void handle_end_sequence ()
{
- m_record_line_callback = ::record_line;
+ m_currently_recording_lines = true;
}
private:
m_line_has_non_zero_discriminator = m_discriminator != 0;
}
+ struct dwarf2_cu *m_cu;
+
gdbarch *m_gdbarch;
/* True if we're recording lines.
/* The last file a line number was recorded for. */
struct subfile *m_last_subfile = NULL;
- /* The function to call to record a line. */
- record_line_ftype *m_record_line_callback = NULL;
+ /* When true, record the lines we decode. */
+ bool m_currently_recording_lines = false;
/* The last line number that was recorded, used to coalesce
consecutive entries for the same line. This can happen, for
{
const char *dir = fe->include_dir (m_line_header);
- m_last_subfile = current_subfile;
+ m_last_subfile = m_cu->get_builder ()->get_current_subfile ();
m_line_has_non_zero_discriminator = m_discriminator != 0;
- dwarf2_start_subfile (fe->name, dir);
+ dwarf2_start_subfile (m_cu, fe->name, dir);
}
}
% m_line_header->maximum_ops_per_instruction);
}
-/* Ignore this record_line request. */
-
-static void
-noop_record_line (struct subfile *subfile, int line, CORE_ADDR pc)
-{
- return;
-}
-
/* Return non-zero if we should add LINE to the line number table.
LINE is the line to add, LAST_LINE is the last line that was added,
LAST_SUBFILE is the subfile for LAST_LINE.
within one sequence, thus this coalescing is ok. */
static int
-dwarf_record_line_p (unsigned int line, unsigned int last_line,
+dwarf_record_line_p (struct dwarf2_cu *cu,
+ unsigned int line, unsigned int last_line,
int line_has_non_zero_discriminator,
struct subfile *last_subfile)
{
- if (current_subfile != last_subfile)
+ if (cu->get_builder ()->get_current_subfile () != last_subfile)
return 1;
if (line != last_line)
return 1;
return 0;
}
-/* Use P_RECORD_LINE to record line number LINE beginning at address ADDRESS
- in the line table of subfile SUBFILE. */
+/* Use the CU's builder to record line number LINE beginning at
+ address ADDRESS in the line table of subfile SUBFILE. */
static void
dwarf_record_line_1 (struct gdbarch *gdbarch, struct subfile *subfile,
unsigned int line, CORE_ADDR address,
- record_line_ftype p_record_line)
+ struct dwarf2_cu *cu)
{
CORE_ADDR addr = gdbarch_addr_bits_remove (gdbarch, address);
paddress (gdbarch, address));
}
- (*p_record_line) (subfile, line, addr);
+ if (cu != nullptr)
+ cu->get_builder ()->record_line (subfile, line, addr);
}
/* Subroutine of dwarf_decode_lines_1 to simplify it.
static void
dwarf_finish_line (struct gdbarch *gdbarch, struct subfile *subfile,
- CORE_ADDR address, record_line_ftype p_record_line)
+ CORE_ADDR address, struct dwarf2_cu *cu)
{
if (subfile == NULL)
return;
paddress (gdbarch, address));
}
- dwarf_record_line_1 (gdbarch, subfile, 0, address, p_record_line);
+ dwarf_record_line_1 (gdbarch, subfile, 0, address, cu);
}
void
else if (m_op_index == 0 || end_sequence)
{
fe->included_p = 1;
- if (m_record_lines_p && m_is_stmt)
+ if (m_record_lines_p && (producer_is_codewarrior (m_cu) || m_is_stmt))
{
- if (m_last_subfile != current_subfile || end_sequence)
+ if (m_last_subfile != m_cu->get_builder ()->get_current_subfile ()
+ || end_sequence)
{
- dwarf_finish_line (m_gdbarch, m_last_subfile,
- m_address, m_record_line_callback);
+ dwarf_finish_line (m_gdbarch, m_last_subfile, m_address,
+ m_currently_recording_lines ? m_cu : nullptr);
}
if (!end_sequence)
{
- if (dwarf_record_line_p (m_line, m_last_line,
+ if (dwarf_record_line_p (m_cu, m_line, m_last_line,
m_line_has_non_zero_discriminator,
m_last_subfile))
{
- dwarf_record_line_1 (m_gdbarch, current_subfile,
+ buildsym_compunit *builder = m_cu->get_builder ();
+ dwarf_record_line_1 (m_gdbarch,
+ builder->get_current_subfile (),
m_line, m_address,
- m_record_line_callback);
+ m_currently_recording_lines ? m_cu : nullptr);
}
- m_last_subfile = current_subfile;
+ m_last_subfile = m_cu->get_builder ()->get_current_subfile ();
m_last_line = m_line;
}
}
}
}
-lnp_state_machine::lnp_state_machine (gdbarch *arch, line_header *lh,
- bool record_lines_p)
+lnp_state_machine::lnp_state_machine (struct dwarf2_cu *cu, gdbarch *arch,
+ line_header *lh, bool record_lines_p)
{
+ m_cu = cu;
m_gdbarch = arch;
m_record_lines_p = record_lines_p;
m_line_header = lh;
- m_record_line_callback = ::record_line;
+ m_currently_recording_lines = true;
/* Call `gdbarch_adjust_dwarf2_line' on the initial 0 address as if there
was a line entry for it so that the backend has a chance to adjust it
void
lnp_state_machine::check_line_address (struct dwarf2_cu *cu,
const gdb_byte *line_ptr,
- CORE_ADDR lowpc, CORE_ADDR address)
+ CORE_ADDR unrelocated_lowpc, CORE_ADDR address)
{
- /* If address < lowpc then it's not a usable value, it's outside the
- pc range of the CU. However, we restrict the test to only address
- values of zero to preserve GDB's previous behaviour which is to
- handle the specific case of a function being GC'd by the linker. */
+ /* If ADDRESS < UNRELOCATED_LOWPC then it's not a usable value, it's outside
+ the pc range of the CU. However, we restrict the test to only ADDRESS
+ values of zero to preserve GDB's previous behaviour which is to handle
+ the specific case of a function being GC'd by the linker. */
- if (address == 0 && address < lowpc)
+ if (address == 0 && address < unrelocated_lowpc)
{
/* This line table is for a function which has been
GCd by the linker. Ignore it. PR gdb/12528 */
struct objfile *objfile = cu->per_cu->dwarf2_per_objfile->objfile;
long line_offset = line_ptr - get_debug_line_section (cu)->buffer;
- complaint (&symfile_complaints,
- _(".debug_line address at offset 0x%lx is 0 [in module %s]"),
+ complaint (_(".debug_line address at offset 0x%lx is 0 [in module %s]"),
line_offset, objfile_name (objfile));
- m_record_line_callback = noop_record_line;
- /* Note: record_line_callback is left as noop_record_line until
- we see DW_LNE_end_sequence. */
+ m_currently_recording_lines = false;
+ /* Note: m_currently_recording_lines is left as false until we see
+ DW_LNE_end_sequence. */
}
}
{
/* The DWARF line number program state machine. Reset the state
machine at the start of each sequence. */
- lnp_state_machine state_machine (gdbarch, lh, record_lines_p);
+ lnp_state_machine state_machine (cu, gdbarch, lh, record_lines_p);
bool end_sequence = false;
if (record_lines_p)
const file_entry *fe = state_machine.current_file ();
if (fe != NULL)
- dwarf2_start_subfile (fe->name, fe->include_dir (lh));
+ dwarf2_start_subfile (cu, fe->name, fe->include_dir (lh));
}
/* Decode the table. */
line_ptr += bytes_read;
state_machine.check_line_address (cu, line_ptr,
- lowpc, address);
+ lowpc - baseaddr, address);
state_machine.handle_set_address (baseaddr, address);
}
break;
}
break;
default:
- complaint (&symfile_complaints,
- _("mangled .debug_line section"));
+ complaint (_("mangled .debug_line section"));
return;
}
/* Make sure that we parsed the extended op correctly. If e.g.
we may have read the wrong number of bytes. */
if (line_ptr != extended_end)
{
- complaint (&symfile_complaints,
- _("mangled .debug_line section"));
+ complaint (_("mangled .debug_line section"));
return;
}
break;
/* Make sure a symtab is created for every file, even files
which contain only variables (i.e. no code with associated
line numbers). */
- struct compunit_symtab *cust = buildsym_compunit_symtab ();
+ buildsym_compunit *builder = cu->get_builder ();
+ struct compunit_symtab *cust = builder->get_compunit_symtab ();
int i;
for (i = 0; i < lh->file_names.size (); i++)
{
file_entry &fe = lh->file_names[i];
- dwarf2_start_subfile (fe.name, fe.include_dir (lh));
+ dwarf2_start_subfile (cu, fe.name, fe.include_dir (lh));
- if (current_subfile->symtab == NULL)
+ if (builder->get_current_subfile ()->symtab == NULL)
{
- current_subfile->symtab
- = allocate_symtab (cust, current_subfile->name);
+ builder->get_current_subfile ()->symtab
+ = allocate_symtab (cust,
+ builder->get_current_subfile ()->name);
}
- fe.symtab = current_subfile->symtab;
+ fe.symtab = builder->get_current_subfile ()->symtab;
}
}
}
subfile's name. */
static void
-dwarf2_start_subfile (const char *filename, const char *dirname)
+dwarf2_start_subfile (struct dwarf2_cu *cu, const char *filename,
+ const char *dirname)
{
char *copy = NULL;
filename = copy;
}
- start_subfile (filename);
+ cu->get_builder ()->start_subfile (filename);
if (copy != NULL)
xfree (copy);
}
-/* Start a symtab for DWARF.
- NAME, COMP_DIR, LOW_PC are passed to start_symtab. */
+/* Start a symtab for DWARF. NAME, COMP_DIR, LOW_PC are passed to the
+ buildsym_compunit constructor. */
-static struct compunit_symtab *
-dwarf2_start_symtab (struct dwarf2_cu *cu,
- const char *name, const char *comp_dir, CORE_ADDR low_pc)
+struct compunit_symtab *
+dwarf2_cu::start_symtab (const char *name, const char *comp_dir,
+ CORE_ADDR low_pc)
{
- struct compunit_symtab *cust
- = start_symtab (cu->per_cu->dwarf2_per_objfile->objfile, name, comp_dir,
- low_pc, cu->language);
+ gdb_assert (m_builder == nullptr);
+
+ m_builder.reset (new struct buildsym_compunit
+ (per_cu->dwarf2_per_objfile->objfile,
+ name, comp_dir, language, low_pc));
- record_debugformat ("DWARF 2");
- record_producer (cu->producer);
+ list_in_scope = get_builder ()->get_file_symbols ();
- /* We assume that we're processing GCC output. */
- processing_gcc_compilation = 2;
+ get_builder ()->record_debugformat ("DWARF 2");
+ get_builder ()->record_producer (producer);
- cu->processing_has_namespace_info = 0;
+ processing_has_namespace_info = false;
- return cust;
+ return get_builder ()->get_compunit_symtab ();
}
static void
dwarf2_symbol_mark_computed (attr, sym, cu, 0);
if (SYMBOL_COMPUTED_OPS (sym)->location_has_loclist)
- cu->has_loclist = 1;
+ cu->has_loclist = true;
}
/* Given a pointer to a DWARF information entry, figure out if we need
fe = NULL;
if (fe == NULL)
- complaint (&symfile_complaints,
- _("file index out of range"));
+ complaint (_("file index out of range"));
else
symbol_set_symtab (sym, fe->symtab);
}
access them globally. For instance, we want to be able
to break on a nested subprogram without having to
specify the context. */
- list_to_add = &global_symbols;
+ list_to_add = cu->get_builder ()->get_global_symbols ();
}
else
{
if (!suppress_add)
{
if (attr2 && (DW_UNSND (attr2) != 0))
- list_to_add = &global_symbols;
+ list_to_add = cu->get_builder ()->get_global_symbols ();
else
list_to_add = cu->list_in_scope;
}
/* A variable with DW_AT_external is never static,
but it may be block-scoped. */
- list_to_add = (cu->list_in_scope == &file_symbols
- ? &global_symbols : cu->list_in_scope);
+ list_to_add
+ = ((cu->list_in_scope
+ == cu->get_builder ()->get_file_symbols ())
+ ? cu->get_builder ()->get_global_symbols ()
+ : cu->list_in_scope);
}
else
list_to_add = cu->list_in_scope;
{
/* A variable with DW_AT_external is never static, but it
may be block-scoped. */
- list_to_add = (cu->list_in_scope == &file_symbols
- ? &global_symbols : cu->list_in_scope);
+ list_to_add
+ = ((cu->list_in_scope
+ == cu->get_builder ()->get_file_symbols ())
+ ? cu->get_builder ()->get_global_symbols ()
+ : cu->list_in_scope);
SYMBOL_ACLASS_INDEX (sym) = LOC_UNRESOLVED;
}
}
break;
case DW_TAG_formal_parameter:
- /* If we are inside a function, mark this as an argument. If
- not, we might be looking at an argument to an inlined function
- when we do not have enough information to show inlined frames;
- pretend it's a local variable in that case so that the user can
- still see it. */
- if (context_stack_depth > 0
- && context_stack[context_stack_depth - 1].name != NULL)
- SYMBOL_IS_ARGUMENT (sym) = 1;
- attr = dwarf2_attr (die, DW_AT_location, cu);
- if (attr)
- {
- var_decode_location (attr, sym, cu);
- }
- attr = dwarf2_attr (die, DW_AT_const_value, cu);
- if (attr)
- {
- dwarf2_const_value (attr, sym, cu);
- }
+ {
+ /* If we are inside a function, mark this as an argument. If
+ not, we might be looking at an argument to an inlined function
+ when we do not have enough information to show inlined frames;
+ pretend it's a local variable in that case so that the user can
+ still see it. */
+ struct context_stack *curr
+ = cu->get_builder ()->get_current_context_stack ();
+ if (curr != nullptr && curr->name != nullptr)
+ SYMBOL_IS_ARGUMENT (sym) = 1;
+ attr = dwarf2_attr (die, DW_AT_location, cu);
+ if (attr)
+ {
+ var_decode_location (attr, sym, cu);
+ }
+ attr = dwarf2_attr (die, DW_AT_const_value, cu);
+ if (attr)
+ {
+ dwarf2_const_value (attr, sym, cu);
+ }
- list_to_add = cu->list_in_scope;
+ list_to_add = cu->list_in_scope;
+ }
break;
case DW_TAG_unspecified_parameters:
/* From varargs functions; gdb doesn't seem to have any
if (!suppress_add)
{
- list_to_add = (cu->list_in_scope == &file_symbols
- && cu->language == language_cplus
- ? &global_symbols : cu->list_in_scope);
+ buildsym_compunit *builder = cu->get_builder ();
+ list_to_add
+ = (cu->list_in_scope == builder->get_file_symbols ()
+ && cu->language == language_cplus
+ ? builder->get_global_symbols ()
+ : cu->list_in_scope);
/* The semantics of C++ state that "struct foo {
... }" also defines a typedef for "foo". */
/* NOTE: carlton/2003-11-10: See comment above in the
DW_TAG_class_type, etc. block. */
- list_to_add = (cu->list_in_scope == &file_symbols
- && cu->language == language_cplus
- ? &global_symbols : cu->list_in_scope);
+ list_to_add
+ = (cu->list_in_scope == cu->get_builder ()->get_file_symbols ()
+ && cu->language == language_cplus
+ ? cu->get_builder ()->get_global_symbols ()
+ : cu->list_in_scope);
}
break;
case DW_TAG_imported_declaration:
case DW_TAG_namespace:
SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
- list_to_add = &global_symbols;
+ list_to_add = cu->get_builder ()->get_global_symbols ();
break;
case DW_TAG_module:
SYMBOL_ACLASS_INDEX (sym) = LOC_TYPEDEF;
SYMBOL_DOMAIN (sym) = MODULE_DOMAIN;
- list_to_add = &global_symbols;
+ list_to_add = cu->get_builder ()->get_global_symbols ();
break;
case DW_TAG_common_block:
SYMBOL_ACLASS_INDEX (sym) = LOC_COMMON_BLOCK;
trash data, but since we must specifically ignore things
we don't recognize, there is nothing else we should do at
this point. */
- complaint (&symfile_complaints, _("unsupported tag: '%s'"),
+ complaint (_("unsupported tag: '%s'"),
dwarf_tag_name (die->tag));
break;
}
namespaces based on the demangled name. */
if (!cu->processing_has_namespace_info
&& cu->language == language_cplus)
- cp_scan_for_anonymous_namespaces (sym, objfile);
+ cp_scan_for_anonymous_namespaces (cu->get_builder (), sym, objfile);
}
return (sym);
}
break;
default:
- complaint (&symfile_complaints,
- _("unsupported const value attribute form: '%s'"),
+ complaint (_("unsupported const value attribute form: '%s'"),
dwarf_form_name (attr->form));
*value = 0;
break;
struct dwarf2_per_objfile *dwarf2_per_objfile
= cu->per_cu->dwarf2_per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
- char *message, *saved;
+ char *saved;
- message = xstrprintf (_("<unknown type in %s, CU %s, DIE %s>"),
- objfile_name (objfile),
- sect_offset_str (cu->header.sect_off),
- sect_offset_str (die->sect_off));
+ std::string message
+ = string_printf (_("<unknown type in %s, CU %s, DIE %s>"),
+ objfile_name (objfile),
+ sect_offset_str (cu->header.sect_off),
+ sect_offset_str (die->sect_off));
saved = (char *) obstack_copy0 (&objfile->objfile_obstack,
- message, strlen (message));
- xfree (message);
+ message.c_str (), message.length ());
return init_type (objfile, TYPE_CODE_ERROR, 0, saved);
}
}
else
{
- complaint (&symfile_complaints,
- _("Dwarf Error: Bad type attribute %s in DIE"
+ complaint (_("Dwarf Error: Bad type attribute %s in DIE"
" at %s [in module %s]"),
dwarf_attr_name (attr->name), sect_offset_str (die->sect_off),
objfile_name (objfile));
this_type = read_tag_atomic_type (die, cu);
break;
default:
- complaint (&symfile_complaints,
- _("unexpected tag in read_type_die: '%s'"),
+ complaint (_("unexpected tag in read_type_die: '%s'"),
dwarf_tag_name (die->tag));
break;
}
doesn't allow it), and break the loop here. */
name = dwarf2_name (die, cu);
parent_name = dwarf2_name (parent, cu);
- complaint (&symfile_complaints,
- _("template param type '%s' defined within parent '%s'"),
+ complaint (_("template param type '%s' defined within parent '%s'"),
name ? name : "<unknown>",
parent_name ? parent_name : "<unknown>");
return "";
DW_TAG_namespace DIEs with a name of "::" for the global namespace.
Work around this problem here. */
if (cu->language == language_cplus
- && strcmp (TYPE_TAG_NAME (parent_type), "::") == 0)
+ && strcmp (TYPE_NAME (parent_type), "::") == 0)
return "";
/* We give a name to even anonymous namespaces. */
- return TYPE_TAG_NAME (parent_type);
+ return TYPE_NAME (parent_type);
case DW_TAG_class_type:
case DW_TAG_interface_type:
case DW_TAG_structure_type:
case DW_TAG_union_type:
case DW_TAG_module:
parent_type = read_type_die (parent, cu);
- if (TYPE_TAG_NAME (parent_type) != NULL)
- return TYPE_TAG_NAME (parent_type);
+ if (TYPE_NAME (parent_type) != NULL)
+ return TYPE_NAME (parent_type);
else
/* An anonymous structure is only allowed non-static data
members; no typedefs, no member functions, et cetera.
parent_type = read_type_die (parent, cu);
if (TYPE_DECLARED_CLASS (parent_type))
{
- if (TYPE_TAG_NAME (parent_type) != NULL)
- return TYPE_TAG_NAME (parent_type);
+ if (TYPE_NAME (parent_type) != NULL)
+ return TYPE_NAME (parent_type);
return "";
}
/* Fall through. */
if (attr_form_is_ref (attr))
return (sect_offset) DW_UNSND (attr);
- complaint (&symfile_complaints,
- _("unsupported die ref attribute form: '%s'"),
+ complaint (_("unsupported die ref attribute form: '%s'"),
dwarf_form_name (attr->form));
return {};
}
else
{
/* For DW_FORM_data16 see attr_form_is_constant. */
- complaint (&symfile_complaints,
- _("Attribute value is not a constant (%s)"),
+ complaint (_("Attribute value is not a constant (%s)"),
dwarf_form_name (attr->form));
return default_value;
}
struct dwarf2_cu *target_cu, *cu = *ref_cu;
struct dwarf2_per_objfile *dwarf2_per_objfile
= cu->per_cu->dwarf2_per_objfile;
- struct objfile *objfile = dwarf2_per_objfile->objfile;
gdb_assert (cu->per_cu != NULL);
/* If necessary, add it to the queue and load its DIEs. */
if (maybe_queue_comp_unit (cu, per_cu, cu->language))
- load_full_comp_unit (per_cu, cu->language);
+ load_full_comp_unit (per_cu, false, cu->language);
target_cu = per_cu->cu;
}
{
/* We're loading full DIEs during partial symbol reading. */
gdb_assert (dwarf2_per_objfile->reading_partial_symbols);
- load_full_comp_unit (cu->per_cu, language_minimal);
+ load_full_comp_unit (cu->per_cu, false, language_minimal);
}
*ref_cu = target_cu;
temp_die.sect_off = sect_off;
+
+ if (target_cu != cu)
+ target_cu->ancestor = cu;
+
return (struct die_info *) htab_find_with_hash (target_cu->die_hash,
&temp_die,
to_underlying (sect_off));
dwarf2_fetch_die_loc_sect_off (sect_offset sect_off,
struct dwarf2_per_cu_data *per_cu,
CORE_ADDR (*get_frame_pc) (void *baton),
- void *baton)
+ void *baton, bool resolve_abstract_p)
{
struct dwarf2_cu *cu;
struct die_info *die;
struct attribute *attr;
struct dwarf2_locexpr_baton retval;
- struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
- struct dwarf2_per_objfile *dwarf2_per_objfile
- = get_dwarf2_per_objfile (objfile);
+ struct dwarf2_per_objfile *dwarf2_per_objfile = per_cu->dwarf2_per_objfile;
+ struct objfile *objfile = dwarf2_per_objfile->objfile;
if (per_cu->cu == NULL)
- load_cu (per_cu);
+ load_cu (per_cu, false);
cu = per_cu->cu;
if (cu == NULL)
{
sect_offset_str (sect_off), objfile_name (objfile));
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.end ()))
+ {
+ CORE_ADDR pc = (*get_frame_pc) (baton);
+
+ for (const auto &cand : dwarf2_per_objfile->abstract_to_concrete[die])
+ {
+ if (!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))
+ continue;
+
+ die = cand;
+ attr = dwarf2_attr (die, DW_AT_location, cu);
+ break;
+ }
+ }
+
if (!attr)
{
/* DWARF: "If there is no such attribute, then there is no effect.".
struct objfile *objfile = per_cu->dwarf2_per_objfile->objfile;
if (per_cu->cu == NULL)
- load_cu (per_cu);
+ load_cu (per_cu, false);
cu = per_cu->cu;
if (cu == NULL)
{
break;
default:
- complaint (&symfile_complaints,
- _("unsupported const value attribute form: '%s'"),
+ complaint (_("unsupported const value attribute form: '%s'"),
dwarf_form_name (attr->form));
break;
}
struct die_info *die;
if (per_cu->cu == NULL)
- load_cu (per_cu);
+ load_cu (per_cu, false);
cu = per_cu->cu;
if (!cu)
return NULL;
struct dwarf2_cu **ref_cu)
{
struct die_info temp_die;
- struct dwarf2_cu *sig_cu;
+ struct dwarf2_cu *sig_cu, *cu = *ref_cu;
struct die_info *die;
/* While it might be nice to assert sig_type->type == NULL here,
}
*ref_cu = sig_cu;
+ if (sig_cu != cu)
+ sig_cu->ancestor = cu;
+
return die;
}
the debug info. */
if (sig_type == NULL)
{
- complaint (&symfile_complaints,
- _("Dwarf Error: Cannot find signatured DIE %s referenced"
+ complaint (_("Dwarf Error: Cannot find signatured DIE %s referenced"
" from DIE at %s [in module %s]"),
hex_string (signature), sect_offset_str (die->sect_off),
objfile_name (dwarf2_per_objfile->objfile));
type = read_type_die (type_die, type_cu);
if (type == NULL)
{
- complaint (&symfile_complaints,
- _("Dwarf Error: Cannot build signatured type %s"
+ complaint (_("Dwarf Error: Cannot build signatured type %s"
" referenced from DIE at %s [in module %s]"),
hex_string (signature), sect_offset_str (die->sect_off),
objfile_name (dwarf2_per_objfile->objfile));
}
else
{
- complaint (&symfile_complaints,
- _("Dwarf Error: Problem reading signatured DIE %s referenced"
+ complaint (_("Dwarf Error: Problem reading signatured DIE %s referenced"
" from DIE at %s [in module %s]"),
hex_string (signature), sect_offset_str (die->sect_off),
objfile_name (dwarf2_per_objfile->objfile));
struct dwarf2_per_objfile *dwarf2_per_objfile
= cu->per_cu->dwarf2_per_objfile;
- complaint (&symfile_complaints,
- _("Dwarf Error: DW_AT_signature has bad form %s in DIE"
+ complaint (_("Dwarf Error: DW_AT_signature has bad form %s in DIE"
" at %s [in module %s]"),
dwarf_form_name (attr->form), sect_offset_str (die->sect_off),
objfile_name (dwarf2_per_objfile->objfile));
gdb_assert (per_cu->is_debug_types);
gdb_assert (per_cu->cu == NULL);
- init_cutu_and_read_dies (per_cu, NULL, 0, 1,
+ init_cutu_and_read_dies (per_cu, NULL, 0, 1, false,
read_signatured_type_reader, NULL);
sig_type->per_cu.tu_read = 1;
}
const char *name = get_DW_OP_name (op);
if (name)
- complaint (&symfile_complaints, _("unsupported stack op: '%s'"),
+ complaint (_("unsupported stack op: '%s'"),
name);
else
- complaint (&symfile_complaints, _("unsupported stack op: '%02x'"),
+ complaint (_("unsupported stack op: '%02x'"),
op);
}
outside of the allocated space. Also enforce minimum>0. */
if (stacki >= ARRAY_SIZE (stack) - 1)
{
- complaint (&symfile_complaints,
- _("location description stack overflow"));
+ complaint (_("location description stack overflow"));
return 0;
}
if (stacki <= 0)
{
- complaint (&symfile_complaints,
- _("location description stack underflow"));
+ complaint (_("location description stack underflow"));
return 0;
}
}
xsnprintf (fake_name, sizeof (fake_name),
"<bad macro file number %d>", file);
- complaint (&symfile_complaints,
- _("bad file number in macro information (%d)"),
+ complaint (_("bad file number in macro information (%d)"),
file);
return xstrdup (fake_name);
static struct macro_source_file *
-macro_start_file (int file, int line,
+macro_start_file (struct dwarf2_cu *cu,
+ int file, int line,
struct macro_source_file *current_file,
struct line_header *lh)
{
{
/* Note: We don't create a macro table for this compilation unit
at all until we actually get a filename. */
- struct macro_table *macro_table = get_macro_table ();
+ struct macro_table *macro_table = cu->get_builder ()->get_macro_table ();
/* If we have no current file, then this must be the start_file
directive for the compilation unit's main source file. */
{
if (*p == ' ')
{
- complaint (&symfile_complaints,
- _("macro definition contains spaces "
+ complaint (_("macro definition contains spaces "
"in formal argument list:\n`%s'"),
body);
default:
{
- complaint (&symfile_complaints,
- _("invalid form 0x%x in `%s'"),
+ complaint (_("invalid form 0x%x in `%s'"),
form, get_section_name (section));
return NULL;
}
if (opcode_definitions[opcode] == NULL)
{
- complaint (&symfile_complaints,
- _("unrecognized DW_MACFINO opcode 0x%x"),
+ complaint (_("unrecognized DW_MACFINO opcode 0x%x"),
opcode);
return NULL;
}
version = read_2_bytes (abfd, mac_ptr);
if (version != 4 && version != 5)
{
- complaint (&symfile_complaints,
- _("unrecognized version `%d' in .debug_macro section"),
+ complaint (_("unrecognized version `%d' in .debug_macro section"),
version);
return NULL;
}
including DW_MACRO_import. */
static void
-dwarf_decode_macro_bytes (struct dwarf2_per_objfile *dwarf2_per_objfile,
+dwarf_decode_macro_bytes (struct dwarf2_cu *cu,
bfd *abfd,
const gdb_byte *mac_ptr, const gdb_byte *mac_end,
struct macro_source_file *current_file,
unsigned int offset_size,
htab_t include_hash)
{
+ struct dwarf2_per_objfile *dwarf2_per_objfile
+ = cu->per_cu->dwarf2_per_objfile;
struct objfile *objfile = dwarf2_per_objfile->objfile;
enum dwarf_macro_record_type macinfo_type;
int at_commandline;
if (! current_file)
{
/* DWARF violation as no main source is present. */
- complaint (&symfile_complaints,
- _("debug info with no main source gives macro %s "
+ complaint (_("debug info with no main source gives macro %s "
"on line %d: %s"),
is_define ? _("definition") : _("undefinition"),
line, body);
}
if ((line == 0 && !at_commandline)
|| (line != 0 && at_commandline))
- complaint (&symfile_complaints,
- _("debug info gives %s macro %s with %s line %d: %s"),
+ complaint (_("debug info gives %s macro %s with %s line %d: %s"),
at_commandline ? _("command-line") : _("in-file"),
is_define ? _("definition") : _("undefinition"),
line == 0 ? _("zero") : _("non-zero"), line, body);
if ((line == 0 && !at_commandline)
|| (line != 0 && at_commandline))
- complaint (&symfile_complaints,
- _("debug info gives source %d included "
+ complaint (_("debug info gives source %d included "
"from %s at %s line %d"),
file, at_commandline ? _("command-line") : _("file"),
line == 0 ? _("zero") : _("non-zero"), line);
at_commandline = 0;
}
else
- current_file = macro_start_file (file, line, current_file, lh);
+ current_file = macro_start_file (cu, file, line, current_file,
+ lh);
}
break;
case DW_MACRO_end_file:
if (! current_file)
- complaint (&symfile_complaints,
- _("macro debug info has an unmatched "
+ complaint (_("macro debug info has an unmatched "
"`close_file' directive"));
else
{
= (enum dwarf_macro_record_type) read_1_byte (abfd,
mac_ptr);
if (next_type != 0)
- complaint (&symfile_complaints,
- _("no terminating 0-type entry for "
+ complaint (_("no terminating 0-type entry for "
"macros in `.debug_macinfo' section"));
return;
{
/* This has actually happened; see
http://sourceware.org/bugzilla/show_bug.cgi?id=13568. */
- complaint (&symfile_complaints,
- _("recursive DW_MACRO_import in "
+ complaint (_("recursive DW_MACRO_import in "
".debug_macro section"));
}
else
{
*slot = (void *) new_mac_ptr;
- dwarf_decode_macro_bytes (dwarf2_per_objfile,
- include_bfd, new_mac_ptr,
+ dwarf_decode_macro_bytes (cu, include_bfd, new_mac_ptr,
include_mac_end, current_file, lh,
section, section_is_gnu, is_dwz,
offset_size, include_hash);
dwarf2_read_section (objfile, section);
if (section->buffer == NULL)
{
- complaint (&symfile_complaints, _("missing %s section"), section_name);
+ complaint (_("missing %s section"), section_name);
return;
}
abfd = get_section_bfd_owner (section);
file = read_unsigned_leb128 (abfd, mac_ptr, &bytes_read);
mac_ptr += bytes_read;
- current_file = macro_start_file (file, line, current_file, lh);
+ current_file = macro_start_file (cu, file, line, current_file, lh);
}
break;
mac_ptr = section->buffer + offset;
slot = htab_find_slot (include_hash.get (), mac_ptr, INSERT);
*slot = (void *) mac_ptr;
- dwarf_decode_macro_bytes (dwarf2_per_objfile,
- abfd, mac_ptr, mac_end,
+ dwarf_decode_macro_bytes (cu, abfd, mac_ptr, mac_end,
current_file, lh, section,
section_is_gnu, 0, offset_size,
include_hash.get ());
fill_in_loclist_baton (cu, baton, attr);
if (cu->base_known == 0)
- complaint (&symfile_complaints,
- _("Location list used without "
+ complaint (_("Location list used without "
"specifying the CU base address."));
SYMBOL_ACLASS_INDEX (sym) = (is_block
{
struct dwarf2_per_cu_data *this_cu;
int low, high;
- const sect_offset *cu_off;
low = 0;
- high = dwarf2_per_objfile->n_comp_units - 1;
+ high = dwarf2_per_objfile->all_comp_units.size () - 1;
while (high > low)
{
struct dwarf2_per_cu_data *mid_cu;
int mid = low + (high - low) / 2;
mid_cu = dwarf2_per_objfile->all_comp_units[mid];
- cu_off = &mid_cu->sect_off;
if (mid_cu->is_dwz > offset_in_dwz
- || (mid_cu->is_dwz == offset_in_dwz && *cu_off >= sect_off))
+ || (mid_cu->is_dwz == offset_in_dwz
+ && mid_cu->sect_off + mid_cu->length >= sect_off))
high = mid;
else
low = mid + 1;
}
gdb_assert (low == high);
this_cu = dwarf2_per_objfile->all_comp_units[low];
- cu_off = &this_cu->sect_off;
- if (this_cu->is_dwz != offset_in_dwz || *cu_off > sect_off)
+ if (this_cu->is_dwz != offset_in_dwz || this_cu->sect_off > sect_off)
{
if (low == 0 || this_cu->is_dwz != offset_in_dwz)
error (_("Dwarf Error: could not find partial DIE containing "
}
else
{
- this_cu = dwarf2_per_objfile->all_comp_units[low];
- if (low == dwarf2_per_objfile->n_comp_units - 1
+ 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));
gdb_assert (sect_off < this_cu->sect_off + this_cu->length);
dwarf2_cu::dwarf2_cu (struct dwarf2_per_cu_data *per_cu_)
: per_cu (per_cu_),
- mark (0),
- has_loclist (0),
- checked_producer (0),
- producer_is_gxx_lt_4_6 (0),
- producer_is_gcc_lt_4_3 (0),
- producer_is_icc_lt_14 (0),
- processing_has_namespace_info (0)
+ mark (false),
+ has_loclist (false),
+ checked_producer (false),
+ producer_is_gxx_lt_4_6 (false),
+ producer_is_gcc_lt_4_3 (false),
+ producer_is_icc (false),
+ producer_is_icc_lt_14 (false),
+ producer_is_codewarrior (false),
+ processing_has_namespace_info (false)
{
per_cu->cu = this;
}
}
}
-/* Release all extra memory associated with OBJFILE. */
+/* Cleanup function for the dwarf2_per_objfile data. */
-void
-dwarf2_free_objfile (struct objfile *objfile)
+static void
+dwarf2_free_objfile (struct objfile *objfile, void *datum)
{
struct dwarf2_per_objfile *dwarf2_per_objfile
- = get_dwarf2_per_objfile (objfile);
+ = static_cast<struct dwarf2_per_objfile *> (datum);
delete dwarf2_per_objfile;
}
}
else if (attr != NULL)
{
- complaint (&symfile_complaints,
- _("DW_AT_allocated has the wrong form (%s) at DIE %s"),
+ complaint (_("DW_AT_allocated has the wrong form (%s) at DIE %s"),
(attr != NULL ? dwarf_form_name (attr->form) : "n/a"),
sect_offset_str (die->sect_off));
}
}
else if (attr != NULL)
{
- complaint (&symfile_complaints,
- _("DW_AT_associated has the wrong form (%s) at DIE %s"),
+ complaint (_("DW_AT_associated has the wrong form (%s) at DIE %s"),
(attr != NULL ? dwarf_form_name (attr->form) : "n/a"),
sect_offset_str (die->sect_off));
}
slot = (struct dwarf2_per_cu_offset_and_type **)
htab_find_slot (dwarf2_per_objfile->die_type_hash, &ofs, INSERT);
if (*slot)
- complaint (&symfile_complaints,
- _("A problem internal to GDB: DIE %s has type already set"),
+ complaint (_("A problem internal to GDB: DIE %s has type already set"),
sect_offset_str (die->sect_off));
*slot = XOBNEW (&objfile->objfile_obstack,
struct dwarf2_per_cu_offset_and_type);
if (per_cu->cu->mark)
return 1;
- per_cu->cu->mark = 1;
+ per_cu->cu->mark = true;
if (per_cu->cu->dependencies != NULL)
htab_traverse (per_cu->cu->dependencies, dwarf2_mark_helper, NULL);
{
if (cu->mark)
return;
- cu->mark = 1;
+ cu->mark = true;
if (cu->dependencies != NULL)
htab_traverse (cu->dependencies, dwarf2_mark_helper, NULL);
}
{
while (per_cu)
{
- per_cu->cu->mark = 0;
+ per_cu->cu->mark = false;
per_cu = per_cu->cu->read_in_chain;
}
}
return part_die_lhs->sect_off == part_die_rhs->sect_off;
}
-static struct cmd_list_element *set_dwarf_cmdlist;
-static struct cmd_list_element *show_dwarf_cmdlist;
+struct cmd_list_element *set_dwarf_cmdlist;
+struct cmd_list_element *show_dwarf_cmdlist;
static void
set_dwarf_cmd (const char *args, int from_tty)
void
_initialize_dwarf2_read (void)
{
-
- dwarf2_objfile_data_key = register_objfile_data ();
+ 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\