#include "build-id.h"
#include "namespace.h"
#include "common/gdb_unlinker.h"
+#include "common/function-view.h"
+#include "common/gdb_optional.h"
+#include "common/underlying.h"
#include <fcntl.h>
#include <sys/types.h>
short version;
unsigned char addr_size;
unsigned char signed_addr_p;
- sect_offset abbrev_offset;
+ sect_offset abbrev_sect_off;
/* Size of file offsets; either 4 or 8. */
unsigned int offset_size;
/* Offset to the first byte of this compilation unit header in the
.debug_info section, for resolving relative reference dies. */
- sect_offset offset;
+ sect_offset sect_off;
/* Offset to first die in this cu from the start of the cu.
This will be the first byte following the compilation unit header. */
- cu_offset first_die_offset;
+ cu_offset first_die_cu_offset;
/* 64-bit signature of this type unit - it is valid only for
UNIT_TYPE DW_UT_type. */
ULONGEST signature;
/* For types, offset in the type's DIE of the type defined by this TU. */
- cu_offset type_offset_in_tu;
+ cu_offset type_cu_offset_in_tu;
};
/* Type used for delaying computation of method physnames.
initial_length_size.
If the DIE refers to a DWO file, this is always of the original die,
not the DWO file. */
- sect_offset offset;
+ sect_offset sect_off;
unsigned int length;
/* DWARF standard version this data has been read from (such as 4 or 5). */
struct dwo_unit *dwo_unit;
/* Offset in .debug_line or .debug_line.dwo. */
- sect_offset line_offset;
+ sect_offset line_sect_off;
};
/* Each element of dwarf2_per_objfile->type_unit_groups is a pointer to
/* The section this CU/TU lives in, in the DWO file. */
struct dwarf2_section_info *section;
- /* Same as dwarf2_per_cu_data:{offset,length} but in the DWO section. */
- sect_offset offset;
+ /* Same as dwarf2_per_cu_data:{sect_off,length} but in the DWO section. */
+ sect_offset sect_off;
unsigned int length;
/* For types, offset in the type's DIE of the type defined by this TU. */
int has_children,
void *data);
+/* A 1-based directory index. This is a strong typedef to prevent
+ accidentally using a directory index as a 0-based index into an
+ array/vector. */
+enum class dir_index : unsigned int {};
+
+/* Likewise, a 1-based file name index. */
+enum class file_name_index : unsigned int {};
+
struct file_entry
{
- const char *name;
- unsigned int dir_index;
- unsigned int mod_time;
- unsigned int length;
- /* Non-zero if referenced by the Line Number Program. */
- int included_p;
+ file_entry () = default;
+
+ file_entry (const char *name_, dir_index d_index_,
+ unsigned int mod_time_, unsigned int length_)
+ : name (name_),
+ d_index (d_index_),
+ mod_time (mod_time_),
+ length (length_)
+ {}
+
+ /* Return the include directory at D_INDEX stored in LH. Returns
+ NULL if D_INDEX is out of bounds. */
+ const char *include_dir (const line_header *lh) const;
+
+ /* The file name. Note this is an observing pointer. The memory is
+ owned by debug_line_buffer. */
+ const char *name {};
+
+ /* The directory index (1-based). */
+ dir_index d_index {};
+
+ unsigned int mod_time {};
+
+ unsigned int length {};
+
+ /* True if referenced by the Line Number Program. */
+ bool included_p {};
+
/* The associated symbol table, if any. */
- struct symtab *symtab;
+ struct symtab *symtab {};
};
/* The line number information for a compilation unit (found in the
which contains the following information. */
struct line_header
{
+ line_header ()
+ : offset_in_dwz {}
+ {}
+
+ /* Add an entry to the include directory table. */
+ void add_include_dir (const char *include_dir);
+
+ /* Add an entry to the file name table. */
+ void add_file_name (const char *name, dir_index d_index,
+ unsigned int mod_time, unsigned int length);
+
+ /* Return the include dir at INDEX (1-based). Returns NULL if INDEX
+ is out of bounds. */
+ const char *include_dir_at (dir_index index) const
+ {
+ /* Convert directory index number (1-based) to vector index
+ (0-based). */
+ size_t vec_index = to_underlying (index) - 1;
+
+ if (vec_index >= include_dirs.size ())
+ return NULL;
+ return include_dirs[vec_index];
+ }
+
+ /* Return the file name at INDEX (1-based). Returns NULL if INDEX
+ is out of bounds. */
+ file_entry *file_name_at (file_name_index index)
+ {
+ /* Convert file name index number (1-based) to vector index
+ (0-based). */
+ size_t vec_index = to_underlying (index) - 1;
+
+ if (vec_index >= file_names.size ())
+ return NULL;
+ return &file_names[vec_index];
+ }
+
+ /* Const version of the above. */
+ const file_entry *file_name_at (unsigned int index) const
+ {
+ if (index >= file_names.size ())
+ return NULL;
+ return &file_names[index];
+ }
+
/* Offset of line number information in .debug_line section. */
- sect_offset offset;
+ sect_offset sect_off {};
/* OFFSET is for struct dwz_file associated with dwarf2_per_objfile. */
- unsigned offset_in_dwz : 1;
-
- unsigned int total_length;
- unsigned short version;
- unsigned int header_length;
- unsigned char minimum_instruction_length;
- unsigned char maximum_ops_per_instruction;
- unsigned char default_is_stmt;
- int line_base;
- unsigned char line_range;
- unsigned char opcode_base;
+ unsigned offset_in_dwz : 1; /* Can't initialize bitfields in-class. */
+
+ unsigned int total_length {};
+ unsigned short version {};
+ unsigned int header_length {};
+ unsigned char minimum_instruction_length {};
+ unsigned char maximum_ops_per_instruction {};
+ unsigned char default_is_stmt {};
+ int line_base {};
+ unsigned char line_range {};
+ unsigned char opcode_base {};
/* standard_opcode_lengths[i] is the number of operands for the
standard opcode whose value is i. This means that
standard_opcode_lengths[0] is unused, and the last meaningful
element is standard_opcode_lengths[opcode_base - 1]. */
- unsigned char *standard_opcode_lengths;
+ std::unique_ptr<unsigned char[]> standard_opcode_lengths;
- /* The include_directories table. NOTE! These strings are not
- allocated with xmalloc; instead, they are pointers into
- debug_line_buffer. If you try to free them, `free' will get
- indigestion. */
- unsigned int num_include_dirs, include_dirs_size;
- const char **include_dirs;
+ /* The include_directories table. Note these are observing
+ pointers. The memory is owned by debug_line_buffer. */
+ std::vector<const char *> include_dirs;
- /* The file_names table. NOTE! These strings are not allocated
- with xmalloc; instead, they are pointers into debug_line_buffer.
- Don't try to free them directly. */
- unsigned int num_file_names, file_names_size;
- struct file_entry *file_names;
+ /* The file_names table. */
+ std::vector<file_entry> file_names;
/* The start and end of the statement program following this
header. These point into dwarf2_per_objfile->line_buffer. */
- const gdb_byte *statement_program_start, *statement_program_end;
+ const gdb_byte *statement_program_start {}, *statement_program_end {};
};
+typedef std::unique_ptr<line_header> line_header_up;
+
+const char *
+file_entry::include_dir (const line_header *lh) const
+{
+ return lh->include_dir_at (d_index);
+}
+
/* When we construct a partial symbol table entry we only
need this much information. */
struct partial_die_info
{
/* Offset of this DIE. */
- sect_offset offset;
+ sect_offset sect_off;
/* DWARF-2 tag for this DIE. */
ENUM_BITFIELD(dwarf_tag) tag : 16;
/* The location description associated with this DIE, if any. */
struct dwarf_block *locdesc;
/* The offset of an import, for DW_TAG_imported_unit. */
- sect_offset offset;
+ sect_offset sect_off;
} d;
/* If HAS_PC_INFO, the PC range associated with this DIE. */
{
/* Where the abbrev table came from.
This is used as a sanity check when the table is used. */
- sect_offset offset;
+ sect_offset sect_off;
/* Storage for the abbrev table. */
struct obstack abbrev_obstack;
unsigned int abbrev;
/* Offset in .debug_info or .debug_types section. */
- sect_offset offset;
+ sect_offset sect_off;
/* The dies in a compilation unit form an n-ary tree. PARENT
points to this die's parent; CHILD points to the first child of
static struct die_info *die_specification (struct die_info *die,
struct dwarf2_cu **);
-static void free_line_header (struct line_header *lh);
-
-static struct line_header *dwarf_decode_line_header (unsigned int offset,
- struct dwarf2_cu *cu);
+static line_header_up dwarf_decode_line_header (sect_offset sect_off,
+ struct dwarf2_cu *cu);
static void dwarf_decode_lines (struct line_header *, const char *,
struct dwarf2_cu *, struct partial_symtab *,
static const char *dwarf_form_name (unsigned int);
-static char *dwarf_bool_name (unsigned int);
+static const char *dwarf_bool_name (unsigned int);
static const char *dwarf_type_encoding_name (unsigned int);
static int partial_die_eq (const void *item_lhs, const void *item_rhs);
static struct dwarf2_per_cu_data *dwarf2_find_containing_comp_unit
- (sect_offset offset, unsigned int offset_in_dwz, struct objfile *objfile);
+ (sect_offset sect_off, unsigned int offset_in_dwz, struct objfile *objfile);
static void init_one_comp_unit (struct dwarf2_cu *cu,
struct dwarf2_per_cu_data *per_cu);
static void process_queue (void);
-static void find_file_and_directory (struct die_info *die,
- struct dwarf2_cu *cu,
- const char **name, const char **comp_dir);
+/* The return type of find_file_and_directory. Note, the enclosed
+ string pointers are only valid while this object is valid. */
+
+struct file_and_directory
+{
+ /* The filename. This is never NULL. */
+ const char *name;
+
+ /* The compilation directory. NULL if not known. If we needed to
+ compute a new string, this points to COMP_DIR_STORAGE, otherwise,
+ points directly to the DW_AT_comp_dir string attribute owned by
+ the obstack that owns the DIE. */
+ const char *comp_dir;
+
+ /* If we needed to build a new string for comp_dir, this is what
+ owns the storage. */
+ std::string comp_dir_storage;
+};
+
+static file_and_directory find_file_and_directory (struct die_info *die,
+ struct dwarf2_cu *cu);
static char *file_full_name (int file, struct line_header *lh,
const char *comp_dir);
static hashval_t
line_header_hash (const struct line_header *ofs)
{
- return ofs->offset.sect_off ^ ofs->offset_in_dwz;
+ return to_underlying (ofs->sect_off) ^ ofs->offset_in_dwz;
}
/* Hash function for htab_create_alloc_ex for line_header_hash. */
const struct line_header *ofs_lhs = (const struct line_header *) item_lhs;
const struct line_header *ofs_rhs = (const struct line_header *) item_rhs;
- return (ofs_lhs->offset.sect_off == ofs_rhs->offset.sect_off
+ return (ofs_lhs->sect_off == ofs_rhs->sect_off
&& ofs_lhs->offset_in_dwz == ofs_rhs->offset_in_dwz);
}
buildid_len = (size_t) buildid_len_arg;
filename = (const char *) data;
+
+ std::string abs_storage;
if (!IS_ABSOLUTE_PATH (filename))
{
char *abs = gdb_realpath (objfile_name (dwarf2_per_objfile->objfile));
- char *rel;
make_cleanup (xfree, abs);
- abs = ldirname (abs);
- make_cleanup (xfree, abs);
-
- rel = concat (abs, SLASH_STRING, filename, (char *) NULL);
- make_cleanup (xfree, rel);
- filename = rel;
+ abs_storage = ldirname (abs) + SLASH_STRING + filename;
+ filename = abs_storage.c_str ();
}
/* First try the file name given in the section. If that doesn't
if (stmt_list_hash->dwo_unit != NULL)
v += (uintptr_t) stmt_list_hash->dwo_unit->dwo_file;
- v += stmt_list_hash->line_offset.sect_off;
+ v += to_underlying (stmt_list_hash->line_sect_off);
return v;
}
&& lhs->dwo_unit->dwo_file != rhs->dwo_unit->dwo_file)
return 0;
- return lhs->line_offset.sect_off == rhs->line_offset.sect_off;
+ return lhs->line_sect_off == rhs->line_sect_off;
}
/* Hash function for a quick_file_names. */
if (!per_cu->v.quick->compunit_symtab)
{
struct cleanup *back_to = make_cleanup (free_cached_comp_units, NULL);
- increment_reading_symtab ();
+ scoped_restore decrementer = increment_reading_symtab ();
dw2_do_instantiate_symtab (per_cu);
process_cu_includes ();
do_cleanups (back_to);
for (i = 0; i < n_elements; i += 2)
{
- struct dwarf2_per_cu_data *the_cu;
- ULONGEST offset, length;
-
gdb_static_assert (sizeof (ULONGEST) >= 8);
- offset = extract_unsigned_integer (cu_list, 8, BFD_ENDIAN_LITTLE);
- length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE);
+
+ sect_offset sect_off
+ = (sect_offset) extract_unsigned_integer (cu_list, 8, BFD_ENDIAN_LITTLE);
+ ULONGEST length = extract_unsigned_integer (cu_list + 8, 8, BFD_ENDIAN_LITTLE);
cu_list += 2 * 8;
- the_cu = OBSTACK_ZALLOC (&objfile->objfile_obstack,
- struct dwarf2_per_cu_data);
- the_cu->offset.sect_off = offset;
+ dwarf2_per_cu_data *the_cu
+ = OBSTACK_ZALLOC (&objfile->objfile_obstack,
+ struct dwarf2_per_cu_data);
+ the_cu->sect_off = sect_off;
the_cu->length = length;
the_cu->objfile = objfile;
the_cu->section = section;
for (i = 0; i < elements; i += 3)
{
struct signatured_type *sig_type;
- ULONGEST offset, type_offset_in_tu, signature;
+ ULONGEST signature;
void **slot;
+ cu_offset type_offset_in_tu;
gdb_static_assert (sizeof (ULONGEST) >= 8);
- offset = extract_unsigned_integer (bytes, 8, BFD_ENDIAN_LITTLE);
- type_offset_in_tu = extract_unsigned_integer (bytes + 8, 8,
- BFD_ENDIAN_LITTLE);
+ sect_offset sect_off
+ = (sect_offset) extract_unsigned_integer (bytes, 8, BFD_ENDIAN_LITTLE);
+ type_offset_in_tu
+ = (cu_offset) extract_unsigned_integer (bytes + 8, 8,
+ BFD_ENDIAN_LITTLE);
signature = extract_unsigned_integer (bytes + 16, 8, BFD_ENDIAN_LITTLE);
bytes += 3 * 8;
sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct signatured_type);
sig_type->signature = signature;
- sig_type->type_offset_in_tu.cu_off = type_offset_in_tu;
+ sig_type->type_offset_in_tu = type_offset_in_tu;
sig_type->per_cu.is_debug_types = 1;
sig_type->per_cu.section = section;
- sig_type->per_cu.offset.sect_off = offset;
+ sig_type->per_cu.sect_off = sect_off;
sig_type->per_cu.objfile = objfile;
sig_type->per_cu.v.quick
= OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct dwarf2_per_cu_data *this_cu = cu->per_cu;
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct dwarf2_per_cu_data *lh_cu;
- struct line_header *lh;
struct attribute *attr;
int i;
- const char *name, *comp_dir;
void **slot;
struct quick_file_names *qfn;
- unsigned int line_offset;
gdb_assert (! this_cu->is_debug_types);
}
lh_cu = this_cu;
- lh = NULL;
slot = NULL;
- line_offset = 0;
+
+ line_header_up lh;
+ sect_offset line_offset {};
attr = dwarf2_attr (comp_unit_die, DW_AT_stmt_list, cu);
if (attr)
{
struct quick_file_names find_entry;
- line_offset = DW_UNSND (attr);
+ line_offset = (sect_offset) DW_UNSND (attr);
/* We may have already read in this line header (TU line header sharing).
If we have we're done. */
find_entry.hash.dwo_unit = cu->dwo_unit;
- find_entry.hash.line_offset.sect_off = line_offset;
+ find_entry.hash.line_sect_off = line_offset;
slot = htab_find_slot (dwarf2_per_objfile->quick_file_names_table,
&find_entry, INSERT);
if (*slot != NULL)
qfn = XOBNEW (&objfile->objfile_obstack, struct quick_file_names);
qfn->hash.dwo_unit = cu->dwo_unit;
- qfn->hash.line_offset.sect_off = line_offset;
+ qfn->hash.line_sect_off = line_offset;
gdb_assert (slot != NULL);
*slot = qfn;
- find_file_and_directory (comp_unit_die, cu, &name, &comp_dir);
+ file_and_directory fnd = find_file_and_directory (comp_unit_die, cu);
- qfn->num_file_names = lh->num_file_names;
+ qfn->num_file_names = lh->file_names.size ();
qfn->file_names =
- XOBNEWVEC (&objfile->objfile_obstack, const char *, lh->num_file_names);
- for (i = 0; i < lh->num_file_names; ++i)
- qfn->file_names[i] = file_full_name (i + 1, lh, comp_dir);
+ XOBNEWVEC (&objfile->objfile_obstack, const char *, lh->file_names.size ());
+ for (i = 0; i < lh->file_names.size (); ++i)
+ qfn->file_names[i] = file_full_name (i + 1, lh.get (), fnd.comp_dir);
qfn->real_names = NULL;
- free_line_header (lh);
-
lh_cu->v.quick->file_names = qfn;
}
dw2_map_expand_apply (struct objfile *objfile,
struct dwarf2_per_cu_data *per_cu,
const char *name, const char *real_path,
- int (*callback) (struct symtab *, void *),
- void *data)
+ gdb::function_view<bool (symtab *)> callback)
{
struct compunit_symtab *last_made = objfile->compunit_symtabs;
all of them. */
dw2_instantiate_symtab (per_cu);
- return iterate_over_some_symtabs (name, real_path, callback, data,
- objfile->compunit_symtabs, last_made);
+ return iterate_over_some_symtabs (name, real_path, objfile->compunit_symtabs,
+ last_made, callback);
}
/* Implementation of the map_symtabs_matching_filename method. */
-static int
-dw2_map_symtabs_matching_filename (struct objfile *objfile, const char *name,
- const char *real_path,
- int (*callback) (struct symtab *, void *),
- void *data)
+static bool
+dw2_map_symtabs_matching_filename
+ (struct objfile *objfile, const char *name, const char *real_path,
+ gdb::function_view<bool (symtab *)> callback)
{
int i;
const char *name_basename = lbasename (name);
if (compare_filenames_for_search (this_name, name))
{
if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
- callback, data))
- return 1;
+ callback))
+ return true;
continue;
}
if (compare_filenames_for_search (this_real_name, name))
{
if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
- callback, data))
- return 1;
+ callback))
+ return true;
continue;
}
&& FILENAME_CMP (real_path, this_real_name) == 0)
{
if (dw2_map_expand_apply (objfile, per_cu, name, real_path,
- callback, data))
- return 1;
+ callback))
+ return true;
continue;
}
}
}
}
- return 0;
+ return false;
}
/* Struct used to manage iterating over all CUs looking for a symbol. */
static void
dw2_expand_symtabs_matching
(struct objfile *objfile,
- expand_symtabs_file_matcher_ftype *file_matcher,
- expand_symtabs_symbol_matcher_ftype *symbol_matcher,
- expand_symtabs_exp_notify_ftype *expansion_notify,
- enum search_domain kind,
- void *data)
+ gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
+ gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
+ gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
+ enum search_domain kind)
{
int i;
offset_type iter;
{
const char *this_real_name;
- if (file_matcher (file_data->file_names[j], data, 0))
+ if (file_matcher (file_data->file_names[j], false))
{
per_cu->v.quick->mark = 1;
break;
files are involved, do a quick comparison of the basenames. */
if (!basenames_may_differ
&& !file_matcher (lbasename (file_data->file_names[j]),
- data, 1))
+ true))
continue;
this_real_name = dw2_get_real_path (objfile, file_data, j);
- if (file_matcher (this_real_name, data, 0))
+ if (file_matcher (this_real_name, false))
{
per_cu->v.quick->mark = 1;
break;
name = index->constant_pool + MAYBE_SWAP (index->symbol_table[idx]);
- if (! (*symbol_matcher) (name, data))
+ if (!symbol_matcher (name))
continue;
/* The name was matched, now expand corresponding CUs that were
&& symtab_was_null
&& per_cu->v.quick->compunit_symtab != NULL)
{
- expansion_notify (per_cu->v.quick->compunit_symtab,
- data);
+ expansion_notify (per_cu->v.quick->compunit_symtab);
}
}
}
return header->initial_length_size + header->length;
}
-/* Return TRUE if OFFSET is within CU_HEADER. */
+/* Return TRUE if SECT_OFF is within CU_HEADER. */
-static inline int
-offset_in_cu_p (const struct comp_unit_head *cu_header, sect_offset offset)
+static inline bool
+offset_in_cu_p (const comp_unit_head *cu_header, sect_offset sect_off)
{
- sect_offset bottom = { cu_header->offset.sect_off };
- sect_offset top = { cu_header->offset.sect_off + get_cu_length (cu_header) };
+ sect_offset bottom = cu_header->sect_off;
+ sect_offset top = cu_header->sect_off + get_cu_length (cu_header);
- return (offset.sect_off >= bottom.sect_off && offset.sect_off < top.sect_off);
+ return sect_off >= bottom && sect_off < top;
}
/* Find the base address of the compilation unit for range lists and
cu_header->addr_size = read_1_byte (abfd, info_ptr);
info_ptr += 1;
}
- cu_header->abbrev_offset.sect_off = read_offset (abfd, info_ptr, cu_header,
- &bytes_read);
+ cu_header->abbrev_sect_off = (sect_offset) read_offset (abfd, info_ptr,
+ cu_header,
+ &bytes_read);
info_ptr += bytes_read;
if (cu_header->version < 5)
{
type_offset = read_offset (abfd, info_ptr, cu_header, &bytes_read);
info_ptr += bytes_read;
- cu_header->type_offset_in_tu.cu_off = type_offset;
- if (cu_header->type_offset_in_tu.cu_off != type_offset)
+ cu_header->type_cu_offset_in_tu = (cu_offset) type_offset;
+ if (to_underlying (cu_header->type_cu_offset_in_tu) != type_offset)
error (_("Dwarf Error: Too big type_offset in compilation unit "
"header (is %s) [in module %s]"), plongest (type_offset),
filename);
"(is %d, should be 2, 3, 4 or 5) [in module %s]"), header->version,
filename);
- if (header->abbrev_offset.sect_off
+ if (to_underlying (header->abbrev_sect_off)
>= dwarf2_section_size (dwarf2_per_objfile->objfile, abbrev_section))
- error (_("Dwarf Error: bad offset (0x%lx) in compilation unit header "
- "(offset 0x%lx + 6) [in module %s]"),
- (long) header->abbrev_offset.sect_off, (long) header->offset.sect_off,
+ error (_("Dwarf Error: bad offset (0x%x) in compilation unit header "
+ "(offset 0x%x + 6) [in module %s]"),
+ to_underlying (header->abbrev_sect_off),
+ to_underlying (header->sect_off),
filename);
- /* Cast to unsigned long to use 64-bit arithmetic when possible to
+ /* Cast to ULONGEST to use 64-bit arithmetic when possible to
avoid potential 32-bit overflow. */
- if (((unsigned long) header->offset.sect_off + get_cu_length (header))
+ if (((ULONGEST) header->sect_off + get_cu_length (header))
> section->size)
- error (_("Dwarf Error: bad length (0x%lx) in compilation unit header "
- "(offset 0x%lx + 0) [in module %s]"),
- (long) header->length, (long) header->offset.sect_off,
+ error (_("Dwarf Error: bad length (0x%x) in compilation unit header "
+ "(offset 0x%x + 0) [in module %s]"),
+ header->length, to_underlying (header->sect_off),
filename);
}
const gdb_byte *beg_of_comp_unit = info_ptr;
bfd *abfd = get_section_bfd_owner (section);
- header->offset.sect_off = beg_of_comp_unit - section->buffer;
+ header->sect_off = (sect_offset) (beg_of_comp_unit - section->buffer);
info_ptr = read_comp_unit_head (header, info_ptr, section, section_kind);
- header->first_die_offset.cu_off = info_ptr - beg_of_comp_unit;
+ header->first_die_cu_offset = (cu_offset) (info_ptr - beg_of_comp_unit);
error_check_comp_unit_head (header, section, abbrev_section);
static sect_offset
read_abbrev_offset (struct dwarf2_section_info *section,
- sect_offset offset)
+ sect_offset sect_off)
{
bfd *abfd = get_section_bfd_owner (section);
const gdb_byte *info_ptr;
unsigned int initial_length_size, offset_size;
- sect_offset abbrev_offset;
uint16_t version;
dwarf2_read_section (dwarf2_per_objfile->objfile, section);
- info_ptr = section->buffer + offset.sect_off;
+ info_ptr = section->buffer + to_underlying (sect_off);
read_initial_length (abfd, info_ptr, &initial_length_size);
offset_size = initial_length_size == 4 ? 4 : 8;
info_ptr += initial_length_size;
info_ptr += 2;
}
- abbrev_offset.sect_off = read_offset_1 (abfd, info_ptr, offset_size);
- return abbrev_offset;
+ return (sect_offset) read_offset_1 (abfd, info_ptr, offset_size);
}
/* Allocate a new partial symtab for file named NAME and mark this new
struct die_info *die,
struct partial_symtab *pst)
{
- struct line_header *lh = NULL;
+ line_header_up lh;
struct attribute *attr;
attr = dwarf2_attr (die, DW_AT_stmt_list, cu);
if (attr)
- lh = dwarf_decode_line_header (DW_UNSND (attr), cu);
+ lh = dwarf_decode_line_header ((sect_offset) DW_UNSND (attr), cu);
if (lh == NULL)
return; /* No linetable, so no includes. */
/* NOTE: pst->dirname is DW_AT_comp_dir (if present). */
- dwarf_decode_lines (lh, pst->dirname, cu, pst, pst->textlow, 1);
-
- free_line_header (lh);
+ dwarf_decode_lines (lh.get (), pst->dirname, cu, pst, pst->textlow, 1);
}
static hashval_t
end_ptr = info_ptr + section->size;
while (info_ptr < end_ptr)
{
- sect_offset offset;
struct signatured_type *sig_type;
struct dwo_unit *dwo_tu;
void **slot;
struct comp_unit_head header;
unsigned int length;
- offset.sect_off = ptr - section->buffer;
+ sect_offset sect_off = (sect_offset) (ptr - section->buffer);
+
+ /* Initialize it due to a false compiler warning. */
+ header.signature = -1;
+ header.type_cu_offset_in_tu = (cu_offset) -1;
/* We need to read the type's signature in order to build the hash
table, but we don't need anything else just yet. */
struct dwo_unit);
dwo_tu->dwo_file = dwo_file;
dwo_tu->signature = header.signature;
- dwo_tu->type_offset_in_tu = header.type_offset_in_tu;
+ dwo_tu->type_offset_in_tu = header.type_cu_offset_in_tu;
dwo_tu->section = section;
- dwo_tu->offset = offset;
+ dwo_tu->sect_off = sect_off;
dwo_tu->length = length;
}
else
sig_type = OBSTACK_ZALLOC (&objfile->objfile_obstack,
struct signatured_type);
sig_type->signature = header.signature;
- sig_type->type_offset_in_tu = header.type_offset_in_tu;
+ sig_type->type_offset_in_tu = header.type_cu_offset_in_tu;
sig_type->per_cu.objfile = objfile;
sig_type->per_cu.is_debug_types = 1;
sig_type->per_cu.section = section;
- sig_type->per_cu.offset = offset;
+ sig_type->per_cu.sect_off = sect_off;
sig_type->per_cu.length = length;
}
gdb_assert (slot != NULL);
if (*slot != NULL)
{
- sect_offset dup_offset;
+ sect_offset dup_sect_off;
if (dwo_file)
{
const struct dwo_unit *dup_tu
= (const struct dwo_unit *) *slot;
- dup_offset = dup_tu->offset;
+ dup_sect_off = dup_tu->sect_off;
}
else
{
const struct signatured_type *dup_tu
= (const struct signatured_type *) *slot;
- dup_offset = dup_tu->per_cu.offset;
+ dup_sect_off = dup_tu->per_cu.sect_off;
}
complaint (&symfile_complaints,
_("debug type entry at offset 0x%x is duplicate to"
" the entry at offset 0x%x, signature %s"),
- offset.sect_off, dup_offset.sect_off,
+ to_underlying (sect_off), to_underlying (dup_sect_off),
hex_string (header.signature));
}
*slot = dwo_file ? (void *) dwo_tu : (void *) sig_type;
if (dwarf_read_debug > 1)
fprintf_unfiltered (gdb_stdlog, " offset 0x%x, signature %s\n",
- offset.sect_off,
+ to_underlying (sect_off),
hex_string (header.signature));
info_ptr += length;
else
gdb_assert (sig_entry->per_cu.v.psymtab == NULL);
gdb_assert (sig_entry->signature == dwo_entry->signature);
- gdb_assert (sig_entry->type_offset_in_section.sect_off == 0);
+ gdb_assert (to_underlying (sig_entry->type_offset_in_section) == 0);
gdb_assert (sig_entry->type_unit_group == NULL);
gdb_assert (sig_entry->dwo_unit == NULL);
sig_entry->per_cu.section = dwo_entry->section;
- sig_entry->per_cu.offset = dwo_entry->offset;
+ sig_entry->per_cu.sect_off = dwo_entry->sect_off;
sig_entry->per_cu.length = dwo_entry->length;
sig_entry->per_cu.reading_dwo_directly = 1;
sig_entry->per_cu.objfile = objfile;
section = dwo_unit->section;
dwarf2_read_section (objfile, section);
abfd = get_section_bfd_owner (section);
- begin_info_ptr = info_ptr = section->buffer + dwo_unit->offset.sect_off;
+ begin_info_ptr = info_ptr = (section->buffer
+ + to_underlying (dwo_unit->sect_off));
dwo_abbrev_section = &dwo_unit->dwo_file->sections.abbrev;
init_cu_die_reader (result_reader, cu, section, dwo_unit->dwo_file);
" TU at offset 0x%x [in module %s]"),
hex_string (sig_type->signature),
hex_string (cu->header.signature),
- dwo_unit->offset.sect_off,
+ to_underlying (dwo_unit->sect_off),
bfd_get_filename (abfd));
}
- gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off);
+ gdb_assert (dwo_unit->sect_off == cu->header.sect_off);
/* For DWOs coming from DWP files, we don't know the CU length
nor the type's offset in the TU until now. */
dwo_unit->length = get_cu_length (&cu->header);
- dwo_unit->type_offset_in_tu = cu->header.type_offset_in_tu;
+ dwo_unit->type_offset_in_tu = cu->header.type_cu_offset_in_tu;
/* Establish the type offset that can be used to lookup the type.
For DWO files, we don't know it until now. */
- sig_type->type_offset_in_section.sect_off =
- dwo_unit->offset.sect_off + dwo_unit->type_offset_in_tu.cu_off;
+ sig_type->type_offset_in_section
+ = dwo_unit->sect_off + to_underlying (dwo_unit->type_offset_in_tu);
}
else
{
info_ptr = read_and_check_comp_unit_head (&cu->header, section,
dwo_abbrev_section,
info_ptr, rcuh_kind::COMPILE);
- gdb_assert (dwo_unit->offset.sect_off == cu->header.offset.sect_off);
+ gdb_assert (dwo_unit->sect_off == cu->header.sect_off);
/* For DWOs coming from DWP files, we don't know the CU length
until now. */
dwo_unit->length = get_cu_length (&cu->header);
if (dwarf_die_debug)
fprintf_unfiltered (gdb_stdlog, "Reading %s unit at offset 0x%x\n",
this_cu->is_debug_types ? "type" : "comp",
- this_cu->offset.sect_off);
+ to_underlying (this_cu->sect_off));
if (use_existing_cu)
gdb_assert (keep);
/* This is cheap if the section is already read in. */
dwarf2_read_section (objfile, section);
- begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off;
+ begin_info_ptr = info_ptr = section->buffer + to_underlying (this_cu->sect_off);
abbrev_section = get_abbrev_section_for_cu (this_cu);
}
/* Get the header. */
- if (cu->header.first_die_offset.cu_off != 0 && ! rereading_dwo_cu)
+ if (to_underlying (cu->header.first_die_cu_offset) != 0 && !rereading_dwo_cu)
{
/* We already have the header, there's no need to read it in again. */
- info_ptr += cu->header.first_die_offset.cu_off;
+ info_ptr += to_underlying (cu->header.first_die_cu_offset);
}
else
{
we can go from a pointer to one to a pointer to the other. */
sig_type = (struct signatured_type *) this_cu;
gdb_assert (sig_type->signature == cu->header.signature);
- gdb_assert (sig_type->type_offset_in_tu.cu_off
- == cu->header.type_offset_in_tu.cu_off);
- gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off);
+ gdb_assert (sig_type->type_offset_in_tu
+ == cu->header.type_cu_offset_in_tu);
+ gdb_assert (this_cu->sect_off == cu->header.sect_off);
/* LENGTH has not been set yet for type units if we're
using .gdb_index. */
this_cu->length = get_cu_length (&cu->header);
/* Establish the type offset that can be used to lookup the type. */
- sig_type->type_offset_in_section.sect_off =
- this_cu->offset.sect_off + sig_type->type_offset_in_tu.cu_off;
+ sig_type->type_offset_in_section =
+ this_cu->sect_off + to_underlying (sig_type->type_offset_in_tu);
this_cu->dwarf_version = cu->header.version;
}
info_ptr,
rcuh_kind::COMPILE);
- gdb_assert (this_cu->offset.sect_off == cu->header.offset.sect_off);
+ gdb_assert (this_cu->sect_off == cu->header.sect_off);
gdb_assert (this_cu->length == get_cu_length (&cu->header));
this_cu->dwarf_version = cu->header.version;
}
if (abbrev_table != NULL)
{
gdb_assert (cu->abbrev_table == NULL);
- gdb_assert (cu->header.abbrev_offset.sect_off
- == abbrev_table->offset.sect_off);
+ gdb_assert (cu->header.abbrev_sect_off == abbrev_table->sect_off);
cu->abbrev_table = abbrev_table;
}
else if (cu->abbrev_table == NULL)
complaint (&symfile_complaints,
_("compilation unit with DW_AT_GNU_dwo_name"
" has children (offset 0x%x) [in module %s]"),
- this_cu->offset.sect_off, bfd_get_filename (abfd));
+ to_underlying (this_cu->sect_off), bfd_get_filename (abfd));
}
dwo_unit = lookup_dwo_unit (this_cu, comp_unit_die);
if (dwo_unit != NULL)
if (dwarf_die_debug)
fprintf_unfiltered (gdb_stdlog, "Reading %s unit at offset 0x%x\n",
this_cu->is_debug_types ? "type" : "comp",
- this_cu->offset.sect_off);
+ to_underlying (this_cu->sect_off));
gdb_assert (this_cu->cu == NULL);
cleanups = make_cleanup (free_stack_comp_unit, &cu);
- begin_info_ptr = info_ptr = section->buffer + this_cu->offset.sect_off;
+ begin_info_ptr = info_ptr = section->buffer + to_underlying (this_cu->sect_off);
info_ptr = read_and_check_comp_unit_head (&cu.header, section,
abbrev_section, info_ptr,
(this_cu->is_debug_types
}
else
{
- unsigned int line_offset = line_offset_struct.sect_off;
+ unsigned int line_offset = to_underlying (line_offset_struct);
struct partial_symtab *pst;
char *name;
}
tu_group->hash.dwo_unit = cu->dwo_unit;
- tu_group->hash.line_offset = line_offset_struct;
+ tu_group->hash.line_sect_off = line_offset_struct;
return tu_group;
}
}
type_unit_group_for_lookup.hash.dwo_unit = cu->dwo_unit;
- type_unit_group_for_lookup.hash.line_offset.sect_off = line_offset;
+ type_unit_group_for_lookup.hash.line_sect_off = (sect_offset) line_offset;
slot = htab_find_slot (dwarf2_per_objfile->type_unit_groups,
&type_unit_group_for_lookup, INSERT);
if (*slot != NULL)
}
else
{
- sect_offset line_offset_struct;
-
- line_offset_struct.sect_off = line_offset;
+ sect_offset line_offset_struct = (sect_offset) line_offset;
tu_group = create_type_unit_group (cu, line_offset_struct);
*slot = tu_group;
++tu_stats->nr_symtabs;
"Psymtab for %s unit @0x%x: %s - %s"
", %d global, %d static syms\n",
per_cu->is_debug_types ? "type" : "comp",
- per_cu->offset.sect_off,
+ to_underlying (per_cu->sect_off),
paddress (gdbarch, pst->textlow),
paddress (gdbarch, pst->texthigh),
pst->n_global_syms, pst->n_static_syms);
= (const struct tu_abbrev_offset * const*) ap;
const struct tu_abbrev_offset * const *b
= (const struct tu_abbrev_offset * const*) bp;
- unsigned int aoff = (*a)->abbrev_offset.sect_off;
- unsigned int boff = (*b)->abbrev_offset.sect_off;
+ sect_offset aoff = (*a)->abbrev_offset;
+ sect_offset boff = (*b)->abbrev_offset;
return (aoff > boff) - (aoff < boff);
}
sorted_by_abbrev[i].sig_type = sig_type;
sorted_by_abbrev[i].abbrev_offset =
read_abbrev_offset (sig_type->per_cu.section,
- sig_type->per_cu.offset);
+ sig_type->per_cu.sect_off);
}
cleanups = make_cleanup (xfree, sorted_by_abbrev);
qsort (sorted_by_abbrev, dwarf2_per_objfile->n_type_units,
sizeof (struct tu_abbrev_offset), sort_tu_by_abbrev_offset);
- abbrev_offset.sect_off = ~(unsigned) 0;
+ abbrev_offset = (sect_offset) ~(unsigned) 0;
abbrev_table = NULL;
make_cleanup (abbrev_table_free_cleanup, &abbrev_table);
/* Switch to the next abbrev table if necessary. */
if (abbrev_table == NULL
- || tu->abbrev_offset.sect_off != abbrev_offset.sect_off)
+ || tu->abbrev_offset != abbrev_offset)
{
if (abbrev_table != NULL)
{
{
unsigned int length, initial_length_size;
struct dwarf2_per_cu_data *this_cu;
- sect_offset offset;
- offset.sect_off = info_ptr - section->buffer;
+ sect_offset sect_off = (sect_offset) (info_ptr - section->buffer);
/* Read just enough information to find out where the next
compilation unit is. */
/* Save the compilation unit for later lookup. */
this_cu = XOBNEW (&objfile->objfile_obstack, struct dwarf2_per_cu_data);
memset (this_cu, 0, sizeof (*this_cu));
- this_cu->offset = offset;
+ this_cu->sect_off = sect_off;
this_cu->length = length + initial_length_size;
this_cu->is_dwz = is_dwz;
this_cu->objfile = objfile;
objfile_name (cu->objfile));
}
- per_cu = dwarf2_find_containing_comp_unit (pdi->d.offset,
+ per_cu = dwarf2_find_containing_comp_unit (pdi->d.sect_off,
pdi->is_dwz,
cu->objfile);
ignoring them. */
complaint (&symfile_complaints,
_("unhandled containing DIE tag %d for DIE at %d"),
- parent->tag, pdi->offset.sect_off);
+ parent->tag, to_underlying (pdi->sect_off));
parent->scope = grandparent_scope;
}
/* DW_FORM_ref_addr is using section offset. */
attr.name = (enum dwarf_attribute) 0;
attr.form = DW_FORM_ref_addr;
- attr.u.unsnd = pdi->offset.sect_off;
+ attr.u.unsnd = to_underlying (pdi->sect_off);
die = follow_die_ref (NULL, &attr, &ref_cu);
return xstrdup (dwarf2_full_name (NULL, die, ref_cu));
error (_("Dwarf Error: Could not find abbrev number %d in %s"
" at offset 0x%x [in module %s]"),
abbrev_number, cu->per_cu->is_debug_types ? "TU" : "CU",
- cu->header.offset.sect_off, bfd_get_filename (abfd));
+ to_underlying (cu->header.sect_off), bfd_get_filename (abfd));
}
return abbrev;
_("ignoring absolute DW_AT_sibling"));
else
{
- unsigned int off = dwarf2_get_ref_die_offset (&attr).sect_off;
- const gdb_byte *sibling_ptr = buffer + off;
+ 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,
case DW_FORM_ref_sig8:
info_ptr += 8;
break;
+ case DW_FORM_data16:
+ info_ptr += 16;
+ break;
case DW_FORM_string:
read_direct_string (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
sprintf (buf, "TU %s at offset 0x%x",
hex_string (sig_type->signature),
- per_cu->offset.sect_off);
+ to_underlying (per_cu->sect_off));
/* There can be 100s of TUs.
Only print them in verbose mode. */
debug_print_threshold = 2;
}
else
{
- sprintf (buf, "CU at offset 0x%x", per_cu->offset.sect_off);
+ sprintf (buf, "CU at offset 0x%x",
+ to_underlying (per_cu->sect_off));
debug_print_threshold = 1;
}
{
const struct die_info *die = (const struct die_info *) item;
- return die->offset.sect_off;
+ return to_underlying (die->sect_off);
}
/* Trivial comparison function for die_info structures: two DIEs
const struct die_info *die_lhs = (const struct die_info *) item_lhs;
const struct die_info *die_rhs = (const struct die_info *) item_rhs;
- return die_lhs->offset.sect_off == die_rhs->offset.sect_off;
+ return die_lhs->sect_off == die_rhs->sect_off;
}
/* die_reader_func for load_full_comp_unit.
attr = dwarf2_attr (die, DW_AT_import, cu);
if (attr != NULL)
{
- struct dwarf2_per_cu_data *per_cu;
- sect_offset offset;
- int is_dwz;
-
- offset = dwarf2_get_ref_die_offset (attr);
- is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
- per_cu = dwarf2_find_containing_comp_unit (offset, is_dwz, cu->objfile);
+ sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
+ bool is_dwz = (attr->form == DW_FORM_GNU_ref_alt || cu->per_cu->is_dwz);
+ dwarf2_per_cu_data *per_cu
+ = dwarf2_find_containing_comp_unit (sect_off, is_dwz, cu->objfile);
/* If necessary, add it to the queue and load its DIEs. */
if (maybe_queue_comp_unit (cu, per_cu, cu->language))
case DW_TAG_pointer_type:
case DW_TAG_ptr_to_member_type:
case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type:
case DW_TAG_string_type:
break;
complaint (&symfile_complaints,
_("Computed physname <%s> does not match demangled <%s> "
"(from linkage <%s>) - DIE at 0x%x [in module %s]"),
- physname, canon, mangled, die->offset.sect_off,
+ physname, canon, mangled, to_underlying (die->sect_off),
objfile_name (objfile));
/* Prefer DW_AT_linkage_name (in the CANON form) - when it
{
complaint (&symfile_complaints,
_("DIE at 0x%x has too many recursively imported "
- "declarations"), d->offset.sect_off);
+ "declarations"), to_underlying (d->sect_off));
return 0;
}
if (attr != NULL)
{
struct type *type;
- sect_offset offset = dwarf2_get_ref_die_offset (attr);
+ sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
- type = get_die_type_at_offset (offset, cu->per_cu);
+ type = get_die_type_at_offset (sect_off, cu->per_cu);
if (type != NULL && TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
{
/* This declaration is a global namespace alias. Add
complaint (&symfile_complaints,
_("child DW_TAG_imported_declaration expected "
"- DIE at 0x%x [in module %s]"),
- child_die->offset.sect_off, objfile_name (objfile));
+ to_underlying (child_die->sect_off), objfile_name (objfile));
continue;
}
complaint (&symfile_complaints,
_("child DW_TAG_imported_declaration has unknown "
"imported name - DIE at 0x%x [in module %s]"),
- child_die->offset.sect_off, objfile_name (objfile));
+ to_underlying (child_die->sect_off), objfile_name (objfile));
continue;
}
do_cleanups (cleanups);
}
-/* Cleanup function for handle_DW_AT_stmt_list. */
-
-static void
-free_cu_line_header (void *arg)
-{
- struct dwarf2_cu *cu = (struct dwarf2_cu *) arg;
-
- free_line_header (cu->line_header);
- cu->line_header = NULL;
-}
-
/* 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. */
return cu->producer_is_gcc_lt_4_3;
}
-static void
-find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu,
- const char **name, const char **comp_dir)
+static file_and_directory
+find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu)
{
+ file_and_directory res;
+
/* Find the filename. Do not use dwarf2_name here, since the filename
is not a source language identifier. */
- *name = dwarf2_string_attr (die, DW_AT_name, cu);
- *comp_dir = dwarf2_string_attr (die, DW_AT_comp_dir, cu);
+ res.name = dwarf2_string_attr (die, DW_AT_name, cu);
+ res.comp_dir = dwarf2_string_attr (die, DW_AT_comp_dir, cu);
- if (*comp_dir == NULL
- && producer_is_gcc_lt_4_3 (cu) && *name != NULL
- && IS_ABSOLUTE_PATH (*name))
+ if (res.comp_dir == NULL
+ && producer_is_gcc_lt_4_3 (cu) && res.name != NULL
+ && IS_ABSOLUTE_PATH (res.name))
{
- char *d = ldirname (*name);
-
- *comp_dir = d;
- if (d != NULL)
- make_cleanup (xfree, d);
+ res.comp_dir_storage = ldirname (res.name);
+ if (!res.comp_dir_storage.empty ())
+ res.comp_dir = res.comp_dir_storage.c_str ();
}
- if (*comp_dir != NULL)
+ if (res.comp_dir != NULL)
{
/* Irix 6.2 native cc prepends <machine>.: to the compilation
directory, get rid of it. */
- const char *cp = strchr (*comp_dir, ':');
+ const char *cp = strchr (res.comp_dir, ':');
- if (cp && cp != *comp_dir && cp[-1] == '.' && cp[1] == '/')
- *comp_dir = cp + 1;
+ if (cp && cp != res.comp_dir && cp[-1] == '.' && cp[1] == '/')
+ res.comp_dir = cp + 1;
}
- if (*name == NULL)
- *name = "<unknown>";
+ if (res.name == NULL)
+ res.name = "<unknown>";
+
+ return res;
}
/* Handle DW_AT_stmt_list for a compilation unit.
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct attribute *attr;
- unsigned int line_offset;
struct line_header line_header_local;
hashval_t line_header_local_hash;
unsigned u;
if (attr == NULL)
return;
- line_offset = DW_UNSND (attr);
+ sect_offset line_offset = (sect_offset) DW_UNSND (attr);
/* The line header hash table is only created if needed (it exists to
prevent redundant reading of the line table for partial_units).
dummy_obstack_deallocate);
}
- line_header_local.offset.sect_off = line_offset;
+ line_header_local.sect_off = line_offset;
line_header_local.offset_in_dwz = cu->per_cu->is_dwz;
line_header_local_hash = line_header_hash (&line_header_local);
if (dwarf2_per_objfile->line_header_hash != NULL)
/* dwarf_decode_line_header does not yet provide sufficient information.
We always have to call also dwarf_decode_lines for it. */
- cu->line_header = dwarf_decode_line_header (line_offset, cu);
- if (cu->line_header == NULL)
+ line_header_up lh = dwarf_decode_line_header (line_offset, cu);
+ if (lh == NULL)
return;
+ cu->line_header = lh.get ();
if (dwarf2_per_objfile->line_header_hash == NULL)
slot = NULL;
number information unit. And if we're not using line_header_hash
then this is what we want as well. */
gdb_assert (die->tag != DW_TAG_partial_unit);
- make_cleanup (free_cu_line_header, cu);
}
decode_mapping = (die->tag != DW_TAG_partial_unit);
dwarf_decode_lines (cu->line_header, comp_dir, cu, NULL, lowpc,
decode_mapping);
+
+ lh.release ();
}
/* Process DW_TAG_compile_unit or DW_TAG_partial_unit. */
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- struct cleanup *back_to = make_cleanup (null_cleanup, 0);
CORE_ADDR lowpc = ((CORE_ADDR) -1);
CORE_ADDR highpc = ((CORE_ADDR) 0);
struct attribute *attr;
- const char *name = NULL;
- const char *comp_dir = NULL;
struct die_info *child_die;
CORE_ADDR baseaddr;
lowpc = highpc;
lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
- find_file_and_directory (die, cu, &name, &comp_dir);
+ file_and_directory fnd = find_file_and_directory (die, cu);
prepare_one_comp_unit (cu, die, cu->language);
if (cu->producer && strstr (cu->producer, "GNU Go ") != NULL)
set_cu_language (DW_LANG_Go, cu);
- dwarf2_start_symtab (cu, name, comp_dir, lowpc);
+ dwarf2_start_symtab (cu, 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
for DW_AT_decl_file. */
- handle_DW_AT_stmt_list (die, cu, comp_dir, lowpc);
+ handle_DW_AT_stmt_list (die, cu, fnd.comp_dir, lowpc);
/* Process all dies in compilation unit. */
if (die->child != NULL)
dwarf_decode_macros (cu, macro_offset, 0);
}
}
-
- do_cleanups (back_to);
}
/* TU version of handle_DW_AT_stmt_list for read_type_unit_scope.
struct dwarf2_per_cu_data *per_cu = cu->per_cu;
struct type_unit_group *tu_group;
int first_time;
- struct line_header *lh;
struct attribute *attr;
- unsigned int i, line_offset;
+ unsigned int i;
struct signatured_type *sig_type;
gdb_assert (per_cu->is_debug_types);
/* We have to handle the case of both a missing DW_AT_stmt_list or bad
debug info. */
- lh = NULL;
+ line_header_up lh;
if (attr != NULL)
{
- line_offset = DW_UNSND (attr);
+ sect_offset line_offset = (sect_offset) DW_UNSND (attr);
lh = dwarf_decode_line_header (line_offset, cu);
}
if (lh == NULL)
return;
}
- cu->line_header = lh;
- make_cleanup (free_cu_line_header, cu);
+ cu->line_header = lh.get ();
if (first_time)
{
process_full_type_unit still needs to know if this is the first
time. */
- tu_group->num_symtabs = lh->num_file_names;
- tu_group->symtabs = XNEWVEC (struct symtab *, lh->num_file_names);
+ tu_group->num_symtabs = lh->file_names.size ();
+ tu_group->symtabs = XNEWVEC (struct symtab *, lh->file_names.size ());
- for (i = 0; i < lh->num_file_names; ++i)
+ for (i = 0; i < lh->file_names.size (); ++i)
{
- const char *dir = NULL;
- struct file_entry *fe = &lh->file_names[i];
+ file_entry &fe = lh->file_names[i];
- if (fe->dir_index && lh->include_dirs != NULL)
- dir = lh->include_dirs[fe->dir_index - 1];
- dwarf2_start_subfile (fe->name, dir);
+ dwarf2_start_subfile (fe.name, fe.include_dir (lh.get ()));
if (current_subfile->symtab == NULL)
{
= allocate_symtab (cust, current_subfile->name);
}
- fe->symtab = current_subfile->symtab;
- tu_group->symtabs[i] = fe->symtab;
+ fe.symtab = current_subfile->symtab;
+ tu_group->symtabs[i] = fe.symtab;
}
}
else
{
restart_symtab (tu_group->compunit_symtab, "", 0);
- for (i = 0; i < lh->num_file_names; ++i)
+ for (i = 0; i < lh->file_names.size (); ++i)
{
struct file_entry *fe = &lh->file_names[i];
}
}
+ lh.release ();
+
/* The main symtab is allocated last. Type units don't have DW_AT_name
so they don't have a "real" (so to speak) symtab anyway.
There is later code that will assign the main symtab to all symbols
void *datap)
{
struct dwarf2_cu *cu = reader->cu;
- sect_offset offset = cu->per_cu->offset;
+ sect_offset sect_off = cu->per_cu->sect_off;
struct dwarf2_section_info *section = cu->per_cu->section;
struct create_dwo_cu_data *data = (struct create_dwo_cu_data *) datap;
struct dwo_file *dwo_file = data->dwo_file;
complaint (&symfile_complaints,
_("Dwarf Error: debug entry at offset 0x%x is missing"
" its dwo_id [in module %s]"),
- offset.sect_off, dwo_file->dwo_name);
+ to_underlying (sect_off), dwo_file->dwo_name);
return;
}
dwo_unit->dwo_file = dwo_file;
dwo_unit->signature = DW_UNSND (attr);
dwo_unit->section = section;
- dwo_unit->offset = offset;
+ dwo_unit->sect_off = sect_off;
dwo_unit->length = cu->per_cu->length;
if (dwarf_read_debug)
fprintf_unfiltered (gdb_stdlog, " offset 0x%x, dwo_id %s\n",
- offset.sect_off, hex_string (dwo_unit->signature));
+ to_underlying (sect_off),
+ hex_string (dwo_unit->signature));
}
/* Create the dwo_unit for the lone CU in DWO_FILE.
memset (&per_cu, 0, sizeof (per_cu));
per_cu.objfile = objfile;
per_cu.is_debug_types = 0;
- per_cu.offset.sect_off = info_ptr - section->buffer;
+ per_cu.sect_off = sect_offset (info_ptr - section->buffer);
per_cu.section = section;
init_cutu_and_read_dies_no_follow (&per_cu, dwo_file,
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
struct dwp_file *dwp_file;
- char *dwp_name;
- struct cleanup *cleanups = make_cleanup (null_cleanup, 0);
/* Try to find first .dwp for the binary file before any symbolic links
resolving. */
/* If the objfile is a debug file, find the name of the real binary
file and get the name of dwp file from there. */
+ std::string dwp_name;
if (objfile->separate_debug_objfile_backlink != NULL)
{
struct objfile *backlink = objfile->separate_debug_objfile_backlink;
const char *backlink_basename = lbasename (backlink->original_name);
- char *debug_dirname = ldirname (objfile->original_name);
- make_cleanup (xfree, debug_dirname);
- dwp_name = xstrprintf ("%s%s%s.dwp", debug_dirname,
- SLASH_STRING, backlink_basename);
+ dwp_name = ldirname (objfile->original_name) + SLASH_STRING + backlink_basename;
}
else
- dwp_name = xstrprintf ("%s.dwp", objfile->original_name);
- make_cleanup (xfree, dwp_name);
+ dwp_name = objfile->original_name;
+
+ dwp_name += ".dwp";
- gdb_bfd_ref_ptr dbfd (open_dwp_file (dwp_name));
+ gdb_bfd_ref_ptr dbfd (open_dwp_file (dwp_name.c_str ()));
if (dbfd == NULL
&& strcmp (objfile->original_name, objfile_name (objfile)) != 0)
{
/* Try to find .dwp for the binary file after gdb_realpath resolving. */
- dwp_name = xstrprintf ("%s.dwp", objfile_name (objfile));
- make_cleanup (xfree, dwp_name);
- dbfd = open_dwp_file (dwp_name);
+ dwp_name = objfile_name (objfile);
+ dwp_name += ".dwp";
+ dbfd = open_dwp_file (dwp_name.c_str ());
}
if (dbfd == NULL)
{
if (dwarf_read_debug)
- fprintf_unfiltered (gdb_stdlog, "DWP file not found: %s\n", dwp_name);
- do_cleanups (cleanups);
+ fprintf_unfiltered (gdb_stdlog, "DWP file not found: %s\n", dwp_name.c_str ());
return NULL;
}
dwp_file = OBSTACK_ZALLOC (&objfile->objfile_obstack, struct dwp_file);
dwp_file->name = bfd_get_filename (dbfd.get ());
dwp_file->dbfd = dbfd.release ();
- do_cleanups (cleanups);
/* +1: section 0 is unused */
dwp_file->num_sections = bfd_count_sections (dwp_file->dbfd) + 1;
error (_("Dwarf Error: DWP file CU version %s doesn't match"
" TU version %s [in DWP file %s]"),
pulongest (dwp_file->cus->version),
- pulongest (dwp_file->tus->version), dwp_name);
+ pulongest (dwp_file->tus->version), dwp_name.c_str ());
}
dwp_file->version = dwp_file->cus->version;
kind, dwo_name, hex_string (signature),
dwp_text != NULL ? dwp_text : "",
this_unit->is_debug_types ? "TU" : "CU",
- this_unit->offset.sect_off, objfile_name (objfile));
+ to_underlying (this_unit->sect_off), objfile_name (objfile));
do_cleanups (cleanups);
}
&& origin_die->tag == DW_TAG_subprogram))
complaint (&symfile_complaints,
_("DIE 0x%x and its abstract origin 0x%x have different tags"),
- die->offset.sect_off, origin_die->offset.sect_off);
+ to_underlying (die->sect_off),
+ to_underlying (origin_die->sect_off));
child_die = die->child;
die_children_count = 0;
&& child_origin_die->tag == DW_TAG_subprogram))
complaint (&symfile_complaints,
_("Child DIE 0x%x and its abstract origin 0x%x have "
- "different tags"), child_die->offset.sect_off,
- child_origin_die->offset.sect_off);
+ "different tags"),
+ to_underlying (child_die->sect_off),
+ to_underlying (child_origin_die->sect_off));
if (child_origin_die->parent != origin_die)
complaint (&symfile_complaints,
_("Child DIE 0x%x and its abstract origin 0x%x have "
- "different parents"), child_die->offset.sect_off,
- child_origin_die->offset.sect_off);
+ "different parents"),
+ to_underlying (child_die->sect_off),
+ to_underlying (child_origin_die->sect_off));
else
- *offsets_end++ = child_origin_die->offset;
+ *offsets_end++ = child_origin_die->sect_off;
}
}
qsort (offsets, offsets_end - offsets, sizeof (*offsets),
unsigned_int_compar);
for (offsetp = offsets + 1; offsetp < offsets_end; offsetp++)
- if (offsetp[-1].sect_off == offsetp->sect_off)
+ if (offsetp[-1] == *offsetp)
complaint (&symfile_complaints,
_("Multiple children of DIE 0x%x refer "
"to DIE 0x%x as their abstract origin"),
- die->offset.sect_off, offsetp->sect_off);
+ to_underlying (die->sect_off), to_underlying (*offsetp));
offsetp = offsets;
origin_child_die = origin_die->child;
{
/* Is ORIGIN_CHILD_DIE referenced by any of the DIE children? */
while (offsetp < offsets_end
- && offsetp->sect_off < origin_child_die->offset.sect_off)
+ && *offsetp < origin_child_die->sect_off)
offsetp++;
if (offsetp >= offsets_end
- || offsetp->sect_off > origin_child_die->offset.sect_off)
+ || *offsetp > origin_child_die->sect_off)
{
/* Found that ORIGIN_CHILD_DIE is really not referenced.
Check whether we're already processing ORIGIN_CHILD_DIE.
{
complaint (&symfile_complaints,
_("missing name for subprogram DIE at %d"),
- die->offset.sect_off);
+ to_underlying (die->sect_off));
return;
}
complaint (&symfile_complaints,
_("cannot get low and high bounds "
"for subprogram DIE at %d"),
- die->offset.sect_off);
+ to_underlying (die->sect_off));
return;
}
complaint (&symfile_complaints,
_("missing DW_AT_call_return_pc for DW_TAG_call_site "
"DIE 0x%x [in module %s]"),
- die->offset.sect_off, objfile_name (objfile));
+ to_underlying (die->sect_off), objfile_name (objfile));
return;
}
pc = attr_value_as_address (attr) + baseaddr;
complaint (&symfile_complaints,
_("Duplicate PC %s for DW_TAG_call_site "
"DIE 0x%x [in module %s]"),
- paddress (gdbarch, pc), die->offset.sect_off,
+ paddress (gdbarch, pc), to_underlying (die->sect_off),
objfile_name (objfile));
return;
}
complaint (&symfile_complaints,
_("Tag %d is not DW_TAG_call_site_parameter in "
"DW_TAG_call_site child DIE 0x%x [in module %s]"),
- child_die->tag, child_die->offset.sect_off,
+ child_die->tag, to_underlying (child_die->sect_off),
objfile_name (objfile));
continue;
}
complaint (&symfile_complaints,
_("Cannot find function owning DW_TAG_call_site "
"DIE 0x%x [in module %s]"),
- die->offset.sect_off, objfile_name (objfile));
+ to_underlying (die->sect_off), objfile_name (objfile));
}
}
complaint (&symfile_complaints,
_("DW_AT_call_target target DIE has invalid "
"physname, for referencing DIE 0x%x [in module %s]"),
- die->offset.sect_off, objfile_name (objfile));
+ to_underlying (die->sect_off), objfile_name (objfile));
else
SET_FIELD_PHYSNAME (call_site->target, target_physname);
}
complaint (&symfile_complaints,
_("DW_AT_call_target target DIE has invalid "
"low pc, for referencing DIE 0x%x [in module %s]"),
- die->offset.sect_off, objfile_name (objfile));
+ to_underlying (die->sect_off), objfile_name (objfile));
else
{
lowpc = gdbarch_adjust_dwarf2_addr (gdbarch, lowpc + baseaddr);
complaint (&symfile_complaints,
_("DW_TAG_call_site DW_AT_call_target is neither "
"block nor reference, for DIE 0x%x [in module %s]"),
- die->offset.sect_off, objfile_name (objfile));
+ to_underlying (die->sect_off), objfile_name (objfile));
call_site->per_cu = cu->per_cu;
}
if (loc == NULL && origin != NULL && attr_form_is_ref (origin))
{
- sect_offset offset;
-
parameter->kind = CALL_SITE_PARAMETER_PARAM_OFFSET;
- offset = dwarf2_get_ref_die_offset (origin);
- if (!offset_in_cu_p (&cu->header, offset))
+
+ sect_offset sect_off
+ = (sect_offset) dwarf2_get_ref_die_offset (origin);
+ if (!offset_in_cu_p (&cu->header, sect_off))
{
/* As DW_OP_GNU_parameter_ref uses CU-relative offset this
binding can be done only inside one CU. Such referenced DIE
complaint (&symfile_complaints,
_("DW_AT_call_parameter offset is not in CU for "
"DW_TAG_call_site child DIE 0x%x [in module %s]"),
- child_die->offset.sect_off, objfile_name (objfile));
+ to_underlying (child_die->sect_off),
+ objfile_name (objfile));
continue;
}
- parameter->u.param_offset.cu_off = (offset.sect_off
- - cu->header.offset.sect_off);
+ parameter->u.param_cu_off
+ = (cu_offset) (sect_off - cu->header.sect_off);
}
else if (loc == NULL || origin != NULL || !attr_form_is_block (loc))
{
complaint (&symfile_complaints,
_("No DW_FORM_block* DW_AT_location for "
"DW_TAG_call_site child DIE 0x%x [in module %s]"),
- child_die->offset.sect_off, objfile_name (objfile));
+ to_underlying (child_die->sect_off), objfile_name (objfile));
continue;
}
else
"for DW_FORM_block* DW_AT_location is supported for "
"DW_TAG_call_site child DIE 0x%x "
"[in module %s]"),
- child_die->offset.sect_off, objfile_name (objfile));
+ to_underlying (child_die->sect_off),
+ objfile_name (objfile));
continue;
}
}
complaint (&symfile_complaints,
_("No DW_FORM_block* DW_AT_call_value for "
"DW_TAG_call_site child DIE 0x%x [in module %s]"),
- child_die->offset.sect_off, objfile_name (objfile));
+ to_underlying (child_die->sect_off),
+ objfile_name (objfile));
continue;
}
parameter->value = DW_BLOCK (attr)->data;
complaint (&symfile_complaints,
_("No DW_FORM_block* DW_AT_call_data_value for "
"DW_TAG_call_site child DIE 0x%x [in module %s]"),
- child_die->offset.sect_off, objfile_name (objfile));
+ to_underlying (child_die->sect_off),
+ objfile_name (objfile));
else
{
parameter->data_value = DW_BLOCK (attr)->data;
while (1)
{
- CORE_ADDR range_beginning, range_end;
+ /* Initialize it due to a false compiler warning. */
+ CORE_ADDR range_beginning = 0, range_end = 0;
const gdb_byte *buf_end = (dwarf2_per_objfile->rnglists.buffer
+ dwarf2_per_objfile->rnglists.size);
unsigned int bytes_read;
dwarf2_ranges_process (offset, cu,
[&] (CORE_ADDR start, CORE_ADDR end)
{
+ start += baseaddr;
+ end += baseaddr;
start = gdbarch_adjust_dwarf2_addr (gdbarch, start);
end = gdbarch_adjust_dwarf2_addr (gdbarch, end);
record_block_range (block, start, end - 1);
complaint (&symfile_complaints,
_("cannot determine context for virtual member "
"function \"%s\" (offset %d)"),
- fieldname, die->offset.sect_off);
+ fieldname, to_underlying (die->sect_off));
}
else
{
complaint (&symfile_complaints,
_("Member function \"%s\" (offset %d) is virtual "
"but the vtable offset is not specified"),
- fieldname, die->offset.sect_off);
+ fieldname, to_underlying (die->sect_off));
ALLOCATE_CPLUS_STRUCT_TYPE (type);
TYPE_CPLUS_DYNAMIC (type) = 1;
}
struct signatured_type *sig_type;
sig_type = (struct signatured_type *) cu->per_cu;
- gdb_assert (sig_type->type_offset_in_section.sect_off != 0);
- if (sig_type->type_offset_in_section.sect_off != die->offset.sect_off)
+ gdb_assert (to_underlying (sig_type->type_offset_in_section) != 0);
+ if (sig_type->type_offset_in_section != die->sect_off)
return;
}
baton->data = ptr;
*ptr++ = DW_OP_call4;
- cu_off = common_die->offset.sect_off - cu->per_cu->offset.sect_off;
+ cu_off = common_die->sect_off - cu->per_cu->sect_off;
store_unsigned_integer (ptr, 4, byte_order, cu_off);
ptr += 4;
_("Variable in common block has "
"DW_AT_data_member_location "
"- DIE at 0x%x [in module %s]"),
- child_die->offset.sect_off,
+ to_underlying (child_die->sect_off),
objfile_name (cu->objfile));
if (attr_form_is_section_offset (member_loc))
if (!module_name)
complaint (&symfile_complaints,
_("DW_TAG_module has no name, offset 0x%x"),
- die->offset.sect_off);
+ to_underlying (die->sect_off));
type = init_type (objfile, TYPE_CODE_MODULE, 0, module_name);
/* determine_prefix uses TYPE_TAG_NAME. */
return set_die_type (die, type, cu);
}
-/* Extract all information from a DW_TAG_reference_type DIE and add to
+/* Extract all information from a DW_TAG_{rvalue_,}reference_type DIE and add to
the user defined type vector. */
static struct type *
-read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu)
+read_tag_reference_type (struct die_info *die, struct dwarf2_cu *cu,
+ enum type_code refcode)
{
struct comp_unit_head *cu_header = &cu->header;
struct type *type, *target_type;
struct attribute *attr;
+ gdb_assert (refcode == TYPE_CODE_REF || refcode == TYPE_CODE_RVALUE_REF);
+
target_type = die_type (die, cu);
/* The die_type call above may have already set the type for this DIE. */
if (type)
return type;
- type = lookup_reference_type (target_type);
+ type = lookup_reference_type (target_type, refcode);
attr = dwarf2_attr (die, DW_AT_byte_size, cu);
if (attr)
{
complaint (&symfile_complaints,
_("Self-referential DW_TAG_typedef "
"- DIE at 0x%x [in module %s]"),
- die->offset.sect_off, objfile_name (objfile));
+ to_underlying (die->sect_off), objfile_name (objfile));
TYPE_TARGET_TYPE (this_type) = NULL;
}
return this_type;
type = init_integer_type (objfile, bits, 1, name);
break;
case DW_ATE_UTF:
- /* We just treat this as an integer and then recognize the
- type by name elsewhere. */
- type = init_integer_type (objfile, bits, 0, name);
+ {
+ gdbarch *arch = get_objfile_arch (objfile);
+
+ if (bits == 16)
+ type = builtin_type (arch)->builtin_char16;
+ else if (bits == 32)
+ type = builtin_type (arch)->builtin_char32;
+ else
+ {
+ complaint (&symfile_complaints,
+ _("unsupported DW_ATE_UTF bit size: '%d'"),
+ bits);
+ type = init_integer_type (objfile, bits, 1, name);
+ }
+ return set_die_type (die, type, cu);
+ }
break;
default:
else if (!low_default_is_valid)
complaint (&symfile_complaints, _("Missing DW_AT_lower_bound "
"- DIE at 0x%x [in module %s]"),
- die->offset.sect_off, objfile_name (cu->objfile));
+ to_underlying (die->sect_off), objfile_name (cu->objfile));
attr = dwarf2_attr (die, DW_AT_upper_bound, cu);
if (!attr_to_dynamic_prop (attr, die, cu, &high))
int *has_children, int num_extra_attrs)
{
unsigned int abbrev_number, bytes_read, i;
- sect_offset offset;
struct abbrev_info *abbrev;
struct die_info *die;
struct dwarf2_cu *cu = reader->cu;
bfd *abfd = reader->abfd;
- offset.sect_off = info_ptr - reader->buffer;
+ sect_offset sect_off = (sect_offset) (info_ptr - reader->buffer);
abbrev_number = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
info_ptr += bytes_read;
if (!abbrev_number)
bfd_get_filename (abfd));
die = dwarf_alloc_die (cu, abbrev->num_attrs + num_extra_attrs);
- die->offset = offset;
+ die->sect_off = sect_off;
die->tag = abbrev->tag;
die->abbrev = abbrev_number;
static struct abbrev_table *
abbrev_table_read_table (struct dwarf2_section_info *section,
- sect_offset offset)
+ sect_offset sect_off)
{
struct objfile *objfile = dwarf2_per_objfile->objfile;
bfd *abfd = get_section_bfd_owner (section);
unsigned int allocated_attrs;
abbrev_table = XNEW (struct abbrev_table);
- abbrev_table->offset = offset;
+ abbrev_table->sect_off = sect_off;
obstack_init (&abbrev_table->abbrev_obstack);
abbrev_table->abbrevs =
XOBNEWVEC (&abbrev_table->abbrev_obstack, struct abbrev_info *,
ABBREV_HASH_SIZE * sizeof (struct abbrev_info *));
dwarf2_read_section (objfile, section);
- abbrev_ptr = section->buffer + offset.sect_off;
+ abbrev_ptr = section->buffer + to_underlying (sect_off);
abbrev_number = read_unsigned_leb128 (abfd, abbrev_ptr, &bytes_read);
abbrev_ptr += bytes_read;
struct dwarf2_section_info *abbrev_section)
{
cu->abbrev_table =
- abbrev_table_read_table (abbrev_section, cu->header.abbrev_offset);
+ abbrev_table_read_table (abbrev_section, cu->header.abbrev_sect_off);
}
/* Release the memory used by the abbrev table for a compilation unit. */
complaint (&symfile_complaints,
_("DW_TAG_typedef has childen - GCC PR debug/47510 bug "
"- DIE at 0x%x [in module %s]"),
- part_die->offset.sect_off, objfile_name (objfile));
+ to_underlying (part_die->sect_off), objfile_name (objfile));
/* If we're at the second level, and we're an enumerator, and
our parent has no specification (meaning possibly lives in a
void **slot;
slot = htab_find_slot_with_hash (cu->partial_dies, part_die,
- part_die->offset.sect_off, INSERT);
+ to_underlying (part_die->sect_off),
+ INSERT);
*slot = part_die;
}
memset (part_die, 0, sizeof (struct partial_die_info));
- part_die->offset.sect_off = info_ptr - buffer;
+ part_die->sect_off = (sect_offset) (info_ptr - buffer);
info_ptr += abbrev_len;
_("ignoring absolute DW_AT_sibling"));
else
{
- unsigned int off = dwarf2_get_ref_die_offset (&attr).sect_off;
- const gdb_byte *sibling_ptr = buffer + off;
+ 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,
case DW_AT_import:
if (part_die->tag == DW_TAG_imported_unit)
{
- part_die->d.offset = dwarf2_get_ref_die_offset (&attr);
+ part_die->d.sect_off = dwarf2_get_ref_die_offset (&attr);
part_die->is_dwz = (attr.form == DW_FORM_GNU_ref_alt
|| cu->per_cu->is_dwz);
}
_("DW_AT_low_pc %s is zero "
"for DIE at 0x%x [in module %s]"),
paddress (gdbarch, part_die->lowpc),
- part_die->offset.sect_off, objfile_name (objfile));
+ to_underlying (part_die->sect_off), objfile_name (objfile));
}
/* dwarf2_get_pc_bounds has also the strict low < high requirement. */
else if (part_die->lowpc >= part_die->highpc)
"for DIE at 0x%x [in module %s]"),
paddress (gdbarch, part_die->lowpc),
paddress (gdbarch, part_die->highpc),
- part_die->offset.sect_off, objfile_name (objfile));
+ to_underlying (part_die->sect_off),
+ objfile_name (objfile));
}
else
part_die->has_pc_info = 1;
/* Find a cached partial DIE at OFFSET in CU. */
static struct partial_die_info *
-find_partial_die_in_comp_unit (sect_offset offset, struct dwarf2_cu *cu)
+find_partial_die_in_comp_unit (sect_offset sect_off, struct dwarf2_cu *cu)
{
struct partial_die_info *lookup_die = NULL;
struct partial_die_info part_die;
- part_die.offset = offset;
+ part_die.sect_off = sect_off;
lookup_die = ((struct partial_die_info *)
htab_find_with_hash (cu->partial_dies, &part_die,
- offset.sect_off));
+ to_underlying (sect_off)));
return lookup_die;
}
DW_FORM_ref_sig8). */
static struct partial_die_info *
-find_partial_die (sect_offset offset, int offset_in_dwz, struct dwarf2_cu *cu)
+find_partial_die (sect_offset sect_off, int offset_in_dwz, struct dwarf2_cu *cu)
{
struct objfile *objfile = cu->objfile;
struct dwarf2_per_cu_data *per_cu = NULL;
struct partial_die_info *pd = NULL;
if (offset_in_dwz == cu->per_cu->is_dwz
- && offset_in_cu_p (&cu->header, offset))
+ && offset_in_cu_p (&cu->header, sect_off))
{
- pd = find_partial_die_in_comp_unit (offset, cu);
+ pd = find_partial_die_in_comp_unit (sect_off, cu);
if (pd != NULL)
return pd;
/* We missed recording what we needed.
/* TUs don't reference other CUs/TUs (except via type signatures). */
if (cu->per_cu->is_debug_types)
{
- error (_("Dwarf Error: Type Unit at offset 0x%lx contains"
- " external reference to offset 0x%lx [in module %s].\n"),
- (long) cu->header.offset.sect_off, (long) offset.sect_off,
+ error (_("Dwarf Error: Type Unit at offset 0x%x contains"
+ " external reference to offset 0x%x [in module %s].\n"),
+ to_underlying (cu->header.sect_off), to_underlying (sect_off),
bfd_get_filename (objfile->obfd));
}
- per_cu = dwarf2_find_containing_comp_unit (offset, offset_in_dwz,
+ per_cu = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
objfile);
if (per_cu->cu == NULL || per_cu->cu->partial_dies == NULL)
load_partial_comp_unit (per_cu);
per_cu->cu->last_used = 0;
- pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
+ pd = find_partial_die_in_comp_unit (sect_off, per_cu->cu);
}
/* If we didn't find it, and not all dies have been loaded,
set. */
load_partial_comp_unit (per_cu);
- pd = find_partial_die_in_comp_unit (offset, per_cu->cu);
+ pd = find_partial_die_in_comp_unit (sect_off, per_cu->cu);
}
if (pd == NULL)
internal_error (__FILE__, __LINE__,
_("could not find partial DIE 0x%x "
"in cache [from module %s]\n"),
- offset.sect_off, bfd_get_filename (objfile->obfd));
+ to_underlying (sect_off), bfd_get_filename (objfile->obfd));
return pd;
}
DW_UNSND (attr) = read_8_bytes (abfd, info_ptr);
info_ptr += 8;
break;
+ case DW_FORM_data16:
+ blk = dwarf_alloc_block (cu);
+ blk->size = 16;
+ blk->data = read_n_bytes (abfd, info_ptr, 16);
+ info_ptr += 16;
+ DW_BLOCK (attr) = blk;
+ break;
case DW_FORM_sec_offset:
DW_UNSND (attr) = read_offset (abfd, info_ptr, &cu->header, &bytes_read);
info_ptr += bytes_read;
info_ptr += bytes_read;
break;
case DW_FORM_ref1:
- DW_UNSND (attr) = (cu->header.offset.sect_off
+ DW_UNSND (attr) = (to_underlying (cu->header.sect_off)
+ read_1_byte (abfd, info_ptr));
info_ptr += 1;
break;
case DW_FORM_ref2:
- DW_UNSND (attr) = (cu->header.offset.sect_off
+ DW_UNSND (attr) = (to_underlying (cu->header.sect_off)
+ read_2_bytes (abfd, info_ptr));
info_ptr += 2;
break;
case DW_FORM_ref4:
- DW_UNSND (attr) = (cu->header.offset.sect_off
+ DW_UNSND (attr) = (to_underlying (cu->header.sect_off)
+ read_4_bytes (abfd, info_ptr));
info_ptr += 4;
break;
case DW_FORM_ref8:
- DW_UNSND (attr) = (cu->header.offset.sect_off
+ DW_UNSND (attr) = (to_underlying (cu->header.sect_off)
+ read_8_bytes (abfd, info_ptr));
info_ptr += 8;
break;
info_ptr += 8;
break;
case DW_FORM_ref_udata:
- DW_UNSND (attr) = (cu->header.offset.sect_off
+ DW_UNSND (attr) = (to_underlying (cu->header.sect_off)
+ read_unsigned_leb128 (abfd, info_ptr, &bytes_read));
info_ptr += bytes_read;
break;
dwarf2_read_section (objfile, str_offsets_section);
if (str_section->buffer == NULL)
error (_("%s used without .debug_str.dwo section"
- " in CU at offset 0x%lx [in module %s]"),
- form_name, (long) cu->header.offset.sect_off, objf_name);
+ " in CU at offset 0x%x [in module %s]"),
+ form_name, to_underlying (cu->header.sect_off), objf_name);
if (str_offsets_section->buffer == NULL)
error (_("%s used without .debug_str_offsets.dwo section"
- " in CU at offset 0x%lx [in module %s]"),
- form_name, (long) cu->header.offset.sect_off, objf_name);
+ " in CU at offset 0x%x [in module %s]"),
+ form_name, to_underlying (cu->header.sect_off), objf_name);
if (str_index * cu->header.offset_size >= str_offsets_section->size)
error (_("%s pointing outside of .debug_str_offsets.dwo"
- " section in CU at offset 0x%lx [in module %s]"),
- form_name, (long) cu->header.offset.sect_off, objf_name);
+ " section in CU at offset 0x%x [in module %s]"),
+ form_name, to_underlying (cu->header.sect_off), objf_name);
info_ptr = (str_offsets_section->buffer
+ str_index * cu->header.offset_size);
if (cu->header.offset_size == 4)
str_offset = bfd_get_64 (abfd, info_ptr);
if (str_offset >= str_section->size)
error (_("Offset from %s pointing outside of"
- " .debug_str.dwo section in CU at offset 0x%lx [in module %s]"),
- form_name, (long) cu->header.offset.sect_off, objf_name);
+ " .debug_str.dwo section in CU at offset 0x%x [in module %s]"),
+ form_name, to_underlying (cu->header.sect_off), objf_name);
return (const char *) (str_section->buffer + str_offset);
}
complaint (&symfile_complaints,
_("string type expected for attribute %s for "
"DIE at 0x%x in module %s"),
- dwarf_attr_name (name), die->offset.sect_off,
+ dwarf_attr_name (name), to_underlying (die->sect_off),
objfile_name (cu->objfile));
}
return follow_die_ref (die, spec_attr, spec_cu);
}
-/* Free the line_header structure *LH, and any arrays and strings it
- refers to.
- NOTE: This is also used as a "cleanup" function. */
-
-static void
-free_line_header (struct line_header *lh)
-{
- if (lh->standard_opcode_lengths)
- xfree (lh->standard_opcode_lengths);
-
- /* Remember that all the lh->file_names[i].name pointers are
- pointers into debug_line_buffer, and don't need to be freed. */
- if (lh->file_names)
- xfree (lh->file_names);
-
- /* Similarly for the include directory names. */
- if (lh->include_dirs)
- xfree (lh->include_dirs);
-
- xfree (lh);
-}
-
/* Stub for free_line_header to match void * callback types. */
static void
{
struct line_header *lh = (struct line_header *) arg;
- free_line_header (lh);
+ delete lh;
}
-/* Add an entry to LH's include directory table. */
-
-static void
-add_include_dir (struct line_header *lh, const char *include_dir)
+void
+line_header::add_include_dir (const char *include_dir)
{
if (dwarf_line_debug >= 2)
- fprintf_unfiltered (gdb_stdlog, "Adding dir %u: %s\n",
- lh->num_include_dirs + 1, include_dir);
-
- /* Grow the array if necessary. */
- if (lh->include_dirs_size == 0)
- {
- lh->include_dirs_size = 1; /* for testing */
- lh->include_dirs = XNEWVEC (const char *, lh->include_dirs_size);
- }
- else if (lh->num_include_dirs >= lh->include_dirs_size)
- {
- lh->include_dirs_size *= 2;
- lh->include_dirs = XRESIZEVEC (const char *, lh->include_dirs,
- lh->include_dirs_size);
- }
+ fprintf_unfiltered (gdb_stdlog, "Adding dir %zu: %s\n",
+ include_dirs.size () + 1, include_dir);
- lh->include_dirs[lh->num_include_dirs++] = include_dir;
+ include_dirs.push_back (include_dir);
}
-/* Add an entry to LH's file name table. */
-
-static void
-add_file_name (struct line_header *lh,
- const char *name,
- unsigned int dir_index,
- unsigned int mod_time,
- unsigned int length)
+void
+line_header::add_file_name (const char *name,
+ dir_index d_index,
+ unsigned int mod_time,
+ unsigned int length)
{
- struct file_entry *fe;
-
if (dwarf_line_debug >= 2)
fprintf_unfiltered (gdb_stdlog, "Adding file %u: %s\n",
- lh->num_file_names + 1, name);
-
- /* Grow the array if necessary. */
- if (lh->file_names_size == 0)
- {
- lh->file_names_size = 1; /* for testing */
- lh->file_names = XNEWVEC (struct file_entry, lh->file_names_size);
- }
- else if (lh->num_file_names >= lh->file_names_size)
- {
- lh->file_names_size *= 2;
- lh->file_names
- = XRESIZEVEC (struct file_entry, lh->file_names, lh->file_names_size);
- }
+ (unsigned) file_names.size () + 1, name);
- fe = &lh->file_names[lh->num_file_names++];
- fe->name = name;
- fe->dir_index = dir_index;
- fe->mod_time = mod_time;
- fe->length = length;
- fe->included_p = 0;
- fe->symtab = NULL;
+ file_names.emplace_back (name, d_index, mod_time, length);
}
/* A convenience function to find the proper .debug_line section for a CU. */
return section;
}
-/* Forwarding function for read_formatted_entries. */
-
-static void
-add_include_dir_stub (struct line_header *lh, const char *name,
- unsigned int dir_index, unsigned int mod_time,
- unsigned int length)
-{
- add_include_dir (lh, name);
-}
-
/* Read directory or file name entry format, starting with byte of
format count entries, ULEB128 pairs of entry formats, ULEB128 of
entries count and the entries themselves in the described entry
const struct comp_unit_head *cu_header,
void (*callback) (struct line_header *lh,
const char *name,
- unsigned int dir_index,
+ dir_index d_index,
unsigned int mod_time,
unsigned int length))
{
const gdb_byte *format = format_header_data;
struct file_entry fe;
- memset (&fe, 0, sizeof (fe));
-
for (formati = 0; formati < format_count; formati++)
{
- ULONGEST content_type, form;
- const char *string_trash;
- const char **stringp = &string_trash;
- unsigned int uint_trash, *uintp = &uint_trash;
-
- content_type = read_unsigned_leb128 (abfd, format, &bytes_read);
+ ULONGEST content_type = read_unsigned_leb128 (abfd, format, &bytes_read);
format += bytes_read;
- switch (content_type)
- {
- case DW_LNCT_path:
- stringp = &fe.name;
- break;
- case DW_LNCT_directory_index:
- uintp = &fe.dir_index;
- break;
- case DW_LNCT_timestamp:
- uintp = &fe.mod_time;
- break;
- case DW_LNCT_size:
- uintp = &fe.length;
- break;
- case DW_LNCT_MD5:
- break;
- default:
- complaint (&symfile_complaints,
- _("Unknown format content type %s"),
- pulongest (content_type));
- }
- form = read_unsigned_leb128 (abfd, format, &bytes_read);
+ ULONGEST form = read_unsigned_leb128 (abfd, format, &bytes_read);
format += bytes_read;
+
+ gdb::optional<const char *> string;
+ gdb::optional<unsigned int> uint;
+
switch (form)
{
case DW_FORM_string:
- *stringp = read_direct_string (abfd, buf, &bytes_read);
+ string.emplace (read_direct_string (abfd, buf, &bytes_read));
buf += bytes_read;
break;
case DW_FORM_line_strp:
- *stringp = read_indirect_line_string (abfd, buf, cu_header, &bytes_read);
+ string.emplace (read_indirect_line_string (abfd, buf,
+ cu_header,
+ &bytes_read));
buf += bytes_read;
break;
case DW_FORM_data1:
- *uintp = read_1_byte (abfd, buf);
+ uint.emplace (read_1_byte (abfd, buf));
buf += 1;
break;
case DW_FORM_data2:
- *uintp = read_2_bytes (abfd, buf);
+ uint.emplace (read_2_bytes (abfd, buf));
buf += 2;
break;
case DW_FORM_data4:
- *uintp = read_4_bytes (abfd, buf);
+ uint.emplace (read_4_bytes (abfd, buf));
buf += 4;
break;
case DW_FORM_data8:
- *uintp = read_8_bytes (abfd, buf);
+ uint.emplace (read_8_bytes (abfd, buf));
buf += 8;
break;
case DW_FORM_udata:
- *uintp = read_unsigned_leb128 (abfd, buf, &bytes_read);
+ uint.emplace (read_unsigned_leb128 (abfd, buf, &bytes_read));
buf += bytes_read;
break;
current GDB. */
break;
}
+
+ switch (content_type)
+ {
+ case DW_LNCT_path:
+ if (string.has_value ())
+ fe.name = *string;
+ break;
+ case DW_LNCT_directory_index:
+ if (uint.has_value ())
+ fe.d_index = (dir_index) *uint;
+ break;
+ case DW_LNCT_timestamp:
+ if (uint.has_value ())
+ fe.mod_time = *uint;
+ break;
+ case DW_LNCT_size:
+ if (uint.has_value ())
+ fe.length = *uint;
+ break;
+ case DW_LNCT_MD5:
+ break;
+ default:
+ complaint (&symfile_complaints,
+ _("Unknown format content type %s"),
+ pulongest (content_type));
+ }
}
- callback (lh, fe.name, fe.dir_index, fe.mod_time, fe.length);
+ callback (lh, fe.name, fe.d_index, fe.mod_time, fe.length);
}
*bufp = buf;
the returned object point into the dwarf line section buffer,
and must not be freed. */
-static struct line_header *
-dwarf_decode_line_header (unsigned int offset, struct dwarf2_cu *cu)
+static line_header_up
+dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu)
{
- struct cleanup *back_to;
- struct line_header *lh;
const gdb_byte *line_ptr;
unsigned int bytes_read, offset_size;
int i;
/* Make sure that at least there's room for the total_length field.
That could be 12 bytes long, but we're just going to fudge that. */
- if (offset + 4 >= section->size)
+ if (to_underlying (sect_off) + 4 >= section->size)
{
dwarf2_statement_list_fits_in_line_number_section_complaint ();
return 0;
}
- lh = XNEW (struct line_header);
- memset (lh, 0, sizeof (*lh));
- back_to = make_cleanup ((make_cleanup_ftype *) free_line_header,
- (void *) lh);
+ line_header_up lh (new line_header ());
- lh->offset.sect_off = offset;
+ lh->sect_off = sect_off;
lh->offset_in_dwz = cu->per_cu->is_dwz;
- line_ptr = section->buffer + offset;
+ line_ptr = section->buffer + to_underlying (sect_off);
/* Read in the header. */
lh->total_length =
if (line_ptr + lh->total_length > (section->buffer + section->size))
{
dwarf2_statement_list_fits_in_line_number_section_complaint ();
- do_cleanups (back_to);
return 0;
}
lh->statement_program_end = line_ptr + lh->total_length;
line_ptr += 1;
lh->opcode_base = read_1_byte (abfd, line_ptr);
line_ptr += 1;
- lh->standard_opcode_lengths = XNEWVEC (unsigned char, lh->opcode_base);
+ lh->standard_opcode_lengths.reset (new unsigned char[lh->opcode_base]);
lh->standard_opcode_lengths[0] = 1; /* This should never be used anyway. */
for (i = 1; i < lh->opcode_base; ++i)
if (lh->version >= 5)
{
/* Read directory table. */
- read_formatted_entries (abfd, &line_ptr, lh, &cu->header,
- add_include_dir_stub);
+ read_formatted_entries (abfd, &line_ptr, lh.get (), &cu->header,
+ [] (struct line_header *lh, const char *name,
+ dir_index d_index, unsigned int mod_time,
+ unsigned int length)
+ {
+ lh->add_include_dir (name);
+ });
/* Read file name table. */
- read_formatted_entries (abfd, &line_ptr, lh, &cu->header, add_file_name);
+ read_formatted_entries (abfd, &line_ptr, lh.get (), &cu->header,
+ [] (struct line_header *lh, const char *name,
+ dir_index d_index, unsigned int mod_time,
+ unsigned int length)
+ {
+ lh->add_file_name (name, d_index, mod_time, length);
+ });
}
else
{
while ((cur_dir = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
{
line_ptr += bytes_read;
- add_include_dir (lh, cur_dir);
+ lh->add_include_dir (cur_dir);
}
line_ptr += bytes_read;
/* Read file name table. */
while ((cur_file = read_direct_string (abfd, line_ptr, &bytes_read)) != NULL)
{
- unsigned int dir_index, mod_time, length;
+ unsigned int mod_time, length;
+ dir_index d_index;
line_ptr += bytes_read;
- dir_index = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ d_index = (dir_index) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
mod_time = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
length = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
- add_file_name (lh, cur_file, dir_index, mod_time, length);
+ lh->add_file_name (cur_file, d_index, mod_time, length);
}
line_ptr += bytes_read;
}
_("line number info header doesn't "
"fit in `.debug_line' section"));
- discard_cleanups (back_to);
return lh;
}
const struct partial_symtab *pst,
const char *comp_dir)
{
- const struct file_entry fe = lh->file_names [file_index];
+ const file_entry &fe = lh->file_names[file_index];
const char *include_name = fe.name;
const char *include_name_to_compare = include_name;
- const char *dir_name = NULL;
const char *pst_filename;
char *copied_name = NULL;
int file_is_pst;
- if (fe.dir_index && lh->include_dirs != NULL)
- dir_name = lh->include_dirs[fe.dir_index - 1];
+ const char *dir_name = fe.include_dir (lh);
if (!IS_ABSOLUTE_PATH (include_name)
&& (dir_name != NULL || comp_dir != NULL))
/* State machine to track the state of the line number program. */
-typedef struct
+class lnp_state_machine
{
- /* These are part of the standard DWARF line number state machine. */
+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);
+
+ file_entry *current_file ()
+ {
+ /* lh->file_names is 0-based, but the file name numbers in the
+ statement program are 1-based. */
+ return m_line_header->file_name_at (m_file);
+ }
+
+ /* Record the line in the state machine. END_SEQUENCE is true if
+ 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. */
+ void check_line_address (struct dwarf2_cu *cu,
+ const gdb_byte *line_ptr,
+ CORE_ADDR lowpc, CORE_ADDR address);
+
+ void handle_set_discriminator (unsigned int discriminator)
+ {
+ m_discriminator = discriminator;
+ m_line_has_non_zero_discriminator |= discriminator != 0;
+ }
+
+ /* Handle DW_LNE_set_address. */
+ void handle_set_address (CORE_ADDR baseaddr, CORE_ADDR address)
+ {
+ m_op_index = 0;
+ address += baseaddr;
+ m_address = gdbarch_adjust_dwarf2_line (m_gdbarch, address, false);
+ }
+
+ /* Handle DW_LNS_advance_pc. */
+ void handle_advance_pc (CORE_ADDR adjust);
+
+ /* Handle a special opcode. */
+ void handle_special_opcode (unsigned char op_code);
+
+ /* Handle DW_LNS_advance_line. */
+ void handle_advance_line (int line_delta)
+ {
+ advance_line (line_delta);
+ }
+
+ /* Handle DW_LNS_set_file. */
+ void handle_set_file (file_name_index file);
+
+ /* Handle DW_LNS_negate_stmt. */
+ void handle_negate_stmt ()
+ {
+ m_is_stmt = !m_is_stmt;
+ }
+
+ /* Handle DW_LNS_const_add_pc. */
+ void handle_const_add_pc ();
- unsigned char op_index;
- unsigned int file;
- unsigned int line;
- CORE_ADDR address;
- int is_stmt;
- unsigned int discriminator;
+ /* Handle DW_LNS_fixed_advance_pc. */
+ void handle_fixed_advance_pc (CORE_ADDR addr_adj)
+ {
+ m_address += gdbarch_adjust_dwarf2_line (m_gdbarch, addr_adj, true);
+ m_op_index = 0;
+ }
+
+ /* Handle DW_LNS_copy. */
+ void handle_copy ()
+ {
+ record_line (false);
+ m_discriminator = 0;
+ }
+
+ /* Handle DW_LNE_end_sequence. */
+ void handle_end_sequence ()
+ {
+ m_record_line_callback = ::record_line;
+ }
+
+private:
+ /* Advance the line by LINE_DELTA. */
+ void advance_line (int line_delta)
+ {
+ m_line += line_delta;
+
+ if (line_delta != 0)
+ m_line_has_non_zero_discriminator = m_discriminator != 0;
+ }
+
+ gdbarch *m_gdbarch;
+
+ /* True if we're recording lines.
+ Otherwise we're building partial symtabs and are just interested in
+ finding include files mentioned by the line number program. */
+ bool m_record_lines_p;
+
+ /* The line number header. */
+ line_header *m_line_header;
+
+ /* These are part of the standard DWARF line number state machine,
+ and initialized according to the DWARF spec. */
+
+ unsigned char m_op_index = 0;
+ /* The line table index (1-based) of the current file. */
+ file_name_index m_file = (file_name_index) 1;
+ unsigned int m_line = 1;
+
+ /* These are initialized in the constructor. */
+
+ CORE_ADDR m_address;
+ bool m_is_stmt;
+ unsigned int m_discriminator;
/* Additional bits of state we need to track. */
/* The last file that we called dwarf2_start_subfile for.
This is only used for TLLs. */
- unsigned int last_file;
+ unsigned int m_last_file = 0;
/* The last file a line number was recorded for. */
- struct subfile *last_subfile;
+ struct subfile *m_last_subfile = NULL;
/* The function to call to record a line. */
- record_line_ftype *record_line;
+ record_line_ftype *m_record_line_callback = NULL;
/* The last line number that was recorded, used to coalesce
consecutive entries for the same line. This can happen, for
example, when discriminators are present. PR 17276. */
- unsigned int last_line;
- int line_has_non_zero_discriminator;
-} lnp_state_machine;
+ unsigned int m_last_line = 0;
+ bool m_line_has_non_zero_discriminator = false;
+};
-/* There's a lot of static state to pass to dwarf_record_line.
- This keeps it all together. */
+void
+lnp_state_machine::handle_advance_pc (CORE_ADDR adjust)
+{
+ CORE_ADDR addr_adj = (((m_op_index + adjust)
+ / m_line_header->maximum_ops_per_instruction)
+ * m_line_header->minimum_instruction_length);
+ m_address += gdbarch_adjust_dwarf2_line (m_gdbarch, addr_adj, true);
+ m_op_index = ((m_op_index + adjust)
+ % m_line_header->maximum_ops_per_instruction);
+}
-typedef struct
+void
+lnp_state_machine::handle_special_opcode (unsigned char op_code)
{
- /* The gdbarch. */
- struct gdbarch *gdbarch;
+ unsigned char adj_opcode = op_code - m_line_header->opcode_base;
+ CORE_ADDR addr_adj = (((m_op_index
+ + (adj_opcode / m_line_header->line_range))
+ / m_line_header->maximum_ops_per_instruction)
+ * m_line_header->minimum_instruction_length);
+ m_address += gdbarch_adjust_dwarf2_line (m_gdbarch, addr_adj, true);
+ m_op_index = ((m_op_index + (adj_opcode / m_line_header->line_range))
+ % m_line_header->maximum_ops_per_instruction);
- /* The line number header. */
- struct line_header *line_header;
+ int line_delta = (m_line_header->line_base
+ + (adj_opcode % m_line_header->line_range));
+ advance_line (line_delta);
+ record_line (false);
+ m_discriminator = 0;
+}
- /* Non-zero if we're recording lines.
- Otherwise we're building partial symtabs and are just interested in
- finding include files mentioned by the line number program. */
- int record_lines_p;
-} lnp_reader_state;
+void
+lnp_state_machine::handle_set_file (file_name_index file)
+{
+ m_file = file;
+
+ const file_entry *fe = current_file ();
+ if (fe == NULL)
+ dwarf2_debug_line_missing_file_complaint ();
+ else if (m_record_lines_p)
+ {
+ const char *dir = fe->include_dir (m_line_header);
+
+ m_last_subfile = current_subfile;
+ m_line_has_non_zero_discriminator = m_discriminator != 0;
+ dwarf2_start_subfile (fe->name, dir);
+ }
+}
+
+void
+lnp_state_machine::handle_const_add_pc ()
+{
+ CORE_ADDR adjust
+ = (255 - m_line_header->opcode_base) / m_line_header->line_range;
+
+ CORE_ADDR addr_adj
+ = (((m_op_index + adjust)
+ / m_line_header->maximum_ops_per_instruction)
+ * m_line_header->minimum_instruction_length);
+
+ m_address += gdbarch_adjust_dwarf2_line (m_gdbarch, addr_adj, true);
+ m_op_index = ((m_op_index + adjust)
+ % m_line_header->maximum_ops_per_instruction);
+}
/* Ignore this record_line request. */
dwarf_record_line_1 (gdbarch, subfile, 0, address, p_record_line);
}
-/* Record the line in STATE.
- END_SEQUENCE is non-zero if we're processing the end of a sequence. */
-
-static void
-dwarf_record_line (lnp_reader_state *reader, lnp_state_machine *state,
- int end_sequence)
+void
+lnp_state_machine::record_line (bool end_sequence)
{
- const struct line_header *lh = reader->line_header;
- unsigned int file, line, discriminator;
- int is_stmt;
-
- file = state->file;
- line = state->line;
- is_stmt = state->is_stmt;
- discriminator = state->discriminator;
-
if (dwarf_line_debug)
{
fprintf_unfiltered (gdb_stdlog,
"Processing actual line %u: file %u,"
" address %s, is_stmt %u, discrim %u\n",
- line, file,
- paddress (reader->gdbarch, state->address),
- is_stmt, discriminator);
+ m_line, to_underlying (m_file),
+ paddress (m_gdbarch, m_address),
+ m_is_stmt, m_discriminator);
}
- if (file == 0 || file - 1 >= lh->num_file_names)
+ file_entry *fe = current_file ();
+
+ if (fe == NULL)
dwarf2_debug_line_missing_file_complaint ();
/* For now we ignore lines not starting on an instruction boundary.
But not when processing end_sequence for compatibility with the
previous version of the code. */
- else if (state->op_index == 0 || end_sequence)
+ else if (m_op_index == 0 || end_sequence)
{
- lh->file_names[file - 1].included_p = 1;
- if (reader->record_lines_p && is_stmt)
+ fe->included_p = 1;
+ if (m_record_lines_p && m_is_stmt)
{
- if (state->last_subfile != current_subfile || end_sequence)
+ if (m_last_subfile != current_subfile || end_sequence)
{
- dwarf_finish_line (reader->gdbarch, state->last_subfile,
- state->address, state->record_line);
+ dwarf_finish_line (m_gdbarch, m_last_subfile,
+ m_address, m_record_line_callback);
}
if (!end_sequence)
{
- if (dwarf_record_line_p (line, state->last_line,
- state->line_has_non_zero_discriminator,
- state->last_subfile))
+ if (dwarf_record_line_p (m_line, m_last_line,
+ m_line_has_non_zero_discriminator,
+ m_last_subfile))
{
- dwarf_record_line_1 (reader->gdbarch, current_subfile,
- line, state->address,
- state->record_line);
+ dwarf_record_line_1 (m_gdbarch, current_subfile,
+ m_line, m_address,
+ m_record_line_callback);
}
- state->last_subfile = current_subfile;
- state->last_line = line;
+ m_last_subfile = current_subfile;
+ m_last_line = m_line;
}
}
}
}
-/* Initialize STATE for the start of a line number program. */
-
-static void
-init_lnp_state_machine (lnp_state_machine *state,
- const lnp_reader_state *reader)
+lnp_state_machine::lnp_state_machine (gdbarch *arch, line_header *lh,
+ bool record_lines_p)
{
- memset (state, 0, sizeof (*state));
-
- /* Just starting, there is no "last file". */
- state->last_file = 0;
- state->last_subfile = NULL;
+ m_gdbarch = arch;
+ m_record_lines_p = record_lines_p;
+ m_line_header = lh;
- state->record_line = record_line;
+ m_record_line_callback = ::record_line;
- state->last_line = 0;
- state->line_has_non_zero_discriminator = 0;
-
- /* Initialize these according to the DWARF spec. */
- state->op_index = 0;
- state->file = 1;
- state->line = 1;
/* 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
and also record it in case it needs it. This is currently used by MIPS
code, cf. `mips_adjust_dwarf2_line'. */
- state->address = gdbarch_adjust_dwarf2_line (reader->gdbarch, 0, 0);
- state->is_stmt = reader->line_header->default_is_stmt;
- state->discriminator = 0;
+ m_address = gdbarch_adjust_dwarf2_line (arch, 0, 0);
+ m_is_stmt = lh->default_is_stmt;
+ m_discriminator = 0;
}
-/* Check address and if invalid nop-out the rest of the lines in this
- sequence. */
-
-static void
-check_line_address (struct dwarf2_cu *cu, lnp_state_machine *state,
- const gdb_byte *line_ptr,
- CORE_ADDR lowpc, CORE_ADDR address)
+void
+lnp_state_machine::check_line_address (struct dwarf2_cu *cu,
+ const gdb_byte *line_ptr,
+ CORE_ADDR 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
complaint (&symfile_complaints,
_(".debug_line address at offset 0x%lx is 0 [in module %s]"),
line_offset, objfile_name (objfile));
- state->record_line = noop_record_line;
- /* Note: sm.record_line is left as noop_record_line
- until we see DW_LNE_end_sequence. */
+ m_record_line_callback = noop_record_line;
+ /* Note: record_line_callback is left as noop_record_line until
+ we see DW_LNE_end_sequence. */
}
}
struct objfile *objfile = cu->objfile;
bfd *abfd = objfile->obfd;
struct gdbarch *gdbarch = get_objfile_arch (objfile);
- /* Non-zero if we're recording line info (as opposed to building partial
- symtabs). */
- int record_lines_p = !decode_for_pst_p;
- /* A collection of things we need to pass to dwarf_record_line. */
- lnp_reader_state reader_state;
+ /* True if we're recording line info (as opposed to building partial
+ symtabs and just interested in finding include files mentioned by
+ the line number program). */
+ bool record_lines_p = !decode_for_pst_p;
baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
line_ptr = lh->statement_program_start;
line_end = lh->statement_program_end;
- reader_state.gdbarch = gdbarch;
- reader_state.line_header = lh;
- reader_state.record_lines_p = record_lines_p;
-
/* Read the statement sequences until there's nothing left. */
while (line_ptr < line_end)
{
- /* The DWARF line number program state machine. */
- lnp_state_machine state_machine;
- int end_sequence = 0;
+ /* 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);
+ bool end_sequence = false;
- /* Reset the state machine at the start of each sequence. */
- init_lnp_state_machine (&state_machine, &reader_state);
-
- if (record_lines_p && lh->num_file_names >= state_machine.file)
+ if (record_lines_p)
{
- /* Start a subfile for the current file of the state machine. */
- /* lh->include_dirs and lh->file_names are 0-based, but the
- directory and file name numbers in the statement program
- are 1-based. */
- struct file_entry *fe = &lh->file_names[state_machine.file - 1];
- const char *dir = NULL;
-
- if (fe->dir_index && lh->include_dirs != NULL)
- dir = lh->include_dirs[fe->dir_index - 1];
+ /* Start a subfile for the current file of the state
+ machine. */
+ const file_entry *fe = state_machine.current_file ();
- dwarf2_start_subfile (fe->name, dir);
+ if (fe != NULL)
+ dwarf2_start_subfile (fe->name, fe->include_dir (lh));
}
/* Decode the table. */
if (op_code >= lh->opcode_base)
{
/* Special opcode. */
- unsigned char adj_opcode;
- CORE_ADDR addr_adj;
- int line_delta;
-
- adj_opcode = op_code - lh->opcode_base;
- addr_adj = (((state_machine.op_index
- + (adj_opcode / lh->line_range))
- / lh->maximum_ops_per_instruction)
- * lh->minimum_instruction_length);
- state_machine.address
- += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- state_machine.op_index = ((state_machine.op_index
- + (adj_opcode / lh->line_range))
- % lh->maximum_ops_per_instruction);
- line_delta = lh->line_base + (adj_opcode % lh->line_range);
- state_machine.line += line_delta;
- if (line_delta != 0)
- state_machine.line_has_non_zero_discriminator
- = state_machine.discriminator != 0;
-
- dwarf_record_line (&reader_state, &state_machine, 0);
- state_machine.discriminator = 0;
+ state_machine.handle_special_opcode (op_code);
}
else switch (op_code)
{
switch (extended_op)
{
case DW_LNE_end_sequence:
- state_machine.record_line = record_line;
- end_sequence = 1;
+ state_machine.handle_end_sequence ();
+ end_sequence = true;
break;
case DW_LNE_set_address:
{
CORE_ADDR address
= read_address (abfd, line_ptr, cu, &bytes_read);
-
line_ptr += bytes_read;
- check_line_address (cu, &state_machine, line_ptr,
- lowpc, address);
- state_machine.op_index = 0;
- address += baseaddr;
- state_machine.address
- = gdbarch_adjust_dwarf2_line (gdbarch, address, 0);
+
+ state_machine.check_line_address (cu, line_ptr,
+ lowpc, address);
+ state_machine.handle_set_address (baseaddr, address);
}
break;
case DW_LNE_define_file:
{
const char *cur_file;
- unsigned int dir_index, mod_time, length;
+ unsigned int mod_time, length;
+ dir_index dindex;
cur_file = read_direct_string (abfd, line_ptr,
&bytes_read);
line_ptr += bytes_read;
- dir_index =
+ dindex = (dir_index)
read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
mod_time =
length =
read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
line_ptr += bytes_read;
- add_file_name (lh, cur_file, dir_index, mod_time, length);
+ lh->add_file_name (cur_file, dindex, mod_time, length);
}
break;
case DW_LNE_set_discriminator:
- /* The discriminator is not interesting to the debugger;
- just ignore it. We still need to check its value though:
- if there are consecutive entries for the same
- (non-prologue) line we want to coalesce them.
- PR 17276. */
- state_machine.discriminator
- = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
- state_machine.line_has_non_zero_discriminator
- |= state_machine.discriminator != 0;
- line_ptr += bytes_read;
+ {
+ /* The discriminator is not interesting to the
+ debugger; just ignore it. We still need to
+ check its value though:
+ if there are consecutive entries for the same
+ (non-prologue) line we want to coalesce them.
+ PR 17276. */
+ unsigned int discr
+ = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+ line_ptr += bytes_read;
+
+ state_machine.handle_set_discriminator (discr);
+ }
break;
default:
complaint (&symfile_complaints,
}
break;
case DW_LNS_copy:
- dwarf_record_line (&reader_state, &state_machine, 0);
- state_machine.discriminator = 0;
+ state_machine.handle_copy ();
break;
case DW_LNS_advance_pc:
{
CORE_ADDR adjust
= read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
- CORE_ADDR addr_adj;
-
- addr_adj = (((state_machine.op_index + adjust)
- / lh->maximum_ops_per_instruction)
- * lh->minimum_instruction_length);
- state_machine.address
- += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- state_machine.op_index = ((state_machine.op_index + adjust)
- % lh->maximum_ops_per_instruction);
line_ptr += bytes_read;
+
+ state_machine.handle_advance_pc (adjust);
}
break;
case DW_LNS_advance_line:
{
int line_delta
= read_signed_leb128 (abfd, line_ptr, &bytes_read);
-
- state_machine.line += line_delta;
- if (line_delta != 0)
- state_machine.line_has_non_zero_discriminator
- = state_machine.discriminator != 0;
line_ptr += bytes_read;
+
+ state_machine.handle_advance_line (line_delta);
}
break;
case DW_LNS_set_file:
{
- /* The arrays lh->include_dirs and lh->file_names are
- 0-based, but the directory and file name numbers in
- the statement program are 1-based. */
- struct file_entry *fe;
- const char *dir = NULL;
-
- state_machine.file = read_unsigned_leb128 (abfd, line_ptr,
- &bytes_read);
+ file_name_index file
+ = (file_name_index) read_unsigned_leb128 (abfd, line_ptr,
+ &bytes_read);
line_ptr += bytes_read;
- if (state_machine.file == 0
- || state_machine.file - 1 >= lh->num_file_names)
- dwarf2_debug_line_missing_file_complaint ();
- else
- {
- fe = &lh->file_names[state_machine.file - 1];
- if (fe->dir_index && lh->include_dirs != NULL)
- dir = lh->include_dirs[fe->dir_index - 1];
- if (record_lines_p)
- {
- state_machine.last_subfile = current_subfile;
- state_machine.line_has_non_zero_discriminator
- = state_machine.discriminator != 0;
- dwarf2_start_subfile (fe->name, dir);
- }
- }
+
+ state_machine.handle_set_file (file);
}
break;
case DW_LNS_set_column:
line_ptr += bytes_read;
break;
case DW_LNS_negate_stmt:
- state_machine.is_stmt = (!state_machine.is_stmt);
+ state_machine.handle_negate_stmt ();
break;
case DW_LNS_set_basic_block:
break;
instruction length since special opcode 255 would have
scaled the increment. */
case DW_LNS_const_add_pc:
- {
- CORE_ADDR adjust = (255 - lh->opcode_base) / lh->line_range;
- CORE_ADDR addr_adj;
-
- addr_adj = (((state_machine.op_index + adjust)
- / lh->maximum_ops_per_instruction)
- * lh->minimum_instruction_length);
- state_machine.address
- += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- state_machine.op_index = ((state_machine.op_index + adjust)
- % lh->maximum_ops_per_instruction);
- }
+ state_machine.handle_const_add_pc ();
break;
case DW_LNS_fixed_advance_pc:
{
- CORE_ADDR addr_adj;
-
- addr_adj = read_2_bytes (abfd, line_ptr);
- state_machine.address
- += gdbarch_adjust_dwarf2_line (gdbarch, addr_adj, 1);
- state_machine.op_index = 0;
+ CORE_ADDR addr_adj = read_2_bytes (abfd, line_ptr);
line_ptr += 2;
+
+ state_machine.handle_fixed_advance_pc (addr_adj);
}
break;
default:
/* We got a DW_LNE_end_sequence (or we ran off the end of the buffer,
in which case we still finish recording the last line). */
- dwarf_record_line (&reader_state, &state_machine, 1);
+ state_machine.record_line (true);
}
}
/* Now that we're done scanning the Line Header Program, we can
create the psymtab of each included file. */
- for (file_index = 0; file_index < lh->num_file_names; file_index++)
+ for (file_index = 0; file_index < lh->file_names.size (); file_index++)
if (lh->file_names[file_index].included_p == 1)
{
const char *include_name =
struct compunit_symtab *cust = buildsym_compunit_symtab ();
int i;
- for (i = 0; i < lh->num_file_names; i++)
+ for (i = 0; i < lh->file_names.size (); i++)
{
- const char *dir = NULL;
- struct file_entry *fe;
+ file_entry &fe = lh->file_names[i];
- fe = &lh->file_names[i];
- if (fe->dir_index && lh->include_dirs != NULL)
- dir = lh->include_dirs[fe->dir_index - 1];
- dwarf2_start_subfile (fe->name, dir);
+ dwarf2_start_subfile (fe.name, fe.include_dir (lh));
if (current_subfile->symtab == NULL)
{
current_subfile->symtab
= allocate_symtab (cust, current_subfile->name);
}
- fe->symtab = current_subfile->symtab;
+ fe.symtab = current_subfile->symtab;
}
}
}
cu);
if (attr)
{
- int file_index = DW_UNSND (attr);
+ file_name_index file_index = (file_name_index) DW_UNSND (attr);
+ struct file_entry *fe;
+
+ if (cu->line_header != NULL)
+ fe = cu->line_header->file_name_at (file_index);
+ else
+ fe = NULL;
- if (cu->line_header == NULL
- || file_index > cu->line_header->num_file_names)
+ if (fe == NULL)
complaint (&symfile_complaints,
_("file index out of range"));
- else if (file_index > 0)
- {
- struct file_entry *fe;
-
- fe = &cu->line_header->file_names[file_index - 1];
- symbol_set_symtab (sym, fe->symtab);
- }
+ else
+ symbol_set_symtab (sym, fe->symtab);
}
switch (die->tag)
case DW_FORM_block4:
case DW_FORM_block:
case DW_FORM_exprloc:
+ case DW_FORM_data16:
blk = DW_BLOCK (attr);
if (TYPE_LENGTH (type) != blk->size)
dwarf2_const_value_length_mismatch_complaint (name, blk->size,
message = xstrprintf (_("<unknown type in %s, CU 0x%x, DIE 0x%x>"),
objfile_name (objfile),
- cu->header.offset.sect_off,
- die->offset.sect_off);
+ to_underlying (cu->header.sect_off),
+ to_underlying (die->sect_off));
saved = (char *) obstack_copy0 (&objfile->objfile_obstack,
message, strlen (message));
xfree (message);
if (attr->form == DW_FORM_GNU_ref_alt)
{
struct dwarf2_per_cu_data *per_cu;
- sect_offset offset = dwarf2_get_ref_die_offset (attr);
+ sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
- per_cu = dwarf2_find_containing_comp_unit (offset, 1, cu->objfile);
- this_type = get_die_type_at_offset (offset, per_cu);
+ per_cu = dwarf2_find_containing_comp_unit (sect_off, 1, cu->objfile);
+ this_type = get_die_type_at_offset (sect_off, per_cu);
}
else if (attr_form_is_ref (attr))
{
- sect_offset offset = dwarf2_get_ref_die_offset (attr);
+ sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
- this_type = get_die_type_at_offset (offset, cu->per_cu);
+ this_type = get_die_type_at_offset (sect_off, cu->per_cu);
}
else if (attr->form == DW_FORM_ref_sig8)
{
complaint (&symfile_complaints,
_("Dwarf Error: Bad type attribute %s in DIE"
" at 0x%x [in module %s]"),
- dwarf_attr_name (attr->name), die->offset.sect_off,
+ dwarf_attr_name (attr->name), to_underlying (die->sect_off),
objfile_name (objfile));
return build_error_marker_type (cu, die);
}
this_type = read_tag_ptr_to_member_type (die, cu);
break;
case DW_TAG_reference_type:
- this_type = read_tag_reference_type (die, cu);
+ this_type = read_tag_reference_type (die, cu, TYPE_CODE_REF);
+ break;
+ case DW_TAG_rvalue_reference_type:
+ this_type = read_tag_reference_type (die, cu, TYPE_CODE_RVALUE_REF);
break;
case DW_TAG_const_type:
this_type = read_tag_const_type (die, cu);
prefix part in such case. See
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=47510. */
-static char *
+static const char *
anonymous_struct_prefix (struct die_info *die, struct dwarf2_cu *cu)
{
struct attribute *attr;
struct die_info *parent, *spec_die;
struct dwarf2_cu *spec_cu;
struct type *parent_type;
- char *retval;
+ const char *retval;
if (cu->language != language_cplus
&& cu->language != language_fortran && cu->language != language_d
return name;
}
-static char *
+static const char *
dwarf_bool_name (unsigned mybool)
{
if (mybool)
print_spaces (indent, f);
fprintf_unfiltered (f, "Die: %s (abbrev %d, offset 0x%x)\n",
- dwarf_tag_name (die->tag), die->abbrev, die->offset.sect_off);
+ dwarf_tag_name (die->tag), die->abbrev,
+ to_underlying (die->sect_off));
if (die->parent != NULL)
{
print_spaces (indent, f);
fprintf_unfiltered (f, " parent at offset: 0x%x\n",
- die->parent->offset.sect_off);
+ to_underlying (die->parent->sect_off));
}
print_spaces (indent, f);
fprintf_unfiltered (f, "expression: size %s",
pulongest (DW_BLOCK (&die->attrs[i])->size));
break;
+ case DW_FORM_data16:
+ fprintf_unfiltered (f, "constant of 16 bytes");
+ break;
case DW_FORM_ref_addr:
fprintf_unfiltered (f, "ref address: ");
fputs_filtered (hex_string (DW_UNSND (&die->attrs[i])), f);
{
void **slot;
- slot = htab_find_slot_with_hash (cu->die_hash, die, die->offset.sect_off,
+ slot = htab_find_slot_with_hash (cu->die_hash, die,
+ to_underlying (die->sect_off),
INSERT);
*slot = die;
static sect_offset
dwarf2_get_ref_die_offset (const struct attribute *attr)
{
- sect_offset retval = { DW_UNSND (attr) };
-
if (attr_form_is_ref (attr))
- return retval;
+ return (sect_offset) DW_UNSND (attr);
- retval.sect_off = 0;
complaint (&symfile_complaints,
_("unsupported die ref attribute form: '%s'"),
dwarf_form_name (attr->form));
- return retval;
+ return {};
}
/* Return the constant value held by ATTR. Return DEFAULT_VALUE if
return DW_UNSND (attr);
else
{
+ /* For DW_FORM_data16 see attr_form_is_constant. */
complaint (&symfile_complaints,
_("Attribute value is not a constant (%s)"),
dwarf_form_name (attr->form));
Returns NULL if OFFSET is invalid. */
static struct die_info *
-follow_die_offset (sect_offset offset, int offset_in_dwz,
+follow_die_offset (sect_offset sect_off, int offset_in_dwz,
struct dwarf2_cu **ref_cu)
{
struct die_info temp_die;
/* .debug_types CUs cannot reference anything outside their CU.
If they need to, they have to reference a signatured type via
DW_FORM_ref_sig8. */
- if (! offset_in_cu_p (&cu->header, offset))
+ if (!offset_in_cu_p (&cu->header, sect_off))
return NULL;
}
else if (offset_in_dwz != cu->per_cu->is_dwz
- || ! offset_in_cu_p (&cu->header, offset))
+ || !offset_in_cu_p (&cu->header, sect_off))
{
struct dwarf2_per_cu_data *per_cu;
- per_cu = dwarf2_find_containing_comp_unit (offset, offset_in_dwz,
+ per_cu = dwarf2_find_containing_comp_unit (sect_off, offset_in_dwz,
cu->objfile);
/* If necessary, add it to the queue and load its DIEs. */
}
*ref_cu = target_cu;
- temp_die.offset = offset;
+ temp_die.sect_off = sect_off;
return (struct die_info *) htab_find_with_hash (target_cu->die_hash,
- &temp_die, offset.sect_off);
+ &temp_die,
+ to_underlying (sect_off));
}
/* Follow reference attribute ATTR of SRC_DIE.
follow_die_ref (struct die_info *src_die, const struct attribute *attr,
struct dwarf2_cu **ref_cu)
{
- sect_offset offset = dwarf2_get_ref_die_offset (attr);
+ sect_offset sect_off = dwarf2_get_ref_die_offset (attr);
struct dwarf2_cu *cu = *ref_cu;
struct die_info *die;
- die = follow_die_offset (offset,
+ die = follow_die_offset (sect_off,
(attr->form == DW_FORM_GNU_ref_alt
|| cu->per_cu->is_dwz),
ref_cu);
if (!die)
error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE "
"at 0x%x [in module %s]"),
- offset.sect_off, src_die->offset.sect_off,
+ to_underlying (sect_off), to_underlying (src_die->sect_off),
objfile_name (cu->objfile));
return die;
}
-/* Return DWARF block referenced by DW_AT_location of DIE at OFFSET at PER_CU.
+/* Return DWARF block referenced by DW_AT_location of DIE at SECT_OFF at PER_CU.
Returned value is intended for DW_OP_call*. Returned
dwarf2_locexpr_baton->data has lifetime of PER_CU->OBJFILE. */
struct dwarf2_locexpr_baton
-dwarf2_fetch_die_loc_sect_off (sect_offset offset,
+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)
/* We shouldn't get here for a dummy CU, but don't crash on the user.
Instead just throw an error, not much else we can do. */
error (_("Dwarf Error: Dummy CU at 0x%x referenced in module %s"),
- offset.sect_off, objfile_name (per_cu->objfile));
+ to_underlying (sect_off), objfile_name (per_cu->objfile));
}
- die = follow_die_offset (offset, per_cu->is_dwz, &cu);
+ die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
if (!die)
error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
- offset.sect_off, objfile_name (per_cu->objfile));
+ to_underlying (sect_off), objfile_name (per_cu->objfile));
attr = dwarf2_attr (die, DW_AT_location, cu);
if (!attr)
if (!attr_form_is_block (attr))
error (_("Dwarf Error: DIE at 0x%x referenced in module %s "
"is neither DW_FORM_block* nor DW_FORM_exprloc"),
- offset.sect_off, objfile_name (per_cu->objfile));
+ to_underlying (sect_off), objfile_name (per_cu->objfile));
retval.data = DW_BLOCK (attr)->data;
retval.size = DW_BLOCK (attr)->size;
CORE_ADDR (*get_frame_pc) (void *baton),
void *baton)
{
- sect_offset offset = { per_cu->offset.sect_off + offset_in_cu.cu_off };
+ sect_offset sect_off = per_cu->sect_off + to_underlying (offset_in_cu);
- return dwarf2_fetch_die_loc_sect_off (offset, per_cu, get_frame_pc, baton);
+ return dwarf2_fetch_die_loc_sect_off (sect_off, per_cu, get_frame_pc, baton);
}
/* Write a constant of a given type as target-ordered bytes into
does not have a DW_AT_const_value, return NULL. */
const gdb_byte *
-dwarf2_fetch_constant_bytes (sect_offset offset,
+dwarf2_fetch_constant_bytes (sect_offset sect_off,
struct dwarf2_per_cu_data *per_cu,
struct obstack *obstack,
LONGEST *len)
/* We shouldn't get here for a dummy CU, but don't crash on the user.
Instead just throw an error, not much else we can do. */
error (_("Dwarf Error: Dummy CU at 0x%x referenced in module %s"),
- offset.sect_off, objfile_name (per_cu->objfile));
+ to_underlying (sect_off), objfile_name (per_cu->objfile));
}
- die = follow_die_offset (offset, per_cu->is_dwz, &cu);
+ die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
if (!die)
error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"),
- offset.sect_off, objfile_name (per_cu->objfile));
+ to_underlying (sect_off), objfile_name (per_cu->objfile));
attr = dwarf2_attr (die, DW_AT_const_value, cu);
case DW_FORM_block4:
case DW_FORM_block:
case DW_FORM_exprloc:
+ case DW_FORM_data16:
result = DW_BLOCK (attr)->data;
*len = DW_BLOCK (attr)->size;
break;
return result;
}
+/* Return the type of the die at OFFSET in PER_CU. Return NULL if no
+ valid type for this die is found. */
+
+struct type *
+dwarf2_fetch_die_type_sect_off (sect_offset sect_off,
+ struct dwarf2_per_cu_data *per_cu)
+{
+ struct dwarf2_cu *cu;
+ struct die_info *die;
+
+ dw2_setup (per_cu->objfile);
+
+ if (per_cu->cu == NULL)
+ load_cu (per_cu);
+ cu = per_cu->cu;
+ if (!cu)
+ return NULL;
+
+ die = follow_die_offset (sect_off, per_cu->is_dwz, &cu);
+ if (!die)
+ return NULL;
+
+ return die_type (die, cu);
+}
+
/* Return the type of the DIE at DIE_OFFSET in the CU named by
PER_CU. */
dwarf2_get_die_type (cu_offset die_offset,
struct dwarf2_per_cu_data *per_cu)
{
- sect_offset die_offset_sect;
-
dw2_setup (per_cu->objfile);
- die_offset_sect.sect_off = per_cu->offset.sect_off + die_offset.cu_off;
+ sect_offset die_offset_sect = per_cu->sect_off + to_underlying (die_offset);
return get_die_type_at_offset (die_offset_sect, per_cu);
}
sig_cu = sig_type->per_cu.cu;
gdb_assert (sig_cu != NULL);
- gdb_assert (sig_type->type_offset_in_section.sect_off != 0);
- temp_die.offset = sig_type->type_offset_in_section;
+ gdb_assert (to_underlying (sig_type->type_offset_in_section) != 0);
+ temp_die.sect_off = sig_type->type_offset_in_section;
die = (struct die_info *) htab_find_with_hash (sig_cu->die_hash, &temp_die,
- temp_die.offset.sect_off);
+ to_underlying (temp_die.sect_off));
if (die)
{
/* For .gdb_index version 7 keep track of included TUs.
{
error (_("Dwarf Error: Cannot find signatured DIE %s referenced"
" from DIE at 0x%x [in module %s]"),
- hex_string (signature), src_die->offset.sect_off,
+ hex_string (signature), to_underlying (src_die->sect_off),
objfile_name ((*ref_cu)->objfile));
}
dump_die_for_error (src_die);
error (_("Dwarf Error: Problem reading signatured DIE %s referenced"
" from DIE at 0x%x [in module %s]"),
- hex_string (signature), src_die->offset.sect_off,
+ hex_string (signature), to_underlying (src_die->sect_off),
objfile_name ((*ref_cu)->objfile));
}
complaint (&symfile_complaints,
_("Dwarf Error: Cannot find signatured DIE %s referenced"
" from DIE at 0x%x [in module %s]"),
- hex_string (signature), die->offset.sect_off,
+ hex_string (signature), to_underlying (die->sect_off),
objfile_name (dwarf2_per_objfile->objfile));
return build_error_marker_type (cu, die);
}
complaint (&symfile_complaints,
_("Dwarf Error: Cannot build signatured type %s"
" referenced from DIE at 0x%x [in module %s]"),
- hex_string (signature), die->offset.sect_off,
+ hex_string (signature), to_underlying (die->sect_off),
objfile_name (dwarf2_per_objfile->objfile));
type = build_error_marker_type (cu, die);
}
complaint (&symfile_complaints,
_("Dwarf Error: Problem reading signatured DIE %s referenced"
" from DIE at 0x%x [in module %s]"),
- hex_string (signature), die->offset.sect_off,
+ hex_string (signature), to_underlying (die->sect_off),
objfile_name (dwarf2_per_objfile->objfile));
type = build_error_marker_type (cu, die);
}
complaint (&symfile_complaints,
_("Dwarf Error: DW_AT_signature has bad form %s in DIE"
" at 0x%x [in module %s]"),
- dwarf_form_name (attr->form), die->offset.sect_off,
+ dwarf_form_name (attr->form), to_underlying (die->sect_off),
objfile_name (dwarf2_per_objfile->objfile));
return build_error_marker_type (cu, die);
}
{
/* Is the file number a valid index into the line header's file name
table? Remember that file numbers start with one, not zero. */
- if (1 <= file && file <= lh->num_file_names)
+ if (1 <= file && file <= lh->file_names.size ())
{
- struct file_entry *fe = &lh->file_names[file - 1];
+ const file_entry &fe = lh->file_names[file - 1];
- if (IS_ABSOLUTE_PATH (fe->name) || fe->dir_index == 0
- || lh->include_dirs == NULL)
- return xstrdup (fe->name);
- return concat (lh->include_dirs[fe->dir_index - 1], SLASH_STRING,
- fe->name, (char *) NULL);
+ if (!IS_ABSOLUTE_PATH (fe.name))
+ {
+ const char *dir = fe.include_dir (lh);
+ if (dir != NULL)
+ return concat (dir, SLASH_STRING, fe.name, (char *) NULL);
+ }
+ return xstrdup (fe.name);
}
else
{
{
/* Is the file number a valid index into the line header's file name
table? Remember that file numbers start with one, not zero. */
- if (1 <= file && file <= lh->num_file_names)
+ if (1 <= file && file <= lh->file_names.size ())
{
char *relative = file_file_name (file, lh);
bytes += 8;
break;
+ case DW_FORM_data16:
+ bytes += 16;
+ break;
+
case DW_FORM_string:
read_direct_string (abfd, bytes, &bytes_read);
bytes += bytes_read;
(lineptr, loclistptr, macptr or rangelistptr). The DWARF spec says
that, if an attribute's can be either a constant or one of the
section offset classes, DW_FORM_data4 and DW_FORM_data8 should be
- taken as section offsets, not constants. */
+ taken as section offsets, not constants.
+
+ DW_FORM_data16 is not considered as dwarf2_get_attr_constant_value
+ cannot handle that. */
static int
attr_form_is_constant (const struct attribute *attr)
if (per_cu->cu)
return &per_cu->cu->header;
- info_ptr = per_cu->section->buffer + per_cu->offset.sect_off;
+ info_ptr = per_cu->section->buffer + to_underlying (per_cu->sect_off);
memset (cu_headerp, 0, sizeof (*cu_headerp));
read_comp_unit_head (cu_headerp, info_ptr, per_cu->section,
the DIE at OFFSET. Raises an error on failure. */
static struct dwarf2_per_cu_data *
-dwarf2_find_containing_comp_unit (sect_offset offset,
+dwarf2_find_containing_comp_unit (sect_offset sect_off,
unsigned int offset_in_dwz,
struct objfile *objfile)
{
int mid = low + (high - low) / 2;
mid_cu = dwarf2_per_objfile->all_comp_units[mid];
- cu_off = &mid_cu->offset;
+ 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 >= offset.sect_off))
+ || (mid_cu->is_dwz == offset_in_dwz && *cu_off >= 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->offset;
- if (this_cu->is_dwz != offset_in_dwz || cu_off->sect_off > offset.sect_off)
+ cu_off = &this_cu->sect_off;
+ if (this_cu->is_dwz != offset_in_dwz || *cu_off > sect_off)
{
if (low == 0 || this_cu->is_dwz != offset_in_dwz)
error (_("Dwarf Error: could not find partial DIE containing "
- "offset 0x%lx [in module %s]"),
- (long) offset.sect_off, bfd_get_filename (objfile->obfd));
+ "offset 0x%x [in module %s]"),
+ to_underlying (sect_off), bfd_get_filename (objfile->obfd));
- gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->offset.sect_off
- <= offset.sect_off);
+ gdb_assert (dwarf2_per_objfile->all_comp_units[low-1]->sect_off
+ <= sect_off);
return dwarf2_per_objfile->all_comp_units[low-1];
}
else
{
this_cu = dwarf2_per_objfile->all_comp_units[low];
if (low == dwarf2_per_objfile->n_comp_units - 1
- && offset.sect_off >= this_cu->offset.sect_off + this_cu->length)
- error (_("invalid dwarf2 offset %u"), offset.sect_off);
- gdb_assert (offset.sect_off < this_cu->offset.sect_off + this_cu->length);
+ && sect_off >= this_cu->sect_off + this_cu->length)
+ error (_("invalid dwarf2 offset %u"), to_underlying (sect_off));
+ gdb_assert (sect_off < this_cu->sect_off + this_cu->length);
return this_cu;
}
}
struct dwarf2_per_cu_offset_and_type
{
const struct dwarf2_per_cu_data *per_cu;
- sect_offset offset;
+ sect_offset sect_off;
struct type *type;
};
const struct dwarf2_per_cu_offset_and_type *ofs
= (const struct dwarf2_per_cu_offset_and_type *) item;
- return (uintptr_t) ofs->per_cu + ofs->offset.sect_off;
+ return (uintptr_t) ofs->per_cu + to_underlying (ofs->sect_off);
}
/* Equality function for a dwarf2_per_cu_offset_and_type. */
= (const struct dwarf2_per_cu_offset_and_type *) item_rhs;
return (ofs_lhs->per_cu == ofs_rhs->per_cu
- && ofs_lhs->offset.sect_off == ofs_rhs->offset.sect_off);
+ && ofs_lhs->sect_off == ofs_rhs->sect_off);
}
/* Set the type associated with DIE to TYPE. Save it in CU's hash
else if (attr != NULL)
{
complaint (&symfile_complaints,
- _("DW_AT_allocated has the wrong form (%s) at DIE 0x%x"),
- (attr != NULL ? dwarf_form_name (attr->form) : "n/a"),
- die->offset.sect_off);
+ _("DW_AT_allocated has the wrong form (%s) at DIE 0x%x"),
+ (attr != NULL ? dwarf_form_name (attr->form) : "n/a"),
+ to_underlying (die->sect_off));
}
/* Read DW_AT_associated and set in type. */
else if (attr != NULL)
{
complaint (&symfile_complaints,
- _("DW_AT_associated has the wrong form (%s) at DIE 0x%x"),
- (attr != NULL ? dwarf_form_name (attr->form) : "n/a"),
- die->offset.sect_off);
+ _("DW_AT_associated has the wrong form (%s) at DIE 0x%x"),
+ (attr != NULL ? dwarf_form_name (attr->form) : "n/a"),
+ to_underlying (die->sect_off));
}
/* Read DW_AT_data_location and set in type. */
}
ofs.per_cu = cu->per_cu;
- ofs.offset = die->offset;
+ ofs.sect_off = die->sect_off;
ofs.type = type;
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 0x%x has type already set"),
- die->offset.sect_off);
+ to_underlying (die->sect_off));
*slot = XOBNEW (&objfile->objfile_obstack,
struct dwarf2_per_cu_offset_and_type);
**slot = ofs;
return type;
}
-/* Look up the type for the die at OFFSET in PER_CU in die_type_hash,
+/* Look up the type for the die at SECT_OFF in PER_CU in die_type_hash,
or return NULL if the die does not have a saved type. */
static struct type *
-get_die_type_at_offset (sect_offset offset,
+get_die_type_at_offset (sect_offset sect_off,
struct dwarf2_per_cu_data *per_cu)
{
struct dwarf2_per_cu_offset_and_type *slot, ofs;
return NULL;
ofs.per_cu = per_cu;
- ofs.offset = offset;
+ ofs.sect_off = sect_off;
slot = ((struct dwarf2_per_cu_offset_and_type *)
htab_find (dwarf2_per_objfile->die_type_hash, &ofs));
if (slot)
static struct type *
get_die_type (struct die_info *die, struct dwarf2_cu *cu)
{
- return get_die_type_at_offset (die->offset, cu->per_cu);
+ return get_die_type_at_offset (die->sect_off, cu->per_cu);
}
/* Add a dependence relationship from CU to REF_PER_CU. */
const struct partial_die_info *part_die
= (const struct partial_die_info *) item;
- return part_die->offset.sect_off;
+ return to_underlying (part_die->sect_off);
}
/* Trivial comparison function for partial_die_info structures: two DIEs
const struct partial_die_info *part_die_rhs
= (const struct partial_die_info *) item_rhs;
- return part_die_lhs->offset.sect_off == part_die_rhs->offset.sect_off;
+ return part_die_lhs->sect_off == part_die_rhs->sect_off;
}
static struct cmd_list_element *set_dwarf_cmdlist;
1);
store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE,
- entry->per_cu.offset.sect_off);
+ to_underlying (entry->per_cu.sect_off));
obstack_grow (info->types_list, val, 8);
store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE,
- entry->type_offset_in_tu.cu_off);
+ to_underlying (entry->type_offset_in_tu));
obstack_grow (info->types_list, val, 8);
store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, entry->signature);
obstack_grow (info->types_list, val, 8);
*slot = map;
store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE,
- per_cu->offset.sect_off);
+ to_underlying (per_cu->sect_off));
obstack_grow (&cu_list, val, 8);
store_unsigned_integer (val, 8, BFD_ENDIAN_LITTLE, per_cu->length);
obstack_grow (&cu_list, val, 8);